search/engine/api/src/main/java/net/sf/mmm/search/engine/base/AbstractSearchQueryBuilder.java
/**
   *
   * @param parser is the scanner of the query-string.
   * @param defaultField is the field to use as default for unqualified search-terms.
   * @param depth is the depth of the query expression (number of open parenthesis).
   * @param options are the {@link SearchQueryBuilderOptions}.
   * @return the parsed query or <code>null</code> if the parsed query segment was void.
   */
@param parser is the scanner of the query-string.
@param defaultField is the field to use as default for unqualified search-terms.
@param depth is the depth of the query expression (number of open parenthesis).
@param options are the  SearchQueryBuilderOptions.
@return the parsed query or null if the parsed query segment was void.
@param parser is the scanner of the query - string . @param defaultField is the field to use as default for unqualified search - terms . @param depth is the depth of the query expression ( number of open parenthesis ) . @param options are the SearchQueryBuilderOptions . @return the parsed query or null if the parsed query segment was void .
private SearchQuery parseStandardClause(CharSequenceScanner parser, String defaultField, int depth,
      SearchQueryBuilderOptions options) {
    char c;
    String fieldName = defaultField;
    int start = parser.getCurrentIndex();
    String ascii = parser.readWhile(CharFilter.ASCII_LETTER_FILTER);
    if (ascii.length() > 0) {
      c = parser.forceNext();
      if (c == ':') {
        fieldName = ascii;
        start = parser.getCurrentIndex();
      } else {
        parser.setCurrentIndex(start);
      }
    }
    try {
      if (parser.hasNext()) {
        c = parser.peek();
        if ((c == '"') || (c == '\'')) {
          parser.next();
          String phrase = parser.readUntil(c, true);
          return createPhraseQuery(fieldName, phrase);
        } else if ((c == '[') || (c == '{')) {
          parser.next();
          boolean minimumInclusive = (c == '[');
          String minimum = parser.readUntil(' ', false);
          if (minimum != null) {
            parser.skipWhile(' ');
            String to = parser.readUntil(' ', false);
            if (to != null) {
              parser.skipWhile(' ');
              if (RANGE_QUERY_SEPARATOR_SET.contains(to)) {
                String maximum = parser.readWhile(CHAR_FILTER_ACCEPT_UNTIL_END_OF_RANGE);
                if (parser.hasNext()) {
                  c = parser.next();
                  boolean maximumInclusive = (c == ']');
                  return createRangeQuery(fieldName, minimum, maximum, minimumInclusive, maximumInclusive);
                }
              }
            }
          }
        } else if (c == '(') {
          parser.next();
          return parseStandardQuery(parser, options, fieldName, depth + 1);
        }
      }
      while (parser.hasNext()) {
        c = parser.next();
        if ((c == ')') || (c == ' ') || (c == '"') || (c == '\'')) {
          parser.stepBack();
          break;
        }
      }
      int end = parser.getCurrentIndex();
      if (end > start) {
        String term = parser.substring(start, end);
        return createWordQuery(fieldName, term);
      }
    } catch (NlsRuntimeException e) {
      options.getErrorHandler().handleError(parser.getOriginalString(), start, parser.getCurrentIndex(), e);
    } catch (RuntimeException e) {
      SearchQueryParseException ex = new SearchQueryParseException(e, parser.getOriginalString());
      options.getErrorHandler().handleError(parser.getOriginalString(), start, parser.getCurrentIndex(), ex);
    }
    return null;
  }
private SearchQuery parseStandardClause ( CharSequenceScanner parser , String defaultField , int depth , SearchQueryBuilderOptions options ) { char c ; String fieldName = defaultField ; int start = parser . getCurrentIndex ( ) ; String ascii = parser . readWhile ( CharFilter . ASCII_LETTER_FILTER ) ; if ( ascii . length ( ) > 0 ) { c = parser . forceNext ( ) ; if ( c == ':' ) { fieldName = ascii ; start = parser . getCurrentIndex ( ) ; } else { parser . setCurrentIndex ( start ) ; } } try { if ( parser . hasNext ( ) ) { c = parser . peek ( ) ; if ( ( c == '"' ) || ( c == '\'' ) ) { parser . next ( ) ; String phrase = parser . readUntil ( c , true ) ; return createPhraseQuery ( fieldName , phrase ) ; } else if ( ( c == '[' ) || ( c == '{' ) ) { parser . next ( ) ; boolean minimumInclusive = ( c == '[' ) ; String minimum = parser . readUntil ( ' ' , false ) ; if ( minimum != null ) { parser . skipWhile ( ' ' ) ; String to = parser . readUntil ( ' ' , false ) ; if ( to != null ) { parser . skipWhile ( ' ' ) ; if ( RANGE_QUERY_SEPARATOR_SET . contains ( to ) ) { String maximum = parser . readWhile ( CHAR_FILTER_ACCEPT_UNTIL_END_OF_RANGE ) ; if ( parser . hasNext ( ) ) { c = parser . next ( ) ; boolean maximumInclusive = ( c == ']' ) ; return createRangeQuery ( fieldName , minimum , maximum , minimumInclusive , maximumInclusive ) ; } } } } } else if ( c == '(' ) { parser . next ( ) ; return parseStandardQuery ( parser , options , fieldName , depth + 1 ) ; } } while ( parser . hasNext ( ) ) { c = parser . next ( ) ; if ( ( c == ')' ) || ( c == ' ' ) || ( c == '"' ) || ( c == '\'' ) ) { parser . stepBack ( ) ; break ; } } int end = parser . getCurrentIndex ( ) ; if ( end > start ) { String term = parser . substring ( start , end ) ; return createWordQuery ( fieldName , term ) ; } } catch ( NlsRuntimeException e ) { options . getErrorHandler ( ) . handleError ( parser . getOriginalString ( ) , start , parser . getCurrentIndex ( ) , e ) ; } catch ( RuntimeException e ) { SearchQueryParseException ex = new SearchQueryParseException ( e , parser . getOriginalString ( ) ) ; options . getErrorHandler ( ) . handleError ( parser . getOriginalString ( ) , start , parser . getCurrentIndex ( ) , ex ) ; } return null ; }
@param parser is the scanner of the query-string.
@param parser is the scanner of the query - string .
// lookahead was negative, step back... // phrase query // range query // [123 - 789] // [mona-lisa TO peter-pan} // {0.24618 , 0.999} // [2010-09-02T23:59:59Z - 2010-09-04T22:35:00Z] // sub-query