
org.daisy.common.saxon.SaxonHelper Maven / Gradle / Ivy
The newest version!
package org.daisy.common.saxon;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.IllformedLocaleException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Vector;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.google.common.collect.ImmutableList;
import net.sf.saxon.Configuration;
import net.sf.saxon.dom.AttrOverNodeInfo;
import net.sf.saxon.dom.ElementOverNodeInfo;
import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.ma.arrays.ArrayItem;
import net.sf.saxon.ma.arrays.SimpleArrayItem;
import net.sf.saxon.ma.map.HashTrieMap;
import net.sf.saxon.ma.map.KeyValuePair;
import net.sf.saxon.ma.map.MapItem;
import net.sf.saxon.om.NamespaceResolver;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.s9api.Axis;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmValue;
import net.sf.saxon.sxpath.XPathDynamicContext;
import net.sf.saxon.sxpath.XPathEvaluator;
import net.sf.saxon.sxpath.XPathExpression;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.ValidationException;
import net.sf.saxon.value.AnyURIValue;
import net.sf.saxon.value.BigDecimalValue;
import net.sf.saxon.value.BooleanValue;
import net.sf.saxon.value.DateTimeValue;
import net.sf.saxon.value.DecimalValue;
import net.sf.saxon.value.DoubleValue;
import net.sf.saxon.value.EmptySequence;
import net.sf.saxon.value.FloatValue;
import net.sf.saxon.value.IntegerValue;
import net.sf.saxon.value.ObjectValue;
import net.sf.saxon.value.SequenceExtent;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.StringValue;
public final class SaxonHelper {
public static Sequence sequenceFromObject(Object object) {
if (object == null)
return EmptySequence.getInstance();
else if (object instanceof Iterator || object instanceof Iterable)
return sequenceFromIterator(
object instanceof Iterable
? ((Iterable>)object).iterator()
: (Iterator>)object);
else if (object.getClass().isArray())
return arrayItemFromIterator(Arrays.asList((Object[])object).iterator());
else
return itemFromObject(object);
}
private static Item itemFromObject(Object object) {
if (object == null)
throw new IllegalArgumentException();
else if (object instanceof String)
return new StringValue((String)object);
else if (object instanceof Integer)
return IntegerValue.makeIntegerValue(BigInteger.valueOf((Integer)object));
else if (object instanceof Long)
return IntegerValue.makeIntegerValue(BigInteger.valueOf((Long)object));
else if (object instanceof Float)
return FloatValue.makeFloatValue((Float)object);
else if (object instanceof Double)
return DoubleValue.makeDoubleValue((Double)object);
else if (object instanceof BigDecimal)
return new BigDecimalValue((BigDecimal)object);
else if (object instanceof Boolean)
return BooleanValue.get((Boolean)object);
else if (object instanceof URI)
return new AnyURIValue(((URI)object).toASCIIString());
else if (object instanceof Locale)
return itemFromObject(((Locale)object).toLanguageTag());
else if (object instanceof Date)
try {
return DateTimeValue.fromJavaDate((Date)object);
} catch (XPathException e) {
throw new RuntimeException(e); // should not happen
}
else if (object instanceof Map)
return mapItemFromMap((Map,?>)object);
else
return new ObjectValue<>(object);
}
private static Sequence sequenceFromIterator(Iterator> iterator) {
List- list = new ArrayList<>();
while (iterator.hasNext())
list.add(itemFromObject(iterator.next()));
return new SequenceExtent(list);
}
private static MapItem mapItemFromMap(Map,?> map) {
MapItem mapItem = new HashTrieMap();
for (Object key : map.keySet()) {
if (!(key instanceof String))
throw new IllegalArgumentException();
mapItem = mapItem.addEntry(
new StringValue((String)key),
sequenceFromObject(map.get(key)));
}
return mapItem;
}
private static ArrayItem arrayItemFromIterator(Iterator> iterator) {
try {
return SimpleArrayItem.makeSimpleArrayItem(sequenceFromIterator(iterator).iterate());
} catch (XPathException e) {
throw new RuntimeException(e); // should not happen
}
}
public static XdmValue xdmValueFromObject(Object object) {
if (object == null)
return XdmValue.wrap(EmptySequence.getInstance());
else if (object instanceof String)
return new XdmAtomicValue((String)object);
else if (object instanceof Integer)
return new XdmAtomicValue((Integer)object);
else if (object instanceof Boolean)
return new XdmAtomicValue((Boolean)object);
else if (object instanceof URI)
return new XdmAtomicValue((URI)object);
else
try {
return XdmValue.wrap(sequenceFromObject(object));
} catch (IllegalArgumentException e) {
return XdmValue.wrap(new ObjectValue<>(object));
}
}
public static SequenceType sequenceTypeFromType(Type type) throws IllegalArgumentException {
if (type.equals(Void.TYPE))
return SequenceType.EMPTY_SEQUENCE;
else if (type.equals(String.class))
return SequenceType.SINGLE_STRING;
else if (type.equals(Integer.class)
|| type.equals(int.class)
|| type.equals(Long.class)
|| type.equals(long.class))
return SequenceType.SINGLE_INTEGER;
else if (type.equals(Float.class)
|| type.equals(float.class))
return SequenceType.SINGLE_FLOAT;
else if (type.equals(BigDecimal.class))
return SequenceType.SINGLE_DECIMAL;
else if (type.equals(Boolean.class)
|| type.equals(boolean.class))
return SequenceType.SINGLE_BOOLEAN;
else if (type.equals(URI.class))
return SequenceType.OPTIONAL_ANY_URI; // SINGLE_ANY_URI
else if (type.equals(Element.class) || type.equals(Node.class) || type.equals(Attr.class))
return SequenceType.SINGLE_NODE;
else if (type.equals(Object.class))
return SequenceType.SINGLE_ITEM;
else if (type instanceof Class && ((Class>)type).isArray()) {
Type itemType = ((Class>)type).getComponentType();
sequenceTypeFromType(itemType);
return ArrayItem.SINGLE_ARRAY_TYPE;
} else if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType)type).getRawType();
if (rawType.equals(Optional.class)) {
Type itemType = ((ParameterizedType)type).getActualTypeArguments()[0];
if (itemType.equals(Node.class) || itemType.equals(Element.class) || itemType.equals(Attr.class))
return SequenceType.OPTIONAL_NODE;
else if (itemType.equals(String.class))
return SequenceType.OPTIONAL_STRING;
else if (itemType.equals(URI.class))
return SequenceType.OPTIONAL_ANY_URI;
else if (itemType.equals(Object.class))
return SequenceType.OPTIONAL_ITEM;
else if (itemType instanceof ParameterizedType) {
rawType = ((ParameterizedType)itemType).getRawType();
if (rawType.equals(Iterator.class) || rawType.equals(Iterable.class))
return sequenceTypeFromType(itemType);
else
return SequenceType.OPTIONAL_ITEM;
} else
return SequenceType.OPTIONAL_ITEM; // optional special wrapper item
} else if (rawType.equals(Iterator.class) || rawType.equals(Iterable.class)) {
Type itemType = ((ParameterizedType)type).getActualTypeArguments()[0];
if (itemType.equals(Node.class))
return SequenceType.NODE_SEQUENCE;
else if (itemType.equals(String.class))
return SequenceType.STRING_SEQUENCE;
else
return SequenceType.ANY_SEQUENCE; // sequence of special wrapper items
} else if (rawType.equals(Map.class)) {
Type keyType = ((ParameterizedType)type).getActualTypeArguments()[0];
if (keyType.equals(String.class)) {
Type valueType = ((ParameterizedType)type).getActualTypeArguments()[1];
sequenceTypeFromType(valueType);
return HashTrieMap.SINGLE_MAP_TYPE;
}
}
} else
return SequenceType.SINGLE_ITEM; // special wrapper item
throw new IllegalArgumentException("Unsupported type: " + type);
}
public static Iterable> iterableFromSequence(Sequence sequence, Type itemType) throws XPathException {
if (itemType instanceof Class)
return iterableFromSequence(sequence, (Class>)itemType);
else {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy