Beispiel #1
0
  /**
   * 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();
  }
Beispiel #2
0
 /**
  * Get the path map for the query expression
  *
  * @return the path map (which is constructed if this has not already been done)
  */
 public PathMap getPathMap() {
   if (pathMap == null) {
     pathMap = new PathMap(expression);
   }
   HashMap map = executable.getCompiledGlobalVariables();
   if (map != null) {
     Iterator iter = map.values().iterator();
     while (iter.hasNext()) {
       GlobalVariable var = (GlobalVariable) iter.next();
       Expression select = var.getSelectExpression();
       select.addToPathMap(pathMap, null);
     }
   }
   return pathMap;
 }
Beispiel #3
0
  /**
   * 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;
    }
  }
Beispiel #4
0
 /**
  * Ask whether this query uses the context item
  *
  * @return true if the context item is referenced either in the query body or in the initializer
  *     of any global variable
  */
 public boolean usesContextItem() {
   if ((expression.getDependencies() & StaticProperty.DEPENDS_ON_FOCUS) != 0) {
     return true;
   }
   HashMap map = executable.getCompiledGlobalVariables();
   if (map != null) {
     Iterator iter = map.values().iterator();
     while (iter.hasNext()) {
       GlobalVariable var = (GlobalVariable) iter.next();
       Expression select = var.getSelectExpression();
       if (select != null && (select.getDependencies() & StaticProperty.DEPENDS_ON_FOCUS) != 0) {
         return true;
       }
     }
   }
   return false;
 }
Beispiel #5
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);
        }
      }
    }
  }
Beispiel #6
0
 /**
  * Diagnostic method: display a representation of the compiled query on the selected output
  * stream.
  *
  * @param out an ExpressionPresenter to which the XML representation of the compiled query will be
  *     sent
  */
 public void explain(ExpressionPresenter out) {
   out.startElement("query");
   staticContext.getExecutable().getKeyManager().explainKeys(out);
   staticContext.getExecutable().explainGlobalVariables(out);
   staticContext.explainGlobalFunctions(out);
   out.startElement("body");
   expression.explain(out);
   out.endElement();
   out.endElement();
   out.close();
 }
Beispiel #7
0
  /**
   * 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;
    }
  }
Beispiel #8
0
  /**
   * 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);
  }