package org.basex.api.xqj; import static org.basex.api.xqj.BXQText.ATT; import static org.basex.api.xqj.BXQText.ELM; import static org.basex.api.xqj.BXQText.OCC; import static org.basex.api.xqj.BXQText.OCCINV; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.Reader; import java.net.URI; import java.util.Iterator; 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.XQItemType; import javax.xml.xquery.XQSequence; import javax.xml.xquery.XQSequenceType; import org.basex.io.IOContent; import org.basex.query.QueryException; import org.basex.query.item.AtomType; import org.basex.query.item.Bln; import org.basex.query.item.Dbl; import org.basex.query.item.Flt; import org.basex.query.item.Int; import org.basex.query.item.NodeType; import org.basex.query.item.Str; import org.basex.query.item.Type; import org.basex.query.iter.ItemCache; import org.basex.util.Token; import org.basex.util.Util; import org.w3c.dom.Node; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSOutput; import org.xml.sax.XMLReader; /** * Java XQuery API - Data Factory. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ class BXQDataFactory extends BXQAbstract implements XQDataFactory { /** * Constructor, specifying a user name and password. * @param name user name * @param pw password * @throws XQException if authentication fails */ protected BXQDataFactory(final String name, final String pw) throws XQException { super(null); context = new BXQStaticContext(name, pw); } @Override public BXQItemType createAtomicType(final int b, final QName qn, final URI uri) throws XQException { return createAtomicType(b); } @Override public BXQItemType createAtomicType(final int b) throws XQException { opened(); return new BXQItemType(b); } @Override public BXQItemType createAttributeType(final QName qn, final int it, final QName qn2, final URI uri) throws XQException { return createAttributeType(qn, it); } @Override public BXQItemType createAttributeType(final QName qn, final int it) throws XQException { opened(); checkAttr(it); return new BXQItemType(NodeType.ATT, qn, it); } @Override public BXQItemType createCommentType() throws XQException { opened(); return new BXQItemType(NodeType.COM); } @Override public BXQItemType createDocumentElementType(final XQItemType it) throws XQException { opened(); valid(it, XQItemType.class); if(it.getItemKind() != XQItemType.XQITEMKIND_ELEMENT) throw new BXQException(ELM); return new BXQItemType(NodeType.DEL, it.getNodeName(), it.getBaseType()); } @Override public BXQItemType createDocumentSchemaElementType(final XQItemType it) throws XQException { opened(); valid(it, XQItemType.class); if(it.getItemKind() != XQItemType.XQITEMKIND_SCHEMA_ELEMENT) throw new BXQException(ELM); return new BXQItemType(NodeType.DEL, it.getNodeName(), it.getBaseType()); } @Override public BXQItemType createDocumentType() throws XQException { opened(); return new BXQItemType(NodeType.DOC); } @Override public BXQItemType createElementType(final QName qn, final int it, final QName qn2, final URI uri, final boolean n) throws XQException { opened(); return new BXQItemType(NodeType.ELM, qn, it); } @Override public BXQItemType createElementType(final QName qn, final int it) throws XQException { return createElementType(qn, it, null, null, false); } @Override public BXQItem createItem(final XQItem v) throws XQException { opened(); valid(v, XQItem.class); try { final Type type = ((BXQItemType) v.getItemType()).getType(); return new BXQItem(type.cast(((BXQItem) v).it, null, null)); } catch(final QueryException ex) { throw new BXQException(ex); } } @Override public BXQItem createItemFromAtomicValue(final String v, final XQItemType it) throws XQException { valid(it, XQItemType.class); try { final Str val = Str.get(valid(v, String.class)); return new BXQItem(check(AtomType.STR, it).cast(val, null, null)); } catch(final QueryException ex) { throw new BXQException(ex); } } @Override public BXQItem createItemFromBoolean(final boolean v, final XQItemType it) throws XQException { check(AtomType.BLN, it); return new BXQItem(Bln.get(v)); } @Override public BXQItem createItemFromByte(final byte v, final XQItemType it) throws XQException { return itr(v, AtomType.BYT, it); } @Override public BXQItem createItemFromDocument(final InputStream is, final String base, final XQItemType it) throws XQException { check(NodeType.DOC, it); return new BXQItem(createNode(is)); } @Override public BXQItem createItemFromDocument(final Reader r, final String base, final XQItemType it) throws XQException { check(NodeType.DOC, it); return new BXQItem(createNode(r)); } @Override public BXQItem createItemFromDocument(final Source s, final XQItemType it) throws XQException { return new BXQItem(createNode(s, it)); } @Override public BXQItem createItemFromDocument(final String v, final String base, final XQItemType it) throws XQException { valid(v, String.class); check(NodeType.DOC, it); return new BXQItem(createNode(new IOContent(Token.token(v)))); } @Override public BXQItem createItemFromDocument(final XMLStreamReader sr, final XQItemType it) throws XQException { check(NodeType.DOC, it); return new BXQItem(createNode(sr)); } @Override public BXQItem createItemFromDouble(final double v, final XQItemType it) throws XQException { check(AtomType.DBL, it); return new BXQItem(Dbl.get(v)); } @Override public BXQItem createItemFromFloat(final float v, final XQItemType it) throws XQException { check(AtomType.FLT, it); return new BXQItem(Flt.get(v)); } @Override public BXQItem createItemFromInt(final int v, final XQItemType it) throws XQException { return itr(v, AtomType.INT, it); } @Override public BXQItem createItemFromLong(final long v, final XQItemType it) throws XQException { return itr(v, AtomType.LNG, it); } @Override public BXQItem createItemFromNode(final Node v, final XQItemType it) throws XQException { opened(); check(NodeType.DOC, it); valid(v, Node.class); final ByteArrayOutputStream ba = new ByteArrayOutputStream(); try { final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); final LSOutput output = impl.createLSOutput(); output.setByteStream(ba); impl.createLSSerializer().write(v, output); } catch(final Exception ex) { Util.stack(ex); } return new BXQItem(createNode(new IOContent(ba.toByteArray()))); } @Override public BXQItem createItemFromObject(final Object v, final XQItemType t) throws XQException { return new BXQItem(create(v, t)); } @Override public BXQItem createItemFromShort(final short v, final XQItemType it) throws XQException { return itr(v, AtomType.SHR, it); } @Override public BXQItem createItemFromString(final String v, final XQItemType it) throws XQException { try { final Str val = Str.get(valid(v, String.class)); return new BXQItem(check(AtomType.STR, it).cast(val, null, null)); } catch(final QueryException ex) { throw new BXQException(ex); } } @Override public BXQItemType createItemType() throws XQException { opened(); return new BXQItemType(AtomType.ITEM); } @Override public BXQItemType createNodeType() throws XQException { opened(); return new BXQItemType(NodeType.NOD); } @Override public BXQItemType createProcessingInstructionType(final String nm) throws XQException { opened(); final QName name = nm == null ? null : new QName(nm); return new BXQItemType(NodeType.PI, name, -1); } @Override public BXQItemType createSchemaAttributeType(final QName qn, final int it, final URI uri) throws XQException { opened(); checkAttr(it); return new BXQItemType(NodeType.ATT, qn, it); } @Override public BXQItemType createSchemaElementType(final QName qn, final int it, final URI uri) throws XQException { opened(); return new BXQItemType(NodeType.ELM, qn, it); } @Override @SuppressWarnings("rawtypes") public BXQSequence createSequence(final Iterator it) throws XQException { opened(); valid(it, Iterator.class); final ItemCache ic = new ItemCache(); while(it.hasNext()) ic.add(create(it.next(), null)); return new BXQSequence(ic, this); } @Override public BXQSequence createSequence(final XQSequence seq) throws XQException { opened(); valid(seq, XQSequence.class); final BXQSequence s = (BXQSequence) seq; s.opened(); try { return new BXQSequence(s.result.value().cache(), this); } catch(final QueryException ex) { throw new BXQException(ex); } } @Override public BXQItemType createSequenceType(final XQItemType it, final int occ) throws XQException { opened(); valid(it, XQItemType.class); if(occ < 1 || occ > 5) throw new BXQException(OCCINV); if(occ == XQSequenceType.OCC_EMPTY && it != null || occ == XQSequenceType.OCC_EXACTLY_ONE && it == null) throw new BXQException(OCC); final Type type = ((BXQItemType) it).getType(); final QName name = type.isNode() ? it.getNodeName() : null; return new BXQItemType(type, name, it.getBaseType(), occ); } @Override public BXQItemType createTextType() throws XQException { opened(); return new BXQItemType(NodeType.TXT); } /** * Performs a type check for attribute operations. * @param it input type * @throws XQException exception */ private static void checkAttr(final int it) throws XQException { if(it != XQItemType.XQBASETYPE_UNTYPED && it != XQItemType.XQBASETYPE_ANYTYPE) return; throw new BXQException(ATT); } /** * Returns an integer item. * @param v input value * @param e expected type * @param t target type * @return resulting item * @throws XQException exception */ private BXQItem itr(final long v, final Type e, final XQItemType t) throws XQException { try { return new BXQItem(check(e, t).cast(Int.get(v), null, null)); } catch(final QueryException ex) { throw new BXQException(ex); } } @Override public XQItem createItemFromDocument(XMLReader arg0, XQItemType arg1) throws XQException { // TODO Auto-generated method stub return null; } }