blob: d57e260bfdf9f6d07b66237c07bb68654f98ccca [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.
*/
package org.apache.chemistry.opencmis.query.example;
import java.util.ArrayList;
import java.util.List;
import org.antlr.runtime.tree.Tree;
import org.apache.chemistry.opencmis.server.support.query.StringUtil;
import org.apache.chemistry.opencmis.server.support.query.TextSearchLexer;
/**
* A class extending the {@link ExtendedAbstractPredicateWalker} class and generating
* CMISQL strings as output while traversing the trees. On each hit of a certain
* node or token the corresponding output of CMISQL is appended to a string
* buffer.
*/
public class ExampleQueryWalker extends ExtendedAbstractPredicateWalker {
private StringBuffer result = new StringBuffer();
public String getResult() {
return result.toString();
}
@Override
public Boolean walkPredicate(Tree whereNode) {
if (null != whereNode) {
onStartProcessing(whereNode);
super.walkPredicate(whereNode);
onStopProcessing();
}
return null; // unused
}
@Override
public Boolean walkNot(Tree opNode, Tree node) {
onNot(opNode, node);
super.walkPredicate(node);
onPostNot(opNode, node);
return false;
}
@Override
public Boolean walkAnd(Tree opNode, Tree leftNode, Tree rightNode) {
onPreAnd(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onAnd(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostAnd(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkOr(Tree opNode, Tree leftNode, Tree rightNode) {
onPreOr(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onOr(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostOr(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkEquals(Tree opNode, Tree leftNode, Tree rightNode) {
onPreEquals(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onEquals(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostEquals(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkNotEquals(Tree opNode, Tree leftNode, Tree rightNode) {
onPreNotEquals(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onNotEquals(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostNotEquals(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkGreaterThan(Tree opNode, Tree leftNode, Tree rightNode) {
onPreGreaterThan(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onGreaterThan(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostGreaterThan(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkGreaterOrEquals(Tree opNode, Tree leftNode, Tree rightNode) {
onPreGreaterOrEquals(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onGreaterOrEquals(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostGreaterOrEquals(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkLessThan(Tree opNode, Tree leftNode, Tree rightNode) {
onPreLessThan(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onLessThan(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostLessThan(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkLessOrEquals(Tree opNode, Tree leftNode, Tree rightNode) {
onPreLessOrEquals(opNode, leftNode, rightNode);
super.walkPredicate(leftNode);
onLessOrEquals(opNode, leftNode, rightNode);
super.walkPredicate(rightNode);
onPostLessOrEquals(opNode, leftNode, rightNode);
return false;
}
@Override
public Boolean walkIn(Tree opNode, Tree colNode, Tree listNode) {
onPreIn(opNode, colNode, listNode);
super.walkPredicate(colNode);
onIn(opNode, colNode, listNode);
super.walkPredicate(listNode);
onPostIn(opNode, colNode, listNode);
return false;
}
@Override
public Boolean walkNotIn(Tree opNode, Tree colNode, Tree listNode) {
onPreNotIn(opNode, colNode, listNode);
super.walkPredicate(colNode);
onNotIn(opNode, colNode, listNode);
super.walkPredicate(listNode);
onPostNotIn(opNode, colNode, listNode);
return false;
}
@Override
public Boolean walkInAny(Tree opNode, Tree colNode, Tree listNode) {
onPreInAny(opNode, colNode, listNode);
super.walkPredicate(colNode);
onInAny(opNode, colNode, listNode);
super.walkPredicate(listNode);
onPostInAny(opNode, colNode, listNode);
return false;
}
@Override
public Boolean walkNotInAny(Tree opNode, Tree colNode, Tree listNode) {
onPreNotInAny(opNode, colNode, listNode);
super.walkPredicate(colNode);
onNotInAny(opNode, colNode, listNode);
super.walkPredicate(listNode);
onPostNotInAny(opNode, colNode, listNode);
return false;
}
@Override
public Boolean walkEqAny(Tree opNode, Tree literalNode, Tree colNode) {
onPreEqAny(opNode, literalNode, colNode);
super.walkPredicate(literalNode);
onEqAny(opNode, literalNode, colNode);
super.walkPredicate(colNode);
onPostEqAny(opNode, literalNode, colNode);
return false;
}
@Override
public Boolean walkIsNull(Tree opNode, Tree colNode) {
onIsNull(opNode, colNode);
super.walkPredicate(colNode);
onPostIsNull(opNode, colNode);
return false;
}
@Override
public Boolean walkIsNotNull(Tree opNode, Tree colNode) {
onIsNotNull(opNode, colNode);
super.walkPredicate(colNode);
onPostIsNotNull(opNode, colNode);
return false;
}
@Override
public Boolean walkLike(Tree opNode, Tree colNode, Tree stringNode) {
onPreIsLike(opNode, colNode, stringNode);
super.walkPredicate(colNode);
onIsLike(opNode, colNode, stringNode);
super.walkPredicate(stringNode);
onPostIsLike(opNode, colNode, stringNode);
return false;
}
@Override
public Boolean walkNotLike(Tree opNode, Tree colNode, Tree stringNode) {
onPreIsNotLike(opNode, colNode, stringNode);
super.walkPredicate(colNode);
onIsNotLike(opNode, colNode, stringNode);
super.walkPredicate(stringNode);
onPostIsNotLike(opNode, colNode, stringNode);
return false;
}
@Override
public Boolean walkContains(Tree opNode, Tree typeNode, Tree textSearchNode) {
onPreContains(opNode, typeNode, textSearchNode);
if (opNode.getChildCount() > 1) {
super.walkPredicate(typeNode);
onBetweenContains(opNode, typeNode, textSearchNode);
} else
result.append("'");
super.walkSearchExpr(textSearchNode);
onContains(opNode, typeNode, textSearchNode);
return false;
}
@Override
public Boolean walkInFolder(Tree opNode, Tree typeNode, Tree paramNode) {
if (opNode.getChildCount() == 1) {
onInFolder(opNode, paramNode, null);
super.walkPredicate(paramNode);
onPostInFolder(opNode, paramNode, null);
} else {
onInFolder(opNode, typeNode, paramNode);
super.walkPredicate(typeNode);
onBetweenInFolder(opNode, typeNode, paramNode);
super.walkPredicate(paramNode);
onPostInFolder(opNode, typeNode, paramNode);
}
return false;
}
@Override
public Boolean walkInTree(Tree opNode, Tree typeNode, Tree paramNode) {
if (opNode.getChildCount() == 1) {
onInTree(opNode, paramNode, null);
super.walkPredicate(paramNode);
onPostInTree(opNode, paramNode, null);
} else {
onInTree(opNode, typeNode, paramNode);
super.walkPredicate(typeNode);
onBetweenInTree(opNode, typeNode, paramNode);
super.walkPredicate(paramNode);
onPostInTree(opNode, typeNode, paramNode);
}
return false;
}
@Override
public Object walkCol(Tree node) {
onColNode(node);
return null;
}
@Override
public Object walkId(Tree node) {
return onId(node);
}
@Override
public Boolean walkScore(Tree node) {
onScore(node);
return false;
}
@Override
protected Boolean walkTextAnd(Tree node) {
List<Tree> children = getChildrenAsList(node);
onPreTextAnd(node, children);
int i=0;
for (Tree child : children) {
walkSearchExpr(child);
onTextAnd(node, children, i++);
}
onPostTextAnd(node, children);
return false;
}
@Override
protected Boolean walkTextOr(Tree node) {
List<Tree> children = getChildrenAsList(node);
onPreTextOr(node, children);
int j=0;
for (Tree child : children) {
walkSearchExpr(child);
onTextOr(node, children, j++);
}
onPostTextOr(node, children);
return false;
}
@Override
protected Boolean walkTextMinus(Tree node) {
onTextMinus(node, node.getChild(0));
walkSearchExpr(node.getChild(0));
onPostTextMinus(node, node.getChild(0));
return false;
}
@Override
protected Boolean walkTextWord(Tree node) {
onTextWord(onTextLiteral(node));
return false;
}
@Override
protected Boolean walkTextPhrase(Tree node) {
onTextPhrase(onTextLiteral(node));
return false;
}
@Override
public Object walkBoolean(Tree node) {
Object obj = super.walkNumber(node);
result.append(obj);
return obj;
}
@Override
public Object walkNumber(Tree node) {
Object obj = super.walkNumber(node);
result.append(obj);
return obj;
}
@Override
public Object walkString(Tree node) {
String val = "'" + super.walkString(node) + "'";
result.append(val);
return val;
}
@Override
public Object walkTimestamp(Tree node) {
String s = (String) super.walkTimestamp(node);
result.append(s);
return s;
}
@Override
public Object walkList(Tree node) {
result.append("(");
int n = node.getChildCount();
boolean first = true;
List<Object> res = new ArrayList<Object>(n);
for (int i = 0; i < n; i++) {
Object o = node.getChild(i);
if (first)
first = false;
else
result.append(", ");
result.append(o.toString());
}
result.append(")");
return res;
}
private void endSubExpr() {
result.append(")");
}
private void startSubExpr() {
result.append("(");
}
@Override
protected void onStartProcessing(Tree whereNode) {
result.append("WHERE ");
}
@Override
protected void onStopProcessing() {
}
@Override
protected void onPreEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
startSubExpr();
}
@Override
protected void onEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
result.append(" = ");
}
@Override
protected void onPostEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
endSubExpr();
}
@Override
protected void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode) {
result.append(" <> ");
}
@Override
protected void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode) {
result.append(" > ");
}
@Override
protected void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode) {
result.append(" >= ");
}
@Override
protected void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode) {
result.append(" < ");
}
@Override
protected void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode) {
result.append(" <= ");
}
@Override
protected void onNot(Tree opNode, Tree leftNode) {
result.append("NOT (");
}
@Override
protected void onPostNot(Tree opNode, Tree leftNode) {
endSubExpr();
}
@Override
protected void onPreAnd(Tree opNode, Tree leftNode, Tree rightNode) {
startSubExpr();
}
@Override
protected void onAnd(Tree opNode, Tree leftNode, Tree rightNode) {
result.append(" AND ");
}
@Override
protected void onPostAnd(Tree opNode, Tree leftNode, Tree rightNode) {
endSubExpr();
}
@Override
protected void onPreOr(Tree opNode, Tree leftNode, Tree rightNode) {
startSubExpr();
}
@Override
protected void onOr(Tree opNode, Tree leftNode, Tree rightNode) {
result.append(" OR ");
}
@Override
protected void onPostOr(Tree opNode, Tree leftNode, Tree rightNode) {
endSubExpr();
}
@Override
protected void onIn(Tree node, Tree colNode, Tree listNode) {
result.append(" IN ");
}
@Override
protected void onNotIn(Tree node, Tree colNode, Tree listNode) {
result.append(" NOT IN ");
}
@Override
protected void onPreInAny(Tree node, Tree colNode, Tree listNode) {
result.append("ANY ");
}
@Override
protected void onInAny(Tree node, Tree colNode, Tree listNode) {
result.append(" IN ");
}
@Override
protected void onPreNotInAny(Tree node, Tree colNode, Tree listNode) {
result.append("ANY ");
}
@Override
protected void onNotInAny(Tree node, Tree colNode, Tree listNode) {
result.append(" NOT IN ");
}
@Override
protected void onEqAny(Tree node, Tree literalNode, Tree colNode) {
result.append(" = ANY ");
}
@Override
protected void onIsNull(Tree nullNode, Tree colNode) {
}
@Override
protected void onPostIsNull(Tree nullNode, Tree colNode) {
result.append(" IS NULL");
}
@Override
protected void onIsNotNull(Tree notNullNode, Tree colNode) {
}
@Override
protected void onPostIsNotNull(Tree notNullNode, Tree colNode) {
result.append(" IS NOT NULL");
}
@Override
protected void onPreIsLike(Tree node, Tree colNode, Tree stringNode) {
startSubExpr();
}
@Override
protected void onIsLike(Tree node, Tree colNode, Tree stringNode) {
result.append(" LIKE ");
}
@Override
protected void onPostIsLike(Tree node, Tree colNode, Tree stringNode) {
endSubExpr();
}
@Override
protected void onIsNotLike(Tree node, Tree colNode, Tree stringNode) {
result.append(" NOT LIKE ");
}
@Override
protected void onInFolder(Tree node, Tree colNode, Tree paramNode) {
result.append("IN_FOLDER(");
}
protected void onBetweenInFolder(Tree node, Tree colNode, Tree paramNode) {
result.append(", ");
}
@Override
protected void onPostInFolder(Tree node, Tree colNode, Tree paramNode) {
result.append(")");
}
@Override
protected void onInTree(Tree node, Tree colNode, Tree paramNode) {
result.append("IN_TREE(");
}
@Override
protected void onBetweenInTree(Tree node, Tree colNode, Tree paramNode) {
result.append(", ");
}
@Override
protected void onPostInTree(Tree node, Tree colNode, Tree paramNode) {
result.append(")");
}
@Override
protected void onScore(Tree node) {
result.append("SCORE()");
}
@Override
protected void onColNode(Tree node) {
result.append(node.getChild(0).getText());
}
@Override
protected void onPreContains(Tree node, Tree typeNode, Tree searchExprNode) {
result.append("CONTAINS(");
}
@Override
protected void onBetweenContains(Tree node, Tree typeNode, Tree searchExprNode) {
result.append(", '");
}
@Override
protected void onContains(Tree node, Tree typeNode, Tree searchExprNode) {
result.append("')");
}
@Override
protected void onTextAnd(Tree node, List<Tree> conjunctionNodes, int index) {
if (index < conjunctionNodes.size()-1)
result.append(" ");
}
@Override
protected void onTextOr(Tree node, List<Tree> termNodes, int index) {
if (index < termNodes.size()-1)
result.append(" OR ");
}
@Override
protected void onTextMinus(Tree node, Tree notNode) {
result.append("-");
}
@Override
protected void onTextWord(String word) {
result.append(word);
}
@Override
protected void onTextPhrase(String phrase) {
result.append("\\'" + phrase + "\\'");
}
private String onId(Tree node) {
String id = node.getText();
result.append(id);
return id;
}
private List<Tree> getChildrenAsList(Tree node) {
List<Tree> res = new ArrayList<Tree>(node.getChildCount());
for (int i=0; i<node.getChildCount(); i++) {
Tree childNnode = node.getChild(i);
res.add(childNnode);
}
return res;
}
protected String onTextLiteral(Tree node) {
int type = node.getType();
String text = node.getText();
switch (type) {
case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
return StringUtil.unescape(text.substring(1, text.length()-1), null);
case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
return StringUtil.unescape(text, null);
default:
throw new RuntimeException("Unknown text literal. " + node);
}
}
}