Example #1
0
  /**
   * Get node number (level="multiple"). Return a vector giving the hierarchic position of this
   * node. See the XSLT spec for details.
   *
   * @exception XPathException
   * @param node The node to be numbered
   * @param count Pattern that identifies which nodes (ancestors and their previous siblings) should
   *     be counted. Default (null) is the element name if the current node is an element, or
   *     "node()" otherwise.
   * @param from Pattern that specifies where counting starts from. Default (null) is the root node.
   *     Only nodes below the first (most recent) node that matches the 'from' pattern are counted.
   * @param controller The controller for the transformation
   * @return a vector containing for each ancestor-or-self that matches the count pattern and that
   *     is below the nearest node that matches the from pattern, an Integer which is one greater
   *     than the number of previous siblings that match the count pattern.
   */
  public static List getNumberMulti(
      NodeInfo node, Pattern count, Pattern from, Controller controller) throws XPathException {

    // checkNumberable(node);

    ArrayList v = new ArrayList();

    if (count == null) {
      if (node.getFingerprint() == -1) { // unnamed node
        count = NodeKindTest.makeNodeKindTest(node.getNodeKind());
      } else {
        count = new NameTest(node);
      }
    }

    NodeInfo curr = node;

    while (true) {
      if (count.matches(curr, controller)) {
        int num = getNumberSingle(curr, count, null, controller);
        v.add(0, new Long(num));
      }
      curr = curr.getParent();
      if (curr == null) break;
      if (from != null && from.matches(curr, controller)) break;
    }

    return v;
  }
Example #2
0
 /**
  * Tests that both RE2's and JDK's pattern class act as we expect them. The regular expression
  * {@code regexp} matches the string {@code match} and doesn't match {@code nonMatch}
  */
 public void testMatches(String regexp, String match, String nonMatch) {
   String errorString = "Pattern with regexp: " + regexp;
   assertTrue(
       "JDK " + errorString + " doesn't match: " + match,
       java.util.regex.Pattern.matches(regexp, match));
   assertFalse(
       "JDK " + errorString + " matches: " + nonMatch,
       java.util.regex.Pattern.matches(regexp, nonMatch));
   assertTrue(
       errorString + " doesn't match: " + match,
       Pattern.matches(regexp, utf8Slice(match), options));
   assertFalse(
       errorString + " matches: " + nonMatch,
       Pattern.matches(regexp, utf8Slice(nonMatch), options));
 }
Example #3
0
  private void scanDir(File dir, List<Pattern> includes) {
    if (!dir.canRead()) return;

    // See if patterns are specific enough to avoid scanning every file in the directory.
    boolean scanAll = false;
    for (Pattern include : includes) {
      if (include.value.indexOf('*') != -1 || include.value.indexOf('?') != -1) {
        scanAll = true;
        break;
      }
    }

    if (!scanAll) {
      // If not scanning all the files, we know exactly which ones to include.
      List matchingIncludes = new ArrayList(1);
      for (Pattern include : includes) {
        if (matchingIncludes.isEmpty()) matchingIncludes.add(include);
        else matchingIncludes.set(0, include);
        process(dir, include.value, matchingIncludes);
      }
    } else {
      // Scan every file.
      for (String fileName : dir.list()) {
        // Get all include patterns that match.
        List<Pattern> matchingIncludes = new ArrayList(includes.size());
        for (Pattern include : includes)
          if (include.matches(fileName)) matchingIncludes.add(include);
        if (matchingIncludes.isEmpty()) continue;
        process(dir, fileName, matchingIncludes);
      }
    }
  }
Example #4
0
  /**
   * Matches.
   *
   * @param src the src
   * @return true, if successful
   */
  public boolean matches(String src) {
    if (pattern == null) {
      pattern = new Pattern(url);
    }

    return pattern.matches(src);
  }
Example #5
0
  /**
   * Get node number (level="single"). If the current node matches the supplied pattern, the
   * returned number is one plus the number of previous siblings that match the pattern. Otherwise,
   * return the element number of the nearest ancestor that matches the supplied pattern.
   *
   * @param node the current node, the one whose node number is required
   * @param count Pattern that identifies which nodes should be counted. Default (null) is the
   *     element name if the current node is an element, or "node()" otherwise.
   * @param from Pattern that specifies where counting starts from. Default (null) is the root node.
   *     (This parameter does not seem useful but is included for the sake of XSLT conformance.)
   * @param controller the controller of the transformation, used if the patterns reference context
   *     values (e.g. variables)
   * @exception XPathException when any error occurs in processing
   * @return the node number established as follows: go to the nearest ancestor-or-self that matches
   *     the 'count' pattern and that is a descendant of the nearest ancestor that matches the
   *     'from' pattern. Return one plus the nunber of preceding siblings of that ancestor that
   *     match the 'count' pattern. If there is no such ancestor, return 0.
   */
  public static int getNumberSingle(
      NodeInfo node, Pattern count, Pattern from, Controller controller) throws XPathException {

    //        checkNumberable(node);

    if (count == null && from == null) {
      return getNumberSimple(node, controller);
    }

    boolean knownToMatch = false;
    if (count == null) {
      if (node.getFingerprint() == -1) { // unnamed node
        count = NodeKindTest.makeNodeKindTest(node.getNodeKind());
      } else {
        count = new NameTest(node);
      }
      knownToMatch = true;
    }

    NodeInfo target = node;
    while (!(knownToMatch || count.matches(target, controller))) {
      target = target.getParent();
      if (target == null) {
        return 0;
      }
      if (from != null && from.matches(target, controller)) {
        return 0;
      }
    }

    // we've found the ancestor to count from

    SequenceIterator preceding = target.iterateAxis(Axis.PRECEDING_SIBLING, count.getNodeTest());
    // pass the filter condition down to the axis enumeration where possible
    boolean alreadyChecked = (count instanceof NodeTest);
    int i = 1;
    while (true) {
      NodeInfo p = (NodeInfo) preceding.next();
      if (p == null) {
        return i;
      }
      if (alreadyChecked || count.matches(p, controller)) {
        i++;
      }
    }
  }
