private void doIntersectTwo()

in utils/src/main/java/com/google/apphosting/utils/glob/GlobIntersector.java [154:283]


  private void doIntersectTwo(Glob inputGlob1, Glob inputGlob2, HashSet<Glob> outputGlobs) {
    String pattern1 = inputGlob1.getPattern();
    String pattern2 = inputGlob2.getPattern();

    // To simplify the work we do below, we first check to see if the
    // supplied globs share a common prefix excluding wildcards.
    //
    // For example:
    //   ab*d   becomes:  a | b*d
    //   a*cd             a | *cd
    String prefix = extractPrefix(pattern1, pattern2);
    if (prefix != null) {
      int prefixLength = prefix.length();
      // The prefix is guaranteed to exclude wildcards, so if they
      // don't match then we're done here.
      if (!prefix.equals(pattern2.substring(0, prefixLength))) {
        outputGlobs.add(inputGlob1);
        outputGlobs.add(inputGlob2);
      } else {
        // Strip off the prefix and recurse on the non-prefixed version.
        HashSet<Glob> newGlobs = new LinkedHashSet<Glob>();
        doIntersectTwo(
            GlobFactory.createChildGlob(pattern1.substring(prefixLength), inputGlob1),
            GlobFactory.createChildGlob(pattern2.substring(prefixLength), inputGlob2),
            newGlobs);
        // Now put the prefix back onto all of the returned globs.
        for (Glob newGlob : newGlobs) {
          outputGlobs.add(GlobFactory.createChildGlob(prefix + newGlob.getPattern(), newGlob));
        }
      }
      return;
    }

    // Now we do the same thing we did for prefixes with suffixes.
    //
    // For example:
    //   b*d   becomes:  b*d | d
    //   *cd             *cd | d
    String suffix = extractSuffix(pattern1, pattern2);
    if (suffix != null) {
      int suffixLength = suffix.length();
      // The suffix is guaranteed to exclude wildcards, so if they
      // don't match then we're done here.
      if (!suffix.equals(pattern2.substring(pattern2.length() - suffixLength))) {
        outputGlobs.add(inputGlob1);
        outputGlobs.add(inputGlob2);
      } else {
        // Strip off the suffix and recurse on the non-suffixed version.
        HashSet<Glob> newGlobs = new LinkedHashSet<Glob>();
        doIntersectTwo(GlobFactory.createChildGlob(
                           pattern1.substring(0, pattern1.length() - suffixLength),
                           inputGlob1),
                       GlobFactory.createChildGlob(
                           pattern2.substring(0, pattern2.length() - suffixLength),
                           inputGlob2),
                       newGlobs);
        // Now put the suffix back onto all of the returned globs.
        for (Glob newGlob : newGlobs) {
          outputGlobs.add(GlobFactory.createChildGlob(newGlob.getPattern() + suffix, newGlob));
        }
      }
      return;
    }

    // For example:
    //   abc*xyz   adds:  abc*ghi*xyz
    //   *ghi*
    if (pattern1.length() > 1 && pattern1.startsWith("*") && pattern1.endsWith("*")) {
      for (int star = pattern2.indexOf("*"); star != -1; star = pattern2.indexOf("*", star + 1)) {
        outputGlobs.add(GlobFactory.createChildGlob(
                            pattern2.substring(0, star) + pattern1 + pattern2.substring(star + 1),
                            inputGlob1, inputGlob2));
      }
    }
    // This is just the opposite of what we just did because we can't
    // be sure about the order.
    //
    // For example:
    //   *ghi*     adds:  abc*ghi*xyz
    //   abc*xyz
    if (pattern2.length() > 1 && pattern2.startsWith("*") && pattern2.endsWith("*")) {
      for (int star = pattern1.indexOf("*"); star != -1; star = pattern1.indexOf("*", star + 1)) {
        outputGlobs.add(GlobFactory.createChildGlob(
                            pattern1.substring(0, star) + pattern2 + pattern1.substring(star + 1),
                            inputGlob1, inputGlob2));
      }
    }

    // For example:
    //   abc*  adds:   abc*xyz
    //   *xyz
    if (pattern1.length() > 1 && pattern2.length() > 1 &&
        pattern1.endsWith("*") && pattern2.startsWith("*")) {
      String trimmedPattern1 = pattern1.substring(0, pattern1.length() - 1);
      outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern1 + pattern2,
                                                  inputGlob1,
                                                  inputGlob2));

      // For example:
      //   abc*  adds:   abc
      //   *c
      if (inputGlob2.matchesAll(trimmedPattern1)) {
        outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern1, inputGlob1, inputGlob2));
      }
    }
    // This is just the opposite of what we just did because we can't
    // be sure about the order.
    //
    // For example:
    //   *xyz
    //   abc*   adds:   abc*xyz
    if (pattern1.length() > 1 && pattern2.length() > 1 &&
        pattern1.startsWith("*") && pattern2.endsWith("*")) {
      String trimmedPattern2 = pattern2.substring(0, pattern2.length() - 1);
      outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern2 + pattern1,
                                                  inputGlob1,
                                                  inputGlob2));

      // For example:
      //   *c    adds:   abc
      //   abc*
      if (inputGlob1.matchesAll(trimmedPattern2)) {
        outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern2, inputGlob1, inputGlob2));
      }
    }

    // Now include the two original patterns.
    outputGlobs.add(inputGlob1);
    outputGlobs.add(inputGlob2);
  }