ZorbaXQPreparedExpression.java
Go to the documentation of this file.
1 /*
2  * Copyright 2006-2012 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.zorbaxquery.api.xqj;
17 
18 import java.io.*;
19 import java.nio.CharBuffer;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.TimeZone;
23 import javax.xml.namespace.QName;
24 import javax.xml.stream.XMLOutputFactory;
25 import javax.xml.stream.XMLStreamReader;
26 import javax.xml.stream.XMLStreamWriter;
27 import javax.xml.transform.*;
28 import javax.xml.transform.dom.DOMSource;
29 import javax.xml.transform.sax.SAXSource;
30 import javax.xml.transform.stax.StAXResult;
31 import javax.xml.transform.stax.StAXSource;
32 import javax.xml.transform.stream.StreamResult;
33 import javax.xml.transform.stream.StreamSource;
34 import javax.xml.xquery.*;
35 import org.w3c.dom.Node;
36 import org.zorbaxquery.api.*;
37  /**
38  * This class describes an expression that can be prepared for multiple subsequent executions. A prepared expression can be created from the connection.
39  *
40  * The preparation of the expression does the static analysis of the expression using the static context information.
41  *
42  * The dynamic context information, such as values for bind variables, can then be set using the setter methods. When setting values for bind variables, these variables should be present as external variables in the prolog of the prepared expression.
43  *
44  * The static type information of the query can also be retrieved if the XQuery implementation provides it using the getStaticResultType method.
45  *
46  * When the expression is executed using the executeQuery method, if the execution is successful, then an ZorbaXQResultSequence object is returned. The ZorbaXQResultSequence object is tied to the ZorbaXQPreparedExpression from which it was prepared and is closed implicitly if that expression is either closed or if re-executed.
47  *
48  * The ZorbaXQPreparedExpression object is dependent on the ZorbaXQConnection object from which it was created and is only valid for the duration of that object. Thus, if the ZorbaXQConnection object is closed then this ZorbaXQPreparedExpression object will be implicitly closed and it can no longer be used.
49  *
50  * An XQJ driver is not required to provide finalizer methods for the connection and other objects. Hence it is strongly recommended that users call close method explicitly to free any resources. It is also recommended that they do so under a final block to ensure that the object is closed even when there are exceptions. Not closing this object implicitly or explicitly might result in serious memory leaks.
51  *
52  * When the ZorbaXQPreparedExpression is closed any ZorbaXQResultSequence object obtained from it is also implicitly closed.
53  *
54  * Example -
55  * \code{.java}
56  * ZorbaXQConnection conn = XQDataSource.getconnection();
57  * ZorbaXQPreparedExpression expr = conn.prepareExpression
58  * ("for $i in (1) return 'abc' ");
59  *
60  * // get the sequence type out.. This would be something like xs:string *
61  * ZorbaXQSequenceType type = expr.getStaticResultType();
62  *
63  * XQSequence result1 = expr.executeQuery();
64  *
65  * // process the result..
66  * result1.next();
67  * System.out.println(" First result1 "+ result1.getAtomicValue());
68  *
69  * ZorbaXQResultSequence result2 = expr.executeQuery();
70  *
71  * // result1 is implicitly closed
72  * // recommended to close the result sequences explicitly.
73  *
74  * // process the result..
75  * while (result2.next())
76  * System.out.println(" result is "+ result2.getAtomicValue());
77  *
78  * result2.close();
79  * expr.close(); // closing expression implicitly closes all result sequence or
80  * // items obtained from this expression.
81  * conn.close(); // closing connections will close expressions and results.
82  * \endcode
83  */
84 public class ZorbaXQPreparedExpression implements javax.xml.xquery.XQPreparedExpression {
85 
86  private XQuery query;
87  private XQConnection connection;
88  private boolean closed;
89  private Collection<XQResultSequence> resultSequences = new ArrayList<XQResultSequence>();
90  private DynamicContext dynamicContext;
91  private XmlDataManager xmlDataManager;
92  private XQStaticContext staticContext;
93  private Collection<String> itemsBounded = new ArrayList<String>();
94 
95 
96  public ZorbaXQPreparedExpression (XQConnection conn, String string) throws XQException {
97  if (conn.isClosed()) {
98  throw new XQException ("Connection is closed");
99  }
100  closed = false;
101  connection = conn;
102  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
103  try {
104  query = zorba.compileQuery(string);
105  dynamicContext = query.getDynamicContext();
106  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
107  } catch (Exception e) {
108  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
109 
110  }
111  }
112 
113  public ZorbaXQPreparedExpression (XQConnection conn, Reader reader) throws XQException {
114  if (conn.isClosed()) {
115  throw new XQException ("Connection is closed");
116  }
117  closed = false;
118  connection = conn;
119  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
120  try {
121  ZorbaReaderWrapper stream = new ZorbaReaderWrapper(reader);
122  query = zorba.compileQuery(stream);
123  dynamicContext = query.getDynamicContext();
124  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
125  } catch (Exception e) {
126  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
127 
128  }
129  }
130 
131  public ZorbaXQPreparedExpression (XQConnection conn, InputStream input) throws XQException {
132  if (conn.isClosed()) {
133  throw new XQException ("Connection is closed");
134  }
135  closed = false;
136  connection = conn;
137  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
138  try {
139  ZorbaInputWrapper stream = new ZorbaInputWrapper(input);
140  query = zorba.compileQuery(stream);
141  dynamicContext = query.getDynamicContext();
142  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
143  } catch (Exception e) {
144  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
145 
146  }
147  }
148 
149  public ZorbaXQPreparedExpression (XQConnection conn, String string, XQStaticContext sc) throws XQException {
150  if (conn.isClosed()) {
151  throw new XQException ("Connection is closed");
152  }
153  closed = false;
154  connection = conn;
155  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
156  try {
157  query = zorba.compileQuery(string, ((org.zorbaxquery.api.xqj.ZorbaXQStaticContext)sc).getZorbaStaticContext());
158  dynamicContext = query.getDynamicContext();
159  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
160  } catch (Exception e) {
161  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
162 
163  }
164  }
165 
166  public ZorbaXQPreparedExpression (XQConnection conn, Reader reader, XQStaticContext sc) throws XQException {
167  if (conn.isClosed()) {
168  throw new XQException ("Connection is closed");
169  }
170  closed = false;
171  connection = conn;
172  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
173  try {
174  ZorbaReaderWrapper stream = new ZorbaReaderWrapper(reader);
175  query = zorba.compileQuery(stream, ((org.zorbaxquery.api.xqj.ZorbaXQStaticContext)sc).getZorbaStaticContext());
176  dynamicContext = query.getDynamicContext();
177  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
178  } catch (Exception e) {
179  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
180 
181  }
182  }
183 
184  public ZorbaXQPreparedExpression (XQConnection conn, InputStream input, XQStaticContext sc) throws XQException {
185  if (conn.isClosed()) {
186  throw new XQException ("Connection is closed");
187  }
188  closed = false;
189  connection = conn;
190  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
191  try {
192  ZorbaInputWrapper stream = new ZorbaInputWrapper(input);
193  query = zorba.compileQuery(stream, ((org.zorbaxquery.api.xqj.ZorbaXQStaticContext)sc).getZorbaStaticContext());
194  dynamicContext = query.getDynamicContext();
195  xmlDataManager = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance().getXmlDataManager();
196  } catch (Exception e) {
197  throw new XQException ("Error creating new Prepared expression with static context: " + e.getLocalizedMessage());
198 
199  }
200  }
201 
202  /** \brief Attempts to cancel the execution if both the XQuery engine and XQJ driver support aborting the execution of an ZorbaXQPreparedExpression.
203  *
204  * This method can be used by one thread to cancel an ZorbaXQPreparedExpression, that is being executed in another thread. If cancellation is not supported or the attempt to cancel the execution was not successful, the method returns without any error. If the cancellation is successful, an XQException is thrown, to indicate that it has been aborted, by executeQuery, executeCommand or any method accessing the ZorbaXQResultSequence returned by executeQuery. If applicable, any open ZorbaXQResultSequence and XQResultItem objects will also be implicitly closed in this case.
205  *
206  * @throw XQException - if the prepared expression is in a closed state
207  */
208  @Override
209  public void cancel() throws XQException {
210  isClosedXQException();
211  }
212 
213  /** \brief Checks if the prepared expression in a closed state.
214  *
215  * @return true if the prepared expression is in a closed state, false otherwise.
216  */
217  @Override
218  public boolean isClosed() {
219  return closed;
220  }
221 
222  /** \brief Closes the expression object and release all resources associated with this prepared expression.
223  *
224  * This also closes any result sequences obtained from this expression. Once the expression is closed, all methods on this object other than the close or isClosed will raise exceptions. Calling close on an XQExpression object that is already closed has no effect.
225  *
226  * @throw XQException - if there are errors when closing the expression
227  */
228  @Override
229  public void close() throws XQException {
230  closed = true;
231  for (XQResultSequence sequence: resultSequences) {
232  sequence.close();
233  }
234  if (query!=null) {
235  query.delete();
236  }
237  }
238 
239  /** \brief Executes the prepared query expression.
240  *
241  * Calling this method implicitly closes any previous result sequence obtained from this expression.
242  *
243  * @return the xquery sequence object containing the result of the query execution
244  * @throw XQException - if (1) there are errors when executing the prepared expression, (2) the prepared expression is in a closed state, or (3) the query execution is cancelled
245  */
246  @Override
247  public XQResultSequence executeQuery() throws XQException {
248  isClosedXQException();
249  XQResultSequence result = null;
250  try {
251  result = new org.zorbaxquery.api.xqj.ZorbaXQResultSequence(connection, query, true);
252  } catch (Exception e) {
253  throw new XQException("Error executing query: " + e.getLocalizedMessage());
254  }
255  resultSequences.add(result);
256  return result;
257  }
258 
259  /** \brief Retrieves all the external variables defined in the prolog of the prepared expression.
260  *
261  * @return an array of QName objects for all the external variables defined in the prolog of a prepared expression. Empty array if there are no external variables present.
262  * @throw XQException - if the prepared expression is in a closed state
263  */
264  @Override
265  public QName[] getAllExternalVariables() throws XQException {
266  isClosedXQException();
267  Collection<QName> result = new ArrayList<QName>();
268  Iterator iter = new Iterator();
269  query.getExternalVariables(iter);
270  iter.open();
271  Item item = new Item();
272  while (iter.next(item)) {
273  result.add(new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
274  }
275  iter.close();
276  iter.delete();
277  return result.toArray(new QName[0]);
278  }
279 
280  private boolean isExternal(String varName) {
281  boolean found=false;
282  Iterator iter = new Iterator();
283  query.getExternalVariables(iter);
284  iter.open();
285  Item item = new Item();
286  while (iter.next(item)) {
287  if (item.getLocalName().equalsIgnoreCase(varName)) {
288  found = true;
289  }
290  }
291  iter.close();
292  iter.delete();
293  return found;
294  }
295 
296  /** \brief Retrieves the names of all unbound external variables.
297  *
298  * Gets the static type information of the result sequence. If an implementation does not do static typing of the query, then this method must return an ZorbaXQSequenceType object corresponding to the XQuery sequence type item()*.
299  *
300  * @return ZorbaXQSequenceType containing the static result information.
301  * @throw XQException - if the prepared expression is in a closed state
302  */
303  @Override
304  public QName[] getAllUnboundExternalVariables() throws XQException {
305  isClosedXQException();
306 
307  Collection<QName> result = new ArrayList<QName>();
308  Iterator iter = new Iterator();
309  query.getExternalVariables(iter);
310  Item item = new Item();
311  iter.open();
312  while (iter.next(item)) {
313  boolean found = false;
314  for (String key: itemsBounded){
315  if (item.getLocalName().equalsIgnoreCase(key)) {
316  found = true;
317  }
318  }
319  if (!found) {
320  result.add(new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
321  }
322  }
323  iter.close();
324  iter.delete();
325  return result.toArray(new QName[0]);
326  }
327 
328  /** \brief Gets the static type information of the result sequence.
329  *
330  * If an implementation does not do static typing of the query, then this method must return an ZorbaXQSequenceType object corresponding to the XQuery sequence type item()*.
331  *
332  * @return ZorbaXQSequenceType containing the static result information.
333  * @throw XQException - if the prepared expression is in a closed state
334  */
335  @Override
336  public XQSequenceType getStaticResultType() throws XQException {
337  isClosedXQException();
338  XQSequenceType result = new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(new org.zorbaxquery.api.xqj.ZorbaXQItemType(XQItemType.XQITEMKIND_ITEM), XQSequenceType.OCC_ZERO_OR_MORE );
339  return result;
340  }
341 
342  /** \brief Retrieves the static type of a given external variable.
343  *
344  * @param varName - the name of the external variable
345  * @return the static type information of the variable as defined in the prolog of the prepared expression
346  * @throw XQException - if (1) the variable does not exist in the static context of the expression, or (2) the sequence is in a closed state, or (3) the name parameter is null
347  */
348  @Override
349  public XQSequenceType getStaticVariableType(QName varName) throws XQException {
350  isClosedXQException();
351  isNullXQException(varName);
352  XQSequenceType result = null;
353  Iterator iter = new Iterator();
354  query.getExternalVariables(iter);
355  iter.open();
356  Item item = new Item();
357  while (iter.next(item)) {
358  if ( item.getLocalName().equalsIgnoreCase(varName.getLocalPart()) &&
359  item.getNamespace().equalsIgnoreCase(varName.getNamespaceURI()) &&
360  item.getPrefix().equalsIgnoreCase(varName.getPrefix()) ) {
361  if (item.getType().getStringValue().equals("xs:QName")) {
362  result = new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(new org.zorbaxquery.api.xqj.ZorbaXQItemType(XQItemType.XQITEMKIND_ITEM), XQItemType.OCC_ZERO_OR_MORE);
363  } else {
364  result = new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(new org.zorbaxquery.api.xqj.ZorbaXQItemType(item), XQItemType.OCC_ZERO_OR_MORE);
365  }
366 
367  }
368  }
369  iter.close();
370  iter.delete();
371  if (result==null) {
372  throw new XQException("Item not found");
373  }
374  return result;
375  }
376 
377  /** \brief Gets an ZorbaXQStaticContext representing the values for all expression properties.
378  *
379  * Note that these properties cannot be changed; in order to change, a new ZorbaXQPreparedExpression needs to be created.
380  *
381  * @return an ZorbaXQStaticContext representing the values for all expression properties
382  * @throw XQException - if the expression is in a closed state
383  */
384  @Override
385  public XQStaticContext getStaticContext() throws XQException {
386  isClosedXQException();
387  if (staticContext==null) {
388  staticContext = new org.zorbaxquery.api.xqj.ZorbaXQStaticContext(query);
389  }
390  return staticContext;
391  }
392 
393  /** \brief Gets the implicit timezone
394  *
395  * @return the implicit timezone. This may have been set by an application using the setImplicitTimeZone method or provided by the implementation
396  * @throw XQException - if the expression is in a closed state
397  */
398  @Override
399  public TimeZone getImplicitTimeZone() throws XQException {
400  isClosedXQException();
401  Integer timeZone = (dynamicContext.getImplicitTimezone()/60); // in minutes
402  TimeZone result = TimeZone.getTimeZone("GMT"+timeZone.toString());
403  return result;
404  }
405 
406  /** \brief Binds a value to the given external variable or the context item.
407  *
408  * The value is converted into an instance of the specified type according to the casting from xs:string rules outlined in 17.1.1 Casting from xs:string and xs:untypedAtomic, XQuery 1.0 and XPath 2.0 Functions and Operators. If the cast fails, or if there is a mismatch between the static and dynamic types, an XQException is thrown either by this method or during query evaluation.
409  *
410  * @param varName - the name of the external variable to bind to
411  * @param value - the lexical string value of the type
412  * @param type - the item type of the bind
413  * @throw XQException - if (1) any of the arguments are null, (2) given type is not an atomic type, (3) the conversion of the value to an XDM instance failed, (4) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (5) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (6) the expression is in a closed state
414  */
415  @Override
416  public void bindAtomicValue(QName varName, String value, XQItemType type) throws XQException {
417  isClosedXQException();
418  isNullXQException(varName);
419  isNullXQException(value);
420  isNullXQException(type);
421  if (!isExternal(varName.getLocalPart())) {
422  throw new XQException ("The bound variable must be declared external in the prepared expression.");
423  }
424  if (type.getItemKind()!=XQItemType.XQITEMKIND_ATOMIC) {
425  throw new XQException ("Item kind is not atomic.");
426  }
427  try {
428  XQItem xqitem = connection.createItemFromAtomicValue(value, type);
429  Item item = ((org.zorbaxquery.api.xqj.ZorbaXQItem)xqitem).getZorbaItem();
430  dynamicContext.setVariable(varName.getLocalPart(), item);
431  itemsBounded.add(varName.getLocalPart());
432  } catch (Exception e) {
433  throw new XQException ("Error binding the atomic value: " + e.getLocalizedMessage());
434  }
435 
436  }
437 
438  /** \brief Binds a value to the given external variable or the context item.
439  *
440  * The value is converted into an instance of the specified type, which must represent an xs:string or a type derived by restriction from xs:string. If the specified type is null, it defaults to xs:string.
441  * Subsequently the value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0,. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
442  *
443  * @param varName - the name of the external variable to bind to, cannot be null
444  * @param value - the value to be converted, cannot be null
445  * @param type - the type of the value to be bound to the external variable. The default type, xs:string, is used in case null is specified
446  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
447  */
448  @Override
449  public void bindString(QName varName, String value, XQItemType type) throws XQException {
450  isClosedXQException();
451  isNullXQException(varName);
452  if (!isExternal(varName.getLocalPart())) {
453  throw new XQException ("The bound variable must be declared external in the prepared expression.");
454  }
455  isNullXQException(value);
456  if (type==null) {
457  type = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).createAtomicType(XQItemType.XQBASETYPE_STRING);
458  }
459  try {
460  Iterator iter = new Iterator();
461  boolean found = false;
462  query.getExternalVariables(iter);
463  Item tmpItem = new Item();
464  iter.open();
465  while (iter.next(tmpItem)) {
466  if (tmpItem.getStringValue().equalsIgnoreCase(varName.getLocalPart())) {
467  XQItem item = connection.createItemFromString(value, type);
468  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
469  itemsBounded.add(varName.getLocalPart());
470  found=true;
471  }
472  }
473  iter.close();
474  iter.delete();
475  if (!found) {
476  throw new XQException ("The variable: " + varName.getLocalPart() + " doesn't exist.");
477  }
478  } catch (XQException e) {
479  throw e;
480  } catch (Exception e) {
481  throw new XQException ("Error binding string to the defined type: " + e.getLocalizedMessage());
482  }
483 
484  }
485 
486  /** \brief Binds a value to the given external variable or the context item.
487  *
488  * If the value represents a well-formed XML document, it will be parsed and results in a document node. The kind of the input type must be null, XQITEMKIND_DOCUMENT_ELEMENT, or XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT.
489  *
490  * The value is converted into an instance of the specified type according to the rules defined in 14.3 Mapping a Java XML document to an XQuery document node, XQuery API for Java (XQJ) 1.0.
491  *
492  * If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation. If the value is not well formed, or if a kind of the input type other than the values list above is specified, behavior is implementation defined and may raise an exception.
493  *
494  * @param varName - the name of the external variable to bind to, cannot be null
495  * @param value - the value to be converted, cannot be null
496  * @param baseURI - an optional base URI, can be null. It can be used, for example, to resolve relative URIs and to include in error messages.
497  * @param type - the type of the value for the created document node. If null is specified, it behaves as if XQDataFactory.createDocumentElementType( XQDataFactory.createElementType(null, ZorbaXQItemType.XQBASETYPE_XS_UNTYPED)) were passed in as the type parameter. That is, the type represents the XQuery sequence type document-node(element(*, xs:untyped))
498  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
499  */
500  @Override
501  public void bindDocument(QName varName, String value, String baseURI, XQItemType type) throws XQException {
502  isClosedXQException();
503  isNullXQException(varName);
504  if (!isExternal(varName.getLocalPart())) {
505  throw new XQException ("The bound variable must be declared external in the prepared expression.");
506  }
507  isNullXQException(value);
508  if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
509  throw new XQException ("Invalid type.");
510  }
511  if (type==null) {
512  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
513  }
514  if (!isExternal(varName.getLocalPart())) {
515  throw new XQException ("Variable not found in context.");
516  }
517  try {
518  Item item = new Item();
519  item = xmlDataManager.parseXMLtoItem(value);
520  dynamicContext.setVariable(varName.getLocalPart(), item);
521  itemsBounded.add(varName.getLocalPart());
522  } catch (Exception e) {
523  throw new XQException ("Error binding document: " + e.getLocalizedMessage());
524  }
525 
526  }
527 
528  /** \brief Binds a value to the given external variable or the context item.
529  *
530  * If the value represents a well-formed XML document, it will be parsed and results in a document node. The kind of the input type must be null, XQITEMKIND_DOCUMENT_ELEMENT, or XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT.
531  *
532  * The value is converted into an instance of the specified type according to the rules defined in 14.3 Mapping a Java XML document to an XQuery document node, XQuery API for Java (XQJ) 1.0.
533  *
534  * If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation. If the value is not well formed, or if a kind of the input type other than the values list above is specified, behavior is implementation defined and may raise an exception.
535  *
536  * @param varName - the name of the external variable to bind to, cannot be null
537  * @param value - the value to be converted, cannot be null
538  * @param baseURI - an optional base URI, can be null. It can be used, for example, to resolve relative URIs and to include in error messages.
539  * @param type - the type of the value for the created document node. If null is specified, it behaves as if XQDataFactory.createDocumentElementType( XQDataFactory.createElementType(null, ZorbaXQItemType.XQBASETYPE_XS_UNTYPED)) were passed in as the type parameter. That is, the type represents the XQuery sequence type document-node(element(*, xs:untyped))
540  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
541  */
542  @Override
543  public void bindDocument(QName varName, Reader value, String baseURI, XQItemType type) throws XQException {
544  isClosedXQException();
545  isNullXQException(varName);
546  if (!isExternal(varName.getLocalPart())) {
547  throw new XQException ("The bound variable must be declared external in the prepared expression.");
548  }
549  isNullXQException(value);
550  if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
551  throw new XQException ("Invalid type.");
552  }
553  if (type==null) {
554  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
555  }
556  StringBuffer string = new StringBuffer();
557  CharBuffer buffer = CharBuffer.allocate(1024);
558  Writer writer = new StringWriter();
559 
560  try {
561  while( value.read(buffer) >= 0 ) {
562  buffer.flip();
563  writer.append(buffer);
564  buffer.clear();
565  }
566  value.close();
567  } catch (Exception ex) {
568  throw new XQException("Error preparing expression" + ex.getLocalizedMessage());
569  }
570 
571  bindDocument(varName, writer.toString(), baseURI, type);
572  }
573 
574  /** \brief Binds a value to the given external variable or the context item.
575  *
576  * If the value represents a well-formed XML document, it will be parsed and results in a document node. The kind of the input type must be null, XQITEMKIND_DOCUMENT_ELEMENT, or XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT.
577  *
578  * The value is converted into an instance of the specified type according to the rules defined in 14.3 Mapping a Java XML document to an XQuery document node, XQuery API for Java (XQJ) 1.0.
579  *
580  * If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation. If the value is not well formed, or if a kind of the input type other than the values list above is specified, behavior is implementation defined and may raise an exception.
581  *
582  * @param varName - the name of the external variable to bind to, cannot be null
583  * @param value - the value to be converted, cannot be null
584  * @param baseURI - an optional base URI, can be null. It can be used, for example, to resolve relative URIs and to include in error messages.
585  * @param type - the type of the value for the created document node. If null is specified, it behaves as if XQDataFactory.createDocumentElementType( XQDataFactory.createElementType(null, ZorbaXQItemType.XQBASETYPE_XS_UNTYPED)) were passed in as the type parameter. That is, the type represents the XQuery sequence type document-node(element(*, xs:untyped))
586  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
587  */
588  @Override
589  public void bindDocument(QName varName, InputStream value, String baseURI, XQItemType type) throws XQException {
590  isClosedXQException();
591  isNullXQException(varName);
592  if (!isExternal(varName.getLocalPart())) {
593  throw new XQException ("The bound variable must be declared external in the prepared expression.");
594  }
595  isNullXQException(value);
596  if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
597  throw new XQException ("Invalid type.");
598  }
599  if (type==null) {
600  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
601  }
602  StringBuffer out = new StringBuffer ();
603  try {
604  byte[] b = new byte[4096];
605  for (int n; (n = value.read(b)) != -1;) {
606  out.append(new String(b, 0, n));
607  }
608  } catch (Exception ex) {
609  throw new XQException("Error preparing expression" + ex.getLocalizedMessage());
610  }
611  bindDocument(varName, out.toString(), baseURI, type);
612  }
613 
614  /** \brief Binds a value to the given external variable or the context item.
615  *
616  * If the value represents a well-formed XML document, it will be parsed and results in a document node. The kind of the input type must be null, XQITEMKIND_DOCUMENT_ELEMENT, or XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT.
617  *
618  * The value is converted into an instance of the specified type according to the rules defined in 14.3 Mapping a Java XML document to an XQuery document node, XQuery API for Java (XQJ) 1.0.
619  *
620  * If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation. If the value is not well formed, or if a kind of the input type other than the values list above is specified, behavior is implementation defined and may raise an exception.
621  *
622  * @param varName - the name of the external variable to bind to, cannot be null
623  * @param value - the value to be converted, cannot be null
624  * @param type - the type of the value for the created document node. If null is specified, it behaves as if XQDataFactory.createDocumentElementType( XQDataFactory.createElementType(null, ZorbaXQItemType.XQBASETYPE_XS_UNTYPED)) were passed in as the type parameter. That is, the type represents the XQuery sequence type document-node(element(*, xs:untyped))
625  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
626  */
627  @Override
628  public void bindDocument(QName varName, XMLStreamReader value, XQItemType type) throws XQException {
629  isClosedXQException();
630  isNullXQException(varName);
631  if (!isExternal(varName.getLocalPart())) {
632  throw new XQException ("The bound variable must be declared external in the prepared expression.");
633  }
634  isNullXQException(value);
635  if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
636  throw new XQException ("Invalid type.");
637  }
638  if (type==null) {
639  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
640  }
641 
642  TransformerFactory tf = TransformerFactory.newInstance();
643  Transformer t;
644  StAXSource source;
645  StAXResult result;
646  XMLOutputFactory xof = XMLOutputFactory.newInstance();
647  Writer writer = new StringWriter();
648  try {
649  XMLStreamWriter xmlStreamWriter = xof.createXMLStreamWriter(writer);
650  t = tf.newTransformer();
651  source = new StAXSource(value);
652  result = new StAXResult(xmlStreamWriter);
653  t.transform(source, result);
654  } catch (Exception ex) {
655  throw new XQException("Error transforming xml expression" + ex.getLocalizedMessage());
656  }
657  bindDocument(varName, writer.toString(), null, type);
658  }
659 
660  private String nodeToString(Node node) {
661  StringWriter sw = new StringWriter();
662  try {
663  Transformer t = TransformerFactory.newInstance().newTransformer();
664  t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
665  t.transform(new DOMSource(node), new StreamResult(sw));
666  } catch (TransformerException te) {
667  System.out.println("nodeToString Transformer Exception" + te.getLocalizedMessage());
668  }
669  return sw.toString();
670  }
671 
672  /** \brief Binds a value to the given external variable or the context item.
673  *
674  * Binds a value to the given external variable or the context item from the given Source. An XQJ implementation must at least support the following implementations:
675  * - javax.xml.transform.dom.DOMSource
676  * - javax.xml.transform.sax.SAXSource
677  * - javax.xml.transform.stream.StreamSource
678  *
679  * If the value represents a well-formed XML document, it will be parsed and results in a document node. The kind of the input type must be null, XQITEMKIND_DOCUMENT_ELEMENT, or XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT.
680  *
681  * The value is converted into an instance of the specified type according to the rules defined in 14.3 Mapping a Java XML document to an XQuery document node, XQuery API for Java (XQJ) 1.0.
682  *
683  * If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation. If the value is not well formed, or if a kind of the input type other than the values list above is specified, behavior is implementation defined and may raise an exception.
684  *
685  * @param varName - the name of the external variable to bind to, cannot be null
686  * @param value - the value to be converted, cannot be null
687  * @param type - the type of the value for the created document node. If null is specified, it behaves as if XQDataFactory.createDocumentElementType( XQDataFactory.createElementType(null, ZorbaXQItemType.XQBASETYPE_XS_UNTYPED)) were passed in as the type parameter. That is, the type represents the XQuery sequence type document-node(element(*, xs:untyped))
688  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
689  */
690  @Override
691  public void bindDocument(QName varName, Source value, XQItemType type) throws XQException {
692  isClosedXQException();
693  isNullXQException(varName);
694  isNullXQException(value);
695  if (!((type==null) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_ELEMENT) || (type.getItemKind()==XQItemType.XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT))) {
696  throw new XQException ("Invalid type.");
697  }
698  if (!isExternal(varName.getLocalPart())) {
699  throw new XQException ("The bound variable must be declared external in the prepared expression.");
700  }
701  if (type==null) {
702  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
703  }
704  if (value instanceof StreamSource) {
705  bindDocument(varName, ((StreamSource)value).getReader(), null, type);
706  } else if (value instanceof SAXSource) {
707  bindDocument(varName, ((SAXSource)value).getInputSource().getCharacterStream(), null, type);
708  } else if (value instanceof DOMSource) {
709  bindDocument(varName, nodeToString(((DOMSource)value).getNode()), null, type);
710  } else {
711  throw new UnsupportedOperationException("Not supported yet.");
712  }
713  }
714 
715  /** \brief Sets the implicit timezone
716  *
717  * @param value - time zone to be set
718  * @throw XQException - if the expression is in a closed state
719  */
720  @Override
721  public void setImplicitTimeZone(TimeZone value) throws XQException {
722  isClosedXQException();
723  isNullXQException(value);
724  try {
725  dynamicContext.setImplicitTimezone((value.getRawOffset()/60000));
726  } catch (Exception e) {
727  throw new XQException("Error setting implicit TimeZone: " + e.getLocalizedMessage());
728  }
729  }
730 
731  /** \brief Binds a value to the given external variable.
732  *
733  * The dynamic type of the value is derived from the ZorbaXQItem. In case of a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
734  *
735  * @param varName - the name of the external variable to bind to, cannot be null
736  * @param value - the value to be bound, cannot be null
737  * @throw XQException - if (1) any of the arguments are null, (2) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (3) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, (4) the expression is in a closed state, or (5) the specified item is closed
738  */
739  @Override
740  public void bindItem(QName varName, XQItem value) throws XQException {
741  isClosedXQException();
742  isNullXQException(varName);
743  isNullXQException(value);
744  if (!isExternal(varName.getLocalPart())) {
745  throw new XQException ("The bound variable must be declared external in the prepared expression.");
746  }
747  try {
748  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)value).getZorbaItem());
749  itemsBounded.add(varName.getLocalPart());
750  } catch (Exception e) {
751  throw new XQException ("Error binding item: " + varName.getLocalPart() + " with error: " + e.getLocalizedMessage());
752  }
753  }
754 
755  /** \brief Binds a value to the given external variable or the context item.
756  *
757  * The input sequence is consumed from its current position to the end, after which the input sequence's position will be set to point after the last item. The dynamic type of the value is derived from the items in the sequence. In case of a mismatch between the static and dynamic types, an XQException is be raised either by this method, or during query evaluation.
758  *
759  * @param varName - the name of the external variable to bind to, cannot be null
760  * @param value - the value to be bound, cannot be null
761  * @throw XQException - if (1) any of the arguments are null, (2) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (3) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, (4) the expression is in a closed state, or (5) the specified item is closed
762  */
763  @Override
764  public void bindSequence(QName varName, XQSequence value) throws XQException {
765  isClosedXQException();
766  isNullXQException(varName);
767  isNullXQException(value);
768  if (value.isClosed()) {
769  throw new XQException ("Sequence is closed.");
770  }
771  if (!isExternal(varName.getLocalPart())) {
772  throw new XQException ("The bound variable must be declared external in the prepared expression.");
773  }
774  try {
775  if (!value.isOnItem()) {
776  value.next();
777  }
778  Item item = new Item(((org.zorbaxquery.api.xqj.ZorbaXQItem)value.getItem()).getZorbaItem());
779  //Item item2 = new Item(item);
780  //String val = item.getStringValue();
781  dynamicContext.setVariable(varName.getLocalPart(), item);
782  itemsBounded.add(varName.getLocalPart());
783  } catch (Exception e) {
784  throw new XQException ("Error binding item: " + varName.getLocalPart() + " with error: " + e.getLocalizedMessage());
785  }
786  }
787 
788  /** \brief Binds a value to the given external variable or the context item.
789  *
790  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
791  *
792  * @param varName - the name of the external variable to bind to, cannot be null
793  * @param value - the value to be bound, cannot be null
794  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
795  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
796  */
797  @Override
798  public void bindObject(QName varName, Object value, XQItemType type) throws XQException {
799  isClosedXQException();
800  isNullXQException(varName);
801  isNullXQException(value);
802  if (!isExternal(varName.getLocalPart())) {
803  throw new XQException ("The bound variable must be declared external in the prepared expression.");
804  }
805  try {
806  XQItem item = connection.createItemFromObject(value, type);
807  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
808  itemsBounded.add(varName.getLocalPart());
809  } catch (Exception e) {
810  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
811  }
812  }
813 
814  /** \brief Binds a value to the given external variable or the context item.
815  *
816  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
817  *
818  * @param varName - the name of the external variable to bind to, cannot be null
819  * @param value - the value to be bound, cannot be null
820  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
821  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
822  */
823  @Override
824  public void bindBoolean(QName varName, boolean value, XQItemType type) throws XQException {
825  isClosedXQException();
826  isNullXQException(varName);
827  if (!isExternal(varName.getLocalPart())) {
828  throw new XQException ("The bound variable must be declared external in the prepared expression.");
829  }
830  try {
831  XQItem item = connection.createItemFromBoolean(value, type);
832  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
833  itemsBounded.add(varName.getLocalPart());
834  } catch (Exception e) {
835  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
836  }
837  }
838 
839  /** \brief Binds a value to the given external variable or the context item.
840  *
841  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
842  *
843  * @param varName - the name of the external variable to bind to, cannot be null
844  * @param value - the value to be bound, cannot be null
845  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
846  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
847  */
848  @Override
849  public void bindByte(QName varName, byte value, XQItemType type) throws XQException {
850  isClosedXQException();
851  isNullXQException(varName);
852  if (!isExternal(varName.getLocalPart())) {
853  throw new XQException ("The bound variable must be declared external in the prepared expression.");
854  }
855  try {
856  XQItem item = connection.createItemFromByte(value, type);
857  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
858  itemsBounded.add(varName.getLocalPart());
859  } catch (Exception e) {
860  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
861  }
862  }
863 
864  /** \brief Binds a value to the given external variable or the context item.
865  *
866  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
867  *
868  * @param varName - the name of the external variable to bind to, cannot be null
869  * @param value - the value to be bound, cannot be null
870  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
871  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
872  */
873  @Override
874  public void bindDouble(QName varName, double value, XQItemType type) throws XQException {
875  isClosedXQException();
876  isNullXQException(varName);
877  if (!isExternal(varName.getLocalPart())) {
878  throw new XQException ("The bound variable must be declared external in the prepared expression.");
879  }
880  try {
881  XQItem item = connection.createItemFromDouble(value, type);
882  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
883  itemsBounded.add(varName.getLocalPart());
884  } catch (Exception e) {
885  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
886  }
887  }
888 
889  /** \brief Binds a value to the given external variable or the context item.
890  *
891  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
892  *
893  * @param varName - the name of the external variable to bind to, cannot be null
894  * @param value - the value to be bound, cannot be null
895  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
896  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
897  */
898  @Override
899  public void bindFloat(QName varName, float value, XQItemType type) throws XQException {
900  isClosedXQException();
901  isNullXQException(varName);
902  if (!isExternal(varName.getLocalPart())) {
903  throw new XQException ("The bound variable must be declared external in the prepared expression.");
904  }
905  try {
906  XQItem item = connection.createItemFromFloat(value, type);
907  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
908  itemsBounded.add(varName.getLocalPart());
909  } catch (Exception e) {
910  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
911  }
912  }
913 
914  /** \brief Binds a value to the given external variable or the context item.
915  *
916  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
917  *
918  * @param varName - the name of the external variable to bind to, cannot be null
919  * @param value - the value to be bound, cannot be null
920  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
921  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
922  */
923  @Override
924  public void bindInt(QName varName, int value, XQItemType type) throws XQException {
925  isClosedXQException();
926  isNullXQException(varName);
927  if (!isExternal(varName.getLocalPart())) {
928  throw new XQException ("The bound variable must be declared external in the prepared expression.");
929  }
930  try {
931  XQItem item = connection.createItemFromInt(value, type);
932  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
933  itemsBounded.add(varName.getLocalPart());
934  } catch (Exception e) {
935  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
936  }
937  }
938 
939  /** \brief Binds a value to the given external variable or the context item.
940  *
941  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
942  *
943  * @param varName - the name of the external variable to bind to, cannot be null
944  * @param value - the value to be bound, cannot be null
945  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
946  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
947  */
948  @Override
949  public void bindLong(QName varName, long value, XQItemType type) throws XQException {
950  isClosedXQException();
951  isNullXQException(varName);
952  if (!isExternal(varName.getLocalPart())) {
953  throw new XQException ("The bound variable must be declared external in the prepared expression.");
954  }
955  try {
956  XQItem item = connection.createItemFromLong(value, type);
957  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
958  itemsBounded.add(varName.getLocalPart());
959  } catch (Exception e) {
960  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
961  }
962  }
963 
964  /** \brief Binds a value to the given external variable or the context item.
965  *
966  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
967  *
968  * @param varName - the name of the external variable to bind to, cannot be null
969  * @param value - the value to be bound, cannot be null
970  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
971  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
972  */
973  @Override
974  public void bindNode(QName varName, Node value, XQItemType type) throws XQException {
975  isClosedXQException();
976  isNullXQException(value);
977  isNullXQException(varName);
978  if (!isExternal(varName.getLocalPart())) {
979  throw new XQException ("The bound variable must be declared external in the prepared expression.");
980  }
981  try {
982  XQItem item = connection.createItemFromNode(value, type);
983  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
984  itemsBounded.add(varName.getLocalPart());
985  } catch (Exception e) {
986  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
987  }
988  }
989 
990  /** \brief Binds a value to the given external variable or the context item.
991  *
992  * The value is converted into an instance of the specified type according to the rule defined in 14.2 Mapping a Java Data Type to an XQuery Data Type, XQuery API for Java (XQJ) 1.0. If the conversion fails, or if there is a mismatch between the static and dynamic types, an XQException is raised either by this method, or during query evaluation.
993  *
994  * @param varName - the name of the external variable to bind to, cannot be null
995  * @param value - the value to be bound, cannot be null
996  * @param type - the type of the value to be bound to the external variable. The default type of the value is used in case null is specified
997  * @throw XQException - if (1) the varName or value argument is null, (2) the conversion of the value to an XDM instance failed, (3) in case of an ZorbaXQPreparedExpression, the dynamic type of the bound value is not compatible with the static type of the variable, (4) in case of an ZorbaXQPreparedExpression, the variable is not defined in the prolog of the expression, or (5) if the expression is in a closed state
998  */
999  @Override
1000  public void bindShort(QName varName, short value, XQItemType type) throws XQException {
1001  isClosedXQException();
1002  isNullXQException(varName);
1003  if (!isExternal(varName.getLocalPart())) {
1004  throw new XQException ("The bound variable must be declared external in the prepared expression.");
1005  }
1006  try {
1007  XQItem item = connection.createItemFromShort(value, type);
1008  dynamicContext.setVariable(varName.getLocalPart(), ((org.zorbaxquery.api.xqj.ZorbaXQItem)item).getZorbaItem());
1009  itemsBounded.add(varName.getLocalPart());
1010  } catch (Exception e) {
1011  throw new XQException ("Error binding object: " + e.getLocalizedMessage());
1012  }
1013  }
1014 
1015  private void isClosedXQException() throws XQException {
1016  if (closed) {
1017  throw new XQException("This prepared expression is closed");
1018  }
1019  }
1020  private void isNullXQException(Object value) throws XQException {
1021  if (value==null) {
1022  throw new XQException("Parameter shouldn't be null");
1023  }
1024  }
1025 
1026 }
void bindFloat(QName varName, float value, XQItemType type)
Binds a value to the given external variable or the context item.
void bindNode(QName varName, Node value, XQItemType type)
Binds a value to the given external variable or the context item.
An ZorbaXQStaticContext represents default values for various XQuery Static Context Components...
void bindItem(QName varName, XQItem value)
Binds a value to the given external variable.
void bindDouble(QName varName, double value, XQItemType type)
Binds a value to the given external variable or the context item.
A connection (session) with a specific XQuery engine.
This class describes an expression that can be prepared for multiple subsequent executions.
The ZorbaXQSequenceType interface represents a sequence type as XQuery 1.0: An XML Query language...
XQResultSequence executeQuery()
Executes the prepared query expression.
ZorbaXQPreparedExpression(XQConnection conn, String string, XQStaticContext sc)
XQSequenceType getStaticVariableType(QName varName)
Retrieves the static type of a given external variable.
ZorbaXQPreparedExpression(XQConnection conn, InputStream input, XQStaticContext sc)
ZorbaXQPreparedExpression(XQConnection conn, InputStream input)
void bindSequence(QName varName, XQSequence value)
Binds a value to the given external variable or the context item.
The ZorbaXQItemType class represents an item type as defined in XQuery 1.0: An XML Query language...
void bindDocument(QName varName, String value, String baseURI, XQItemType type)
Binds a value to the given external variable or the context item.
QName[] getAllUnboundExternalVariables()
Retrieves the names of all unbound external variables.
void bindString(QName varName, String value, XQItemType type)
Binds a value to the given external variable or the context item.
TimeZone getImplicitTimeZone()
Gets the implicit timezone.
void bindDocument(QName varName, InputStream value, String baseURI, XQItemType type)
Binds a value to the given external variable or the context item.
void bindBoolean(QName varName, boolean value, XQItemType type)
Binds a value to the given external variable or the context item.
QName[] getAllExternalVariables()
Retrieves all the external variables defined in the prolog of the prepared expression.
void bindShort(QName varName, short value, XQItemType type)
Binds a value to the given external variable or the context item.
void bindObject(QName varName, Object value, XQItemType type)
Binds a value to the given external variable or the context item.
XQStaticContext getStaticContext()
Gets an ZorbaXQStaticContext representing the values for all expression properties.
void setImplicitTimeZone(TimeZone value)
Sets the implicit timezone.
void bindByte(QName varName, byte value, XQItemType type)
Binds a value to the given external variable or the context item.
ZorbaXQPreparedExpression(XQConnection conn, Reader reader, XQStaticContext sc)
void bindDocument(QName varName, Reader value, String baseURI, XQItemType type)
Binds a value to the given external variable or the context item.
void close()
Closes the expression object and release all resources associated with this prepared expression...
void bindInt(QName varName, int value, XQItemType type)
Binds a value to the given external variable or the context item.
This class represents a sequence of items obtained as a result of evaluation XQuery expressions...
boolean isClosed()
Checks if the prepared expression in a closed state.
void bindAtomicValue(QName varName, String value, XQItemType type)
Binds a value to the given external variable or the context item.
void cancel()
Attempts to cancel the execution if both the XQuery engine and XQJ driver support aborting the execut...
void bindLong(QName varName, long value, XQItemType type)
Binds a value to the given external variable or the context item.
void bindDocument(QName varName, XMLStreamReader value, XQItemType type)
Binds a value to the given external variable or the context item.
XQSequenceType getStaticResultType()
Gets the static type information of the result sequence.
void bindDocument(QName varName, Source value, XQItemType type)
Binds a value to the given external variable or the context item.