/** * $Id: $ * $Date: $ * */ package org.xmlsh.marklogic.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.xml.transform.stream.StreamSource; import net.sf.saxon.om.Item; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.om.Sequence; import net.sf.saxon.om.SequenceTool; import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.XdmAtomicValue; import net.sf.saxon.trans.XPathException; import net.sf.saxon.value.AtomicValue; import org.xmlsh.core.CoreException; import org.xmlsh.core.InvalidArgumentException; import org.xmlsh.core.XValue; import org.xmlsh.core.io.IXdmItemOutputStream; import org.xmlsh.core.io.OutputPort; import org.xmlsh.sh.shell.SerializeOpts; import org.xmlsh.sh.shell.Shell; import org.xmlsh.util.Util; import com.marklogic.xcc.types.XdmItem; import com.marklogic.xcc.ResultItem; import com.marklogic.xcc.ResultSequence; import com.marklogic.xcc.SecurityOptions; import com.marklogic.xcc.ValueFactory; import com.marklogic.xcc.types.ItemType; import com.marklogic.xcc.types.ValueType; import com.marklogic.xcc.types.XName; import com.marklogic.xcc.types.XSBoolean; import com.marklogic.xcc.types.XSDate; import com.marklogic.xcc.types.XSDecimal; import com.marklogic.xcc.types.XSDouble; import com.marklogic.xcc.types.XSDuration; import com.marklogic.xcc.types.XSFloat; import com.marklogic.xcc.types.XSGDay; import com.marklogic.xcc.types.XSGMonth; import com.marklogic.xcc.types.XSGYearMonth; import com.marklogic.xcc.types.XSHexBinary; import com.marklogic.xcc.types.XSInteger; import com.marklogic.xcc.types.XSQName; import com.marklogic.xcc.types.XSString; import com.marklogic.xcc.types.XSUntypedAtomic; import com.marklogic.xcc.types.XdmAttribute; import com.marklogic.xcc.types.XdmVariable; public class MLUtil { public static SecurityOptions newTrustOptions(URI uri) throws Exception { return newTrustOptions( uri.getScheme() ); } public static SecurityOptions newTrustOptions(String scheme) throws Exception { if( !scheme.equals("xccs")) return null ; TrustManager[] trust = new TrustManager[] { new X509TrustManager() { public void checkClientTrusted( X509Certificate[] x509Certificates, String s) throws CertificateException // nothing to do { } public void checkServerTrusted( X509Certificate[] x509Certificates, String s) throws CertificateException { // nothing to do } public X509Certificate[] getAcceptedIssuers() { return null; } } }; SSLContext sslContext = SSLContext.getInstance("SSLv3"); sslContext.init(null, trust, null); return new SecurityOptions(sslContext); } public static String quote(String s) { return "'" + s.replace("'", "''").replace("&", "&").replace("<", "<") + "'"; } public static XdmVariable newVariable(String name, XValue value, SerializeOpts opts) throws XPathException, InvalidArgumentException, SaxonApiException, IOException { XName xname = new XName(name); com.marklogic.xcc.types.XdmValue xvalue = MLUtil.newValue(value, opts); XdmVariable var = ValueFactory.newVariable(xname, xvalue); return var; } public static XdmVariable newVariable(String name, com.marklogic.xcc.types.XdmValue xvalue) throws XPathException, InvalidArgumentException, SaxonApiException { XName xname = new XName(name); XdmVariable var = ValueFactory.newVariable(xname, xvalue); return var; } public static XdmVariable newVariable(String name, String value) { XName xname = new XName(name); XdmVariable var = ValueFactory.newVariable(xname, ValueFactory.newXSString(value ) ); return var; } /* * Create a marklogic XdmValue from an XValue * * Truncates sequences to 1 element because ML doesnt support sequences */ public static com.marklogic.xcc.types.XdmValue newValue(XValue value, SerializeOpts opts) throws XPathException, InvalidArgumentException, SaxonApiException, IOException { if( ! value.isXdmItem() ){ String s = value.toString(); return ValueFactory.newXSString(s); } net.sf.saxon.s9api.XdmItem item = value.asXdmItem(); if (item.isAtomicValue()) { net.sf.saxon.value.AtomicValue atom = (net.sf.saxon.value.AtomicValue) item .getUnderlyingValue(); // int type = atom.getItemType(null).getPrimitiveType(); if (atom instanceof net.sf.saxon.value.Base64BinaryValue) { byte[] v = ((net.sf.saxon.value.Base64BinaryValue) atom).getBinaryValue(); return ValueFactory.newBinaryNode(v); } else if (atom instanceof net.sf.saxon.value.BooleanValue) { boolean v = ((net.sf.saxon.value.BooleanValue) atom).effectiveBooleanValue(); return ValueFactory.newXSBoolean(v); } else if (atom instanceof net.sf.saxon.value.DateTimeValue) { String v = ((net.sf.saxon.value.DateTimeValue) atom).toString(); return ValueFactory.newXSDateTime(v, null, null); } else if (atom instanceof net.sf.saxon.value.GDateValue) { String v = ((net.sf.saxon.value.GDateValue) atom).toString(); return ValueFactory.newXSDate(v, null, null); } else if (atom instanceof net.sf.saxon.value.TimeValue) { String v = ((net.sf.saxon.value.TimeValue) atom).toString(); return ValueFactory.newXSTime(v, null, null); } else if (atom instanceof net.sf.saxon.value.DurationValue) { String v = ((net.sf.saxon.value.DurationValue) atom).toString(); return ValueFactory.newXSDuration(v); } else if (atom instanceof net.sf.saxon.value.HexBinaryValue) { byte b[] = ((net.sf.saxon.value.HexBinaryValue) atom).getBinaryValue(); return ValueFactory.newBinaryNode(b); } else if (atom instanceof net.sf.saxon.value.IntegerValue) { BigInteger v = ((net.sf.saxon.value.IntegerValue) atom).asBigInteger(); return ValueFactory.newXSInteger(v); } else if (atom instanceof net.sf.saxon.value.DecimalValue) { BigDecimal v = ((net.sf.saxon.value.DecimalValue) atom).getDecimalValue(); return ValueFactory.newValue(ValueType.XS_DECIMAL, v); } else if (atom instanceof net.sf.saxon.value.DoubleValue) { Double v = ((net.sf.saxon.value.DoubleValue) atom).getDoubleValue(); // box return ValueFactory.newValue(ValueType.XS_DOUBLE , v); } else if (atom instanceof net.sf.saxon.value.FloatValue) { Double v = ((net.sf.saxon.value.FloatValue) atom).getDoubleValue(); // box return ValueFactory.newValue(ValueType.XS_FLOAT , v); } else if (atom instanceof net.sf.saxon.value.NumericValue) { long v = ((net.sf.saxon.value.IntegerValue) atom).longValue(); return ValueFactory.newXSInteger(v); } else { return ValueFactory.newXSString(atom.getStringValue()); } } // Node node = // NodeOverNodeInfo.wrap(value.asXdmNode().getUnderlyingNode()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); Util.writeXdmValue(value.asXdmNode(), Util.streamToDestination(buf, opts)); InputStream is = new ByteArrayInputStream(buf.toByteArray()); return ValueFactory.newElement(is); } /** * Get the effective boolean value of the expression. This returns false if * the value is the empty sequence, a zero-length string, a number equal to * zero, or the boolean false. Otherwise it returns true. * * @throws InvalidArgumentException */ public static boolean effectiveBoolean(ResultSequence rs) throws InvalidArgumentException { // Empty sequence if (rs.isEmpty()) return false; if (rs.size() > 1) throw new InvalidArgumentException("Boolean value undefined for sequence of > 1 item"); XdmItem item = rs.itemAt(0); ItemType type = item.getItemType(); if (type.isAtomic()) { // Zero length string if (item instanceof XSString) return ((XSString) item).asString().length() == 0 ? false : true; // Numeber eq if (item instanceof XSInteger) return ((XSInteger) item).asPrimitiveInt() == 0 ? false : true; // Boolean if (item instanceof XSBoolean) return ((XSBoolean) item).asPrimitiveBoolean(); } return true; } public static BigInteger[] toBigIntArray(List<XValue> values) { BigInteger bi[] = new BigInteger[ values.size() ]; int i = 0; for( XValue v : values ) bi[i++] = new BigInteger( v.toString() ); return bi; } public static boolean isAtomic(net.sf.saxon.s9api.XdmItem item) { if( item == null ) return true ; @SuppressWarnings("rawtypes") Sequence value = item.getUnderlyingValue(); Item i; try { i = SequenceTool.asItem(value); } catch (XPathException e) { return false ; } boolean isAtom = ( i instanceof AtomicValue ) || ( value instanceof NodeInfo && ((NodeInfo)value).getNodeKind() == net.sf.saxon.type.Type.TEXT ) ; return isAtom; } public static byte[] bytesFromItem( net.sf.saxon.s9api.XdmItem item, SerializeOpts opts ) throws SaxonApiException, IOException { if( isAtomic(item) ) return item.toString().getBytes("UTF8"); ByteArrayOutputStream buf = new ByteArrayOutputStream(); Util.writeXdmItem(item, Util.streamToDestination(buf, opts)); // uses output xml encoding return buf.toByteArray(); } public static net.sf.saxon.s9api.XdmItem asSaxonItem( XdmItem it ) throws SaxonApiException, IOException { ItemType type = it.getItemType(); if( type.isAtomic() ){ if( it instanceof XSBoolean ) return new XdmAtomicValue( ((XSBoolean)it).asPrimitiveBoolean() ); else if( it instanceof XSDate ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.DATE ); else if( it instanceof XSDecimal ) return new XdmAtomicValue( ((XSDecimal)it).asBigDecimal() ); else if( it instanceof XSDouble ) return new XdmAtomicValue( ((XSDouble)it).asPrimitiveDouble() ); else if( it instanceof XSDuration ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.DURATION ); else if( it instanceof XSFloat ) return new XdmAtomicValue( ((XSFloat)it).asPrimitiveFloat() ); else if( it instanceof XSGDay ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.G_DAY ); else if( it instanceof XSGMonth ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.G_MONTH ); else if( it instanceof XSGYearMonth ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.G_YEAR_MONTH ); else if( it instanceof XSHexBinary) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.HEX_BINARY); else if( it instanceof XSInteger) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.INTEGER ); else if( it instanceof XSQName ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.QNAME ); else if( it instanceof XSString ) return new XdmAtomicValue( ((XSString) it).toString() ); else if( it instanceof XSUntypedAtomic ) return new XdmAtomicValue( it.toString() , net.sf.saxon.s9api.ItemType.UNTYPED_ATOMIC ); else return new XdmAtomicValue( it.toString() ); } else if( type.isNode() ){ if( it instanceof XdmAttribute ) return new XdmAtomicValue( it.toString() ); else if( it instanceof XdmAttribute ) return new XdmAtomicValue( it.toString() ); else return Shell.getProcessor().newDocumentBuilder().build( new StreamSource( it.asReader()) ); } else return new XdmAtomicValue( it.toString() ); } public static boolean writeResult(ResultSequence rs, OutputPort out, SerializeOpts sopts, boolean asText, boolean bBinary) throws InvalidArgumentException, IOException, CoreException, SaxonApiException { IXdmItemOutputStream ser = null ; OutputStream os = null ; PrintWriter writer = null; if( bBinary ) os = out.asOutputStream(sopts); else if( asText ) writer = out.asPrintWriter(sopts); else ser = out.asXdmItemOutputStream(sopts); boolean bFirst = true ; boolean bAnyOut = false ; while (rs.hasNext()) { ResultItem rsItem = rs.next(); XdmItem it = rsItem.getItem(); bAnyOut = true ; if( ! bFirst ) out.writeSequenceSeperator(sopts); // Thrashes variable output ! bFirst = false ; if( bBinary ) rsItem.writeTo(os ); else if( asText ) rsItem.writeTo( writer ); else { net.sf.saxon.s9api.XdmItem item = null ; if (asText ) { item = new XdmAtomicValue( it.asString()); } else item = asSaxonItem( it ); ser.write(item); } } return bAnyOut; } public static XdmVariable newVariable(String name, long value) { XName xname = new XName(name); XdmVariable var = ValueFactory.newVariable(xname, ValueFactory.newXSInteger(value) ); return var; } public static int getIntValue(Object value) { if( value instanceof String ) return Integer.parseInt((String) value); if( value instanceof Integer ) return ((Integer)value).intValue(); if( value instanceof Long ) return ((Long)value).intValue() ; return Integer.parseInt(value.toString()); } } /* * Copyright (C) 2008-2014 David A. Lee. * * The contents of this file are subject to the "Simplified BSD License" (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy of the * License at http://www.opensource.org/licenses/bsd-license.php * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights and limitations under the License. * * The Original Code is: all this file. * * The Initial Developer of the Original Code is David A. Lee * * Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved. * * Contributor(s): David A. Lee * */