예제 #1
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;
    }
  }
예제 #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;
 }
예제 #3
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;
 }
예제 #4
0
  private void initializeController(DynamicQueryContext env, Controller controller) {
    HashMap parameters = env.getParameters();
    if (parameters != null) {
      Iterator iter = parameters.keySet().iterator();
      while (iter.hasNext()) {
        String paramName = (String) iter.next();
        Object paramValue = parameters.get(paramName);
        controller.setParameter(paramName, paramValue);
      }
    }

    controller.setURIResolver(env.getURIResolver());
    controller.setErrorListener(env.getErrorListener());
    controller.addTraceListener(env.getTraceListener());
    controller.setTraceFunctionDestination(env.getTraceFunctionDestination());
    DateTimeValue currentDateTime = env.getCurrentDateTime();
    if (currentDateTime != null) {
      try {
        controller.setCurrentDateTime(currentDateTime);
      } catch (XPathException e) {
        throw new AssertionError(e); // the value should already have been checked
      }
    }
  }