public Collection convert()

in solr/core/src/java/org/apache/solr/spelling/SpellingQueryConverter.java [104:177]


  public Collection<Token> convert(String original) {
    if (original == null) { // this can happen with q.alt = and no query
      return Collections.emptyList();
    }
    boolean mightContainRangeQuery =
        (original.indexOf('[') != -1 || original.indexOf('{') != -1)
            && (original.indexOf(']') != -1 || original.indexOf('}') != -1);
    Collection<Token> result = new ArrayList<>();
    Matcher matcher = QUERY_REGEX.matcher(original);
    String nextWord = null;
    int nextStartIndex = 0;
    String lastBooleanOp = null;
    while (nextWord != null || matcher.find()) {
      String word = null;
      int startIndex = 0;
      if (nextWord != null) {
        word = nextWord;
        startIndex = nextStartIndex;
        nextWord = null;
      } else {
        word = matcher.group(0);
        startIndex = matcher.start();
      }
      if (matcher.find()) {
        nextWord = matcher.group(0);
        nextStartIndex = matcher.start();
      }
      if (mightContainRangeQuery && "TO".equals(word)) {
        continue;
      }
      if ("AND".equals(word) || "OR".equals(word) || "NOT".equals(word)) {
        lastBooleanOp = word;
        continue;
      }
      // treat "AND NOT" as "NOT"...
      if ("AND".equals(nextWord)
          && original.length() > nextStartIndex + 7
          && original.substring(nextStartIndex, nextStartIndex + 7).equals("AND NOT")) {
        nextWord = "NOT";
      }

      int flagValue = 0;
      if (word.charAt(0) == '-' || (startIndex > 0 && original.charAt(startIndex - 1) == '-')) {
        flagValue = PROHIBITED_TERM_FLAG;
      } else if (word.charAt(0) == '+'
          || (startIndex > 0 && original.charAt(startIndex - 1) == '+')) {
        flagValue = REQUIRED_TERM_FLAG;
        // we don't know the default operator so just assume the first operator isn't new.
      } else if (nextWord != null
          && lastBooleanOp != null
          && !nextWord.equals(lastBooleanOp)
          && ("AND".equals(nextWord) || "OR".equals(nextWord) || "NOT".equals(nextWord))) {
        flagValue = TERM_PRECEDES_NEW_BOOLEAN_OPERATOR_FLAG;
        // ...unless the 1st boolean operator is a NOT, because only AND/OR can be default.
      } else if (nextWord != null
          && lastBooleanOp == null
          && !nextWord.equals(lastBooleanOp)
          && ("NOT".equals(nextWord))) {
        flagValue = TERM_PRECEDES_NEW_BOOLEAN_OPERATOR_FLAG;
      }
      try {
        analyze(result, word, startIndex, flagValue);
      } catch (IOException e) {
        // TODO: shouldn't we log something?
      }
    }
    if (lastBooleanOp != null) {
      for (Token t : result) {
        int f = t.getFlags();
        t.setFlags(f |= QueryConverter.TERM_IN_BOOLEAN_QUERY_FLAG);
      }
    }
    return result;
  }