blob: 1cf42132f05616eb3b5a71c1537159300540d81d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Contributors:
* Florent Guillaume, Nuxeo
*/
package org.apache.chemistry.opencmis.server.support.query;
import java.util.ArrayList;
import java.util.List;
import org.antlr.runtime.tree.Tree;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
/**
* Basic implementation walking a predicate in lexical order.
* <p>
* The {@code walkXYZ} methods can be overridden to change the walking order.
*/
public abstract class AbstractPredicateWalker implements PredicateWalker {
public Boolean walkPredicate(Tree node) {
switch (node.getType()) {
case CmisQlStrictLexer.NOT:
return walkNot(node, node.getChild(0));
case CmisQlStrictLexer.AND:
return walkAnd(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.OR:
return walkOr(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.EQ:
return walkEquals(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.NEQ:
return walkNotEquals(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.GT:
return walkGreaterThan(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.GTEQ:
return walkGreaterOrEquals(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.LT:
return walkLessThan(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.LTEQ:
return walkLessOrEquals(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.IN:
return walkIn(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.NOT_IN:
return walkNotIn(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.IN_ANY:
return walkInAny(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.NOT_IN_ANY:
return walkNotInAny(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.EQ_ANY:
return walkEqAny(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.IS_NULL:
return walkIsNull(node, node.getChild(0));
case CmisQlStrictLexer.IS_NOT_NULL:
return walkIsNotNull(node, node.getChild(0));
case CmisQlStrictLexer.LIKE:
return walkLike(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.NOT_LIKE:
return walkNotLike(node, node.getChild(0), node.getChild(1));
case CmisQlStrictLexer.CONTAINS:
if (node.getChildCount() == 1) {
return walkContains(node, null, node.getChild(0));
} else {
return walkContains(node, node.getChild(0), node.getChild(1));
}
case CmisQlStrictLexer.IN_FOLDER:
if (node.getChildCount() == 1) {
return walkInFolder(node, null, node.getChild(0));
} else {
return walkInFolder(node, node.getChild(0), node.getChild(1));
}
case CmisQlStrictLexer.IN_TREE:
if (node.getChildCount() == 1) {
return walkInTree(node, null, node.getChild(0));
} else {
return walkInTree(node, node.getChild(0), node.getChild(1));
}
case CmisQlStrictLexer.BOOL_LIT:
walkBoolean(node);
return false;
case CmisQlStrictLexer.NUM_LIT:
walkNumber(node);
return false;
case CmisQlStrictLexer.STRING_LIT:
walkString(node);
return false;
case CmisQlStrictLexer.TIME_LIT:
walkTimestamp(node);
return false;
case CmisQlStrictLexer.IN_LIST:
walkList(node);
return false;
case CmisQlStrictLexer.COL:
walkCol(node);
return false;
case CmisQlStrictLexer.ID:
walkId(node);
return false;
case CmisQlStrictLexer.SCORE:
return walkScore(node);
default:
return walkOtherPredicate(node);
}
}
/** For extensibility. */
protected Boolean walkOtherPredicate(Tree node) {
throw new CmisRuntimeException("Unknown node type: " + node.getType() + " (" + node.getText() + ")");
}
public Boolean walkNot(Tree opNode, Tree node) {
walkPredicate(node);
return false;
}
public Boolean walkAnd(Tree opNode, Tree leftNode, Tree rightNode) {
walkPredicate(leftNode);
walkPredicate(rightNode);
return false;
}
public Boolean walkOr(Tree opNode, Tree leftNode, Tree rightNode) {
walkPredicate(leftNode);
walkPredicate(rightNode);
return false;
}
public Object walkExpr(Tree node) {
switch (node.getType()) {
case CmisQlStrictLexer.BOOL_LIT:
return walkBoolean(node);
case CmisQlStrictLexer.NUM_LIT:
return walkNumber(node);
case CmisQlStrictLexer.STRING_LIT:
return walkString(node);
case CmisQlStrictLexer.TIME_LIT:
return walkTimestamp(node);
case CmisQlStrictLexer.IN_LIST:
return walkList(node);
case CmisQlStrictLexer.COL:
return walkCol(node);
case CmisQlStrictLexer.ID:
return walkId(node);
default:
return walkOtherExpr(node);
}
}
public Boolean walkSearchExpr(Tree node) {
switch (node.getType()) {
case TextSearchLexer.TEXT_AND:
return walkTextAnd(node);
case TextSearchLexer.TEXT_OR:
return walkTextOr(node);
case TextSearchLexer.TEXT_MINUS:
return walkTextMinus(node);
case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
return walkTextWord(node);
case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
return walkTextPhrase(node);
default:
walkOtherExpr(node);
return null;
}
}
/** For extensibility. */
protected Object walkOtherExpr(Tree node) {
throw new CmisRuntimeException("Unknown node type: " + node.getType() + " (" + node.getText() + ")");
}
public Boolean walkEquals(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkNotEquals(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkGreaterThan(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkGreaterOrEquals(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkLessThan(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkLessOrEquals(Tree opNode, Tree leftNode, Tree rightNode) {
walkExpr(leftNode);
walkExpr(rightNode);
return false;
}
public Boolean walkIn(Tree opNode, Tree colNode, Tree listNode) {
walkExpr(colNode);
walkExpr(listNode);
return false;
}
public Boolean walkNotIn(Tree opNode, Tree colNode, Tree listNode) {
walkExpr(colNode);
walkExpr(listNode);
return false;
}
public Boolean walkInAny(Tree opNode, Tree colNode, Tree listNode) {
walkExpr(colNode);
walkExpr(listNode);
return false;
}
public Boolean walkNotInAny(Tree opNode, Tree colNode, Tree listNode) {
walkExpr(colNode);
walkExpr(listNode);
return false;
}
public Boolean walkEqAny(Tree opNode, Tree literalNode, Tree colNode) {
walkExpr(literalNode);
walkExpr(colNode);
return false;
}
public Boolean walkIsNull(Tree opNode, Tree colNode) {
walkExpr(colNode);
return false;
}
public Boolean walkIsNotNull(Tree opNode, Tree colNode) {
walkExpr(colNode);
return false;
}
public Boolean walkLike(Tree opNode, Tree colNode, Tree stringNode) {
walkExpr(colNode);
walkExpr(stringNode);
return false;
}
public Boolean walkNotLike(Tree opNode, Tree colNode, Tree stringNode) {
walkExpr(colNode);
walkExpr(stringNode);
return false;
}
public Boolean walkContains(Tree opNode, Tree qualNode, Tree queryNode) {
if (qualNode != null) {
return walkSearchExpr(qualNode);
}
return walkSearchExpr(queryNode);
}
public Boolean walkInFolder(Tree opNode, Tree qualNode, Tree paramNode) {
if (qualNode != null) {
walkExpr(qualNode);
}
walkExpr(paramNode);
return false;
}
public Boolean walkInTree(Tree opNode, Tree qualNode, Tree paramNode) {
if (qualNode != null) {
walkExpr(qualNode);
}
walkExpr(paramNode);
return false;
}
public Object walkList(Tree node) {
int n = node.getChildCount();
List<Object> res = new ArrayList<Object>(n);
for (int i = 0; i < n; i++) {
res.add(walkExpr(node.getChild(i)));
}
return res;
}
public Object walkBoolean(Tree node) {
String s = node.getText();
return Boolean.valueOf(s);
}
public Object walkNumber(Tree node) {
String s = node.getText();
if (s.contains(".") || s.contains("e") || s.contains("E")) {
return Double.valueOf(s);
} else {
return Long.valueOf(s);
}
}
public Object walkString(Tree node) {
String s = node.getText();
s = s.substring(1, s.length() - 1);
s = s.replace("''", "'"); // unescape quotes
return s;
}
public Object walkTimestamp(Tree node) {
String s = node.getText();
s = s.substring(s.indexOf('\'') + 1, s.length() - 1);
return CalendarHelper.fromString(s);
}
public Object walkCol(Tree node) {
return null;
}
public Object walkId(Tree node) {
return null;
}
protected Boolean walkTextAnd(Tree node) {
return null;
}
protected Boolean walkTextOr(Tree node) {
return null;
}
protected Boolean walkTextMinus(Tree node) {
return null;
}
protected Boolean walkTextWord(Tree node) {
return null;
}
protected Boolean walkTextPhrase(Tree node) {
return null;
}
protected Boolean walkScore(Tree node) {
return false;
}
}