/** * Run an updating query, writing back eligible updated node to persistent storage. * * <p>A node is eligible to be written back to disk if it is present in the document pool, which * generally means that it was originally read using the doc() or collection() function. * * <p>On completion of this method it is generally unsafe to rely on the contents or relationships * of NodeInfo objects that were obtained before the updating query was run. Such objects may or * may not reflect the results of the update operations. This is especially true in the case of * nodes that are part of a subtree that has been deleted (detached from its parent). Instead, the * new updated tree should be accessed by navigation from the root nodes returned by this method. * * <p>If one or more eligible updated nodes cannot be written back to disk, perhaps because the * URI identifies a non-updatable location, then an exception is thrown. In this case it is * undefined * * @param dynamicEnv the dynamic context for query execution * @throws XPathException if evaluation of the update query fails, or it this is not an updating * query */ public void runUpdate(DynamicQueryContext dynamicEnv, UpdateAgent agent) throws XPathException { if (!isUpdating) { throw new XPathException("Calling runUpdate() on a non-updating query"); } Configuration config = executable.getConfiguration(); Controller controller = newController(); initializeController(dynamicEnv, controller); XPathContextMajor context = initialContext(dynamicEnv, controller); try { PendingUpdateList pul = config.newPendingUpdateList(); context.openStackFrame(stackFrameMap); expression.evaluatePendingUpdates(context, pul); pul.apply(context, staticContext.getRevalidationMode()); for (Iterator iter = pul.getAffectedTrees().iterator(); iter.hasNext(); ) { NodeInfo node = (NodeInfo) iter.next(); agent.update(node, controller); } } catch (XPathException e) { if (!e.hasBeenReported()) { try { controller.getErrorListener().fatalError(e); } catch (TransformerException e2) { // ignore secondary error } } throw e; } }
/** * Run the query, sending the results directly to a JAXP Result object. This way of executing the * query is most efficient in the case of queries that produce a single document (or parentless * element) as their output, because it avoids constructing the result tree in memory: instead, it * is piped straight to the serializer. * * @param env the dynamic query context * @param result the destination for the results of the query. The query is effectively wrapped in * a document{} constructor, so that the items in the result are concatenated to form a single * document; this is then written to the requested Result destination, which may be (for * example) a DOMResult, a SAXResult, or a StreamResult * @param outputProperties Supplies serialization properties, in JAXP format, if the result is to * be serialized. This parameter can be defaulted to null. * @throws XPathException if the query fails. */ public void run(DynamicQueryContext env, Result result, Properties outputProperties) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call run() on an updating query"); } Controller controller = newController(); initializeController(env, controller); if (allowDocumentProjection) { controller.setUseDocumentProjection(getPathMap()); } Properties actualProperties = validateOutputProperties(controller, outputProperties); controller.defineGlobalParameters(); XPathContextMajor context = initialContext(env, controller); // In tracing/debugging mode, evaluate all the global variables first TraceListener tracer = controller.getTraceListener(); if (tracer != null) { controller.preEvaluateGlobals(context); tracer.open(); } context.openStackFrame(stackFrameMap); boolean mustClose = (result instanceof StreamResult && ((StreamResult) result).getOutputStream() == null); context.changeOutputDestination( actualProperties, result, true, Configuration.XQUERY, Validation.PRESERVE, null); context.getReceiver().open(); // Run the query try { expression.process(context); } catch (XPathException err) { controller.reportFatalError(err); throw err; } if (tracer != null) { tracer.close(); } context.getReceiver().close(); if (mustClose) { OutputStream os = ((StreamResult) result).getOutputStream(); if (os != null) { try { os.close(); } catch (java.io.IOException err) { throw new XPathException(err); } } } }
/** * Get an iterator over the results of the expression. This returns results without any conversion * of the returned items to "native" Java classes. The iterator will deliver a sequence of Item * objects, each item being either a NodeInfo (representing a node) or an AtomicValue * (representing an atomic value). * * <p> * * <p>To get the results of the query in the form of an XML document in which each item is wrapped * by an element indicating its type, use: * * <p> * * <p><code>QueryResult.wrap(iterator(env))</code> * * <p> * * <p>To serialize the results to a file, use the QueryResult.serialize() method. * * @param env Provides the dynamic query evaluation context * @return an iterator over the results of the query. The class SequenceIterator is modeled on the * standard Java Iterator class, but has extra functionality and can throw exceptions when * errors occur. * @throws XPathException if a dynamic error occurs in evaluating the query. Some dynamic errors * will not be reported by this method, but will only be reported when the individual items of * the result are accessed using the returned iterator. */ public SequenceIterator iterator(DynamicQueryContext env) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call iterator() on an updating query"); } Controller controller = newController(); initializeController(env, controller); try { Item contextItem = env.getContextItem(); // Bindery bindery = controller.getBindery(); // bindery.openStackFrame(); controller.defineGlobalParameters(); XPathContextMajor context = controller.newXPathContext(); if (contextItem != null) { if (!staticContext .getUserQueryContext() .getRequiredContextItemType() .matchesItem(contextItem, false, env.getConfiguration())) { throw new XPathException( "The supplied context item does not match the required context item type"); } UnfailingIterator single = SingletonIterator.makeIterator(contextItem); single.next(); context.setCurrentIterator(single); controller.setInitialContextItem(contextItem); } // In tracing/debugging mode, evaluate all the global variables first if (controller.getTraceListener() != null) { controller.preEvaluateGlobals(context); } context.openStackFrame(stackFrameMap); SequenceIterator iterator = expression.iterate(context); return new ErrorReportingIterator(iterator, controller.getErrorListener()); } catch (XPathException err) { TransformerException terr = err; while (terr.getException() instanceof TransformerException) { terr = (TransformerException) terr.getException(); } XPathException de = XPathException.makeXPathException(terr); controller.reportFatalError(de); throw de; } }
private XPathContextMajor initialContext(DynamicQueryContext dynamicEnv, Controller controller) throws XPathException { Item contextItem = dynamicEnv.getContextItem(); controller.defineGlobalParameters(); XPathContextMajor context = controller.newXPathContext(); if (contextItem != null) { if (!staticContext .getUserQueryContext() .getRequiredContextItemType() .matchesItem(contextItem, false, dynamicEnv.getConfiguration())) { throw new XPathException( "The supplied context item does not match the required context item type"); } UnfailingIterator single = SingletonIterator.makeIterator(contextItem); single.next(); context.setCurrentIterator(single); controller.setInitialContextItem(contextItem); } return context; }
/** * Run the query returning the results as an EventIterator * * @param controller The Controller used to run the query * @param dynamicEnv the XQuery dynamic context for evaluating the query * @return an EventIterator representing the results of the query as a sequence of events */ public EventIterator iterateEvents(Controller controller, DynamicQueryContext dynamicEnv) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call iterateEvents() on an updating query"); } initializeController(dynamicEnv, controller); XPathContextMajor context = initialContext(dynamicEnv, controller); // In tracing/debugging mode, evaluate all the global variables first if (controller.getTraceListener() != null) { controller.preEvaluateGlobals(context); } context.openStackFrame(stackFrameMap); final Configuration config = executable.getConfiguration(); EventIterator ei = expression.iterateEvents(context); // ei = new TracingEventIterator(EventStackIterator.flatten(ei)); return new ComplexContentProcessor(config, ei); }