package com.bagri.support.util; import static com.bagri.core.Constants.*; import static javax.xml.datatype.DatatypeConstants.*; import static javax.xml.xquery.XQItemType.*; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.util.Properties; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import javax.xml.xquery.XQDataFactory; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItem; import javax.xml.xquery.XQItemType; import javax.xml.xquery.XQStaticContext; import org.apache.xerces.impl.dv.util.Base64; import org.apache.xerces.util.XMLChar; import org.w3c.dom.Node; import com.bagri.core.api.BagriException; /** * set of XQJ static utilities * * @author Denis Sukhoroslov * */ public class XQUtils { /** * converts XQJ baseType to the corresponding {@link QName}. Return null if the provided type does not correspond to any XQJ type constant. * * @param baseType one of XQJ base type constants * @return QName representation for the type specified */ public static QName getTypeName(int baseType) { switch (baseType) { case XQBASETYPE_ANYATOMICTYPE: return new QName(xs_ns, "anyAtomicType", xs_prefix); case XQBASETYPE_ANYSIMPLETYPE: return new QName(xs_ns, "anySimpleType", xs_prefix); case XQBASETYPE_ANYTYPE: return new QName(xs_ns, "anyType", xs_prefix); case XQBASETYPE_ANYURI: return new QName(xs_ns, "anyURI", xs_prefix); case XQBASETYPE_BASE64BINARY: return new QName(xs_ns, "base64Binary", xs_prefix); case XQBASETYPE_BOOLEAN: return new QName(xs_ns, "boolean", xs_prefix); case XQBASETYPE_BYTE: return new QName(xs_ns, "byte", xs_prefix); case XQBASETYPE_DATE: return new QName(xs_ns, "date"); case XQBASETYPE_DATETIME: return new QName(xs_ns, "dateTime", xs_prefix); case XQBASETYPE_DAYTIMEDURATION: return new QName(xs_ns, "dayTimeDuration", xs_prefix); case XQBASETYPE_DECIMAL: return new QName(xs_ns, "decimal", xs_prefix); case XQBASETYPE_DOUBLE: return new QName(xs_ns, "double", xs_prefix); case XQBASETYPE_DURATION: return new QName(xs_ns, "duration", xs_prefix); case XQBASETYPE_ENTITIES: return new QName(xs_ns, "ENTITIES", xs_prefix); case XQBASETYPE_ENTITY: return new QName(xs_ns, "ENTITY", xs_prefix); case XQBASETYPE_FLOAT: return new QName(xs_ns, "float", xs_prefix); case XQBASETYPE_GDAY: return new QName(xs_ns, "gDay", xs_prefix); case XQBASETYPE_GMONTH: return new QName(xs_ns, "gMonth", xs_prefix); case XQBASETYPE_GMONTHDAY: return new QName(xs_ns, "gMonthDay", xs_prefix); case XQBASETYPE_GYEAR: return new QName(xs_ns, "gYear", xs_prefix); case XQBASETYPE_GYEARMONTH: return new QName(xs_ns, "gYearMonth", xs_prefix); case XQBASETYPE_HEXBINARY: return new QName(xs_ns, "hexBinary", xs_prefix); case XQBASETYPE_ID: return new QName(xs_ns, "ID", xs_prefix); case XQBASETYPE_IDREF: return new QName(xs_ns, "IDREF", xs_prefix); case XQBASETYPE_IDREFS: return new QName(xs_ns, "IDREFS", xs_prefix); case XQBASETYPE_INT: return new QName(xs_ns, "int", xs_prefix); case XQBASETYPE_INTEGER: return new QName(xs_ns, "integer", xs_prefix); case XQBASETYPE_LANGUAGE: return new QName(xs_ns, "language", xs_prefix); case XQBASETYPE_LONG: return new QName(xs_ns, "long", xs_prefix); case XQBASETYPE_NAME: return new QName(xs_ns, "Name", xs_prefix); case XQBASETYPE_NCNAME: return new QName(xs_ns, "NCName", xs_prefix); case XQBASETYPE_NEGATIVE_INTEGER: return new QName(xs_ns, "negativeInteger", xs_prefix); case XQBASETYPE_NMTOKEN: return new QName(xs_ns, "NMTOKEN", xs_prefix); case XQBASETYPE_NMTOKENS: return new QName(xs_ns, "NMTOKENS", xs_prefix); case XQBASETYPE_NONNEGATIVE_INTEGER: return new QName(xs_ns, "nonNegativeInteger", xs_prefix); case XQBASETYPE_NONPOSITIVE_INTEGER: return new QName(xs_ns, "nonPositiveInteger", xs_prefix); case XQBASETYPE_NORMALIZED_STRING: return new QName(xs_ns, "normalizedString", xs_prefix); case XQBASETYPE_NOTATION: return new QName(xs_ns, "NOTATION", xs_prefix); case XQBASETYPE_POSITIVE_INTEGER: return new QName(xs_ns, "positiveInteger", xs_prefix); case XQBASETYPE_QNAME: return new QName(xs_ns, "QName", xs_prefix); case XQBASETYPE_SHORT: return new QName(xs_ns, "short", xs_prefix); case XQBASETYPE_STRING: return new QName(xs_ns, "string", xs_prefix); case XQBASETYPE_TIME: return new QName(xs_ns, "time", xs_prefix); case XQBASETYPE_TOKEN: return new QName(xs_ns, "token", xs_prefix); case XQBASETYPE_UNSIGNED_BYTE: return new QName(xs_ns, "unsignedByte", xs_prefix); case XQBASETYPE_UNSIGNED_INT: return new QName(xs_ns, "unsignedInt", xs_prefix); case XQBASETYPE_UNSIGNED_LONG: return new QName(xs_ns, "unsignedLong", xs_prefix); case XQBASETYPE_UNSIGNED_SHORT: return new QName(xs_ns, "unsignedShort", xs_prefix); case XQBASETYPE_UNTYPED: return new QName(xs_ns, "untyped", xs_prefix); case XQBASETYPE_UNTYPEDATOMIC: return new QName(xs_ns, "untypedAtomic", xs_prefix); case XQBASETYPE_YEARMONTHDURATION: return new QName(xs_ns, "yearMonthDuration", xs_prefix); } return null; } /** * converts String value to its Object representation. The resulting class constructed from the type provided. * * @param baseType one of XQJ base type constants * @param value String representation of the value * @return Object representation of the value */ public static Object getAtomicValue(int baseType, String value) { switch (baseType) { case XQBASETYPE_ANYATOMICTYPE: return value; case XQBASETYPE_ANYSIMPLETYPE: return value; case XQBASETYPE_ANYTYPE: return value; case XQBASETYPE_ANYURI: return URI.create(value); case XQBASETYPE_BASE64BINARY: return Base64.encode(value.getBytes()); case XQBASETYPE_BOOLEAN: return new Boolean(value); case XQBASETYPE_BYTE: return new Byte(value); case XQBASETYPE_DATE: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_DATETIME: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_DAYTIMEDURATION: return XMLUtils.getXMLDuration(value, XQBASETYPE_DAYTIMEDURATION); case XQBASETYPE_DECIMAL: return new BigDecimal(value); case XQBASETYPE_DOUBLE: return new Double(value); case XQBASETYPE_DURATION: return XMLUtils.getXMLDuration(value, XQBASETYPE_DURATION); case XQBASETYPE_ENTITIES: return value; case XQBASETYPE_ENTITY: return value; case XQBASETYPE_FLOAT: return new Float(value); case XQBASETYPE_GDAY: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_GMONTH: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_GMONTHDAY: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_GYEAR: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_GYEARMONTH: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_HEXBINARY: return Base64.encode(value.getBytes()); case XQBASETYPE_ID: return value; case XQBASETYPE_IDREF: return value; case XQBASETYPE_IDREFS: return value; case XQBASETYPE_INT: return new Integer(value); case XQBASETYPE_INTEGER: return new BigInteger(value); case XQBASETYPE_LANGUAGE: return value; case XQBASETYPE_LONG: return new Long(value); case XQBASETYPE_NAME: return value; case XQBASETYPE_NCNAME: return value; case XQBASETYPE_NEGATIVE_INTEGER: return new BigInteger(value); case XQBASETYPE_NMTOKEN: return value; case XQBASETYPE_NMTOKENS: return value; case XQBASETYPE_NONNEGATIVE_INTEGER: return new BigInteger(value); case XQBASETYPE_NONPOSITIVE_INTEGER: return new BigInteger(value); case XQBASETYPE_NORMALIZED_STRING: return value; case XQBASETYPE_NOTATION: return value; case XQBASETYPE_POSITIVE_INTEGER: return new BigInteger(value); case XQBASETYPE_QNAME: return new QName(value); case XQBASETYPE_SHORT: return new Short(value); case XQBASETYPE_STRING: return value; case XQBASETYPE_TIME: return XMLUtils.newXMLCalendar(value); case XQBASETYPE_TOKEN: return value; case XQBASETYPE_UNSIGNED_BYTE: return new Byte(value); case XQBASETYPE_UNSIGNED_INT: return new Integer(value); case XQBASETYPE_UNSIGNED_LONG: return new Long(value); case XQBASETYPE_UNSIGNED_SHORT: return new Short(value); case XQBASETYPE_UNTYPED: return value; case XQBASETYPE_UNTYPEDATOMIC: return value; case XQBASETYPE_YEARMONTHDURATION: return XMLUtils.getXMLDuration(value, XQBASETYPE_YEARMONTHDURATION); } return null; } public static Object getAtomicValue(String typeName, String value) { int baseType = getBaseTypeForTypeName(typeName); return getAtomicValue(baseType, value); } /** * converts {@link QName} to the corresponding XQJ baseType. * Return XQBASETYPE_STRING if the provided typeName's local name is not recognized. * Return XQBASETYPE_ANYTYPE if the provided typeName is not from standard xs: namespace. * * @param typeName the QName type representation * @return one of XQJ base type constants */ public static int getBaseTypeForTypeName(QName typeName) { if (xs_ns.equals(typeName.getNamespaceURI())) { return getBaseTypeForTypeName(typeName.getLocalPart()); } return XQBASETYPE_ANYTYPE; } public static int getBaseTypeForTypeName(String typeName) { switch (typeName) { case "anyAtomicType": return XQBASETYPE_ANYATOMICTYPE; case "anySimpleType": return XQBASETYPE_ANYSIMPLETYPE; case "anyType": return XQBASETYPE_ANYTYPE; case "anyURI": return XQBASETYPE_ANYURI; case "base64Binary": return XQBASETYPE_BASE64BINARY; case "boolean": return XQBASETYPE_BOOLEAN; case "byte": return XQBASETYPE_BYTE; case "date": return XQBASETYPE_DATE; case "dateTime": return XQBASETYPE_DATETIME; case "dayTimeDuration": return XQBASETYPE_DAYTIMEDURATION; case "decimal": return XQBASETYPE_DECIMAL; case "double": return XQBASETYPE_DOUBLE; case "duration": return XQBASETYPE_DURATION; case "ENTITIES": return XQBASETYPE_ENTITIES; case "ENTITY": return XQBASETYPE_ENTITY; case "float": return XQBASETYPE_FLOAT; case "gDay": return XQBASETYPE_GDAY; case "gMonth": return XQBASETYPE_GMONTH; case "gMonthDay": return XQBASETYPE_GMONTHDAY; case "gYear": return XQBASETYPE_GYEAR; case "gYearMonth": return XQBASETYPE_GYEARMONTH; case "hexBinary": return XQBASETYPE_HEXBINARY; case "ID": return XQBASETYPE_ID; case "IDREF": return XQBASETYPE_IDREF; case "IDREFS": return XQBASETYPE_IDREFS; case "int": return XQBASETYPE_INT; case "integer": return XQBASETYPE_INTEGER; case "language": return XQBASETYPE_LANGUAGE; case "long": return XQBASETYPE_LONG; case "Name": return XQBASETYPE_NAME; case "NCName": return XQBASETYPE_NCNAME; case "negativeInteger": return XQBASETYPE_NEGATIVE_INTEGER; case "NMTOKEN": return XQBASETYPE_NMTOKEN; case "NMTOKENS": return XQBASETYPE_NMTOKENS; case "nonNegativeInteger": return XQBASETYPE_NONNEGATIVE_INTEGER; case "nonPositiveInteger": return XQBASETYPE_NONPOSITIVE_INTEGER; case "normalizedString": return XQBASETYPE_NORMALIZED_STRING; case "NOTATION": return XQBASETYPE_NOTATION; case "positiveInteger": return XQBASETYPE_POSITIVE_INTEGER; case "QName": return XQBASETYPE_QNAME; case "short": return XQBASETYPE_SHORT; case "string": return XQBASETYPE_STRING; case "time": return XQBASETYPE_TIME; case "token": return XQBASETYPE_TOKEN; case "unsignedByte": return XQBASETYPE_UNSIGNED_BYTE; case "unsignedInt": return XQBASETYPE_UNSIGNED_INT; case "unsignedLong": return XQBASETYPE_UNSIGNED_LONG; case "unsignedShort": return XQBASETYPE_UNSIGNED_SHORT; case "untyped": return XQBASETYPE_UNTYPED; case "untypedAtomic": return XQBASETYPE_UNTYPEDATOMIC; case "yearMonthDuration": return XQBASETYPE_YEARMONTHDURATION; } return XQBASETYPE_STRING; } /** * checks if the provided XQJ base type constant corresponds to XQJ atomic type or not * * @param type one of XQJ base type constants * @return true if the {@code type} corresponds to XQJ atomic type, false otherwise */ public static boolean isAtomicType(int type) { return type >= XQBASETYPE_ANYATOMICTYPE && type <= XQBASETYPE_ENTITY; } /** * checks if XQJ base type feature is supported by the data kind provided * * @param kind one of XQJ data kind constants * @return true if base type supported for this data kind, false otherwise */ public static boolean isBaseTypeSupported(int kind) { return kind == XQITEMKIND_DOCUMENT_ELEMENT || kind == XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT || kind == XQITEMKIND_ELEMENT || kind == XQITEMKIND_SCHEMA_ELEMENT || kind == XQITEMKIND_ATTRIBUTE || kind == XQITEMKIND_SCHEMA_ATTRIBUTE || kind == XQITEMKIND_ATOMIC; } /** * checks if the node name feature is supported by the data kind provided * * @param kind one of XQJ data kind constants * @return true if node name is supported, false otherwise */ public static boolean isNodeNameSupported(int kind) { return kind == XQITEMKIND_DOCUMENT_ELEMENT || kind == XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT || kind == XQITEMKIND_ELEMENT || kind == XQITEMKIND_SCHEMA_ELEMENT || kind == XQITEMKIND_ATTRIBUTE || kind == XQITEMKIND_SCHEMA_ATTRIBUTE; } /** * checks if the processing instructions name feature is supported by the data kind provided * * @param kind one of XQJ data kind constants * @return true if processing instruction name is supported, false otherwise */ public static boolean isPINameSupported(int kind) { return kind == XQITEMKIND_PI; } /** * checks if the provided XQJ base type constant is assignable from String * * @param baseType one of XQJ base type constants * @return true if the value of the type is compatible with String, false otherwise */ public static boolean isStringTypeCompatible(int baseType) { return baseType == XQBASETYPE_ANYATOMICTYPE || baseType == XQBASETYPE_ANYSIMPLETYPE || baseType == XQBASETYPE_ANYTYPE || baseType == XQBASETYPE_ENTITIES || baseType == XQBASETYPE_ENTITY || baseType == XQBASETYPE_ID || baseType == XQBASETYPE_IDREF || baseType == XQBASETYPE_IDREF || baseType == XQBASETYPE_LANGUAGE || baseType == XQBASETYPE_NAME || baseType == XQBASETYPE_NCNAME || baseType == XQBASETYPE_NMTOKEN || baseType == XQBASETYPE_NMTOKENS || baseType == XQBASETYPE_NORMALIZED_STRING || baseType == XQBASETYPE_NOTATION || baseType == XQBASETYPE_STRING || baseType == XQBASETYPE_TOKEN || baseType == XQBASETYPE_UNTYPED || baseType == XQBASETYPE_UNTYPEDATOMIC; } /** * checks if the provided XQJ base type constant is compatible with provided {@code value} * * @param baseType one of XQJ base type constants * @param value the Object value representation * @return true if the type is compatible with the value, false otherwise */ public static boolean isTypeValueCompatible(int baseType, Object value) { String sval = value.toString(); switch (baseType) { case XQBASETYPE_ANYATOMICTYPE: case XQBASETYPE_ANYSIMPLETYPE: case XQBASETYPE_ANYTYPE: return true; case XQBASETYPE_ANYURI: if (value instanceof URI) { return true; } else if (value instanceof String) { try { URI.create(sval); return true; } catch (Exception ex) { // } } return false; case XQBASETYPE_BASE64BINARY: return true; //? case XQBASETYPE_BOOLEAN: if (value instanceof Boolean) { return true; } else if (value instanceof String) { try { Boolean.parseBoolean(sval); return true; } catch (Exception e) { // } } return false; case XQBASETYPE_BYTE: case XQBASETYPE_UNSIGNED_BYTE: if (value instanceof Byte) { return true; } try { Byte.parseByte(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_DECIMAL: if (value instanceof BigDecimal) { return true; } try { new BigDecimal(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_DOUBLE: if (value instanceof Double) { return true; } try { Double.parseDouble(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_DURATION: case XQBASETYPE_DAYTIMEDURATION: case XQBASETYPE_YEARMONTHDURATION: if (value instanceof Duration) { return true; } return false; case XQBASETYPE_ENTITIES: case XQBASETYPE_ENTITY: return true; case XQBASETYPE_FLOAT: if (value instanceof Float) { return true; } try { Float.parseFloat(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_DATE: case XQBASETYPE_DATETIME: case XQBASETYPE_TIME: case XQBASETYPE_GDAY: case XQBASETYPE_GMONTH: case XQBASETYPE_GMONTHDAY: case XQBASETYPE_GYEAR: case XQBASETYPE_GYEARMONTH: if (value instanceof XMLGregorianCalendar) { return true; } return false; case XQBASETYPE_HEXBINARY: case XQBASETYPE_ID: case XQBASETYPE_IDREF: case XQBASETYPE_IDREFS: return true; case XQBASETYPE_INT: case XQBASETYPE_UNSIGNED_INT: if (value instanceof Integer) { return true; } try { Integer.parseInt(sval); return true; } catch (Exception e) { // } return false; case XQBASETYPE_INTEGER: case XQBASETYPE_NEGATIVE_INTEGER: case XQBASETYPE_NONNEGATIVE_INTEGER: case XQBASETYPE_NONPOSITIVE_INTEGER: case XQBASETYPE_POSITIVE_INTEGER: if (value instanceof BigInteger) { return true; } try { new BigInteger(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_LANGUAGE: return true; //? case XQBASETYPE_LONG: case XQBASETYPE_UNSIGNED_LONG: if (value instanceof Long) { return true; } try { Long.parseLong(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_NAME: return true; case XQBASETYPE_NCNAME: if (XMLChar.isValidNCName(sval)) { return true; } return false; case XQBASETYPE_NMTOKEN: case XQBASETYPE_NMTOKENS: case XQBASETYPE_NORMALIZED_STRING: case XQBASETYPE_NOTATION: case XQBASETYPE_QNAME: return true; case XQBASETYPE_SHORT: case XQBASETYPE_UNSIGNED_SHORT: if (value instanceof Short) { return true; } try { Integer.parseInt(sval); return true; } catch (Exception e) { } return false; case XQBASETYPE_STRING: return true; case XQBASETYPE_TOKEN: case XQBASETYPE_UNTYPED: case XQBASETYPE_UNTYPEDATOMIC: return true; } return false; } /** * constructs XQJ item type for the {@code value} specified * * @param factory the XQJ data factory to produce XQ item type * @param value the value to get item type from * @return XQ item type * @throws XQException in case of construction error */ public static XQItemType getTypeForObject(XQDataFactory factory, Object value) throws XQException { if (value instanceof org.w3c.dom.Node) { return getTypeForNode(factory, (org.w3c.dom.Node) value); } int baseType = XQBASETYPE_ANYATOMICTYPE; //XQBASETYPE_ANYTYPE; if (value instanceof XQItem) { value = ((XQItem) value).getObject(); } if (value instanceof Integer) { baseType = XQBASETYPE_INT; } else if (value instanceof Long) { baseType = XQBASETYPE_LONG; } else if (value instanceof Double) { baseType = XQBASETYPE_DOUBLE; } else if (value instanceof Boolean) { baseType = XQBASETYPE_BOOLEAN; } else if (value instanceof Short) { baseType = XQBASETYPE_SHORT; } else if (value instanceof Float) { baseType = XQBASETYPE_FLOAT; } else if (value instanceof Byte) { baseType = XQBASETYPE_BYTE; } else if (value instanceof String) { baseType = XQBASETYPE_STRING; } else if (value instanceof java.math.BigDecimal) { baseType = XQBASETYPE_DECIMAL; } else if (value instanceof java.math.BigInteger) { baseType = XQBASETYPE_INTEGER; } else if (value instanceof javax.xml.datatype.Duration) { javax.xml.datatype.Duration d = (javax.xml.datatype.Duration) value; boolean setYM = d.isSet(YEARS) || d.isSet(MONTHS); boolean setDT = d.isSet(DAYS) || d.isSet(HOURS) || d.isSet(MINUTES) || d.isSet(SECONDS); if (setYM) { if (setDT) { baseType = XQBASETYPE_DURATION; } else { baseType = XQBASETYPE_YEARMONTHDURATION; } } else { baseType = XQBASETYPE_DAYTIMEDURATION; } } else if (value instanceof javax.xml.datatype.XMLGregorianCalendar) { javax.xml.datatype.XMLGregorianCalendar c = (javax.xml.datatype.XMLGregorianCalendar) value; boolean setYear = c.getYear() != FIELD_UNDEFINED; boolean setMonth = c.getMonth() != FIELD_UNDEFINED; boolean setDay = c.getDay() != FIELD_UNDEFINED; boolean setHour = c.getHour() != FIELD_UNDEFINED; boolean setMinute = c.getMinute() != FIELD_UNDEFINED; boolean setSecond = c.getSecond() != FIELD_UNDEFINED; if (setYear) { if (setMonth) { if (setDay) { if (setHour || setMinute || setSecond) { baseType = XQBASETYPE_DATETIME; } else { baseType = XQBASETYPE_DATE; } } else { baseType = XQBASETYPE_GYEARMONTH; } } else { baseType = XQBASETYPE_GYEAR; } } else { if (setMonth) { if (setDay) { baseType = XQBASETYPE_GMONTHDAY; } else { baseType = XQBASETYPE_GMONTH; } } else { if (setDay) { baseType = XQBASETYPE_GDAY; } else { if (setHour || setMinute || setSecond) { baseType = XQBASETYPE_TIME; } else { throw new XQException("Unknown Calendar type: " + c); } } } } } else if (value instanceof javax.xml.namespace.QName) { baseType = XQBASETYPE_QNAME; } return factory.createAtomicType(baseType, getTypeName(baseType), null); } /** * constructs XQJ item type for the w3c {@link Node} instance provided * * @param factory the XQJ data factory to produce XQ item type * @param node w3c XML Node instance * @return XQ item type * @throws XQException in case of processing error */ public static XQItemType getTypeForNode(XQDataFactory factory, org.w3c.dom.Node node) throws XQException { switch (node.getNodeType()) { case Node.DOCUMENT_NODE: return factory.createDocumentType(); case Node.DOCUMENT_FRAGMENT_NODE: return factory.createDocumentType(); case Node.ELEMENT_NODE: return factory.createElementType(new QName(node.getNodeName()), XQItemType.XQBASETYPE_ANYTYPE); case Node.ATTRIBUTE_NODE: return factory.createAttributeType(new QName(node.getNodeName()), XQItemType.XQBASETYPE_ANYSIMPLETYPE); case Node.COMMENT_NODE: return factory.createCommentType(); case Node.PROCESSING_INSTRUCTION_NODE: return factory.createProcessingInstructionType(null); case Node.TEXT_NODE: return factory.createTextType(); default: return factory.createNodeType(); } } /** * a utility method to extract XQ exception information from the error stack provided * * @param ex the full error chain * @return XQ exception */ public static XQException getXQException(Throwable ex) { int errorCode = 0; Throwable cause = null; String message = ""; while (ex != null) { if (ex instanceof XQException) { return (XQException) ex; } else if (/*errorCode == 0 &&*/ ex instanceof BagriException) { // deeper is better! message += ex.getMessage() + "; "; errorCode = ((BagriException) ex).getErrorCode(); cause = ex; } ex = ex.getCause(); } XQException xqe = new XQException(message, String.valueOf(errorCode)); xqe.initCause(cause); return xqe; } /** * converts XQuery Static Context to set of Properties * * @param ctx XQuery context * @return java Properties * @throws XQException in case of conversion error */ public static Properties context2Props(XQStaticContext ctx) throws XQException { Properties result = new Properties(); result.put(pn_xqj_baseURI, ctx.getBaseURI()); result.setProperty(pn_xqj_bindingMode, String.valueOf(ctx.getBindingMode())); result.setProperty(pn_xqj_boundarySpacePolicy, String.valueOf(ctx.getBoundarySpacePolicy())); result.setProperty(pn_xqj_constructionMode, String.valueOf(ctx.getConstructionMode())); //ctx.getContextItemStaticType() result.setProperty(pn_xqj_copyNamespacesModeInherit, String.valueOf(ctx.getCopyNamespacesModeInherit())); result.setProperty(pn_xqj_copyNamespacesModePreserve, String.valueOf(ctx.getCopyNamespacesModePreserve())); result.setProperty(pn_xqj_defaultCollationUri, ctx.getDefaultCollation()); result.setProperty(pn_xqj_defaultElementTypeNamespace, ctx.getDefaultElementTypeNamespace()); result.setProperty(pn_xqj_defaultFunctionNamespace, ctx.getDefaultFunctionNamespace()); if (ctx.getNamespacePrefixes().length > 0) { StringBuffer namespaces = new StringBuffer(); for (String prefix: ctx.getNamespacePrefixes()) { namespaces.append(prefix).append(":").append(ctx.getNamespaceURI(prefix)); namespaces.append(" "); } result.put(pn_xqj_defaultNamespaces, namespaces.toString()); } result.setProperty(pn_xqj_defaultOrderForEmptySequences, String.valueOf(ctx.getDefaultOrderForEmptySequences())); result.setProperty(pn_xqj_holdability, String.valueOf(ctx.getHoldability())); result.setProperty(pn_xqj_orderingMode, String.valueOf(ctx.getOrderingMode())); result.setProperty(pn_xqj_queryLanguageTypeAndVersion, String.valueOf(ctx.getQueryLanguageTypeAndVersion())); result.setProperty(pn_xqj_queryTimeout, String.valueOf(ctx.getQueryTimeout())); result.setProperty(pn_xqj_scrollability, String.valueOf(ctx.getScrollability())); return result; } /** * converts set of Properties to XQuery Static Context * * @param props source Properties to convert * @param ctx target XQuery context * @throws XQException in case of conversion error */ public static void props2Context(Properties props, XQStaticContext ctx) throws XQException { String prop = props.getProperty(pn_xqj_baseURI); if (prop != null) { ctx.setBaseURI(prop); } prop = props.getProperty(pn_xqj_bindingMode); if (prop != null) { ctx.setBindingMode(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_boundarySpacePolicy); if (prop != null) { ctx.setBoundarySpacePolicy(Integer.valueOf(prop)); } // pass it as URI!? //ctx.setContextItemStaticType(...) prop = props.getProperty(pn_xqj_constructionMode); if (prop != null) { ctx.setConstructionMode(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_copyNamespacesModeInherit); if (prop != null) { ctx.setCopyNamespacesModeInherit(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_copyNamespacesModePreserve); if (prop != null) { ctx.setCopyNamespacesModePreserve(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_defaultCollationUri); if (prop != null) { ctx.setDefaultCollation(prop); } prop = props.getProperty(pn_xqj_defaultElementTypeNamespace); if (prop != null) { ctx.setDefaultElementTypeNamespace(prop); } prop = props.getProperty(pn_xqj_defaultFunctionNamespace); if (prop != null) { ctx.setDefaultFunctionNamespace(prop); } prop = props.getProperty(pn_xqj_defaultNamespaces); if (prop != null) { String[] nspaces = prop.split(" "); for (String ns: nspaces) { int pos = ns.indexOf(":"); ctx.declareNamespace(ns.substring(0, pos), ns.substring(pos + 1)); } } prop = props.getProperty(pn_xqj_defaultOrderForEmptySequences); if (prop != null) { ctx.setDefaultOrderForEmptySequences(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_holdability); if (prop != null) { ctx.setHoldability(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_orderingMode); if (prop != null) { ctx.setOrderingMode(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_queryLanguageTypeAndVersion); if (prop != null) { ctx.setQueryLanguageTypeAndVersion(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_queryTimeout); if (prop != null) { ctx.setQueryTimeout(Integer.valueOf(prop)); } prop = props.getProperty(pn_xqj_scrollability); if (prop != null) { ctx.setScrollability(Integer.valueOf(prop)); } } }