Example #1
0
  /**
   * 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);
        }
      }
    }
  }