/** * 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 in pull mode. * * <p> * * <p>For maximum effect this method should be used when lazyConstructionMode has been set in the * Configuration. * * <p> * * <p><b>Note: this method usually has very similar performance to the {@link * #run(DynamicQueryContext,javax.xml.transform.Result,java.util.Properties)} method (which does * the same thing), but sometimes it is significantly slower. Therefore, the run() method is * preferred.</b> * * @param dynamicEnv the dynamic context for query evaluation * @param destination the destination of the query results * @param outputProperties the serialization parameters * @see Configuration#setLazyConstructionMode(boolean) */ public void pull(DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call pull() on an updating query"); } Configuration config = dynamicEnv.getConfiguration(); try { Controller controller = newController(); // initializeController(dynamicEnv, controller); EventIterator iter = iterateEvents(controller, dynamicEnv); // iter = new Decomposer(iter, config); Properties actualProperties = validateOutputProperties(controller, outputProperties); SerializerFactory sf = config.getSerializerFactory(); PipelineConfiguration pipe = config.makePipelineConfiguration(); pipe.setSerializing(true); Receiver receiver = sf.getReceiver(destination, pipe, actualProperties); receiver = new NamespaceReducer(receiver); if ("yes".equals(actualProperties.getProperty(SaxonOutputKeys.WRAP))) { receiver = new SequenceWrapper(receiver); // receiver = new TracingFilter(receiver); } else { receiver = new TreeReceiver(receiver); } EventIteratorToReceiver.copy(iter, (SequenceReceiver) receiver); } catch (XPathException err) { config.reportFatalError(err); throw err; } }
/** * Run the query in pull mode. * * <p> * * <p>For maximum effect this method should be used when lazyConstructionMode has been set in the * Configuration. * * <p> * * <p><b>Note: this method usually has very similar performance to the {@link * #run(DynamicQueryContext,javax.xml.transform.Result,java.util.Properties)} method (which does * the same thing), but sometimes it is significantly slower. Therefore, the run() method is * preferred.</b> * * @param dynamicEnv the dynamic context for query evaluation * @param destination the destination of the query results * @param outputProperties the serialization parameters * @see Configuration#setLazyConstructionMode(boolean) */ public void pullOLD( DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties) throws XPathException { try { SequenceIterator iter = iterator(dynamicEnv); PullProvider pull = new PullFromIterator(iter); pull = new PullNamespaceReducer(pull); final Configuration config = executable.getConfiguration(); pull.setPipelineConfiguration(config.makePipelineConfiguration()); SerializerFactory sf = config.getSerializerFactory(); Receiver receiver = sf.getReceiver(destination, pull.getPipelineConfiguration(), outputProperties); // NamespaceReducer reducer = new NamespaceReducer(); // PipelineConfiguration pipe = pull.getPipelineConfiguration(); // reducer.setPipelineConfiguration(pipe); // reducer.setUnderlyingReceiver(receiver); // ComplexContentOutputter outputter = new ComplexContentOutputter(); // outputter.setReceiver(reducer); // outputter.setPipelineConfiguration(pipe); Receiver outputter = receiver; if ("yes".equals(outputProperties.getProperty(SaxonOutputKeys.WRAP))) { receiver = new SequenceWrapper(outputter); } else { // receiver = new TreeReceiver(outputter); } new PullPushCopier(pull, receiver).copy(); } catch (UncheckedXPathException e) { throw e.getXPathException(); } }
/** * The constructor is protected, to ensure that instances can only be created using the * compileQuery() methods of StaticQueryContext * * @param exp an expression to be wrapped as an XQueryExpression * @param exec the executable * @param mainModule the static context of the main module * @param config the configuration * @throws XPathException if an error occurs */ protected XQueryExpression( Expression exp, Executable exec, QueryModule mainModule, Configuration config) throws XPathException { stackFrameMap = config.makeSlotManager(); executable = exec; exp.setContainer(this); try { ExpressionVisitor visitor = ExpressionVisitor.make(mainModule); visitor.setExecutable(exec); exp = visitor.simplify(exp); exp.checkForUpdatingSubexpressions(); exp = visitor.typeCheck(exp, mainModule.getUserQueryContext().getRequiredContextItemType()); // ExpressionPresenter presenter = new ExpressionPresenter(config, // ExpressionPresenter.defaultDestination(config, new // FileOutputStream("c:/projects/montreal/before50.xml"))); // exp.explain(presenter); // presenter.close(); exp = exp.optimize(visitor, Type.ITEM_TYPE); } catch (XPathException err) { // err.printStackTrace(); mainModule.reportFatalError(err); throw err; } ExpressionTool.allocateSlots(exp, 0, stackFrameMap); expression = exp; executable.setConfiguration(config); executable.setDefaultCollationName(mainModule.getDefaultCollationName()); executable.setCollationTable(mainModule.getUserQueryContext().getAllCollations()); staticContext = mainModule; isUpdating = exp.isUpdatingExpression(); }