FileDocCategorySizeDatePackage
WildcardTermEnum.javaAPI DocApache Lucene 2.1.05894Wed Feb 14 10:46:40 GMT 2007org.apache.lucene.search

WildcardTermEnum

public class WildcardTermEnum extends FilteredTermEnum
Subclass of FilteredTermEnum for enumerating all terms that match the specified wildcard filter term.

Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than all that precede it.

version
$Id: WildcardTermEnum.java 472959 2006-11-09 16:21:50Z yonik $

Fields Summary
Term
searchTerm
String
field
String
text
String
pre
int
preLen
boolean
endEnum
public static final char
WILDCARD_STRING
String equality with support for wildcards
public static final char
WILDCARD_CHAR
Constructors Summary
public WildcardTermEnum(IndexReader reader, Term term)
Creates a new WildcardTermEnum. Passing in a {@link org.apache.lucene.index.Term Term} that does not contain a WILDCARD_CHAR will cause an exception to be thrown.

After calling the constructor the enumeration is already pointing to the first valid term if such a term exists.


                                                  
         
    super();
    searchTerm = term;
    field = searchTerm.field();
    text = searchTerm.text();

    int sidx = text.indexOf(WILDCARD_STRING);
    int cidx = text.indexOf(WILDCARD_CHAR);
    int idx = sidx;
    if (idx == -1) {
      idx = cidx;
    }
    else if (cidx >= 0) {
      idx = Math.min(idx, cidx);
    }

    pre = searchTerm.text().substring(0,idx);
    preLen = pre.length();
    text = text.substring(preLen);
    setEnum(reader.terms(new Term(searchTerm.field(), pre)));
  
Methods Summary
public voidclose()

    super.close();
    searchTerm = null;
    field = null;
    text = null;
  
public final floatdifference()

    return 1.0f;
  
public final booleanendEnum()

    return endEnum;
  
protected final booleantermCompare(org.apache.lucene.index.Term term)

    if (field == term.field()) {
      String searchText = term.text();
      if (searchText.startsWith(pre)) {
        return wildcardEquals(text, 0, searchText, preLen);
      }
    }
    endEnum = true;
    return false;
  
public static final booleanwildcardEquals(java.lang.String pattern, int patternIdx, java.lang.String string, int stringIdx)
Determines if a word matches a wildcard pattern. Work released by Granta Design Ltd after originally being done on company time.


                          
         
       
  
    int p = patternIdx;
    
    for (int s = stringIdx; ; ++p, ++s)
      {
        // End of string yet?
        boolean sEnd = (s >= string.length());
        // End of pattern yet?
        boolean pEnd = (p >= pattern.length());

        // If we're looking at the end of the string...
        if (sEnd)
        {
          // Assume the only thing left on the pattern is/are wildcards
          boolean justWildcardsLeft = true;

          // Current wildcard position
          int wildcardSearchPos = p;
          // While we haven't found the end of the pattern,
          // and haven't encountered any non-wildcard characters
          while (wildcardSearchPos < pattern.length() && justWildcardsLeft)
          {
            // Check the character at the current position
            char wildchar = pattern.charAt(wildcardSearchPos);
            
            // If it's not a wildcard character, then there is more
            // pattern information after this/these wildcards.
            if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING)
            {
              justWildcardsLeft = false;
            }
            else
            {
              // to prevent "cat" matches "ca??"
              if (wildchar == WILDCARD_CHAR) {
                return false;
              }
              
              // Look at the next character
              wildcardSearchPos++;
            }
          }

          // This was a prefix wildcard search, and we've matched, so
          // return true.
          if (justWildcardsLeft)
          {
            return true;
          }
        }

        // If we've gone past the end of the string, or the pattern,
        // return false.
        if (sEnd || pEnd)
        {
          break;
        }

        // Match a single character, so continue.
        if (pattern.charAt(p) == WILDCARD_CHAR)
        {
          continue;
        }

        //
        if (pattern.charAt(p) == WILDCARD_STRING)
        {
          // Look at the character beyond the '*'.
          ++p;
          // Examine the string, starting at the last character.
          for (int i = string.length(); i >= s; --i)
          {
            if (wildcardEquals(pattern, p, string, i))
            {
              return true;
            }
          }
          break;
        }
        if (pattern.charAt(p) != string.charAt(s))
        {
          break;
        }
      }
      return false;