Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * #%L
   * Wikitty :: api
   * %%
   * Copyright (C) 2012 CodeLutin, Benjamin Poussin
   * %%
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as 
   * published by the Free Software Foundation, either version 3 of the 
  * License, or (at your option) any later version.
  * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
  * 
  * You should have received a copy of the GNU General Lesser Public 
  * License along with this program.  If not, see
  * <http://www.gnu.org/licenses/lgpl-3.0.html>.
  * #L%
  */
 package org.nuiton.wikitty.query;
 
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
Cette classe permet d'interpreter une requete faite textuellement en la convertisant en sa representation objet. Si l'objet est instancier pour utiliser les fonctionnalites d'alias, il est possible de l'utiliser dans plusieurs thread concurent. La map d'alias est protegee. Pour plus d'information reportez-vous à la documentation

Author(s):
poussin
Version:
$Revision$
Since:
3.3 Last update: $Date$ by : $Author$
 
 public class WikittyQueryParser extends BaseParser<Object> {
 
     public static final String AS = "AS";
     public static final String DATE = "DATE";
     public static final String SELECT = "SELECT";
     public static final String WHERE = "WHERE";
     public static final String IN = "IN";
     public static final String LITERAL_OPEN_SIMPLE = "'";
    public static final String LITERAL_CLOSE_SIMPLE = "'";
    public static final String LITERAL_OPEN_DOUBLE = "\"";
    public static final String LITERAL_CLOSE_DOUBLE = "\"";
    public static final String NULL = "NULL";
    public static final String TO = "TO";
    public static final String FALSE = "FALSE";
    public static final String TRUE = "TRUE";
    public static final String UNLIKE = "UNLIKE";
    public static final String AND = "AND";
    public static final String COMMA = ",";
    public static final String CURLY_BRACKET_CLOSE = "}";
    public static final String CURLY_BRACKET_OPEN = "{";
    public static final String EQUALS = "=";
    public static final String EQUALS_IGNORE_CASE_AND_ACCENT = "~";
    public static final String GREATER = ">";
    public static final String GREATER_OR_EQUALS = ">=";
    public static final String LESS = "<";
    public static final String LESS_OR_EQUALS = "<=";
    public static final String LIKE = "LIKE";
    public static final String NOT = "NOT";
    public static final String NOT_EQUALS = "!=";
    public static final String NOT_EQUALS_IGNORE_CASE_AND_ACCENT = "!~";
    public static final String OR = "OR";
    public static final String BRACKET_CLOSE = ")";
    public static final String BRACKET_OPEN = "(";
    public static final String SQUARE_BRACKET_CLOSE = "]";
    public static final String SQUARE_BRACKET_OPEN = "[";
    public static final String OFFSET = "#OFFSET";
    public static final String LIMIT = "#LIMIT";
    public static final String DEPTH = "#DEPTH";
    public Rule icOFFSET = IgnoreCase();
    public Rule icLIMIT = IgnoreCase();
    public Rule icDEPTH = IgnoreCase();
    
    public Rule icID = IgnoreCase(..getValue());
    public Rule icNOT = IgnoreCase();
    public Rule icAND = IgnoreCase();
    public Rule icOR = IgnoreCase();
    public Rule icSELECT = IgnoreCase();
    public Rule icWHERE = IgnoreCase();
    public Rule icIN = IgnoreCase();
    public Rule icTO = IgnoreCase();
    public Rule icFALSE = IgnoreCase();
    public Rule icTRUE = IgnoreCase();
    public Rule icLIKE = IgnoreCase();
    public Rule icUNLIKE = IgnoreCase();
    public Rule icNULL = IgnoreCase();
    public Rule icDATE = IgnoreCase();
    public Rule icAS = IgnoreCase();

    
to use log facility, just put in your code: log.info(\"...\");
    static private Log log = LogFactory.getLog(WikittyQueryParser.class);
    protected Map<StringStringalias = new LinkedHashMap<StringString>();
    public WikittyQueryParser() {
    }
    boolean debug(String textContext context) {
        ..println("DEBUG("+context.getCurrentIndex()+"):" + text + "  nodes:" +context.getSubNodes());
        return true;
    }

    
Retourne une vue non modifiable des alias disponibles.

Returns:
    public Map<StringStringgetAlias() {
        return Collections.unmodifiableMap();
    }

    
Modifie l'ensemble des alias, la map passee en parametre est copiee en interne.

Parameters:
alias la map des alias qui sera copiee
Returns:
le WikittyQueryParser lui meme (this)
    public WikittyQueryParser setAlias(Map<StringStringalias) {
        // on passe par la creation d'une nouvelle map, pour eviter que l'utilisateur
        // ne puisse modifier les alias depuis l'exterieur et eviter le plus
        // possible les synchronize
        this. = new LinkedHashMap<StringString>();
        if (alias != null) {
            this..putAll(alias);
        }
        return this;
    }
    public WikittyQueryParser addAlias(String aliasNameString aliasValue) {
        synchronized() {
            .put(aliasNamealiasValue);
        }
        return this;
    }
    public WikittyQueryParser clearAlias() {
        // on passe par la creation d'une nouvelle map, pour eviter le plus
        // possible les synchronize
        this. = new LinkedHashMap<StringString>();
        return this;
    }

    
Parse query and use alias added with addAlias(java.lang.String,java.lang.String) or setAlias(java.util.Map)

Parameters:
queryString query to parse
Returns:
    public WikittyQuery parseQuery(String queryString) {
        WikittyQuery result = parse(queryString);
        return result;
    }

    
Parse query without alias

Parameters:
queryString query to parse
Returns:
    static public WikittyQuery parse(String queryString) {
        WikittyQuery result = parse(queryStringnull);
        return result;
    }

    
Parse query and use alias in argument

Parameters:
queryString query to parse
alias alias to used to change query
Returns:
    static public WikittyQuery parse(String queryStringMap<StringStringalias) {
        queryString = StringUtils.strip(queryString);
        if (queryString == null) {
            queryString = "";
        }
        if (alias != null) {
            String queryStringInit = queryString;
            // on synchronise l'utilisation de la map, pour etre sur qu'il n'y
            // ait pas d'ajout/modif durant son utilisation pour le remplacement
            // on fait direcement les remplacements de la requete car, c'est
            // le seul endroit ou l'alias est utilise, et c'est aussi rapide
            // que de faire une copie de la map
            synchronized(alias) {
                // first replace alias in queryString
                for (Map.Entry<StringStringa : alias.entrySet()) {
                    queryString = queryString.replaceAll(a.getKey(), a.getValue());
                }
            }
            if (.isDebugEnabled()) {
                .debug(String.format("QueryString \n'%s' become after alias \n'%s'\naliases are %s",
                        queryStringInitqueryStringalias));
            }
        }
        WikittyQueryParser parser = Parboiled.createParser(WikittyQueryParser.class);
       ParsingResult<?> result = new ReportingParseRunner(parser.start()).run(queryString);
//        ParsingResult<?> result = new TracingParseRunner(parser.start()).run(queryString);
//        ParsingResult<?> result = new RecoveringParseRunner(parser.start()).run(queryString);
        if (result.hasErrors() || !result.matched) {
            ..println("\nParse Errors:\n" + ErrorUtils.printParseErrors(result));
        }
        if (.isDebugEnabled()) {
            .debug("\nParse Tree:\n" + ParseTreeUtils.printNodeTree(result) + '\n');
        }
//        System.out.println("\nParse Tree:\n" + ParseTreeUtils.printNodeTree(result) + '\n');
        
        WikittyQuery query = (WikittyQuery)result.resultValue;
        return query;
    }

    
can be field, extension name or id element

Parameters:
v
Returns:
    protected Element toElement(String v) {
        Element result = Element.get(v);
        return result;
    }
    protected int toInt(String v) {
        int result = Integer.parseInt(v);
        return result;
    }

    
Remove quote at beginning and ending of String in parameter if necessary
  • "toto" return toto
  • "toto return "toto
  • toto return toto"
  • to"to return to"to

    Parameters:
    s
    Returns:
  •     protected String removeQuote(String s) {
            String result = s;
            if (StringUtils.startsWithAny(s)
                    && StringUtils.endsWithAny(s)) {
                result = StringUtils.substring(s, 1, -1);
            }
            return result;
        }
        protected String toDate(Object s) {
            if (s instanceof ConditionValueString) {
                s = ((ConditionValueString)s).getValue();
            }
            Date d = WikittyUtil.toDate(s);
            String result = WikittyUtil.toString(d);
            return result;
        }

        

    Parameters:
    list la collection en object pour eviter le cast dans les Rules
    e l'element a ajouter a la liste
    Returns:
    la liste passee en parametre
        protected Object addToList(Object listObject e) {
            ((Collection)list).add(e);
            return list;
        }
       Rule start() {
           return Sequence(FirstOf(or(), empty()), push(new WikittyQuery((Condition)pop())),
                   offset(), limit(), depth(), space(), );
       }
       Rule empty() {
           return Sequence(push(new True()));
       }
       Rule offset() {
           return Optional(space(), FirstOf(space()), OneOrMore(AnyOf("1234567890")),
                   push(((WikittyQuery)pop()).setOffset(toInt(match())))
                   );
       }
       Rule limit() {
           return Optional(space(), FirstOf(space()), OneOrMore(AnyOf("1234567890")),
                   push(((WikittyQuery)pop()).setLimit(toInt(match())))
                   );
       }
       Rule depth() {
           return Optional(space(), FirstOf(space()), OneOrMore(AnyOf("1234567890")),
                   push(((WikittyQuery)pop()).setWikittyFieldSearchDepth(toInt(match())))
                   );
       }
       Rule or() {
            return Sequence(and(), ZeroOrMore(space(), space(), and(),
                    push(new Or((Condition)pop(1), (Condition)pop()))));
        }
        Rule and() {
            return Sequence(term(), ZeroOrMore(
                    // when no AND or OR is used, AND is default
                    // don't change order of FirstOf, this order is important
                    FirstOf(Sequence(space(), space()), Sequence(space(), TestNot())),
                    term(),
                    push(new And((Condition)pop(1), (Condition)pop()))));
        }
        Rule term() {
            return FirstOf(condition(), Parens());
        }
        Rule Parens() {
            return Sequence(space(), space(), or(), space(), space());
        }
        Rule condition() {
            // ATTENTION l'ordre est important par exemple le '>' doit etre apres le '>='
            return FirstOf(
                    not(), isNull(), isNotNull(), select(),
                    greatereq(), lesseq(),
                    between(), containsAll(), containsOne(),
                    eq(), neq(), eqIgnoreCaseAndAccent(), neqIgnoreCaseAndAccent(),
                    less(), greater(), like(), notlike(),
                    rTrue(), rFalse(), keyword()
                    );
        }
        Rule not() {
            return Sequence(space(), space(), term(),
                    push(new Not((Condition)pop())));
        }

        
    gere eq, startsWith, endsWith, isNull

    Returns:
        Rule isNull() {
            return Sequence(field(), push(match()), space(), space(), ,
                    push(new Null(toElement(pop().toString()))));
        }

        
    gere eq, isNull

    Returns:
        Rule isNotNull() {
            return Sequence(field(), push(match()), space(), space(), ,
                    push(new NotNull(toElement(pop().toString()))));
        }

        
    gere eq, startsWith, endsWith, isNull

    Returns:
        Rule eq() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Equals(toElement(pop(1).toString()), (ConditionValue)pop())));
        }

        
    gere eq, isNull

    Returns:
        Rule neq() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new NotEquals(toElement(pop(1).toString()), (ConditionValue)pop())));
        }

        
    gere eq, startsWith, endsWith, isNull

    Returns:
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Equals(toElement(pop(1).toString()), (ConditionValue)pop(), true)));
        }

        
    gere eq, isNull

    Returns:
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new NotEquals(toElement(pop(1).toString()), (ConditionValue)pop(), true)));
        }
        Rule less() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Less(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule lesseq() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new LessOrEquals(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule greater() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Greater(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule greatereq() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new GreaterOrEquals(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule like() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Like(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule notlike() {
            return Sequence(field(), push(match()), space(), space(), value(),
                    push(new Unlike(toElement(pop(1).toString()), (ConditionValue)pop())));
        }
        Rule between() {
            return Sequence(field(), push(match()), space(), space(), space(),
                    value(), space(), space(),
                    value(), space(), ,
                    push(new Between(toElement(pop(2).toString()), (ConditionValue)pop(1), (ConditionValue)pop())));
        }
        Rule containsAll() {
            Var<List<ConditionValue>> elems = new Var<List<ConditionValue>>(new LinkedList<ConditionValue>());
            return Sequence(field(), push(match()), space(), space(), space(),
                    value(), elems.get().add((ConditionValue)pop()), space(), ZeroOrMore(space(),
                    value(), elems.get().add((ConditionValue)pop()), space()), ,
                    push(new ContainsAll(toElement(pop().toString()), elems.get())));
        }
        Rule containsOne() {
            Var<List<ConditionValue>> elems = new Var<List<ConditionValue>>(new LinkedList<ConditionValue>());
            return Sequence(field(), push(match()), space(), space(), space(),
                    value(), elems.get().add((ConditionValue)pop()), space(), ZeroOrMore(space(),
                    value(), elems.get().add((ConditionValue)pop()), space()), ,
                    push(new ContainsOne(toElement(pop().toString()), elems.get())));
        }
        Rule select() {
            return Sequence(space(),
                    functionOrFieldList() /*, field(), push(match())*/space(),
                    
                    FirstOf(Sequence(space(), term()), empty()),
                    push(new Select(((WikittyQueryFunction)pop(1)), (Condition)pop())));
        }
                    push(WikittyQueryFunction.createFusionIfNeeded((List)pop())));
        }
            return Sequence(FirstOf(function(), fieldFunction(), stringFunction()),
                    push(addToList(pop(1), pop())));
        }
        Rule function() {
            Var<Stringalias = new Var<String>();
            return Sequence(OneOrMore(FirstOf(field(), AnyOf("#"))), push(match()), ,
                    push(new LinkedList()),
                    Optional(alias(alias)),
                    push(WikittyQueryFunction.create(pop(1).toString(), alias.get(), (List)pop())));
        }
        Rule fieldFunction() {
            Var<Stringalias = new Var<String>();
            return Sequence(field(), push(toElement(match())), Optional(alias(alias)),
                    push(new FunctionFieldValue(alias.get(), pop().toString())));
        }
        Rule stringFunction() {
            Var<Stringalias = new Var<String>();
            return Sequence(valueText(), Optional(alias(alias)),
                    push(new FunctionValue(alias.get(), ((ConditionValueString)pop()).getValue() )));
        }
        Rule alias(Var<Stringalias) {
            return Sequence(space(), space(), field(), alias.set(match()));
        }
        Rule element() {
            return Sequence(field(), push(toElement(match())));
        }
        Rule keyword() {
            return Sequence(value(), push(new Keyword().addCondition((ConditionValue)pop())));
        }
        Rule field() {
            return OneOrMore(FirstOf(CharRange('0''9'), CharRange('a''z'), CharRange('A''Z'), AnyOf("_.*")));
        }
        Rule rTrue() {
            return Sequence(push(new True()));
        }
        Rule rFalse() {
            return Sequence(push(new False()));
        }
        Rule value() {
            return FirstOf(select(), date(), valueText());
        }
        Rule date() {
            return Sequence(valueText() ,,
                    push(new ConditionValueString(toDate(pop()))));
        }
        Rule valueText() {
                    push(new ConditionValueString(removeQuote(match()))));
        }

        
    Une chaine simple sans espace, parenthese, retour chariot, tabulation, accolade, crochet, ", '.

    Returns:
        Rule SimpleString() {
            return OneOrMore(FirstOf(
                    Escape(),
                    Sequence(TestNot(AnyOf(" #\t\r\n\\"
                    +
                    ++
                    ++
                    ++
                    ++)), )
                    )).suppressSubnodes();
        }
            return Sequence(
                    ,
                    ZeroOrMore(
                            FirstOf(
                                    EscapeSimple(),
                                    Sequence(TestNot(AnyOf("\r\n\\"+)), )
                            )
                    ).suppressSubnodes(),
                    
                    );
        }
            return Sequence(
                    ,
                    ZeroOrMore(
                            FirstOf(
                                    EscapeDouble(),
                                    Sequence(TestNot(AnyOf("\r\n\\"+)), )
                            )
                    ).suppressSubnodes(),
                    
                    );
        }
        Rule Escape() {
            return Sequence('\\'FirstOf(AnyOf("btnfr\'\\"
                    OctalEscape(), UnicodeEscape()));
        }
        Rule EscapeSimple() {
            return Sequence('\\'FirstOf(AnyOf("btnfr\'\\"+),
                    OctalEscape(), UnicodeEscape()));
        }
        Rule EscapeDouble() {
            return Sequence('\\'FirstOf(AnyOf("btnfr\'\\"+),
                    OctalEscape(), UnicodeEscape()));
        }
        Rule OctalEscape() {
            return FirstOf(
                    Sequence(CharRange('0''3'), CharRange('0''7'), CharRange('0''7')),
                    Sequence(CharRange('0''7'), CharRange('0''7')),
                    CharRange('0''7')
            );
        }
        Rule UnicodeEscape() {
            return Sequence(OneOrMore('u'), HexDigit(), HexDigit(), HexDigit(), HexDigit());
        }
        Rule HexDigit() {
            return FirstOf(CharRange('a''f'), CharRange('A''F'), CharRange('0''9'));
        }
        Rule space() {
            return ZeroOrMore(AnyOf(" \t\f"));
        }
    New to GrepCode? Check out our FAQ X