public void testSubstringBeforeFunctionRequiresAtMostTwoArguments() throws JaxenException {
   BaseXPath xpath = new DOMXPath("substring-before('a', 'a', 'a')");
   try {
     xpath.selectNodes(doc);
     fail("Allowed substring-before function with three arguments");
   } catch (FunctionCallException ex) {
     assertNotNull(ex.getMessage());
   }
 }
 public void testNormalizeSpaceRequiresAtMostOneArguments() throws JaxenException {
   BaseXPath xpath = new DOMXPath("normalize-space('a', 'a')");
   try {
     xpath.selectNodes(doc);
     fail("Allowed normalize-space function with two arguments");
   } catch (FunctionCallException ex) {
     assertNotNull(ex.getMessage());
   }
 }
Example #3
0
  public void testContainsFunctionRequiresAtLeastTwoArguments() throws JaxenException {

    BaseXPath xpath = new DOMXPath("contains('a')");

    try {
      xpath.selectNodes(doc);
      fail("Allowed contains function with one argument");
    } catch (FunctionCallException ex) {
      assertNotNull(ex.getMessage());
    }
  }
Example #4
0
 @SuppressWarnings("unchecked")
 public static Iterator<Node> findNodes(
     Node node, String xpathquery, Map<String, String> namespaces) {
   Iterator<Node> it = null;
   try {
     BaseXPath expression = getXpath(xpathquery, namespaces);
     it = expression.selectNodes(node).iterator();
   } catch (Exception exe) {
   }
   if (it == null) {
     it = new Vector().iterator();
   }
   return it;
 }
Example #5
0
  private BaseXPath createXPath(String xpathQueryString, Navigator navigator)
      throws JaxenException {

    BaseXPath xpath = new BaseXPath(xpathQueryString, navigator);
    if (properties.size() > 1) {
      SimpleVariableContext vc = new SimpleVariableContext();
      for (Entry<PropertyDescriptor<?>, Object> e : properties.entrySet()) {
        String propName = e.getKey().name();
        if (!"xpath".equals(propName)) {
          Object value = e.getValue();
          vc.setVariableValue(propName, value != null ? value.toString() : null);
        }
      }
      xpath.setVariableContext(vc);
    }
    return xpath;
  }
Example #6
0
 /**
  * Static saving of xpath queries reduces the compile time of the query up to 90%. A complete
  * XPath Query on a more then 100 line XML document will be up to 10 times faster, 0.1 ms instead
  * of 1 ms (core2duo)
  *
  * @param xpath
  * @param namespaces
  * @return
  * @throws JaxenException
  */
 public static BaseXPath getXpath(String xpath, Map<String, String> namespaces)
     throws JaxenException {
   if (xpathCache.containsKey(xpath + namespaces.hashCode())) {
     return xpathCache.get(xpath + namespaces.hashCode());
   } else {
     final BaseXPath expression = new DOMXPath(xpath);
     Set<Entry<String, String>> nsKeys = namespaces.entrySet();
     for (Entry<String, String> entry : nsKeys) {
       expression.addNamespace(entry.getKey(), entry.getValue());
     }
     if (xpathCache.size() > 20000) {
       log.info("Size of XPath Cache exceeded size of 20000, starting with new cache.");
       xpathCache = new HashMap<String, BaseXPath>();
     }
     xpathCache.put(xpath + namespaces.hashCode(), expression);
     return expression;
   }
 }
Example #7
0
  @SuppressWarnings("unchecked")
  private void initializeXPathExpression(Navigator navigator) throws JaxenException {
    if (initializationStatus == InitializationStatus.FULL) {
      return;
    } else if (initializationStatus == InitializationStatus.PARTIAL && navigator == null) {
      if (LOG.isLoggable(Level.SEVERE)) {
        LOG.severe(
            "XPathRule is not initialized because no navigator was provided. "
                + "Please make sure to implement getXPathHandler in the handler of the language. "
                + "See also AbstractLanguageVersionHandler.");
      }
      return;
    }

    //
    // Attempt to use the RuleChain with this XPath query.  To do so, the queries
    // should generally look like //TypeA or //TypeA | //TypeB.  We will look at the
    // parsed XPath AST using the Jaxen APIs to make this determination.
    // If the query is not exactly what we are looking for, do not use the RuleChain.
    //
    nodeNameToXPaths = new HashMap<String, List<XPath>>();

    BaseXPath originalXPath = createXPath(xpath, navigator);
    indexXPath(originalXPath, AST_ROOT);

    boolean useRuleChain = true;
    Stack<Expr> pending = new Stack<Expr>();
    pending.push(originalXPath.getRootExpr());
    while (!pending.isEmpty()) {
      Expr node = pending.pop();

      // Need to prove we can handle this part of the query
      boolean valid = false;

      // Must be a LocationPath... that is something like //Type
      if (node instanceof LocationPath) {
        LocationPath locationPath = (LocationPath) node;
        if (locationPath.isAbsolute()) {
          // Should be at least two steps
          List<Step> steps = locationPath.getSteps();
          if (steps.size() >= 2) {
            Step step1 = steps.get(0);
            Step step2 = steps.get(1);
            // First step should be an AllNodeStep using the descendant or self axis
            if (step1 instanceof AllNodeStep
                && ((AllNodeStep) step1).getAxis() == Axis.DESCENDANT_OR_SELF) {
              // Second step should be a NameStep using the child axis.
              if (step2 instanceof NameStep && ((NameStep) step2).getAxis() == Axis.CHILD) {
                // Construct a new expression that is appropriate for RuleChain use
                XPathFactory xpathFactory = new DefaultXPathFactory();

                // Instead of an absolute location path, we'll be using a relative path
                LocationPath relativeLocationPath = xpathFactory.createRelativeLocationPath();
                // The first step will be along the self axis
                Step allNodeStep = xpathFactory.createAllNodeStep(Axis.SELF);
                // Retain all predicates from the original name step
                for (Iterator<Predicate> i = step2.getPredicates().iterator(); i.hasNext(); ) {
                  allNodeStep.addPredicate(i.next());
                }
                relativeLocationPath.addStep(allNodeStep);

                // Retain the remaining steps from the original location path
                for (int i = 2; i < steps.size(); i++) {
                  relativeLocationPath.addStep(steps.get(i));
                }

                BaseXPath xpath = createXPath(relativeLocationPath.getText(), navigator);
                indexXPath(xpath, ((NameStep) step2).getLocalName());
                valid = true;
              }
            }
          }
        }
      } else if (node
          instanceof UnionExpr) { // Or a UnionExpr, that is something like //TypeA | //TypeB
        UnionExpr unionExpr = (UnionExpr) node;
        pending.push(unionExpr.getLHS());
        pending.push(unionExpr.getRHS());
        valid = true;
      }
      if (!valid) {
        useRuleChain = false;
        break;
      }
    }

    if (useRuleChain) {
      // Use the RuleChain for all the nodes extracted from the xpath queries
      super.ruleChainVisits.addAll(nodeNameToXPaths.keySet());
    } else {
      // Use original XPath if we cannot use the RuleChain
      nodeNameToXPaths.clear();
      indexXPath(originalXPath, AST_ROOT);
      if (LOG.isLoggable(Level.FINE)) {
        LOG.log(Level.FINE, "Unable to use RuleChain for for XPath: " + xpath);
      }
    }

    if (navigator == null) {
      this.initializationStatus = InitializationStatus.PARTIAL;
      // Clear the node data, because we did not have a Navigator
      nodeNameToXPaths = null;
    } else {
      this.initializationStatus = InitializationStatus.FULL;
    }
  }