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.daisy.common.saxon.SaxonHelper Maven / Gradle / Ivy
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.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.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 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
list = new ArrayList<>();
SequenceIterator iterator = sequence.iterate();
Item next;
while ((next = iterator.next()) != null)
list.add(objectFromItem(next, itemType));
return list;
}
}
@SuppressWarnings("unchecked") // safe casts
public static Iterable iterableFromSequence(Sequence sequence, Class itemType) throws XPathException {
if (itemType.equals(Node.class))
return (Iterable)ImmutableList.copyOf(iteratorFromNodeSequence(sequence));
else {
List list = new ArrayList<>();
SequenceIterator iterator = sequence.iterate();
Item next;
while ((next = iterator.next()) != null)
list.add(objectFromItem(next, itemType));
return list;
}
}
@SuppressWarnings("unchecked") // safe casts
public static Iterator> iteratorFromSequence(Sequence sequence, Type itemType) throws XPathException {
if (itemType.equals(Node.class))
return iteratorFromSequence(sequence, (Class)itemType);
else
return iterableFromSequence(sequence, itemType).iterator();
}
@SuppressWarnings("unchecked") // safe casts
public static Iterator iteratorFromSequence(Sequence sequence, Class itemType) throws XPathException {
if (itemType.equals(Node.class))
return (Iterator)iteratorFromNodeSequence(sequence);
else
return iterableFromSequence(sequence, itemType).iterator();
}
@SuppressWarnings("unchecked") // safe casts
private static Iterator iteratorFromNodeSequence(Sequence sequence) throws XPathException {
List list = new ArrayList<>();
SequenceIterator iterator = sequence.iterate();
Item next;
while ((next = iterator.next()) != null)
list.add(objectFromItem(next, XdmNode.class));
return list.isEmpty()
? ((Iterable)Collections.EMPTY_LIST).iterator()
: new SaxonInputValue(list.iterator()).asNodeIterator();
}
@SuppressWarnings("unchecked") // safe casts
public static T[] arrayFromArrayItem(ArrayItem array, Class itemType) throws XPathException {
T[] a = (T[])Array.newInstance(itemType, array.arrayLength());
int i = 0;
for (Sequence s : array)
a[i++] = objectFromItem(getSingleItem(s), itemType);
return a;
}
public static Map mapFromMapItem(MapItem item, Type itemType) throws XPathException {
if (itemType instanceof Class)
return mapFromMapItem(item, (Class>)itemType);
else {
Map map = new HashMap<>();
for (KeyValuePair kv : item)
map.put(kv.key.getStringValue(), objectFromItem(getSingleItem(kv.value), itemType));
return map;
}
}
public static Map mapFromMapItem(MapItem item, Class itemType) throws XPathException {
Map map = new HashMap<>();
for (KeyValuePair kv : item)
map.put(kv.key.getStringValue(), objectFromItem(getSingleItem(kv.value), itemType));
return map;
}
public static Object objectFromItem(Item item, Type type) throws XPathException {
if (type instanceof Class)
return objectFromItem(item, (Class>)type);
else if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType)type).getRawType();
if (rawType.equals(Map.class)) {
if (item instanceof MapItem)
return mapFromMapItem(
(MapItem)item,
((ParameterizedType)type).getActualTypeArguments()[1]);
}
}
throw new IllegalArgumentException();
}
@SuppressWarnings("unchecked") // safe casts
public static T objectFromItem(Item item, Class type) throws XPathException {
if (type.isArray())
if (item instanceof ArrayItem) {
return (T)arrayFromArrayItem(
(ArrayItem)item,
((Class>)type).getComponentType());
} else
throw new IllegalArgumentException();
else if (type.equals(XdmNode.class))
if (item instanceof NodeInfo)
return (T)new XdmNode((NodeInfo)item);
else
throw new IllegalArgumentException();
else if (type.equals(Element.class))
if (item instanceof NodeInfo)
return (T)ElementOverNodeInfo.wrap((NodeInfo)item);
else
throw new IllegalArgumentException();
else if (type.equals(Attr.class))
if (item instanceof NodeInfo)
return (T)AttrOverNodeInfo.wrap((NodeInfo)item);
else
throw new IllegalArgumentException();
else if (type.equals(Node.class))
if (item instanceof NodeInfo)
return (T)NodeOverNodeInfo.wrap((NodeInfo)item);
else
throw new IllegalArgumentException();
else if (type.equals(String.class))
if (item instanceof StringValue)
return (T)(String)((StringValue)item).getStringValue();
else
throw new IllegalArgumentException();
else if (type.equals(Integer.class) || type.equals(int.class))
if (item instanceof IntegerValue)
return (T)(Integer)((IntegerValue)item).asBigInteger().intValue();
else
throw new IllegalArgumentException();
else if (type.equals(Long.class) || type.equals(long.class))
if (item instanceof IntegerValue)
return (T)(Long)((IntegerValue)item).asBigInteger().longValue();
else
throw new IllegalArgumentException();
else if (type.equals(Float.class) || type.equals(float.class))
if (item instanceof FloatValue)
return (T)(Float)((FloatValue)item).getFloatValue();
else
throw new IllegalArgumentException();
else if (type.equals(BigDecimal.class))
if (item instanceof DecimalValue)
try {
return (T)(BigDecimal)((DecimalValue)item).getDecimalValue();
} catch (ValidationException e) {
throw new RuntimeException(e); // should not happen
}
else
throw new IllegalArgumentException();
else if (type.equals(Boolean.class))
if (item instanceof BooleanValue)
return (T)(Boolean)((BooleanValue)item).getBooleanValue();
else
throw new IllegalArgumentException();
else if (type.equals(URI.class))
if (item instanceof AnyURIValue)
try {
return (T)(new URI((String)((StringValue)item).getStringValue()));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e); // should not happen
}
else
throw new IllegalArgumentException();
else if (type.equals(Locale.class))
if (item instanceof StringValue) {
try {
return (T)(new Locale.Builder()).setLanguageTag((String)((StringValue)item).getStringValue().replace('_','-'))
.build();
} catch (IllformedLocaleException e) {
throw new IllegalArgumentException(e);
}
} else
throw new IllegalArgumentException();
else if (type.equals(Object.class))
// argument can be anything
if (item instanceof ArrayItem)
return (T)objectFromItem(item, Object[].class);
else if (item instanceof NodeInfo)
return (T)objectFromItem(item, Node.class);
else if (item instanceof StringValue)
return (T)objectFromItem(item, String.class);
else if (item instanceof IntegerValue)
return (T)objectFromItem(item, Long.class);
else if (item instanceof FloatValue)
return (T)objectFromItem(item, Float.class);
else if (item instanceof DecimalValue)
return (T)objectFromItem(item, BigDecimal.class);
else if (item instanceof BooleanValue)
return (T)objectFromItem(item, Boolean.class);
else if (item instanceof AnyURIValue)
return (T)objectFromItem(item, URI.class);
if (item instanceof ObjectValue) {
Object o = ((ObjectValue>)item).getObject();
if (type.isInstance(o))
return (T)o;
else
throw new IllegalArgumentException("expected " + type + " object, but got " + o);
} else
throw new IllegalArgumentException();
}
public static Item getSingleItem(Sequence sequence) throws XPathException {
SequenceIterator iterator = sequence.iterate();
Item item = iterator.next();
if (item == null)
throw new IllegalArgumentException();
if (iterator.next() != null)
throw new IllegalArgumentException();
return item;
}
public static Optional- getOptionalItem(Sequence sequence) throws XPathException {
SequenceIterator iterator = sequence.iterate();
Item item = iterator.next();
if (iterator.next() != null)
throw new IllegalArgumentException();
return Optional.ofNullable(item);
}
public static javax.xml.namespace.QName jaxpQName(QName name) {
String prefix = name.getPrefix();
String ns = name.getNamespaceURI();
String localPart = name.getLocalName();
if (prefix != null)
return new javax.xml.namespace.QName(ns, localPart, prefix);
else
return new javax.xml.namespace.QName(ns, localPart);
}
public static Iterable
axisIterable(XdmNode node, Axis axis) {
return new Iterable() {
public Iterator iterator() {
return node.axisIterator(axis);
}
};
}
public static XPathExpression compileExpression(String expression, Hashtable namespaceBindings, Configuration configuration)
throws XPathException {
XPathEvaluator xpathEvaluator = new XPathEvaluator(configuration);
xpathEvaluator.getStaticContext().setNamespaceResolver(new MatchingNamespaceResolver(namespaceBindings));
return xpathEvaluator.createPattern(expression);
}
public static boolean evaluateBoolean(XPathExpression expression, XdmNode contextNode) {
try {
XPathDynamicContext context = expression.createDynamicContext(contextNode.getUnderlyingNode());
return expression.effectiveBooleanValue(context);
} catch (XPathException e) {
return false;
}
}
// copied from com.xmlcalabash.util.ProcessMatch
public static class MatchingNamespaceResolver implements NamespaceResolver {
private Hashtable ns = new Hashtable();
public MatchingNamespaceResolver(Hashtable bindings) {
ns = bindings;
}
public String getURIForPrefix(String prefix, boolean useDefault) {
if ("".equals(prefix) && !useDefault) {
return "";
}
return ns.get(prefix);
}
public Iterator iteratePrefixes() {
Vector p = new Vector ();
for (String pfx : ns.keySet()) {
p.add(pfx);
}
return p.iterator();
}
}
private SaxonHelper() {
// no instantiation
}
}