Example #6
0
  public GlobScanner(
      File rootDir, List<String> includes, List<String> excludes, boolean ignoreCase) {
    if (rootDir == null) throw new IllegalArgumentException("rootDir cannot be null.");
    if (!rootDir.exists())
      throw new IllegalArgumentException("Directory does not exist: " + rootDir);
    if (!rootDir.isDirectory())
      throw new IllegalArgumentException("File must be a directory: " + rootDir);
    try {
      rootDir = rootDir.getCanonicalFile();
    } catch (IOException ex) {
      throw new RuntimeException("OS error determining canonical path: " + rootDir, ex);
    }
    this.rootDir = rootDir;

    if (includes == null) throw new IllegalArgumentException("includes cannot be null.");
    if (excludes == null) throw new IllegalArgumentException("excludes cannot be null.");

    if (includes.isEmpty()) includes.add("**");
    List<Pattern> includePatterns = new ArrayList(includes.size());
    for (String include : includes) includePatterns.add(new Pattern(include, ignoreCase));

    List<Pattern> allExcludePatterns = new ArrayList(excludes.size());
    for (String exclude : excludes) allExcludePatterns.add(new Pattern(exclude, ignoreCase));

    scanDir(rootDir, includePatterns);

    if (!allExcludePatterns.isEmpty()) {
      // For each file, see if any exclude patterns match.
      outerLoop:
      //
      for (Iterator matchIter = matches.iterator(); matchIter.hasNext(); ) {
        String filePath = (String) matchIter.next();
        List<Pattern> excludePatterns = new ArrayList(allExcludePatterns);
        try {
          // Shortcut for excludes that are "**/XXX", just check file name.
          for (Iterator excludeIter = excludePatterns.iterator(); excludeIter.hasNext(); ) {
            Pattern exclude = (Pattern) excludeIter.next();
            if (exclude.values.length == 2 && exclude.values[0].equals("**")) {
              exclude.incr();
              String fileName = filePath.substring(filePath.lastIndexOf(File.separatorChar) + 1);
              if (exclude.matches(fileName)) {
                matchIter.remove();
                continue outerLoop;
              }
              excludeIter.remove();
            }
          }
          // Get the file names after the root dir.
          String[] fileNames = filePath.split("\\" + File.separator);
          for (String fileName : fileNames) {
            for (Iterator excludeIter = excludePatterns.iterator(); excludeIter.hasNext(); ) {
              Pattern exclude = (Pattern) excludeIter.next();
              if (!exclude.matches(fileName)) {
                excludeIter.remove();
                continue;
              }
              exclude.incr(fileName);
              if (exclude.wasFinalMatch()) {
                // Exclude pattern matched.
                matchIter.remove();
                continue outerLoop;
              }
            }
            // Stop processing the file if none of the exclude patterns matched.
            if (excludePatterns.isEmpty()) continue outerLoop;
          }
        } finally {
          for (Pattern exclude : allExcludePatterns) exclude.reset();
        }
      }
    }
  }
Example #7
0
 /**
  * This takes a regex and it's compile time flags, a string that is expected to match the regex
  * and a string that is not expected to match the regex.
  *
  * <p>We don't check for JDK compatibility here, since the flags are not in a 1-1 correspondence.
  */
 public void testMatchesRE2(String regexp, int flags, String match, String nonMatch) {
   Pattern p = Pattern.compile(regexp, flags, options);
   String errorString = "Pattern with regexp: " + regexp + " and flags: " + flags;
   assertTrue(errorString + " doesn't match: " + match, p.matches(utf8Slice(match)));
   assertFalse(errorString + " matches: " + nonMatch, p.matches(utf8Slice(nonMatch)));
 }
