16 package org.zorbaxquery.api.xqj;
18 import java.io.InputStream;
19 import java.io.Reader;
20 import java.io.StringWriter;
21 import java.io.Writer;
22 import java.nio.CharBuffer;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.TimeZone;
26 import javax.xml.namespace.QName;
27 import javax.xml.stream.XMLOutputFactory;
28 import javax.xml.stream.XMLStreamReader;
29 import javax.xml.stream.XMLStreamWriter;
30 import javax.xml.transform.*;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.sax.SAXSource;
33 import javax.xml.transform.stax.StAXResult;
34 import javax.xml.transform.stax.StAXSource;
35 import javax.xml.transform.stream.StreamResult;
36 import javax.xml.transform.stream.StreamSource;
37 import javax.xml.xquery.*;
38 import org.w3c.dom.Node;
39 import org.zorbaxquery.api.*;
90 private XQConnection connection;
91 private boolean closed;
92 private Collection<XQResultSequence> resultSequences =
new ArrayList<XQResultSequence>();
93 private DynamicContext dynamicContext;
94 private XmlDataManager xmlDataManager;
95 private XQStaticContext staticContext;
96 private Collection<String> itemsBounded =
new ArrayList<String>();
100 if (conn.isClosed()) {
101 throw new XQException (
"Connection is closed");
105 Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
107 query = zorba.compileQuery(
string);
108 dynamicContext = query.getDynamicContext();
109 xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
110 }
catch (Exception e) {
111 throw new XQException (
"Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
116 if (conn.isClosed()) {
117 throw new XQException (
"Connection is closed");
121 Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
123 query = zorba.compileQuery(
string, ((org.zorbaxquery.api.xqj.ZorbaXQStaticContext)sc).getZorbaStaticContext());
124 dynamicContext = query.getDynamicContext();
125 xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
126 }
catch (Exception e) {
127 throw new XQException (
"Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
139 public void cancel() throws XQException {
140 isClosedXQException();
159 public void close() throws XQException {
161 for (XQResultSequence sequence: resultSequences) {
178 isClosedXQException();
179 XQResultSequence result = null;
181 result =
new org.zorbaxquery.api.xqj.ZorbaXQResultSequence(connection, query,
true);
182 }
catch (Exception e) {
183 throw new XQException(
"Error executing query: " + e.getLocalizedMessage());
185 resultSequences.add(result);
196 isClosedXQException();
197 Collection<QName> result =
new ArrayList<QName>();
198 Iterator iter =
new Iterator();
199 query.getExternalVariables(iter);
201 Item item =
new Item();
202 while (iter.next(item)) {
203 result.add(
new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
207 return result.toArray(
new QName[0]);
210 private boolean isExternal(String varName) {
212 Iterator iter =
new Iterator();
213 query.getExternalVariables(iter);
215 Item item =
new Item();
216 while (iter.next(item)) {
217 if (item.getLocalName().equalsIgnoreCase(varName)) {
235 isClosedXQException();
237 Collection<QName> result =
new ArrayList<QName>();
238 Iterator iter =
new Iterator();
239 query.getExternalVariables(iter);
240 Item item =
new Item();
242 while (iter.next(item)) {
243 boolean found =
false;
244 for (String key: itemsBounded){
245 if (item.getLocalName().equalsIgnoreCase(key)) {
250 result.add(
new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
255 return result.toArray(
new QName[0]);
267 isClosedXQException();
268 XQSequenceType result =
new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(
new org.zorbaxquery.api.xqj.ZorbaXQItemType(XQItemType.XQITEMKIND_ITEM), XQSequenceType.OCC_ZERO_OR_MORE );
280 isClosedXQException();
281 isNullXQException(varName);
282 XQSequenceType result = null;
283 Iterator iter =
new Iterator();
284 query.getExternalVariables(iter);
286 Item item =
new Item();
287 while (iter.next(item)) {
288 if ( item.getLocalName().equalsIgnoreCase(varName.getLocalPart()) &&
289 item.getNamespace().equalsIgnoreCase(varName.getNamespaceURI()) &&
290 item.getPrefix().equalsIgnoreCase(varName.getPrefix()) ) {
291 if (item.getType().getStringValue().equals(
"xs:QName")) {
292 result =
new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(
new org.zorbaxquery.api.xqj.ZorbaXQItemType(XQItemType.XQITEMKIND_ITEM), XQItemType.OCC_ZERO_OR_MORE);
294 result =
new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(
new org.zorbaxquery.api.xqj.ZorbaXQItemType(item), XQItemType.OCC_ZERO_OR_MORE);
302 throw new XQException(
"Item not found");
316 isClosedXQException();
317 if (staticContext==null) {
318 staticContext =
new org.zorbaxquery.api.xqj.ZorbaXQStaticContext(query);
320 return staticContext;
330 isClosedXQException();
331 Integer timeZone = (dynamicContext.getImplicitTimezone()/60);
332 TimeZone result = TimeZone.getTimeZone(
"GMT"+timeZone.toString());
346 public void bindAtomicValue(QName varName, String value, XQItemType type)
throws XQException {
347 isClosedXQException();
348 isNullXQException(varName);
349 isNullXQException(value);
350 isNullXQException(type);
351 if (!isExternal(varName.getLocalPart())) {
352 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
354 if (type.getItemKind()!=XQItemType.XQITEMKIND_ATOMIC) {
355 throw new XQException (
"Item kind is not atomic.");
358 XQItem xqitem = connection.createItemFromAtomicValue(value, type);
359 Item item = ((org.zorbaxquery.api.xqj.ZorbaXQItem)xqitem).getZorbaItem();
360 dynamicContext.setVariable(varName.getLocalPart(), item);
361 itemsBounded.add(varName.getLocalPart());
362 }
catch (Exception e) {
363 throw new XQException (
"Error binding the atomic value: " + e.getLocalizedMessage());
379 public void bindString(QName varName, String value, XQItemType type)
throws XQException {
380 isClosedXQException();
381 isNullXQException(varName);
382 if (!isExternal(varName.getLocalPart())) {
383 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
385 isNullXQException(value);
387 type = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).createAtomicType(XQItemType.XQBASETYPE_STRING);
390 Iterator iter =
new Iterator();
391 boolean found =
false;
392 query.getExternalVariables(iter);
393 Item tmpItem =
new Item();
395 while (iter.next(tmpItem)) {
396 if (tmpItem.getStringValue().equalsIgnoreCase(varName.getLocalPart())) {
397 XQItem item = connection.createItemFromString(value, type);
398 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
399 itemsBounded.add(varName.getLocalPart());
406 throw new XQException (
"The variable: " + varName.getLocalPart() +
" doesn't exist.");
408 }
catch (XQException e) {
410 }
catch (Exception e) {
411 throw new XQException (
"Error binding string to the defined type: " + e.getLocalizedMessage());
431 public void bindDocument(QName varName, String value, String baseURI, XQItemType type)
throws XQException {
432 isClosedXQException();
433 isNullXQException(varName);
434 if (!isExternal(varName.getLocalPart())) {
435 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
437 isNullXQException(value);
438 if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
439 throw new XQException (
"Invalid type.");
442 type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
444 if (!isExternal(varName.getLocalPart())) {
445 throw new XQException (
"Variable not found in context.");
448 Iterator iter = xmlDataManager.parseXML(value);
449 Item item =
new Item();
451 dynamicContext.setVariable(varName.getLocalPart(), item);
452 itemsBounded.add(varName.getLocalPart());
453 }
catch (Exception e) {
454 throw new XQException (
"Error binding document: " + e.getLocalizedMessage());
474 public void bindDocument(QName varName, Reader value, String baseURI, XQItemType type)
throws XQException {
475 isClosedXQException();
476 isNullXQException(varName);
477 if (!isExternal(varName.getLocalPart())) {
478 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
480 isNullXQException(value);
481 if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
482 throw new XQException (
"Invalid type.");
485 type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
487 StringBuffer
string =
new StringBuffer();
488 CharBuffer buffer = CharBuffer.allocate(1024);
489 Writer writer =
new StringWriter();
492 while( value.read(buffer) >= 0 ) {
494 writer.append(buffer);
498 }
catch (Exception ex) {
499 throw new XQException(
"Error preparing expression" + ex.getLocalizedMessage());
502 bindDocument(varName, writer.toString(), baseURI, type);
520 public void bindDocument(QName varName, InputStream value, String baseURI, XQItemType type)
throws XQException {
521 isClosedXQException();
522 isNullXQException(varName);
523 if (!isExternal(varName.getLocalPart())) {
524 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
526 isNullXQException(value);
527 if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
528 throw new XQException (
"Invalid type.");
531 type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
533 StringBuffer out =
new StringBuffer ();
535 byte[] b =
new byte[4096];
536 for (
int n; (n = value.read(b)) != -1;) {
537 out.append(
new String(b, 0, n));
539 }
catch (Exception ex) {
540 throw new XQException(
"Error preparing expression" + ex.getLocalizedMessage());
559 public void bindDocument(QName varName, XMLStreamReader value, XQItemType type)
throws XQException {
560 isClosedXQException();
561 isNullXQException(varName);
562 if (!isExternal(varName.getLocalPart())) {
563 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
565 isNullXQException(value);
566 if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
567 throw new XQException (
"Invalid type.");
570 type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
573 TransformerFactory tf = TransformerFactory.newInstance();
577 XMLOutputFactory xof = XMLOutputFactory.newInstance();
578 Writer writer =
new StringWriter();
580 XMLStreamWriter xmlStreamWriter = xof.createXMLStreamWriter(writer);
581 t = tf.newTransformer();
582 source =
new StAXSource(value);
583 result =
new StAXResult(xmlStreamWriter);
584 t.transform(source, result);
585 }
catch (Exception ex) {
586 throw new XQException(
"Error transforming xml expression" + ex.getLocalizedMessage());
591 private String nodeToString(Node node) {
592 StringWriter sw =
new StringWriter();
594 Transformer t = TransformerFactory.newInstance().newTransformer();
595 t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
596 t.transform(
new DOMSource(node),
new StreamResult(sw));
597 }
catch (TransformerException te) {
598 System.out.println(
"nodeToString Transformer Exception" + te.getLocalizedMessage());
600 return sw.toString();
622 public void bindDocument(QName varName, Source value, XQItemType type)
throws XQException {
623 isClosedXQException();
624 isNullXQException(varName);
625 isNullXQException(value);
626 if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
627 throw new XQException (
"Invalid type.");
629 if (!isExternal(varName.getLocalPart())) {
630 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
633 type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
635 if (value instanceof StreamSource) {
636 bindDocument(varName, ((StreamSource)value).getReader(), null, type);
637 }
else if (value instanceof SAXSource) {
638 bindDocument(varName, ((SAXSource)value).getInputSource().getCharacterStream(), null, type);
639 }
else if (value instanceof DOMSource) {
640 bindDocument(varName, nodeToString(((DOMSource)value).getNode()), null, type);
642 throw new UnsupportedOperationException(
"Not supported yet.");
653 isClosedXQException();
654 isNullXQException(value);
656 dynamicContext.setImplicitTimezone((value.getRawOffset()/60000));
657 }
catch (Exception e) {
658 throw new XQException(
"Error setting implicit TimeZone: " + e.getLocalizedMessage());
671 public void bindItem(QName varName, XQItem value)
throws XQException {
672 isClosedXQException();
673 isNullXQException(varName);
674 isNullXQException(value);
675 if (!isExternal(varName.getLocalPart())) {
676 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
679 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)value).getZorbaItem());
680 itemsBounded.add(varName.getLocalPart());
681 }
catch (Exception e) {
682 throw new XQException (
"Error binding item: " + varName.getLocalPart() +
" with error: " + e.getLocalizedMessage());
695 public void bindSequence(QName varName, XQSequence value)
throws XQException {
696 isClosedXQException();
697 isNullXQException(varName);
698 isNullXQException(value);
699 if (value.isClosed()) {
700 throw new XQException (
"Sequence is closed.");
702 if (!isExternal(varName.getLocalPart())) {
703 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
706 if (!value.isOnItem()) {
709 Item item =
new Item(((org.zorbaxquery.api.xqj.ZorbaXQItem)value.getItem()).getZorbaItem());
712 dynamicContext.setVariable(varName.getLocalPart(), item);
713 itemsBounded.add(varName.getLocalPart());
714 }
catch (Exception e) {
715 throw new XQException (
"Error binding item: " + varName.getLocalPart() +
" with error: " + e.getLocalizedMessage());
729 public void bindObject(QName varName, Object value, XQItemType type)
throws XQException {
730 isClosedXQException();
731 isNullXQException(varName);
732 isNullXQException(value);
733 if (!isExternal(varName.getLocalPart())) {
734 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
737 XQItem item = connection.createItemFromObject(value, type);
738 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
739 itemsBounded.add(varName.getLocalPart());
740 }
catch (Exception e) {
741 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
755 public void bindBoolean(QName varName,
boolean value, XQItemType type)
throws XQException {
756 isClosedXQException();
757 isNullXQException(varName);
758 if (!isExternal(varName.getLocalPart())) {
759 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
762 XQItem item = connection.createItemFromBoolean(value, type);
763 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
764 itemsBounded.add(varName.getLocalPart());
765 }
catch (Exception e) {
766 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
780 public void bindByte(QName varName, byte value, XQItemType type)
throws XQException {
781 isClosedXQException();
782 isNullXQException(varName);
783 if (!isExternal(varName.getLocalPart())) {
784 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
787 XQItem item = connection.createItemFromByte(value, type);
788 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
789 itemsBounded.add(varName.getLocalPart());
790 }
catch (Exception e) {
791 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
805 public void bindDouble(QName varName,
double value, XQItemType type)
throws XQException {
806 isClosedXQException();
807 isNullXQException(varName);
808 if (!isExternal(varName.getLocalPart())) {
809 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
812 XQItem item = connection.createItemFromDouble(value, type);
813 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
814 itemsBounded.add(varName.getLocalPart());
815 }
catch (Exception e) {
816 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
830 public void bindFloat(QName varName,
float value, XQItemType type)
throws XQException {
831 isClosedXQException();
832 isNullXQException(varName);
833 if (!isExternal(varName.getLocalPart())) {
834 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
837 XQItem item = connection.createItemFromFloat(value, type);
838 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
839 itemsBounded.add(varName.getLocalPart());
840 }
catch (Exception e) {
841 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
855 public void bindInt(QName varName,
int value, XQItemType type)
throws XQException {
856 isClosedXQException();
857 isNullXQException(varName);
858 if (!isExternal(varName.getLocalPart())) {
859 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
862 XQItem item = connection.createItemFromInt(value, type);
863 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
864 itemsBounded.add(varName.getLocalPart());
865 }
catch (Exception e) {
866 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
880 public void bindLong(QName varName,
long value, XQItemType type)
throws XQException {
881 isClosedXQException();
882 isNullXQException(varName);
883 if (!isExternal(varName.getLocalPart())) {
884 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
887 XQItem item = connection.createItemFromLong(value, type);
888 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
889 itemsBounded.add(varName.getLocalPart());
890 }
catch (Exception e) {
891 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
905 public void bindNode(QName varName, Node value, XQItemType type)
throws XQException {
906 isClosedXQException();
907 isNullXQException(value);
908 isNullXQException(varName);
909 if (!isExternal(varName.getLocalPart())) {
910 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
913 XQItem item = connection.createItemFromNode(value, type);
914 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
915 itemsBounded.add(varName.getLocalPart());
916 }
catch (Exception e) {
917 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
931 public void bindShort(QName varName,
short value, XQItemType type)
throws XQException {
932 isClosedXQException();
933 isNullXQException(varName);
934 if (!isExternal(varName.getLocalPart())) {
935 throw new XQException (
"The bound variable must be declared external in the prepared expression.");
938 XQItem item = connection.createItemFromShort(value, type);
939 dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
940 itemsBounded.add(varName.getLocalPart());
941 }
catch (Exception e) {
942 throw new XQException (
"Error binding object: " + e.getLocalizedMessage());
946 private void isClosedXQException() throws XQException {
948 throw new XQException(
"This prepared expression is closed");
951 private void isNullXQException(Object value)
throws XQException {
953 throw new XQException(
"Parameter shouldn't be null");