Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.xcsp.common.Utilities Maven / Gradle / Ivy
/*
* Copyright (c) 2016 XCSP3 Team ([email protected] )
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.xcsp.common;
import static org.xcsp.common.Constants.BIG_MAX_SAFE_LONG;
import static org.xcsp.common.Constants.BIG_MIN_SAFE_LONG;
import static org.xcsp.common.Constants.MINUS_INFINITY;
import static org.xcsp.common.Constants.MINUS_INFINITY_STRING;
import static org.xcsp.common.Constants.PLUS_INFINITY;
import static org.xcsp.common.Constants.PLUS_INFINITY_STRING;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xcsp.common.Types.TypeChild;
import org.xcsp.common.predicates.XNode;
import org.xcsp.common.predicates.XNodeLeaf;
/**
* A class with some utility (static) methods.
*
* @author Christophe Lecoutre
*/
public class Utilities {
public static final Comparator lexComparatorInt = (t1, t2) -> {
for (int i = 0; i < t1.length; i++)
if (t1[i] < t2[i])
return -1;
else if (t1[i] > t2[i])
return +1;
return 0;
};
public static final Comparator lexComparatorString = (t1, t2) -> {
for (int i = 0; i < t1.length; i++) {
int res = t1[i].compareTo(t2[i]);
if (res != 0)
return res;
}
return 0;
};
public static T[] buildArray(Class> cl, int length) {
return (T[]) Array.newInstance(cl, length);
}
public static T[][] buildArray(Class> cl, int length1, int length2) {
return (T[][]) Array.newInstance(cl, length1, length2);
}
public static Object firstNonNull(Object array) {
if (array != null && array.getClass().isArray())
return IntStream.range(0, Array.getLength(array)).mapToObj(i -> firstNonNull(Array.get(array, i))).filter(o -> o != null).findFirst().orElse(null);
return array;
}
/**
* Builds a one-dimensional array of T with the objects of the specified list. If the list does not contain any object other than null, null is
* returned.
*/
public static T[] convert(Collection list) {
Object firstObject = list.stream().filter(o -> o != null).findFirst().orElse(null);
if (firstObject == null)
return null;
T[] ts = buildArray(firstObject.getClass(), list.size());
int i = 0;
for (T x : list)
ts[i++] = x;
return ts;
}
/**
* Builds a one-dimensional array of T with the objects of the specified stream. If the stream does not contain any object other than null, null
* is returned.
*/
public static T[] convert(Stream stream) {
return convert(stream.collect(Collectors.toList()));
}
public static T[] convert(Object[] t) {
Object firstObject = Stream.of(t).filter(o -> o != null).findFirst().orElse(null);
Class> clazz = firstObject == null ? null
: Stream.of(t).noneMatch(o -> o != null && o.getClass() != firstObject.getClass()) ? firstObject.getClass() : null;
if (clazz == null)
return null; // null is returned if the array has only null or elements of several types
T[] ts = buildArray(firstObject.getClass(), t.length);
int i = 0;
for (Object x : t)
ts[i++] = (T) x;
return ts;
}
public static T[][] convert(Object[][] t) {
control(isRegular(t), " pb");
// other controls to add
T[][] m = buildArray(t[0][0].getClass(), t.length, t[0].length);
for (int i = 0; i < t.length; i++)
for (int j = 0; j < t[i].length; j++)
m[i][j] = (T) t[i][j];
return m;
}
public static Object[] specificArrayFrom(List list) {
Object firstObject = list.stream().filter(o -> o != null).findFirst().orElse(null);
Class> clazz = firstObject == null ? null
: list.stream().noneMatch(o -> o != null && o.getClass() != firstObject.getClass()) ? firstObject.getClass() : null;
return clazz == null ? list.toArray() : list.toArray((Object[]) Array.newInstance(clazz, list.size()));
}
public static Object[][] specificArray2DFrom(List list) {
Class> clazz = list.stream().noneMatch(o -> o.getClass() != list.get(0).getClass()) ? list.get(0).getClass() : null;
return clazz == null ? list.toArray(new Object[0][]) : list.toArray((Object[][]) Array.newInstance(clazz, list.size()));
}
private static List collectRec(Class clazz, List list, Object src) {
if (src != null) {
if (src instanceof Collection)
collectRec(clazz, list, ((Collection>) src).stream());
else if (src instanceof Stream)
((Stream>) src).forEach(o -> collectRec(clazz, list, o));
else if (src.getClass().isArray())
IntStream.range(0, Array.getLength(src)).forEach(i -> collectRec(clazz, list, Array.get(src, i)));
else if (clazz.isAssignableFrom(src.getClass()))
list.add(clazz.cast(src));
else if (src instanceof IntStream)
((IntStream) src).forEach(o -> collectRec(clazz, list, o));
else if (src.getClass() == Range.class)
collectRec(clazz, list, ((Range) src).toArray()); // in order to deal with clazz being Integer.class
}
return list;
}
/**
* Returns a 1-dimensional array of objects of the specified type after collecting any object of this type being present in the specified objects.
* The specified objects can be stream (and IntStream), collections and arrays. The collecting process is made recursively.
*
* @param clazz
* the class of the objects to be collected
* @param src
* the objects where to collect the objects
* @return a 1-dimensional array of objects of the specified type after collecting any object of this type being present in the specified objects
*/
public static T[] collect(Class clazz, Object... src) {
List list = new ArrayList<>();
Stream.of(src).forEach(o -> collectRec(clazz, list, o));
return convert(list.stream().collect(Collectors.toList()));
}
/**
* Builds a 1-dimensional array of integers (int) from the specified sequence of parameters. Each parameter can be an integer, a Range, an array,
* a stream, a collection, etc. All integers are collected and concatenated to form a 1-dimensional array.
*
* @param src
* the objects where to collect the integers
* @return a 1-dimensional array of integers after collecting any encountered integer in the specified objects
*/
public static int[] collectInt(Object... src) {
Integer[] t = collect(Integer.class, src);
return t == null ? new int[0] : Stream.of(t).filter(i -> i != null).mapToInt(i -> i).toArray();
}
public static boolean isNumeric(String token) {
return token.matches("-?\\d+(\\.\\d+)?"); // match a number with optional '-' and decimal.
}
public static boolean isNumericInterval(String token) {
return token.matches("-?\\d+\\.\\.-?\\d+");
}
public static int[] splitToInts(String s, String regex) {
return Arrays.stream(s.trim().split(regex)).filter(tok -> tok.length() > 0).mapToInt(tok -> Integer.parseInt(tok)).toArray();
}
public static int[] splitToInts(String s) {
return splitToInts(s, Constants.REG_WS);
}
public static int splitToInt(String s, String regex) {
int[] t = splitToInts(s, regex);
control(t.length > 0, "Not possible to extract an int from this call");
return t[0];
}
public static int[] wordAsIntArray(String s) {
assert s.chars().allMatch(c -> ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'));
int[] t = new int[s.length()]; // We don't use streams here for efficiency reasons (when dealing with large sets of words)
for (int i = 0; i < s.length(); i++)
t[i] = s.charAt(i) - (Character.isUpperCase(s.charAt(i)) ? 'A' : 'a');
return t;
}
public static Boolean toBoolean(String s) {
s = s.toLowerCase();
if (s.equals("yes") || s.equals("y") || s.equals("true") || s.equals("t") || s.equals("1"))
return Boolean.TRUE;
if (s.equals("no") || s.equals("n") || s.equals("false") || s.equals("f") || s.equals("0"))
return Boolean.FALSE;
return null;
}
public static boolean isInteger(String token) {
try {
Integer.parseInt(token);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static Integer toInteger(String token, Predicate p) {
try {
Integer i = Integer.parseInt(token);
Utilities.control(p == null || p.test(i), "Value " + i + " not accepted by " + p);
return i;
} catch (RuntimeException e) {
return null;
}
}
public static Integer toInteger(String token) {
return toInteger(token, null);
}
public static Double toDouble(String token, Predicate p) {
try {
Double d = Double.parseDouble(token);
Utilities.control(p == null || p.test(d), "Value " + d + " not accepted by " + p);
return d;
} catch (RuntimeException e) {
return null;
}
}
public static double toDouble(String token) {
return toDouble(token, null);
}
public static BigInteger powerBig(long a, int b) {
return BigInteger.valueOf(a).pow(b);
}
public static int power(long a, int b) {
return powerBig(a, b).intValueExact();
}
private static BigInteger recursiveFactorial(long start, long n) {
long i;
if (n <= 16) {
BigInteger r = BigInteger.valueOf(start);
for (i = start + 1; i < start + n; i++)
r = r.multiply(BigInteger.valueOf(i));
return r;
}
i = n / 2;
return recursiveFactorial(start, i).multiply(recursiveFactorial(start + i, n - i));
}
public static BigInteger factorialBig(int n) {
return recursiveFactorial(1, n);
}
public static int factorial(int n) {
return factorialBig(n).intValueExact();
}
public static BigInteger binomialBig(int n, int k) {
if (k < 0 || n < k)
return BigInteger.ZERO;
if (k > n - k)
k = n - k;
BigInteger i = BigInteger.ONE;
for (int v = 0; v < k; v++)
i = i.multiply(BigInteger.valueOf(n - v)).divide(BigInteger.valueOf(v + 1));
return i;
}
public static int binomial(int n, int k) {
return binomialBig(n, k).intValueExact();
}
public static BigInteger nArrangementsFor(int[] nValues) {
return IntStream.of(nValues).mapToObj(v -> BigInteger.valueOf(v)).reduce(BigInteger.ONE, (acc, v) -> acc.multiply(v));
}
public static boolean contains(int[] tab, int v, int from, int to) {
return IntStream.rangeClosed(from, to).anyMatch(i -> tab[i] == v);
}
public static boolean contains(int[] tab, int v) {
return contains(tab, v, 0, tab.length - 1);
}
public static int indexOf(String s, String... t) {
return IntStream.range(0, t.length).filter(i -> t[i].equals(s)).findFirst().orElse(-1);
}
public static int indexOf(String s, List list) {
return IntStream.range(0, list.size()).filter(i -> list.get(i).equals(s)).findFirst().orElse(-1);
}
public static int indexOf(int value, int[] t) {
for (int i = 0; i < t.length; i++)
if (value == t[i])
return i;
return -1;
// return IntStream.range(0, t.length).filter(i -> t[i] == value).findFirst().orElse(-1);
}
public static int indexOf(Object value, Object[] t) {
return IntStream.range(0, t.length).filter(i -> t[i] == value).findFirst().orElse(-1);
}
/**
* Returns true is the array is regular and matches exactly the specified size. For example, if size is [5,4] then the specified array must be a
* 2-dimensional array of 5 x 4 squares.
*/
public static boolean hasSize(Object array, int... size) {
boolean b1 = array != null && array.getClass().isArray(), b2 = size.length > 0;
if (!b1 && !b2)
return true;
if (b1 && !b2 || !b1 && b2 || Array.getLength(array) != size[0])
return false;
return IntStream.range(0, size[0]).noneMatch(i -> !hasSize(Array.get(array, i), Arrays.stream(size).skip(1).toArray()));
}
/**
* Returns true is the array is regular, that is to say has the form of a rectangle for a 2-dimensional array, a cube for a 3-dimensional array...
* For example, if the specified array is a 2-dimensional array of 5 x 4 squares, then it is regular. But it has 3 squares for the first row, and
* 4 squares for the second row, then it is not regular.
*/
public static boolean isRegular(Object array) {
List list = new ArrayList<>();
for (Object a = array; a != null && a.getClass().isArray(); a = Array.getLength(a) == 0 ? null : Array.get(a, 0))
list.add(Array.getLength(a));
return hasSize(array, list.stream().mapToInt(i -> i).toArray());
}
/**
* Method that controls that the specified condition is verified. If it is not the case, a message is displayed and the program is stopped.
*/
public static Object control(boolean condition, String message) {
if (!condition) {
System.out.println("\n\nFatal Error: " + message);
throw new RuntimeException();
// System.exit(1);
}
return null;
}
public static Object exit(String message) {
return control(false, message);
}
/**
* Checks if the specified {@code Runnable} object raises an {@code ArithmeticException} object, when run. The value {@code true} is returned iff
* no such exception is raised.
*
* @param r
* a {@code Runnable} object to be run
* @return {@code true} iff no {@code ArithmeticException} is raised when running the specified code
*/
public static boolean checkSafeArithmeticOperation(Runnable r) {
try {
r.run();
return true;
} catch (ArithmeticException e) {
return false;
}
}
/**
* Method that parses the specified string as a long integer. If the value is too small or too big, an exception is raised. The specified boolean
* allows us to indicate if some special values (such as +infinity) must be checked.
*/
public static Long safeLong(String s, boolean checkSpecialValues) {
if (checkSpecialValues) {
if (s.equals(PLUS_INFINITY_STRING))
return PLUS_INFINITY;
if (s.equals(MINUS_INFINITY_STRING))
return MINUS_INFINITY;
}
if (s.length() > 18) { // 18 because MAX_LONG and MIN_LONG are composed of at most 19 characters
BigInteger big = new BigInteger(s);
control(big.compareTo(BIG_MIN_SAFE_LONG) >= 0 && big.compareTo(BIG_MAX_SAFE_LONG) <= 0, "Too small or big value for this parser : " + s);
return big.longValue();
} else
return Long.parseLong(s);
}
/** Method that parses the specified string as a long integer. If the value is too small or too big, an exception is raised. */
public static Long safeLong(String s) {
return safeLong(s, false);
}
public static boolean isSafeInt(long l, boolean useMargin) {
return (useMargin ? Constants.MIN_SAFE_INT : Integer.MIN_VALUE) <= l && l <= (useMargin ? Constants.MAX_SAFE_INT : Integer.MAX_VALUE);
}
public static boolean isSafeInt(long l) {
return isSafeInt(l, true);
}
/**
* Converts the specified long number to int if it is safe to do it. When the specified boolean is set to true, we control that it is safe
* according to the constants MIN_SAFE_INT and MAX_SAFE_INT.
*/
public static int safeInt(Long l, boolean useMargin) {
control(isSafeInt(l, useMargin), "Too big integer value " + l);
return l.intValue();
// return safeLong2Int(number.longValue(), useMargin);
}
/**
* Converts the specified long to int if it is safe to do it. We control that it is safe according to the constants MIN_SAFE_INT and MAX_SAFE_INT.
*/
public static int safeInt(Long l) {
return safeInt(l, true);
}
/**
* Converts the specified long to int if it is safe to do it. Note that VAL_MINUS_INFINITY will be translated to VAL_MINUS_INFINITY_INT and that
* VAL_PLUS_INFINITY will be translated to VAL_PLUS_INFINITY_INT . We control that it is safe according to the constants MIN_SAFE_INT and
* MAX_SAFE_INT.
*/
public static int safeIntWhileHandlingInfinity(long l) {
if (l == Constants.MINUS_INFINITY)
return Constants.MINUS_INFINITY_INT;
if (l == Constants.PLUS_INFINITY)
return Constants.PLUS_INFINITY_INT;
return safeInt(l);
}
public static T[] swap(T[] t, int i, int j) {
T tmp = t[i];
t[i] = t[j];
t[j] = tmp;
return t;
}
/** Method that joins the elements of the specified array, using the specified delimiter to separate them. */
public static String join(Object array, String delimiter) {
StringBuilder sb = new StringBuilder();
for (int i = 0, length = Array.getLength(array); i < length; i++) {
Object item = Array.get(array, i);
if (item != null && item.getClass().isArray())
sb.append("[").append(join(item, delimiter)).append("]");
else
sb.append(item != null ? item.toString() : "null").append(i < length - 1 ? delimiter : "");
}
return sb.toString();
}
/** Method that joins the elements of the specified array, using a white-space as delimiter. */
public static String join(Object array) {
return join(array, " ");
}
public static String join(Collection extends Object> c) {
return join(c.toArray());
}
/** Method that joins the elements of the specified map, using the specified separator and delimiter. */
public static String join(Map m, String separator, String delimiter) {
return m.entrySet().stream().map(e -> e.getKey() + separator + e.getValue()).reduce("", (n, p) -> n + (n.length() == 0 ? "" : delimiter) + p);
}
/** Method that joins the elements of the specified two-dimensional array, using the specified separator and delimiter. */
public static String join(Object[][] m, String separator, String delimiter) {
return Arrays.stream(m).map(t -> join(t, delimiter)).reduce("", (n, p) -> n + (n.length() == 0 ? "" : separator) + p);
}
public static String join(int[][] m, String separator, String delimiter) {
return Arrays.stream(m).map(t -> join(t, delimiter)).reduce("", (n, p) -> n + (n.length() == 0 ? "" : separator) + p);
}
/**
* Returns the specified string in camel case form (with the first letter of the first word in lower case).
*/
public static String toCamelCase(String s) {
String[] words = s.split("_");
return IntStream.range(0, words.length)
.mapToObj(i -> i == 0 ? words[i].toLowerCase() : words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase())
.collect(Collectors.joining());
}
/**
* Returns the specified string in kebab case form.
*/
public static String toKebabCase(String s) {
String[] words = s.split("_");
return Stream.of(words).map(w -> w.toLowerCase()).collect(Collectors.joining("-"));
}
/** Method for converting an array into a string. */
public static String arrayToString(Object array, final char LEFT, final char RIGHT, final String SEP) {
assert array.getClass().isArray();
if (array instanceof boolean[])
return Arrays.toString((boolean[]) array);
if (array instanceof byte[])
return Arrays.toString((byte[]) array);
if (array instanceof short[])
return Arrays.toString((short[]) array);
if (array instanceof int[])
return Arrays.toString((int[]) array);
if (array instanceof long[])
return Arrays.toString((long[]) array);
if (array instanceof String[])
return LEFT + String.join(SEP, (String[]) array) + RIGHT;
if (array instanceof IVar[])
return LEFT + String.join(SEP, Stream.of((IVar[]) array).map(x -> x.toString()).toArray(String[]::new)) + RIGHT;
if (array instanceof boolean[][])
return LEFT + String.join(SEP, Stream.of((boolean[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof byte[][])
return LEFT + String.join(SEP, Stream.of((byte[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof short[][])
return LEFT + String.join(SEP, Stream.of((short[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof int[][])
return LEFT + String.join(SEP, Stream.of((int[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof long[][])
return LEFT + String.join(SEP, Stream.of((long[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof String[][])
return LEFT + String.join(SEP, Stream.of((String[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof boolean[][][])
return LEFT + String.join(SEP, Stream.of((boolean[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof byte[][][])
return LEFT + String.join(SEP, Stream.of((byte[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof short[][][])
return LEFT + String.join(SEP, Stream.of((short[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof int[][][])
return LEFT + String.join(SEP, Stream.of((int[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof long[][][])
return LEFT + String.join(SEP, Stream.of((long[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof String[][][])
return LEFT + String.join(SEP, Stream.of((String[][][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof Long[][])
return LEFT + String.join(SEP, Stream.of((Long[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof IVar[][])
return LEFT + String.join(SEP, Stream.of((IVar[][]) array).map(t -> arrayToString(t, LEFT, RIGHT, SEP)).toArray(String[]::new)) + RIGHT;
if (array instanceof Object[][])
return LEFT + String.join(SEP, Stream.of((Object[][]) array).map(t -> arrayToString(t)).toArray(String[]::new)) + RIGHT;
// return "(" + String.join(")(", Stream.of((Object[][]) array).map(t -> simplify(Arrays.toString(t))).toArray(String[]::new)) +
// ")";
if (array instanceof Object[])
return String.join(SEP,
Stream.of((Object[]) array).map(t -> t.getClass().isArray() ? LEFT + arrayToString(t) + RIGHT : t.toString()).toArray(String[]::new));
return null;
}
/** Method for converting an array into a string. */
public static String arrayToString(Object array) {
return arrayToString(array, '[', ']', ", ");
}
/**
* Returns true if inside the specified object, there is an element that checks the predicate. If syntactic trees are encountered, we check the
* leaves only.
*/
public static boolean check(Object obj, Predicate p) {
if (obj instanceof Object[])
return IntStream.range(0, Array.getLength(obj)).anyMatch(i -> check(Array.get(obj, i), p));
if (obj instanceof XNode)
return ((XNode>) obj).firstNodeSuchThat(n -> n instanceof XNodeLeaf && p.test(((XNodeLeaf>) n).value)) != null;
// if (obj instanceof XNode)
// return ((XNode>) obj).containsLeafSuchThat(leaf -> p.test(leaf.value));
return p.test(obj);
}
public static class ModifiableBoolean {
public Boolean value;
public ModifiableBoolean(Boolean value) {
this.value = value;
}
}
// ************************************************************************
// ***** Methods for XML
// ************************************************************************
/** Method that loads an XML document, using the specified file name. */
public static Document loadDocument(String fileName) throws Exception {
Utilities.control(new File(fileName).exists(), "Filename " + fileName + " not found\n");
if (fileName.endsWith("xml.bz2") || fileName.endsWith("xml.lzma")) {
Process p = Runtime.getRuntime().exec((fileName.endsWith("xml.bz2") ? "bunzip2 -c " : "lzma -c -d ") + fileName);
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
p.waitFor();
return document;
} else
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream(new File(fileName)));
}
public static void save(Document document, PrintWriter out) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(document), new StreamResult(out));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String save(Document document, String fileName) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)))) {
save(document, out);
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
/** Method that returns an array with the child elements of the specified element. */
public static Element[] childElementsOf(Element element) {
NodeList childs = element.getChildNodes();
return IntStream.range(0, childs.getLength()).mapToObj(i -> childs.item(i)).filter(e -> e.getNodeType() == Node.ELEMENT_NODE).toArray(Element[]::new);
}
/** Determines whether the specified element has the specified type as tag name. */
public static boolean isTag(Element elt, TypeChild type) {
return elt.getTagName().equals(type.name());
}
public static Element element(Document doc, String tag, List sons) {
Element elt = doc.createElement(tag);
sons.stream().forEach(c -> elt.appendChild(c));
return elt;
}
public static Element element(Document doc, String tag, Element son) {
return element(doc, tag, Arrays.asList(son));
}
public static Element element(Document doc, String tag, Element son, Element... otherSons) {
return element(doc, tag, IntStream.range(0, 1 + otherSons.length).mapToObj(i -> i == 0 ? son : otherSons[i - 1]).collect(Collectors.toList()));
}
public static Element element(Document doc, String tag, Element son, Stream otherSons) {
return element(doc, tag, Stream.concat(Stream.of(son), otherSons).collect(Collectors.toList()));
}
public static Element element(Document doc, String tag, Object textContent) {
Element elt = doc.createElement(tag);
elt.setTextContent(" " + textContent + " ");
return elt;
}
public static Element element(Document doc, String tag, String attName, String attValue, Object textContent) {
Element elt = element(doc, tag, textContent);
elt.setAttribute(attName, attValue);
return elt;
}
public static Element element(Document doc, String tag, String attName, String attValue) {
Element elt = doc.createElement(tag);
elt.setAttribute(attName, attValue);
return elt;
}
public static Element element(Document doc, String tag, String attName1, String attValue1, String attName2, String attValue2) {
Element elt = doc.createElement(tag);
elt.setAttribute(attName1, attValue1);
elt.setAttribute(attName2, attValue2);
return elt;
}
public static Element element(Document doc, String tag, Collection> attributes) {
Element elt = doc.createElement(tag);
if (attributes != null)
attributes.stream().forEach(e -> elt.setAttribute(e.getKey(), e.getValue().toString()));
return elt;
}
}