package org.basex.api.xqj; import static org.basex.api.xqj.BXQText.*; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItemType; import org.basex.build.xml.SAXWrapper; import org.basex.core.Context; import org.basex.core.cmd.CreateDB; import org.basex.data.Data; import org.basex.io.IO; import org.basex.io.serial.Serializer; import org.basex.query.QueryException; import org.basex.query.func.JavaMapping; import org.basex.query.item.AtomType; import org.basex.query.item.DBNode; import org.basex.query.item.Item; import org.basex.query.item.NodeType; import org.basex.query.item.Type; import org.basex.util.Util; import org.basex.util.list.ByteList; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; /** * Java XQuery API - Abstract objects. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ abstract class BXQAbstract { /** Parent closer. */ protected final BXQAbstract par; /** Database connection. */ protected BXQStaticContext context; /** Closed flag. */ protected boolean closed; /** * Constructor. * @param p parent reference */ protected BXQAbstract(final BXQAbstract p) { par = p; if(par != null) context = p.context; } /** * Closes the class. * @throws XQException exception */ @SuppressWarnings("unused") public void close() throws XQException { if(!closed) BXQDataSource.context().close(); closed = true; } /** * Returns the closed flag. * @return flag */ public final boolean isClosed() { return closed || par != null && par.isClosed(); } /** * Checks if the object is open. * @throws XQException exception */ protected final void opened() throws XQException { if(isClosed()) throw new BXQException(Util.name(this) + CLOSED); } /** * Checks if the specified object is {@code null}. * @param obj object to be checked * @param type data type * @return object * @throws BXQException exception */ protected static Object valid(final Object obj, final Class<?> type) throws BXQException { if(obj == null) throw new BXQException(NULL, Util.name(type)); return obj; } /** * Checks the specified data type; throws an error if the type is wrong. * @param e expected type * @param tar target type * @return target type * @throws XQException xquery exception */ protected final Type check(final Type e, final XQItemType tar) throws XQException { opened(); if(tar == null) return e; final Type t = ((BXQItemType) tar).getType(); if(e != t && e != AtomType.ATM && (e.isNode() || t.isNode())) throw new BXQException(WRONG, tar, e); return t; } /** * Creates an XQuery item from the specified Java object. * @param v input object * @param t target type * @return resulting item * @throws XQException exception */ protected final Item create(final Object v, final XQItemType t) throws XQException { // check if object exists valid(v, Object.class); // return xquery items if(t == null && v instanceof BXQItem) return ((BXQItem) v).it; // get xquery mapping final Type e = JavaMapping.type(v); if(e == null) throw new BXQException(CONV, Util.name(v)); try { // return item with correct type return check(e, t).cast(v, null); } catch(final QueryException ex) { throw new BXQException(ex); } } /** * Returns the contents of the specified reader as a string. * @param r reader * @return string * @throws BXQException exception */ protected static final byte[] content(final Reader r) throws BXQException { valid(r, XMLReader.class); try { final ByteList bl = new ByteList(); final BufferedReader br = new BufferedReader(r); for(int i; (i = br.read()) != -1;) bl.add(i); br.close(); return bl.toArray(); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Returns the contents of the specified input stream as a string. * @param is input stream * @return string * @throws BXQException exception */ protected static final byte[] content(final InputStream is) throws BXQException { valid(is, InputStream.class); try { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final BufferedInputStream bis = new BufferedInputStream(is); for(int i; (i = bis.read()) != -1;) bos.write(i); bis.close(); return bos.toByteArray(); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Creates a database instance from the specified byte array. * @param s input source * @param it item type * @return document node * @throws XQException exception */ protected final DBNode createNode(final Source s, final XQItemType it) throws XQException { valid(s, Source.class); check(NodeType.DOC, it); if(s instanceof SAXSource) { return createNode((SAXSource) s); } else if(s instanceof StreamSource) { final StreamSource ss = (StreamSource) s; final InputStream is = ss.getInputStream(); if(is != null) return createNode(is); final Reader r = ss.getReader(); if(r != null) return createNode(r); return createNode(IO.get(ss.getSystemId())); } Util.notimplemented(); return null; } /** * Creates a database node from the specified byte array. * @param is input stream * @return document node * @throws XQException exception */ protected final DBNode createNode(final InputStream is) throws XQException { valid(is, InputStream.class); return createNode(new SAXSource(new InputSource(is))); } /** * Creates a database node from the specified byte array. * @param r reader * @return document node * @throws XQException exception */ protected final DBNode createNode(final Reader r) throws XQException { valid(r, Reader.class); return createNode(new SAXSource(new InputSource(r))); } /** * Creates a database node from the specified byte array. * @param s SAX source * @return document node * @throws XQException exception */ private DBNode createNode(final SAXSource s) throws XQException { opened(); try { final Context ctx = BXQDataSource.context(); return checkNode(CreateDB.mainMem(new SAXWrapper(s, ctx.prop) , ctx)); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Creates a database node from the specified xml reader. * @param sr xml stream reader * @return document node * @throws XQException exception */ protected final DBNode createNode(final XMLStreamReader sr) throws XQException { opened(); valid(sr, XMLStreamReader.class); try { final Context ctx = BXQDataSource.context(); return checkNode(CreateDB.mainMem(new XMLStreamWrapper(sr), ctx)); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Creates a database instance from the specified io instance. * @param io io reference * @return document node * @throws BXQException exception */ protected static final DBNode createNode(final IO io) throws BXQException { try { final Context ctx = BXQDataSource.context(); return checkNode(CreateDB.mainMem(io, ctx)); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Serializes an item to the specified serializer. * @param it item * @param ser serializer * @throws XQException exception */ protected final void serialize(final Item it, final Serializer ser) throws XQException { opened(); try { if(it.type == NodeType.ATT) throw new BXQException(ATTR); it.serialize(ser); } catch(final IOException ex) { throw new BXQException(ex); } } /** * Checks the specified database instance and returns a document node. * @param d database instance * @return document node * @throws BXQException exception */ private static DBNode checkNode(final Data d) throws BXQException { valid(d, Data.class); return new DBNode(d, 0); } }