package com.bagri.xqj; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.net.URI; import java.net.URISyntaxException; import java.util.Properties; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.sax.SAXResult; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItemAccessor; import javax.xml.xquery.XQItemType; import static com.bagri.support.util.PropUtils.getOutputProperties; import static com.bagri.xqj.BagriXQErrors.ex_item_closed; import static javax.xml.xquery.XQItemType.*; import org.w3c.dom.Node; import org.xml.sax.ContentHandler; import com.bagri.core.xquery.api.XQProcessor; import com.bagri.support.util.XMLUtils; public abstract class BagriXQItemAccessor extends BagriXQCloseable implements XQItemAccessor { protected XQItemType type; protected Object value; protected boolean positioned = false; private XQProcessor xqProcessor; BagriXQItemAccessor(XQProcessor xqProcessor) { if (xqProcessor == null) { throw new NullPointerException("Got NULL processor at initialization!"); } this.xqProcessor = xqProcessor; } protected void setCurrent(XQItemType type, Object value) { this.type = type; this.value = value; this.positioned = true; } XQProcessor getXQProcessor() { return xqProcessor; } @Override public boolean getBoolean() throws XQException { checkState(ex_item_closed); if (type == null) { throw new XQException("ItemType is null"); } if (type.getBaseType() == XQBASETYPE_BOOLEAN) { return (Boolean) value; } throw new XQException("ItemType is not boolean"); } protected Properties checkOutputProperties(Properties props) { Properties outProps; if (props == null) { outProps = new Properties(); outProps.setProperty(OutputKeys.INDENT, "yes"); outProps.setProperty(OutputKeys.METHOD, "xml"); outProps.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } else { outProps = getOutputProperties(props); } return outProps; } private long convertDecimal(long min, long max, String typeName) throws XQException { switch (type.getBaseType()) { case XQBASETYPE_BYTE: { Byte b = (Byte) value; if (b.longValue() >= min && b.longValue() <= max) { return b.longValue(); } break; } case XQBASETYPE_INT: case XQBASETYPE_UNSIGNED_SHORT: { Integer i = (Integer) value; if (i.longValue() >= min && i.longValue() <= max) { return i.longValue(); } break; } case XQBASETYPE_LONG: case XQBASETYPE_UNSIGNED_INT: { Long l = (Long) value; if (l.longValue() >= min && l.longValue() <= max) { return l.longValue(); } break; } case XQBASETYPE_SHORT: case XQBASETYPE_UNSIGNED_BYTE: { Short s = (Short) value; if (s.longValue() >= min && s.longValue() <= max) { return s.longValue(); } break; } case XQBASETYPE_INTEGER: case XQBASETYPE_NEGATIVE_INTEGER: case XQBASETYPE_NONNEGATIVE_INTEGER: case XQBASETYPE_NONPOSITIVE_INTEGER: case XQBASETYPE_POSITIVE_INTEGER: case XQBASETYPE_UNSIGNED_LONG: { java.math.BigInteger i = (java.math.BigInteger) value; if (i.longValue() >= min && i.longValue() <= max) { return i.longValue(); } break; } case XQBASETYPE_DECIMAL: { java.math.BigDecimal d = (java.math.BigDecimal) value; //if (d.longValue() >= min && d.longValue() <= max) { // return d.longValue(); //} try { return d.longValueExact(); } catch (ArithmeticException e) { // } break; } //default: } throw new XQException("ItemType is not " + typeName + "; the value is: " + value); } @Override public byte getByte() throws XQException { checkState(ex_item_closed); return (byte) convertDecimal(Byte.MIN_VALUE, Byte.MAX_VALUE, "byte"); } @Override public double getDouble() throws XQException { checkState(ex_item_closed); if (type.getBaseType() == XQBASETYPE_DOUBLE) { return (Double) value; } if (type.getBaseType() == XQBASETYPE_FLOAT) { return ((Float) value).doubleValue(); } throw new XQException("ItemType is not double"); } @Override public float getFloat() throws XQException { checkState(ex_item_closed); if (type.getBaseType() == XQBASETYPE_FLOAT) { return (Float) value; } if (type.getBaseType() == XQBASETYPE_DOUBLE) { return ((Double) value).floatValue(); } throw new XQException("ItemType is not float"); } @Override public int getInt() throws XQException { checkState(ex_item_closed); return (int) convertDecimal(Integer.MIN_VALUE, Integer.MAX_VALUE, "int"); } @Override public XQItemType getItemType() throws XQException { if (closed) { throw new XQException(ex_item_closed); } if (!positioned) { throw new XQException("not positioned on the Item"); } return type; } @Override public String getAtomicValue() throws XQException { return getItemAsString(null); } @Override public long getLong() throws XQException { checkState(ex_item_closed); return (long) convertDecimal(Long.MIN_VALUE, Long.MAX_VALUE, "long"); } @Override public Node getNode() throws XQException { checkState(ex_item_closed); switch (type.getItemKind()) { case XQITEMKIND_ATTRIBUTE: case XQITEMKIND_SCHEMA_ATTRIBUTE: return (org.w3c.dom.Attr) value; case XQITEMKIND_COMMENT: return (org.w3c.dom.Comment) value; case XQITEMKIND_DOCUMENT: return (org.w3c.dom.Document) value; case XQITEMKIND_ELEMENT: case XQITEMKIND_DOCUMENT_ELEMENT: case XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT: case XQITEMKIND_SCHEMA_ELEMENT: return (org.w3c.dom.Element) value; case XQITEMKIND_PI: return (org.w3c.dom.ProcessingInstruction) value; case XQITEMKIND_TEXT: return (org.w3c.dom.Text) value; default: throw new XQException("ItemType is not Node: " + value.getClass().getName()); } } @Override public URI getNodeUri() throws XQException { Node node = getNode(); try { String base = node.getBaseURI(); if (base == null) { base = ""; } return new URI(base); } catch (URISyntaxException ex) { throw new XQException(ex.getMessage()); } } @Override public Object getObject() throws XQException { if (closed) { throw new XQException(ex_item_closed); } return value; } @Override public XMLStreamReader getItemAsStream() throws XQException { if (closed) { throw new XQException(ex_item_closed); } try { return XMLUtils.stringToStream(getItemAsString(null)); } catch (IOException ex) { throw new XQException(ex.getMessage()); } } @Override public String getItemAsString(Properties props) throws XQException { if (closed) { throw new XQException(ex_item_closed); } if (value == null) { throw new XQException("Value is not accessible"); } props = checkOutputProperties(props); return xqProcessor.convertToString(value, props); } @Override public short getShort() throws XQException { checkState(ex_item_closed); return (short) convertDecimal(Short.MIN_VALUE, Short.MAX_VALUE, "short"); } @Override public boolean instanceOf(XQItemType type) throws XQException { checkState(ex_item_closed); if (!positioned) { throw new XQException("not positioned on the Item"); } if (type == null) { throw new XQException("Provided type is null"); } return this.type.equals(type); } @Override public void writeItem(OutputStream os, Properties props) throws XQException { checkState(ex_item_closed); if (os == null) { throw new XQException("Provided OutputStream is null"); } String result = getItemAsString(props); try { os.write(result.getBytes()); } catch (IOException ex) { throw new XQException(ex.getMessage()); } } @Override public void writeItem(Writer ow, Properties props) throws XQException { checkState(ex_item_closed); if (ow == null) { throw new XQException("Provided Writer is null"); } try { ow.write(getItemAsString(props)); } catch (IOException ex) { throw new XQException(ex.getMessage()); } } @Override public void writeItemToSAX(ContentHandler saxhdlr) throws XQException { checkState(ex_item_closed); if (saxhdlr == null) { throw new XQException("Provided ContextHandler is null"); } try { XMLUtils.stringToResult(getItemAsString(null), new SAXResult(saxhdlr)); } catch (IOException ex) { throw new XQException(ex.getMessage()); } } @Override public void writeItemToResult(Result result) throws XQException { checkState(ex_item_closed); if (result == null) { throw new XQException("Provided Result is null"); } try { XMLUtils.stringToResult(getItemAsString(null), result); } catch (IOException ex) { throw new XQException(ex.getMessage()); } } }