package com.bagri.xquery.saxon; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.List; import java.util.NoSuchElementException; import java.util.Properties; import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; import javax.xml.xquery.XQDataFactory; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItem; import javax.xml.xquery.XQItemAccessor; import javax.xml.xquery.XQItemType; import org.w3c.dom.Attr; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; import com.bagri.core.system.DataType; import com.bagri.support.util.XMLUtils; import com.bagri.support.util.XQUtils; import net.sf.saxon.Configuration; import net.sf.saxon.dom.DOMObjectModel; import net.sf.saxon.dom.NodeOverNodeInfo; import net.sf.saxon.event.Builder; import net.sf.saxon.event.PipelineConfiguration; import net.sf.saxon.event.Sender; import net.sf.saxon.evpull.PullEventSource; import net.sf.saxon.evpull.StaxToEventBridge; import net.sf.saxon.expr.EarlyEvaluationContext; import net.sf.saxon.expr.JPConverter; import net.sf.saxon.expr.StaticProperty; 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.Item; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.om.Sequence; import net.sf.saxon.om.SequenceIterator; import net.sf.saxon.om.SequenceTool; import net.sf.saxon.om.StandardNames; import net.sf.saxon.trans.XPathException; import net.sf.saxon.tree.iter.AtomicIterator; import net.sf.saxon.tree.tiny.TinyBuilder; import net.sf.saxon.type.AtomicType; import net.sf.saxon.type.BuiltInAtomicType; import net.sf.saxon.type.ItemType; import net.sf.saxon.value.*; import static net.sf.saxon.om.StandardNames.*; import static javax.xml.xquery.XQItemType.*; public class SaxonUtils { public static final int saxon_xquery_version = 31; public static Object itemToObject(Item item) throws XPathException { if (item instanceof AtomicValue) { AtomicValue p = ((AtomicValue) item).asAtomic(); // ((AtomicValue)item); int t = p.getItemType().getPrimitiveType(); switch (t) { case XS_ANY_URI: case XS_ANY_ATOMIC_TYPE: return p.getStringValue(); case XS_BASE64_BINARY: return ((Base64BinaryValue)p).getBinaryValue(); case XS_BOOLEAN: return Boolean.valueOf(((BooleanValue)p).getBooleanValue()); case XS_DATE: return getCalendar((CalendarValue) p, XQBASETYPE_DATE); // new SaxonXMLGregorianCalendar((CalendarValue)p); case XS_DATE_TIME: return getCalendar((CalendarValue) p, XQBASETYPE_DATETIME); // new SaxonXMLGregorianCalendar((CalendarValue)p); case XS_DECIMAL: return ((DecimalValue)p).getDecimalValue(); case XS_DOUBLE: return new Double(((DoubleValue)p).getDoubleValue()); case XS_DURATION: return getDuration((DurationValue)p, XQBASETYPE_DURATION); case XS_FLOAT: return new Float(((FloatValue)p).getFloatValue()); case XS_G_DAY: return getCalendar((CalendarValue) p, XQBASETYPE_GDAY); case XS_G_MONTH: return getCalendar((CalendarValue) p, XQBASETYPE_GMONTH); case XS_G_MONTH_DAY: return getCalendar((CalendarValue) p, XQBASETYPE_GMONTHDAY); case XS_G_YEAR: return getCalendar((CalendarValue) p, XQBASETYPE_GYEAR); case XS_G_YEAR_MONTH: return getCalendar((CalendarValue) p, XQBASETYPE_GYEARMONTH); case XS_HEX_BINARY: return ((HexBinaryValue)p).getBinaryValue(); case XS_INTEGER: if (p instanceof BigIntegerValue) { return ((BigIntegerValue)p).asBigInteger(); } else { int sub = ((AtomicType)p.getItemType()).getFingerprint(); switch (sub) { case XS_INTEGER: case XS_NEGATIVE_INTEGER: case XS_NON_NEGATIVE_INTEGER: case XS_NON_POSITIVE_INTEGER: case XS_POSITIVE_INTEGER: case XS_UNSIGNED_LONG: return BigInteger.valueOf(((Int64Value)p).longValue()); case XS_BYTE: return Byte.valueOf((byte)((Int64Value)p).longValue()); case XS_INT: case XS_UNSIGNED_SHORT: return Integer.valueOf((int)((Int64Value)p).longValue()); case XS_LONG: case XS_UNSIGNED_INT: return Long.valueOf(((Int64Value)p).longValue()); case XS_SHORT: case XS_UNSIGNED_BYTE: return Short.valueOf((short)((Int64Value)p).longValue()); default: throw new XPathException("Unrecognized integer subtype " + sub); } } case XS_QNAME: return ((QualifiedNameValue)p).toJaxpQName(); case XS_STRING: case XS_UNTYPED_ATOMIC: return p.getStringValue(); case XS_TIME: return getCalendar((CalendarValue) p, XQBASETYPE_TIME); case XS_DAY_TIME_DURATION: return getDuration((DurationValue)p, XQBASETYPE_DAYTIMEDURATION); case XS_YEAR_MONTH_DURATION: return getDuration((DurationValue)p, XQBASETYPE_YEARMONTHDURATION); default: throw new XPathException("unsupported type: " + t); } } else if (item instanceof NodeInfo) { return NodeOverNodeInfo.wrap((NodeInfo)item); //try { //return QueryResult.serialize((NodeInfo)item); //} catch (XPathException ex) { // throw new XQException(ex.getMessage()); //} } else if (item instanceof ObjectValue) { Object value = ((ObjectValue) item).getObject(); if (value instanceof XQItem) { // //return ((XQItem) value).getObject(); return value; } } return item; } public static Item objectToItem(Object value, Configuration config) throws XPathException { if (value == null) { return null; } // convert to switch.. if (value instanceof Boolean) { return BooleanValue.get(((Boolean)value).booleanValue()); } else if (value instanceof byte[]) { return new HexBinaryValue((byte[])value); } else if (value instanceof Byte) { return new Int64Value(((Byte)value).byteValue(), BuiltInAtomicType.BYTE, false); } else if (value instanceof Float) { return new FloatValue(((Float)value).floatValue()); } else if (value instanceof Double) { return new DoubleValue(((Double)value).doubleValue()); } else if (value instanceof Integer) { return new Int64Value(((Integer)value).intValue(), BuiltInAtomicType.INT, false); } else if (value instanceof Long) { return new Int64Value(((Long)value).longValue(), BuiltInAtomicType.LONG, false); } else if (value instanceof Short) { return new Int64Value(((Short)value).shortValue(), BuiltInAtomicType.SHORT, false); } else if (value instanceof String) { return new StringValue((String)value); } else if (value instanceof BigDecimal) { return new DecimalValue((BigDecimal)value); } else if (value instanceof BigInteger) { return new BigIntegerValue((BigInteger)value); } else if (value instanceof SaxonDuration) { return ((SaxonDuration)value).getDurationValue(); } else if (value instanceof Duration) { // this is simpler and safer (but perhaps slower) than extracting all the components //return DurationValue.makeDuration(value.toString()).asAtomic(); Duration dv = (Duration) value; return new DurationValue(dv.getSign() >= 0, dv.getYears(), dv.getMonths(), dv.getDays(), dv.getHours(), dv.getMinutes(), dv.getSeconds(), 0); // take correct millis.. } else if (value instanceof SaxonXMLGregorianCalendar) { return ((SaxonXMLGregorianCalendar)value).toCalendarValue(); } else if (value instanceof XMLGregorianCalendar) { XMLGregorianCalendar g = (XMLGregorianCalendar)value; QName gtype = g.getXMLSchemaType(); if (gtype.equals(DatatypeConstants.DATETIME)) { return DateTimeValue.makeDateTimeValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.DATE)) { return DateValue.makeDateValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.TIME)) { return TimeValue.makeTimeValue(value.toString()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GYEAR)) { return GYearValue.makeGYearValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GYEARMONTH)) { return GYearMonthValue.makeGYearMonthValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GMONTH)) { // a workaround for X3C schema bug String val = value.toString(); if (val.endsWith("--")) { val = val.substring(0, val.length() - 2); } return GMonthValue.makeGMonthValue(val).asAtomic(); } else if (gtype.equals(DatatypeConstants.GMONTHDAY)) { return GMonthDayValue.makeGMonthDayValue(value.toString()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GDAY)) { return GDayValue.makeGDayValue(value.toString()).asAtomic(); } else { throw new AssertionError("Unknown Gregorian date type"); } } else if (value instanceof QName) { QName q = (QName)value; return new QNameValue(q.getPrefix(), q.getNamespaceURI(), q.getLocalPart()); //BuiltInAtomicType.QNAME, null); } else if (value instanceof URI) { return new AnyURIValue(value.toString()); } else { return new ObjectValue(value); } } public static Item convertToItem(Object value, Configuration config, BuiltInAtomicType type) throws XPathException { if (value == null) { return null; } // convert to switch.. //try { if (value instanceof Boolean) { return BooleanValue.get(((Boolean)value).booleanValue()); } else if (value instanceof byte[]) { return new HexBinaryValue((byte[])value); } else if (value instanceof Byte) { return new Int64Value(((Byte)value).byteValue(), type, false); //BuiltInAtomicType.BYTE, false); } else if (value instanceof Float) { return new FloatValue(((Float)value).floatValue(), type); } else if (value instanceof Double) { return new DoubleValue(((Double)value).doubleValue(), type); } else if (value instanceof Integer) { return new Int64Value(((Integer)value).intValue(), type, false); //BuiltInAtomicType.INT, false); } else if (value instanceof Long) { return new Int64Value(((Long)value).longValue(), type, false); //BuiltInAtomicType.LONG, false); } else if (value instanceof Short) { return new Int64Value(((Short)value).shortValue(), type, false); //BuiltInAtomicType.SHORT, false); } else if (value instanceof String) { return new StringValue((String)value, type); } else if (value instanceof BigDecimal) { return new DecimalValue((BigDecimal)value); } else if (value instanceof BigInteger) { return new BigIntegerValue((BigInteger)value, type); } else if (value instanceof SaxonDuration) { return ((SaxonDuration)value).getDurationValue(); } else if (value instanceof Duration) { // this is simpler and safer (but perhaps slower) than extracting all the components //return DurationValue.makeDuration(value.toString()).asAtomic(); Duration dv = (Duration) value; return new DurationValue(dv.getSign() >= 0, dv.getYears(), dv.getMonths(), dv.getDays(), dv.getHours(), dv.getMinutes(), dv.getSeconds(), 0, type); // take correct millis.. } else if (value instanceof SaxonXMLGregorianCalendar) { return ((SaxonXMLGregorianCalendar)value).toCalendarValue(); } else if (value instanceof XMLGregorianCalendar) { XMLGregorianCalendar g = (XMLGregorianCalendar)value; QName gtype = g.getXMLSchemaType(); if (gtype.equals(DatatypeConstants.DATETIME)) { return DateTimeValue.makeDateTimeValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.DATE)) { return DateValue.makeDateValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.TIME)) { return TimeValue.makeTimeValue(value.toString()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GYEAR)) { return GYearValue.makeGYearValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GYEARMONTH)) { return GYearMonthValue.makeGYearMonthValue(value.toString(), config.getConversionRules()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GMONTH)) { // a workaround for X3C schema bug String val = value.toString(); if (val.endsWith("--")) { val = val.substring(0, val.length() - 2); } return GMonthValue.makeGMonthValue(val).asAtomic(); } else if (gtype.equals(DatatypeConstants.GMONTHDAY)) { return GMonthDayValue.makeGMonthDayValue(value.toString()).asAtomic(); } else if (gtype.equals(DatatypeConstants.GDAY)) { return GDayValue.makeGDayValue(value.toString()).asAtomic(); } else { throw new AssertionError("Unknown Gregorian date type"); } } else if (value instanceof QName) { QName q = (QName)value; return new QNameValue(q.getPrefix(), q.getNamespaceURI(), q.getLocalPart(), type); //BuiltInAtomicType.QNAME, null); } else if (value instanceof URI) { return new AnyURIValue(value.toString()); } else { throw new XPathException("Java object cannot be converted to an XQuery value"); } //} catch (XPathException e) { // XQException xqe = new XQException(e.getMessage()); // xqe.initCause(e); // throw xqe; //} } public static Item convertToItem(Object value, Configuration config, int kind) throws XPathException { if (value instanceof String) { try { value = XMLUtils.textToDocument((String) value); } catch (IOException ex) { throw new XPathException(ex); } } if (value instanceof Node) { JPConverter jp; switch (kind) { case XQITEMKIND_DOCUMENT: jp = DOMObjectModel.getInstance().getJPConverter(Document.class, config); break; case XQITEMKIND_ELEMENT: jp = DOMObjectModel.getInstance().getJPConverter(Element.class, config); break; case XQITEMKIND_ATTRIBUTE: jp = DOMObjectModel.getInstance().getJPConverter(Attr.class, config); break; case XQITEMKIND_COMMENT: jp = DOMObjectModel.getInstance().getJPConverter(Comment.class, config); break; case XQITEMKIND_PI: jp = DOMObjectModel.getInstance().getJPConverter(ProcessingInstruction.class, config); break; case XQITEMKIND_TEXT: jp = DOMObjectModel.getInstance().getJPConverter(Text.class, config); break; //case XQItemType.XQITEMKIND_NODE: default: jp = DOMObjectModel.getInstance().getJPConverter(Node.class, config); } //return Value.asItem(DOMObjectModel.getInstance().convertObjectToXPathValue(value, config)); return SequenceTool.asItem(jp.convert(value, new EarlyEvaluationContext(config))); } else if (value instanceof Source) { // Saxon extension to the XQJ specification PipelineConfiguration pipe = config.makePipelineConfiguration(); Builder b = new TinyBuilder(pipe); Sender.send((Source)value, b, null); NodeInfo node = b.getCurrentRoot(); b.reset(); return node; } else if (value instanceof XMLStreamReader) { // Saxon extension to the XQJ specification StaxToEventBridge bridge = new StaxToEventBridge(); bridge.setXMLStreamReader((XMLStreamReader)value); PipelineConfiguration pipe = config.makePipelineConfiguration(); bridge.setPipelineConfiguration(pipe); Builder b = new TinyBuilder(pipe); Sender.send(new PullEventSource(bridge), b, null); NodeInfo node = b.getCurrentRoot(); b.reset(); return node; } return null; } public static Item convertXQItem(XQItem xqItem, Configuration config) throws XQException, XPathException { BuiltInAtomicType type = getAtomicType(xqItem.getItemType()); if (type == null) { return convertToItem(xqItem.getObject(), config, xqItem.getItemType().getItemKind()); } return convertToItem(xqItem.getObject(), config, type); } public static BuiltInAtomicType getAtomicType(XQItemType type) throws XQException { int kind = type.getItemKind(); if (XQUtils.isBaseTypeSupported(kind)) { switch (type.getBaseType()) { case XQBASETYPE_ANYATOMICTYPE: return BuiltInAtomicType.ANY_ATOMIC; case XQBASETYPE_ANYSIMPLETYPE: return null; case XQBASETYPE_ANYTYPE: return null; case XQBASETYPE_ANYURI: return BuiltInAtomicType.ANY_URI; case XQBASETYPE_BASE64BINARY: return BuiltInAtomicType.BASE64_BINARY; case XQBASETYPE_BOOLEAN: return BuiltInAtomicType.BOOLEAN; case XQBASETYPE_BYTE: return BuiltInAtomicType.BYTE; case XQBASETYPE_DATE: return BuiltInAtomicType.DATE; case XQBASETYPE_DATETIME: return BuiltInAtomicType.DATE_TIME; case XQBASETYPE_DAYTIMEDURATION: return BuiltInAtomicType.DAY_TIME_DURATION; case XQBASETYPE_DECIMAL: return BuiltInAtomicType.DECIMAL; case XQBASETYPE_DOUBLE: return BuiltInAtomicType.DOUBLE; case XQBASETYPE_DURATION: return BuiltInAtomicType.DURATION; case XQBASETYPE_ENTITIES: return null; case XQBASETYPE_ENTITY: return BuiltInAtomicType.ENTITY; case XQBASETYPE_FLOAT: return BuiltInAtomicType.FLOAT; case XQBASETYPE_GDAY: return BuiltInAtomicType.G_DAY; case XQBASETYPE_GMONTH: return BuiltInAtomicType.G_MONTH; case XQBASETYPE_GMONTHDAY: return BuiltInAtomicType.G_MONTH_DAY; case XQBASETYPE_GYEAR: return BuiltInAtomicType.G_YEAR; case XQBASETYPE_GYEARMONTH: return BuiltInAtomicType.G_YEAR_MONTH; case XQBASETYPE_HEXBINARY: return BuiltInAtomicType.HEX_BINARY; case XQBASETYPE_ID: return BuiltInAtomicType.ID; case XQBASETYPE_IDREF: return BuiltInAtomicType.IDREF; case XQBASETYPE_IDREFS: return null; case XQBASETYPE_INT: return BuiltInAtomicType.INT; case XQBASETYPE_INTEGER: return BuiltInAtomicType.INTEGER; case XQBASETYPE_LANGUAGE: return BuiltInAtomicType.LANGUAGE; case XQBASETYPE_LONG: return BuiltInAtomicType.LONG; case XQBASETYPE_NAME: return BuiltInAtomicType.NAME; case XQBASETYPE_NCNAME: return BuiltInAtomicType.NCNAME; case XQBASETYPE_NEGATIVE_INTEGER: return BuiltInAtomicType.NEGATIVE_INTEGER; case XQBASETYPE_NMTOKEN: return BuiltInAtomicType.NMTOKEN; case XQBASETYPE_NMTOKENS: return null; case XQBASETYPE_NONNEGATIVE_INTEGER: return BuiltInAtomicType.NON_NEGATIVE_INTEGER; case XQBASETYPE_NONPOSITIVE_INTEGER: return BuiltInAtomicType.NON_POSITIVE_INTEGER; case XQBASETYPE_NORMALIZED_STRING: return BuiltInAtomicType.NORMALIZED_STRING; case XQBASETYPE_NOTATION: return BuiltInAtomicType.NOTATION; case XQBASETYPE_POSITIVE_INTEGER: return BuiltInAtomicType.POSITIVE_INTEGER; case XQBASETYPE_QNAME: return BuiltInAtomicType.QNAME; case XQBASETYPE_SHORT: return BuiltInAtomicType.SHORT; case XQBASETYPE_STRING: return BuiltInAtomicType.STRING; case XQBASETYPE_TIME: return BuiltInAtomicType.TIME; case XQBASETYPE_TOKEN: return BuiltInAtomicType.TOKEN; case XQBASETYPE_UNSIGNED_BYTE: return BuiltInAtomicType.UNSIGNED_BYTE; case XQBASETYPE_UNSIGNED_INT: return BuiltInAtomicType.UNSIGNED_INT; case XQBASETYPE_UNSIGNED_LONG: return BuiltInAtomicType.UNSIGNED_LONG; case XQBASETYPE_UNSIGNED_SHORT: return BuiltInAtomicType.UNSIGNED_SHORT; case XQBASETYPE_UNTYPED: return null; case XQBASETYPE_UNTYPEDATOMIC: return BuiltInAtomicType.UNTYPED_ATOMIC; case XQBASETYPE_YEARMONTHDURATION: return BuiltInAtomicType.YEAR_MONTH_DURATION; } } return null; } public static SequenceType type2Sequence(DataType type) { ItemType it = type2Item(type.getType()); int cardinality; switch (type.getCardinality()) { case one_or_more: cardinality = StaticProperty.ALLOWS_ONE_OR_MORE; break; case zero_or_one: cardinality = StaticProperty.ALLOWS_ZERO_OR_ONE; break; case zero_or_more: cardinality = StaticProperty.ALLOWS_ZERO_OR_MORE; break; default: cardinality = StaticProperty.ALLOWS_ONE; } return SequenceType.makeSequenceType(it, cardinality); } public static com.bagri.core.system.Cardinality getCardinality(int cardinality) { switch (cardinality) { case StaticProperty.ALLOWS_ONE_OR_MORE: return com.bagri.core.system.Cardinality.one_or_more; case StaticProperty.ALLOWS_ZERO_OR_ONE: return com.bagri.core.system.Cardinality.zero_or_one; case StaticProperty.ALLOWS_ZERO_OR_MORE: return com.bagri.core.system.Cardinality.zero_or_more; } return com.bagri.core.system.Cardinality.one; } public static ItemType type2Item(String type) { switch (type) { case "anyAtomicType": return BuiltInAtomicType.ANY_ATOMIC; //case "anySimpleType": return XQBASETYPE_ANYSIMPLETYPE; //case "anyType": return XQBASETYPE_ANYTYPE; case "anyURI": return BuiltInAtomicType.ANY_URI; case "base64Binary": return BuiltInAtomicType.BASE64_BINARY; case "boolean": return BuiltInAtomicType.BOOLEAN; case "byte": return BuiltInAtomicType.BYTE; case "date": return BuiltInAtomicType.DATE; case "dateTime": return BuiltInAtomicType.DATE_TIME; case "dayTimeDuration": return BuiltInAtomicType.DAY_TIME_DURATION; case "decimal": return BuiltInAtomicType.DECIMAL; case "double": return BuiltInAtomicType.DOUBLE; case "duration": return BuiltInAtomicType.DURATION; //case "ENTITIES": return BuiltInAtomicType.ENTITIES; case "ENTITY": return BuiltInAtomicType.ENTITY; case "float": return BuiltInAtomicType.FLOAT; case "gDay": return BuiltInAtomicType.G_DAY; case "gMonth": return BuiltInAtomicType.G_MONTH; case "gMonthDay": return BuiltInAtomicType.G_MONTH_DAY; case "gYear": return BuiltInAtomicType.G_YEAR; case "gYearMonth": return BuiltInAtomicType.G_YEAR_MONTH; case "hexBinary": return BuiltInAtomicType.HEX_BINARY; case "ID": return BuiltInAtomicType.ID; case "IDREF": return BuiltInAtomicType.IDREF; //case "IDREFS": return BuiltInAtomicType.IDREFS; case "int": return BuiltInAtomicType.INT; case "integer": return BuiltInAtomicType.INTEGER; case "language": return BuiltInAtomicType.LANGUAGE; case "long": return BuiltInAtomicType.LONG; case "Name": return BuiltInAtomicType.NAME; case "NCName": return BuiltInAtomicType.NCNAME; case "negativeInteger": return BuiltInAtomicType.NEGATIVE_INTEGER; case "NMTOKEN": return BuiltInAtomicType.NMTOKEN; //case "NMTOKENS": return BuiltInAtomicType.NMTOKENS; case "nonNegativeInteger": return BuiltInAtomicType.NON_NEGATIVE_INTEGER; case "nonPositiveInteger": return BuiltInAtomicType.NON_POSITIVE_INTEGER; case "normalizedString": return BuiltInAtomicType.NORMALIZED_STRING; case "NOTATION": return BuiltInAtomicType.NOTATION; case "positiveInteger": return BuiltInAtomicType.POSITIVE_INTEGER; case "QName": return BuiltInAtomicType.QNAME; case "short": return BuiltInAtomicType.SHORT; case "string": return BuiltInAtomicType.STRING; case "time": return BuiltInAtomicType.TIME; case "token": return BuiltInAtomicType.TOKEN; case "unsignedByte": return BuiltInAtomicType.UNSIGNED_BYTE; case "unsignedInt": return BuiltInAtomicType.UNSIGNED_INT; case "unsignedLong": return BuiltInAtomicType.UNSIGNED_LONG; case "unsignedShort": return BuiltInAtomicType.UNSIGNED_SHORT; //case "untyped": return BuiltInAtomicType.UNTYPED; case "untypedAtomic": return BuiltInAtomicType.UNTYPED_ATOMIC; case "yearMonthDuration": return BuiltInAtomicType.YEAR_MONTH_DURATION; } return BuiltInAtomicType.ANY_ATOMIC; } private static XMLGregorianCalendar getCalendar(CalendarValue c, int cType) { GregorianCalendar cal = c.getCalendar(); return XMLUtils.getXMLCalendar(cal, cType); } private static Duration getDuration(DurationValue d, int type) { return XMLUtils.getXMLDuration(d.getStringValue(), type); } public static String getTypeName(ItemType type) { if (type.isAtomicType()) { return type.getAtomizedItemType().getTypeName().getLocalPart(); } String result = type.toString(); // delete () at the end return result.substring(0, result.length() - 2); } @SuppressWarnings({ "rawtypes" }) public static XQItemAccessor itemToXQItem(Item item, XQDataFactory xqFactory) throws XPathException, XQException { if (item instanceof AtomicValue) { int type; Object value; AtomicValue p = ((AtomicValue)item); int t = p.getItemType().getPrimitiveType(); switch (t) { case XS_ANY_URI: type = XQBASETYPE_ANYURI; value = p.getStringValue(); break; case XS_ANY_ATOMIC_TYPE: type = XQBASETYPE_ANYATOMICTYPE; value = p.getStringValue(); break; case XS_BASE64_BINARY: type = XQBASETYPE_BASE64BINARY; value = ((Base64BinaryValue)p).getBinaryValue(); break; case XS_BOOLEAN: type = XQBASETYPE_BOOLEAN; value = Boolean.valueOf(((BooleanValue)p).getBooleanValue()); break; case XS_DATE: type = XQBASETYPE_DATE; value = getCalendar((CalendarValue) p, XQBASETYPE_DATE); break; case XS_TIME: type = XQBASETYPE_TIME; value = getCalendar((CalendarValue) p, XQBASETYPE_TIME); break; case XS_DATE_TIME: type = XQBASETYPE_DATETIME; value = getCalendar((CalendarValue) p, XQBASETYPE_DATETIME); break; case XS_DECIMAL: type = XQBASETYPE_DECIMAL; value = ((DecimalValue)p).getDecimalValue(); break; case XS_DOUBLE: type = XQBASETYPE_DOUBLE; value = ((DoubleValue)p).getDoubleValue(); break; case XS_DURATION: type = XQBASETYPE_DURATION; value = getDuration((DurationValue) p, type); break; case XS_DAY_TIME_DURATION: type = XQBASETYPE_DAYTIMEDURATION; value = getDuration((DurationValue) p, type); break; case XS_YEAR_MONTH_DURATION: type = XQBASETYPE_YEARMONTHDURATION; value = getDuration((DurationValue) p, type); break; case XS_FLOAT: type = XQBASETYPE_FLOAT; value = ((FloatValue)p).getFloatValue(); break; case XS_G_DAY: type = XQBASETYPE_GDAY; value = getCalendar((CalendarValue) p, XQBASETYPE_GDAY); break; case XS_G_MONTH: type = XQBASETYPE_GMONTH; value = getCalendar((CalendarValue) p, XQBASETYPE_GMONTH); break; case XS_G_MONTH_DAY: type = XQBASETYPE_GMONTHDAY; value = getCalendar((CalendarValue) p, XQBASETYPE_GMONTHDAY); break; case XS_G_YEAR: type = XQBASETYPE_GYEAR; value = getCalendar((CalendarValue) p, XQBASETYPE_GYEAR); break; case XS_G_YEAR_MONTH: type = XQBASETYPE_GYEARMONTH; value = getCalendar((CalendarValue) p, XQBASETYPE_GYEARMONTH); break; case XS_HEX_BINARY: type = XQBASETYPE_HEXBINARY; value = ((HexBinaryValue)p).getBinaryValue(); break; case XS_INTEGER: if (p instanceof BigIntegerValue) { type = XQBASETYPE_INTEGER; value = ((BigIntegerValue)p).asBigInteger(); } else { int sub = ((AtomicType)p.getItemType()).getFingerprint(); switch (sub) { case XS_INTEGER: type = XQBASETYPE_INTEGER; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_NEGATIVE_INTEGER: type = XQBASETYPE_NEGATIVE_INTEGER; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_NON_NEGATIVE_INTEGER: type = XQBASETYPE_NONNEGATIVE_INTEGER; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_NON_POSITIVE_INTEGER: type = XQBASETYPE_NONPOSITIVE_INTEGER; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_POSITIVE_INTEGER: type = XQBASETYPE_POSITIVE_INTEGER; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_UNSIGNED_LONG: type = XQBASETYPE_UNSIGNED_LONG; value = BigInteger.valueOf(((Int64Value)p).longValue()); break; case XS_BYTE: type = XQBASETYPE_BYTE; value = Byte.valueOf(((Int64Value)p).getStringValue()); break; case XS_INT: type = XQBASETYPE_INT; value = Integer.valueOf((int)((Int64Value)p).longValue()); break; case XS_UNSIGNED_SHORT: type = XQBASETYPE_UNSIGNED_SHORT; value = Integer.valueOf((int)((Int64Value)p).longValue()); break; case XS_LONG: type = XQBASETYPE_LONG; value = Long.valueOf((int)((Int64Value)p).longValue()); break; case XS_UNSIGNED_INT: type = XQBASETYPE_UNSIGNED_INT; value = Long.valueOf((int)((Int64Value)p).longValue()); break; case StandardNames.XS_SHORT: type = XQBASETYPE_SHORT; value = Short.valueOf((short)((Int64Value)p).longValue()); break; case XS_UNSIGNED_BYTE: type = XQBASETYPE_UNSIGNED_BYTE; value = Short.valueOf((short)((Int64Value)p).longValue()); break; default: throw new XPathException("Unrecognized integer subtype " + sub); } } break; case XS_STRING: value = p.getStringValue(); int sub = ((AtomicType)p.getItemType()).getFingerprint(); switch (sub) { case XS_NAME: type = XQBASETYPE_NAME; break; case XS_NCNAME: type = XQBASETYPE_NCNAME; break; case XS_NMTOKEN: type = XQBASETYPE_NMTOKEN; break; default: type = XQBASETYPE_STRING; } break; case XS_QNAME: type = XQBASETYPE_QNAME; value = ((QualifiedNameValue)p).toJaxpQName(); break; case XS_UNTYPED_ATOMIC: type = XQBASETYPE_UNTYPEDATOMIC; value = p.getStringValue(); break; default: throw new XPathException("unsupported type: " + t); } XQItemType xqt = xqFactory.createAtomicType(type); return xqFactory.createItemFromObject(value, xqt); } else if (item instanceof NodeInfo) { org.w3c.dom.Node node = NodeOverNodeInfo.wrap((NodeInfo)item); XQItemType xqt = XQUtils.getTypeForNode(xqFactory, node); return xqFactory.createItemFromNode(node, xqt); } else if (item instanceof ObjectValue) { Object value = ((ObjectValue) item).getObject(); if (value instanceof XQItem) { //Accessor) { return (XQItemAccessor) value; } else { XQItemType xqt = XQUtils.getTypeForObject(xqFactory, value); return xqFactory.createItemFromObject(value, xqt); } } else if (item instanceof MapItem) { // TODO: we'll need a new XQ type for maps, probably.. AtomicValue key; MapItem mi = (MapItem) item; AtomicIterator itr = mi.keys(); List<List<XQItemAccessor>> pairs = new ArrayList<>(); while ((key = itr.next()) != null) { Sequence val = mi.get(key); List<XQItemAccessor> pair = new ArrayList<>(); pair.add(itemToXQItem(key, xqFactory)); if (val instanceof Item) { pair.add(itemToXQItem((Item) val, xqFactory)); } else { pair.add(xqFactory.createSequence(new XQIterator(xqFactory, val.iterate()))); } pairs.add(pair); } return xqFactory.createSequence(pairs.iterator()); } else if (item instanceof Sequence) { return xqFactory.createSequence(new XQIterator(xqFactory, ((Sequence) item).iterate())); } return null; } public static Properties sequence2Properties(Sequence sq) throws XPathException { SequenceIterator itr = sq.iterate(); Properties props = new Properties(); do { Item item = itr.next(); if (item != null) { String prop = item.getStringValue(); int pos = prop.indexOf("="); if (pos > 0) { props.setProperty(prop.substring(0, pos), prop.substring(pos + 1)); } } else { break; } } while (true); return props; } /* public static int getBaseType(AtomicValue value) { int type = value.getItemType().getPrimitiveType(); switch (type) { case StandardNames.XS_ANY_URI: return XQItemType.XQBASETYPE_ANYURI; case StandardNames.XS_BASE64_BINARY: return XQItemType.XQBASETYPE_BASE64BINARY; case StandardNames.XS_BOOLEAN: return XQItemType.XQBASETYPE_BOOLEAN; case StandardNames.XS_DATE: return XQItemType.XQBASETYPE_DATE; case StandardNames.XS_TIME: return XQItemType.XQBASETYPE_TIME; case StandardNames.XS_DATE_TIME: return XQItemType.XQBASETYPE_DATETIME; case StandardNames.XS_DECIMAL: return XQItemType.XQBASETYPE_DECIMAL; case StandardNames.XS_DOUBLE: return XQItemType.XQBASETYPE_DOUBLE; case StandardNames.XS_DURATION: return XQItemType.XQBASETYPE_DURATION; case StandardNames.XS_FLOAT: return XQItemType.XQBASETYPE_FLOAT; case StandardNames.XS_G_DAY: return XQItemType.XQBASETYPE_GDAY; case StandardNames.XS_G_MONTH: return XQItemType.XQBASETYPE_GMONTH; case StandardNames.XS_G_MONTH_DAY: return XQItemType.XQBASETYPE_GMONTHDAY; case StandardNames.XS_G_YEAR: return XQItemType.XQBASETYPE_GYEAR; case StandardNames.XS_G_YEAR_MONTH: return XQItemType.XQBASETYPE_GYEARMONTH; case StandardNames.XS_HEX_BINARY: return XQItemType.XQBASETYPE_HEXBINARY; case StandardNames.XS_INTEGER: { int sub = value.getItemType().getFingerprint(); switch (sub) { //case StandardNames.XS_INTEGER: return XQItemType.XQBASETYPE_INTEGER; case StandardNames.XS_NEGATIVE_INTEGER: return XQItemType.XQBASETYPE_NEGATIVE_INTEGER; case StandardNames.XS_NON_NEGATIVE_INTEGER: return XQItemType.XQBASETYPE_NONNEGATIVE_INTEGER; case StandardNames.XS_NON_POSITIVE_INTEGER: return XQItemType.XQBASETYPE_NONPOSITIVE_INTEGER; case StandardNames.XS_POSITIVE_INTEGER: return XQItemType.XQBASETYPE_POSITIVE_INTEGER; case StandardNames.XS_UNSIGNED_LONG: return XQItemType.XQBASETYPE_UNSIGNED_LONG; case StandardNames.XS_BYTE: return XQItemType.XQBASETYPE_BYTE; case StandardNames.XS_INT: return XQItemType.XQBASETYPE_INT; case StandardNames.XS_UNSIGNED_SHORT: return XQItemType.XQBASETYPE_UNSIGNED_SHORT; case StandardNames.XS_LONG: return XQItemType.XQBASETYPE_LONG; case StandardNames.XS_UNSIGNED_INT: return XQItemType.XQBASETYPE_UNSIGNED_INT; case StandardNames.XS_SHORT: return XQItemType.XQBASETYPE_SHORT; case StandardNames.XS_UNSIGNED_BYTE: return XQItemType.XQBASETYPE_UNSIGNED_BYTE; default: return XQItemType.XQBASETYPE_INTEGER; } } case StandardNames.XS_STRING: { int sub = value.getItemType().getFingerprint(); switch (sub) { case StandardNames.XS_NAME: return XQItemType.XQBASETYPE_NAME; case StandardNames.XS_NCNAME: return XQItemType.XQBASETYPE_NCNAME; case StandardNames.XS_NMTOKEN: return XQItemType.XQBASETYPE_NMTOKEN; default: return XQItemType.XQBASETYPE_STRING; } } case StandardNames.XS_QNAME: return XQItemType.XQBASETYPE_QNAME; case StandardNames.XS_UNTYPED_ATOMIC: return XQItemType.XQBASETYPE_UNTYPEDATOMIC; case StandardNames.XS_DAY_TIME_DURATION: return XQItemType.XQBASETYPE_DAYTIMEDURATION; case StandardNames.XS_YEAR_MONTH_DURATION: return XQItemType.XQBASETYPE_YEARMONTHDURATION; default: //throw new XPathException("unsupported type"); } return XQItemType.XQBASETYPE_UNTYPEDATOMIC; } */ }