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.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.*;
40  /**
41  * This class describes an expression that can be prepared for multiple subsequent executions. A prepared expression can be created from the connection.
42  *
43  * The preparation of the expression does the static analysis of the expression using the static context information.
44  *
45  * 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.
46  *
47  * The static type information of the query can also be retrieved if the XQuery implementation provides it using the getStaticResultType method.
48  *
49  * 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.
50  *
51  * 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.
52  *
53  * 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.
54  *
55  * When the ZorbaXQPreparedExpression is closed any ZorbaXQResultSequence object obtained from it is also implicitly closed.
56  *
57  * Example -
58  * \code{.java}
59  * ZorbaXQConnection conn = XQDataSource.getconnection();
60  * ZorbaXQPreparedExpression expr = conn.prepareExpression
61  * ("for $i in (1) return 'abc' ");
62  *
63  * // get the sequence type out.. This would be something like xs:string *
64  * ZorbaXQSequenceType type = expr.getStaticResultType();
65  *
66  * XQSequence result1 = expr.executeQuery();
67  *
68  * // process the result..
69  * result1.next();
70  * System.out.println(" First result1 "+ result1.getAtomicValue());
71  *
72  * ZorbaXQResultSequence result2 = expr.executeQuery();
73  *
74  * // result1 is implicitly closed
75  * // recommended to close the result sequences explicitly.
76  *
77  * // process the result..
78  * while (result2.next())
79  * System.out.println(" result is "+ result2.getAtomicValue());
80  *
81  * result2.close();
82  * expr.close(); // closing expression implicitly closes all result sequence or
83  * // items obtained from this expression.
84  * conn.close(); // closing connections will close expressions and results.
85  * \endcode
86  */
87 public class ZorbaXQPreparedExpression implements javax.xml.xquery.XQPreparedExpression {
88 
89  private XQuery query;
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>();
97 
98 
99  public ZorbaXQPreparedExpression (XQConnection conn, String string) throws XQException {
100  if (conn.isClosed()) {
101  throw new XQException ("Connection is closed");
102  }
103  closed = false;
104  connection = conn;
105  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
106  try {
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());
112 
113  }
114  }
115  public ZorbaXQPreparedExpression (XQConnection conn, String string, XQStaticContext sc) throws XQException {
116  if (conn.isClosed()) {
117  throw new XQException ("Connection is closed");
118  }
119  closed = false;
120  connection = conn;
121  Zorba zorba = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).getZorbaInstance();
122  try {
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());
128 
129  }
130  }
131 
132  /** \brief Attempts to cancel the execution if both the XQuery engine and XQJ driver support aborting the execution of an ZorbaXQPreparedExpression.
133  *
134  * 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.
135  *
136  * @throw XQException - if the prepared expression is in a closed state
137  */
138  @Override
139  public void cancel() throws XQException {
140  isClosedXQException();
141  }
142 
143  /** \brief Checks if the prepared expression in a closed state.
144  *
145  * @return true if the prepared expression is in a closed state, false otherwise.
146  */
147  @Override
148  public boolean isClosed() {
149  return closed;
150  }
151 
152  /** \brief Closes the expression object and release all resources associated with this prepared expression.
153  *
154  * 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.
155  *
156  * @throw XQException - if there are errors when closing the expression
157  */
158  @Override
159  public void close() throws XQException {
160  closed = true;
161  for (XQResultSequence sequence: resultSequences) {
162  sequence.close();
163  }
164  if (query!=null) {
165  query.delete();
166  }
167  }
168 
169  /** \brief Executes the prepared query expression.
170  *
171  * Calling this method implicitly closes any previous result sequence obtained from this expression.
172  *
173  * @return the xquery sequence object containing the result of the query execution
174  * @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
175  */
176  @Override
177  public XQResultSequence executeQuery() throws XQException {
178  isClosedXQException();
179  XQResultSequence result = null;
180  try {
181  result = new org.zorbaxquery.api.xqj.ZorbaXQResultSequence(connection, query, true);
182  } catch (Exception e) {
183  throw new XQException("Error executing query: " + e.getLocalizedMessage());
184  }
185  resultSequences.add(result);
186  return result;
187  }
188 
189  /** \brief Retrieves all the external variables defined in the prolog of the prepared expression.
190  *
191  * @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.
192  * @throw XQException - if the prepared expression is in a closed state
193  */
194  @Override
195  public QName[] getAllExternalVariables() throws XQException {
196  isClosedXQException();
197  Collection<QName> result = new ArrayList<QName>();
198  Iterator iter = new Iterator();
199  query.getExternalVariables(iter);
200  iter.open();
201  Item item = new Item();
202  while (iter.next(item)) {
203  result.add(new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
204  }
205  iter.close();
206  iter.delete();
207  return result.toArray(new QName[0]);
208  }
209 
210  private boolean isExternal(String varName) {
211  boolean found=false;
212  Iterator iter = new Iterator();
213  query.getExternalVariables(iter);
214  iter.open();
215  Item item = new Item();
216  while (iter.next(item)) {
217  if (item.getLocalName().equalsIgnoreCase(varName)) {
218  found = true;
219  }
220  }
221  iter.close();
222  iter.delete();
223  return found;
224  }
225 
226  /** \brief Retrieves the names of all unbound external variables.
227  *
228  * 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()*.
229  *
230  * @return ZorbaXQSequenceType containing the static result information.
231  * @throw XQException - if the prepared expression is in a closed state
232  */
233  @Override
234  public QName[] getAllUnboundExternalVariables() throws XQException {
235  isClosedXQException();
236 
237  Collection<QName> result = new ArrayList<QName>();
238  Iterator iter = new Iterator();
239  query.getExternalVariables(iter);
240  Item item = new Item();
241  iter.open();
242  while (iter.next(item)) {
243  boolean found = false;
244  for (String key: itemsBounded){
245  if (item.getLocalName().equalsIgnoreCase(key)) {
246  found = true;
247  }
248  }
249  if (!found) {
250  result.add(new QName(item.getNamespace(), item.getLocalName(), item.getPrefix()));
251  }
252  }
253  iter.close();
254  iter.delete();
255  return result.toArray(new QName[0]);
256  }
257 
258  /** \brief Gets the static type information of the result sequence.
259  *
260  * 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()*.
261  *
262  * @return ZorbaXQSequenceType containing the static result information.
263  * @throw XQException - if the prepared expression is in a closed state
264  */
265  @Override
266  public XQSequenceType getStaticResultType() throws XQException {
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 );
269  return result;
270  }
271 
272  /** \brief Retrieves the static type of a given external variable.
273  *
274  * @param varName - the name of the external variable
275  * @return the static type information of the variable as defined in the prolog of the prepared expression
276  * @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
277  */
278  @Override
279  public XQSequenceType getStaticVariableType(QName varName) throws XQException {
280  isClosedXQException();
281  isNullXQException(varName);
282  XQSequenceType result = null;
283  Iterator iter = new Iterator();
284  query.getExternalVariables(iter);
285  iter.open();
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);
293  } else {
294  result = new org.zorbaxquery.api.xqj.ZorbaXQSequenceType(new org.zorbaxquery.api.xqj.ZorbaXQItemType(item), XQItemType.OCC_ZERO_OR_MORE);
295  }
296 
297  }
298  }
299  iter.close();
300  iter.delete();
301  if (result==null) {
302  throw new XQException("Item not found");
303  }
304  return result;
305  }
306 
307  /** \brief Gets an ZorbaXQStaticContext representing the values for all expression properties.
308  *
309  * Note that these properties cannot be changed; in order to change, a new ZorbaXQPreparedExpression needs to be created.
310  *
311  * @return an ZorbaXQStaticContext representing the values for all expression properties
312  * @throw XQException - if the expression is in a closed state
313  */
314  @Override
315  public XQStaticContext getStaticContext() throws XQException {
316  isClosedXQException();
317  if (staticContext==null) {
318  staticContext = new org.zorbaxquery.api.xqj.ZorbaXQStaticContext(query);
319  }
320  return staticContext;
321  }
322 
323  /** \brief Gets the implicit timezone
324  *
325  * @return the implicit timezone. This may have been set by an application using the setImplicitTimeZone method or provided by the implementation
326  * @throw XQException - if the expression is in a closed state
327  */
328  @Override
329  public TimeZone getImplicitTimeZone() throws XQException {
330  isClosedXQException();
331  Integer timeZone = (dynamicContext.getImplicitTimezone()/60); // in minutes
332  TimeZone result = TimeZone.getTimeZone("GMT"+timeZone.toString());
333  return result;
334  }
335 
336  /** \brief Binds a value to the given external variable or the context item.
337  *
338  * 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.
339  *
340  * @param varName - the name of the external variable to bind to
341  * @param value - the lexical string value of the type
342  * @param type - the item type of the bind
343  * @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
344  */
345  @Override
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.");
353  }
354  if (type.getItemKind()!=XQItemType.XQITEMKIND_ATOMIC) {
355  throw new XQException ("Item kind is not atomic.");
356  }
357  try {
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());
364  }
365 
366  }
367 
368  /** \brief Binds a value to the given external variable or the context item.
369  *
370  * 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.
371  * 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.
372  *
373  * @param varName - the name of the external variable to bind to, cannot be null
374  * @param value - the value to be converted, cannot be null
375  * @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
376  * @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
377  */
378  @Override
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.");
384  }
385  isNullXQException(value);
386  if (type==null) {
387  type = ((org.zorbaxquery.api.xqj.ZorbaXQConnection)connection).createAtomicType(XQItemType.XQBASETYPE_STRING);
388  }
389  try {
390  Iterator iter = new Iterator();
391  boolean found = false;
392  query.getExternalVariables(iter);
393  Item tmpItem = new Item();
394  iter.open();
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());
400  found=true;
401  }
402  }
403  iter.close();
404  iter.delete();
405  if (!found) {
406  throw new XQException ("The variable: " + varName.getLocalPart() + " doesn't exist.");
407  }
408  } catch (XQException e) {
409  throw e;
410  } catch (Exception e) {
411  throw new XQException ("Error binding string to the defined type: " + e.getLocalizedMessage());
412  }
413 
414  }
415 
416  /** \brief Binds a value to the given external variable or the context item.
417  *
418  * 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.
419  *
420  * 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.
421  *
422  * 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.
423  *
424  * @param varName - the name of the external variable to bind to, cannot be null
425  * @param value - the value to be converted, cannot be null
426  * @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.
427  * @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))
428  * @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
429  */
430  @Override
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.");
436  }
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.");
440  }
441  if (type==null) {
442  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
443  }
444  if (!isExternal(varName.getLocalPart())) {
445  throw new XQException ("Variable not found in context.");
446  }
447  try {
448  Iterator iter = xmlDataManager.parseXML(value);
449  Item item = new Item();
450  iter.next(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());
455  }
456 
457  }
458 
459  /** \brief Binds a value to the given external variable or the context item.
460  *
461  * 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.
462  *
463  * 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.
464  *
465  * 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.
466  *
467  * @param varName - the name of the external variable to bind to, cannot be null
468  * @param value - the value to be converted, cannot be null
469  * @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.
470  * @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))
471  * @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
472  */
473  @Override
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.");
479  }
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.");
483  }
484  if (type==null) {
485  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
486  }
487  StringBuffer string = new StringBuffer();
488  CharBuffer buffer = CharBuffer.allocate(1024);
489  Writer writer = new StringWriter();
490 
491  try {
492  while( value.read(buffer) >= 0 ) {
493  buffer.flip();
494  writer.append(buffer);
495  buffer.clear();
496  }
497  value.close();
498  } catch (Exception ex) {
499  throw new XQException("Error preparing expression" + ex.getLocalizedMessage());
500  }
501 
502  bindDocument(varName, writer.toString(), baseURI, type);
503  }
504 
505  /** \brief Binds a value to the given external variable or the context item.
506  *
507  * 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.
508  *
509  * 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.
510  *
511  * 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.
512  *
513  * @param varName - the name of the external variable to bind to, cannot be null
514  * @param value - the value to be converted, cannot be null
515  * @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.
516  * @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))
517  * @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
518  */
519  @Override
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.");
525  }
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.");
529  }
530  if (type==null) {
531  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
532  }
533  StringBuffer out = new StringBuffer ();
534  try {
535  byte[] b = new byte[4096];
536  for (int n; (n = value.read(b)) != -1;) {
537  out.append(new String(b, 0, n));
538  }
539  } catch (Exception ex) {
540  throw new XQException("Error preparing expression" + ex.getLocalizedMessage());
541  }
542  bindDocument(varName, out.toString(), baseURI, type);
543  }
544 
545  /** \brief Binds a value to the given external variable or the context item.
546  *
547  * 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.
548  *
549  * 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.
550  *
551  * 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.
552  *
553  * @param varName - the name of the external variable to bind to, cannot be null
554  * @param value - the value to be converted, cannot be null
555  * @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))
556  * @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
557  */
558  @Override
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.");
564  }
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.");
568  }
569  if (type==null) {
570  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
571  }
572 
573  TransformerFactory tf = TransformerFactory.newInstance();
574  Transformer t;
575  StAXSource source;
576  StAXResult result;
577  XMLOutputFactory xof = XMLOutputFactory.newInstance();
578  Writer writer = new StringWriter();
579  try {
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());
587  }
588  bindDocument(varName, writer.toString(), null, type);
589  }
590 
591  private String nodeToString(Node node) {
592  StringWriter sw = new StringWriter();
593  try {
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());
599  }
600  return sw.toString();
601  }
602 
603  /** \brief Binds a value to the given external variable or the context item.
604  *
605  * 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:
606  * - javax.xml.transform.dom.DOMSource
607  * - javax.xml.transform.sax.SAXSource
608  * - javax.xml.transform.stream.StreamSource
609  *
610  * 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.
611  *
612  * 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.
613  *
614  * 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.
615  *
616  * @param varName - the name of the external variable to bind to, cannot be null
617  * @param value - the value to be converted, cannot be null
618  * @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))
619  * @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
620  */
621  @Override
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.");
628  }
629  if (!isExternal(varName.getLocalPart())) {
630  throw new XQException ("The bound variable must be declared external in the prepared expression.");
631  }
632  if (type==null) {
633  type = connection.createDocumentElementType(connection.createElementType(null, XQItemType.XQBASETYPE_UNTYPED));
634  }
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);
641  } else {
642  throw new UnsupportedOperationException("Not supported yet.");
643  }
644  }
645 
646  /** \brief Sets the implicit timezone
647  *
648  * @param value - time zone to be set
649  * @throw XQException - if the expression is in a closed state
650  */
651  @Override
652  public void setImplicitTimeZone(TimeZone value) throws XQException {
653  isClosedXQException();
654  isNullXQException(value);
655  try {
656  dynamicContext.setImplicitTimezone((value.getRawOffset()/60000));
657  } catch (Exception e) {
658  throw new XQException("Error setting implicit TimeZone: " + e.getLocalizedMessage());
659  }
660  }
661 
662  /** \brief Binds a value to the given external variable.
663  *
664  * 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.
665  *
666  * @param varName - the name of the external variable to bind to, cannot be null
667  * @param value - the value to be bound, cannot be null
668  * @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
669  */
670  @Override
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.");
677  }
678  try {
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());
683  }
684  }
685 
686  /** \brief Binds a value to the given external variable or the context item.
687  *
688  * 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.
689  *
690  * @param varName - the name of the external variable to bind to, cannot be null
691  * @param value - the value to be bound, cannot be null
692  * @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
693  */
694  @Override
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.");
701  }
702  if (!isExternal(varName.getLocalPart())) {
703  throw new XQException ("The bound variable must be declared external in the prepared expression.");
704  }
705  try {
706  if (!value.isOnItem()) {
707  value.next();
708  }
709  Item item = new Item(((org.zorbaxquery.api.xqj.ZorbaXQItem)value.getItem()).getZorbaItem());
710  //Item item2 = new Item(item);
711  //String val = item.getStringValue();
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());
716  }
717  }
718 
719  /** \brief Binds a value to the given external variable or the context item.
720  *
721  * 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.
722  *
723  * @param varName - the name of the external variable to bind to, cannot be null
724  * @param value - the value to be bound, cannot be null
725  * @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
726  * @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
727  */
728  @Override
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.");
735  }
736  try {
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());
742  }
743  }
744 
745  /** \brief Binds a value to the given external variable or the context item.
746  *
747  * 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.
748  *
749  * @param varName - the name of the external variable to bind to, cannot be null
750  * @param value - the value to be bound, cannot be null
751  * @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
752  * @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
753  */
754  @Override
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.");
760  }
761  try {
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());
767  }
768  }
769 
770  /** \brief Binds a value to the given external variable or the context item.
771  *
772  * 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.
773  *
774  * @param varName - the name of the external variable to bind to, cannot be null
775  * @param value - the value to be bound, cannot be null
776  * @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
777  * @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
778  */
779  @Override
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.");
785  }
786  try {
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());
792  }
793  }
794 
795  /** \brief Binds a value to the given external variable or the context item.
796  *
797  * 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.
798  *
799  * @param varName - the name of the external variable to bind to, cannot be null
800  * @param value - the value to be bound, cannot be null
801  * @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
802  * @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
803  */
804  @Override
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.");
810  }
811  try {
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());
817  }
818  }
819 
820  /** \brief Binds a value to the given external variable or the context item.
821  *
822  * 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.
823  *
824  * @param varName - the name of the external variable to bind to, cannot be null
825  * @param value - the value to be bound, cannot be null
826  * @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
827  * @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
828  */
829  @Override
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.");
835  }
836  try {
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());
842  }
843  }
844 
845  /** \brief Binds a value to the given external variable or the context item.
846  *
847  * 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.
848  *
849  * @param varName - the name of the external variable to bind to, cannot be null
850  * @param value - the value to be bound, cannot be null
851  * @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
852  * @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
853  */
854  @Override
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.");
860  }
861  try {
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());
867  }
868  }
869 
870  /** \brief Binds a value to the given external variable or the context item.
871  *
872  * 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.
873  *
874  * @param varName - the name of the external variable to bind to, cannot be null
875  * @param value - the value to be bound, cannot be null
876  * @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
877  * @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
878  */
879  @Override
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.");
885  }
886  try {
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());
892  }
893  }
894 
895  /** \brief Binds a value to the given external variable or the context item.
896  *
897  * 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.
898  *
899  * @param varName - the name of the external variable to bind to, cannot be null
900  * @param value - the value to be bound, cannot be null
901  * @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
902  * @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
903  */
904  @Override
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.");
911  }
912  try {
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());
918  }
919  }
920 
921  /** \brief Binds a value to the given external variable or the context item.
922  *
923  * 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.
924  *
925  * @param varName - the name of the external variable to bind to, cannot be null
926  * @param value - the value to be bound, cannot be null
927  * @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
928  * @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
929  */
930  @Override
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.");
936  }
937  try {
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());
943  }
944  }
945 
946  private void isClosedXQException() throws XQException {
947  if (closed) {
948  throw new XQException("This prepared expression is closed");
949  }
950  }
951  private void isNullXQException(Object value) throws XQException {
952  if (value==null) {
953  throw new XQException("Parameter shouldn't be null");
954  }
955  }
956 
957 }
blog comments powered by Disqus