Example #8
0
  /**
   * Get node number (level="any"). Return one plus the number of previous nodes in the document
   * that match the supplied pattern
   *
   * @exception XPathException
   * @param inst Identifies the xsl:number instruction; this is relevant when the function is
   *     memoised to support repeated use of the same instruction to number modulple nodes
   * @param node Identifies the xsl:number instruction; this is relevant when the function is
   *     memoised to support repeated use of the same instruction to number modulple nodes
   * @param count Pattern that identifies which nodes should be counted. Default (null) is the
   *     element name if the current node is an element, or "node()" otherwise.
   * @param from Pattern that specifies where counting starts from. Default (null) is the root node.
   *     Only nodes after the first (most recent) node that matches the 'from' pattern are counted.
   * @param controller The controller
   * @param hasVariablesInPatterns if the count or from patterns contain variables, then it's not
   *     safe to get the answer by adding one to the number of the most recent node that matches
   * @return one plus the number of nodes that precede the current node, that match the count
   *     pattern, and that follow the first node that matches the from pattern if specified.
   */
  public static int getNumberAny(
      Instruction inst,
      NodeInfo node,
      Pattern count,
      Pattern from,
      Controller controller,
      boolean hasVariablesInPatterns)
      throws XPathException {

    NodeInfo memoNode = null;
    int memoNumber = 0;
    boolean memoise = (!hasVariablesInPatterns && count != null);
    if (memoise) {
      Object[] memo = (Object[]) controller.getUserData(inst, "xsl:number");
      if (memo != null) {
        memoNode = (NodeInfo) memo[0];
        memoNumber = ((Integer) memo[1]).intValue();
      }
    }

    int num = 0;
    if (count == null) {
      if (node.getFingerprint() == -1) { // unnamed node
        count = NodeKindTest.makeNodeKindTest(node.getNodeKind());
      } else {
        count = new NameTest(node);
      }
      num = 1;
    } else if (count.matches(node, controller)) {
      num = 1;
    }

    // We use a special axis invented for the purpose: the union of the preceding and
    // ancestor axes, but in reverse document order

    // Pass part of the filtering down to the axis iterator if possible
    NodeTest filter;
    if (from == null) {
      filter = count.getNodeTest();
    } else if (from.getNodeKind() == Type.ELEMENT && count.getNodeKind() == Type.ELEMENT) {
      filter = NodeKindTest.ELEMENT;
    } else {
      filter = AnyNodeTest.getInstance();
    }

    SequenceIterator preceding = node.iterateAxis(Axis.PRECEDING_OR_ANCESTOR, filter);

    while (true) {
      NodeInfo prev = (NodeInfo) preceding.next();
      if (prev == null) {
        break;
      }
      if (from != null && from.matches(prev, controller)) {
        return num;
      }
      if (count.matches(prev, controller)) {
        if (num == 1 && memoNode != null && prev.isSameNode(memoNode)) {
          num = memoNumber + 1;
          break;
        }
        num++;
      }
    }
    if (memoise) {
      Object[] memo = new Object[2];
      memo[0] = node;
      memo[1] = new Integer(num);
      controller.setUserData(inst, "xsl:number", memo);
    }
    return num;
  }
  private static int evaluateForPattern(State state, int patternSize) {
    int size = State.BORAD_SIZE;
    int value = 0;
    int i, j;
    Pattern pattern1 = new Pattern(patternSize);
    Pattern pattern2 = new Pattern(patternSize);
    for (i = 0; i < size; i++) {
      pattern1.reset();
      pattern2.reset();
      for (j = 0; j < patternSize; j++) {
        pattern1.put(state.board[j][i]);
        pattern2.put(state.board[i][j]);
      }
      j--;
      do {
        //                System.out.println("i:" + i + " j:" + j);
        value += pattern1.matches();
        value += pattern2.matches();

        j++;
        if (j == size) break;
        //                pattern1 -= state.board[j - patternSize][i];
        pattern1.put(state.board[j][i]);
        //                pattern1 += state.board[j][i];
        //                pattern2 -= state.board[i][j - patternSize];
        pattern2.put(state.board[i][j]);
        //                pattern2 += state.board[i][j];
      } while (true);
    }
    // (k1-k2: 45 degree, k1-k3 : 135 degree)
    int k1, k2, k3;
    for (i = -(size - patternSize); i <= size - patternSize; i++) {
      if (i < 0) {
        k1 = -i;
        k2 = 0;
        k3 = size - 1;
      } else {
        k1 = 0;
        k2 = i;
        k3 = size - i - 1;
      }
      pattern1.reset();
      pattern2.reset();
      for (j = 0; j < patternSize; j++) {
        pattern1.put(state.board[k1 + j][k2 + j]);
        pattern2.put(state.board[k1 + j][k3 - j]);
      }
      j--;
      do {
        value += pattern1.matches();
        value += pattern2.matches();

        j++;
        // 2 patterns are symmetric, so detection for 1 is enough
        if (k1 + j == size || k2 + j == size) break;
        //                pattern1 -= state.board[k1 + j - patternSize][k2 + j - patternSize];
        pattern1.put(state.board[k1 + j][k2 + j]);
        //                pattern1 += state.board[k1 + j][k2 + j];
        //                pattern2 -= state.board[k1 + j - patternSize][k3 - j + patternSize];
        pattern2.put(state.board[k1 + j][k3 - j]);
        //                pattern2 += state.board[k1 + j][k3 - j];
      } while (true);
    }

    return value;
  }