Package org.apache.chemistry.opencmis.jcr.query

Source Code of org.apache.chemistry.opencmis.jcr.query.ParseTreeWalker

/*
* 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.jcr.query;

import org.antlr.runtime.tree.Tree;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.server.support.query.CalendarHelper;
import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
import org.apache.chemistry.opencmis.server.support.query.PredicateWalkerBase;
import org.apache.chemistry.opencmis.server.support.query.TextSearchLexer;

import java.util.ArrayList;
import java.util.List;

/**
* This implementation of {@link PredicateWalkerBase} traverses the parse tree of a CMIS query.
* It uses an {@link Evaluator} to accumulate the result of the traversal. <code>Evaluator</code>
* has a corresponding method for each {@link Tree#getType() node type} in the parse tree.
* <code>ParseTreeWalker</code> calls these methods while traversing the parse tree passing an
* <code>Evaluator</code> for each of the corresponding operation's arguments.
* </br>
* The {@link #walkPredicate(Tree)} serves as entry point for traversing a parse tree. After
* successful traversal, the result is obtained from the {@link #getResult()} method.
*
* @param <T>  type of the result determined by the <code>Evaluator</code> used.
*/
public class ParseTreeWalker<T> implements PredicateWalkerBase {

    private final Evaluator<T> evaluator;
    private T result;

    /**
     * Create a new instance for traversing CMIS query parse trees.
     *
     * @param evaluator  <code>Evaluator</code> for evaluating the nodes of the parse tree
     */
    public ParseTreeWalker(Evaluator<T> evaluator) {
        this.evaluator = evaluator;
    }

    /**
     * Retrieve the result of a successful traversal.
     *
     * @return  result of traversal or <code>null</code> if either not yet traversed, an error occurred
     *      on traversal or the query has an empty where clause.
     */
    public T getResult() {
        return result;
    }

    //------------------------------------------< PredicateWalkerBase >---
   
    public Boolean walkPredicate(Tree node) {
        result = null;
        result = walkPredicate(evaluator, node);
        return false; // Return value is ignored by caller
    }

    //------------------------------------------< protected >---

    /** For extensibility. */
    protected T walkOtherExpr(Evaluator evaluator, Tree node) {
        throw new CmisRuntimeException("Unknown node type: " + node.getType() + " (" + node.getText() + ")");
    }

    /** For extensibility. */
    protected T walkOtherPredicate(Evaluator evaluator, Tree node) {
        throw new CmisRuntimeException("Unknown node type: " + node.getType() + " (" + node.getText() + ")");
    }

    //------------------------------------------< private >---

    private T walkPredicate(Evaluator<T> evaluator, Tree node) {
        switch (node.getType()) {
            case CmisQlStrictLexer.NOT:
                return evaluator.not(walkPredicate(evaluator.op(), node.getChild(0)));
            case CmisQlStrictLexer.AND:
                return evaluator.and(
                        walkPredicate(evaluator.op(), node.getChild(0)),
                        walkPredicate(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.OR:
                return evaluator.or(
                        walkPredicate(evaluator.op(), node.getChild(0)),
                        walkPredicate(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.EQ:
                return evaluator.eq(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.NEQ:
                return evaluator.neq(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.GT:
                return evaluator.gt(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.GTEQ:
                return evaluator.gteq(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.LT:
                return evaluator.lt(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.LTEQ:
                return evaluator.lteq(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.IN:
                return evaluator.in(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.NOT_IN:
                return evaluator.notIn(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.IN_ANY:
                return evaluator.inAny(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.NOT_IN_ANY:
                return evaluator.notInAny(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.EQ_ANY:
                return evaluator.eqAny(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.IS_NULL:
                return evaluator.isNull(walkExpr(evaluator.op(), node.getChild(0)));
            case CmisQlStrictLexer.IS_NOT_NULL:
                return evaluator.notIsNull(walkExpr(evaluator.op(), node.getChild(0)));
            case CmisQlStrictLexer.LIKE:
                return evaluator.like(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.NOT_LIKE:
                return evaluator.notLike(
                        walkExpr(evaluator.op(), node.getChild(0)),
                        walkExpr(evaluator.op(), node.getChild(1)));
            case CmisQlStrictLexer.CONTAINS:
                if (node.getChildCount() == 1) {
                    return evaluator.contains(
                            null,
                            walkExprTextSearch(evaluator.op(), node.getChild(0)));
                }
                else {
                    return evaluator.contains(
                            walkExpr(evaluator.op(), node.getChild(0)),
                            walkExpr(evaluator.op(), node.getChild(1)));
                }
            case CmisQlStrictLexer.IN_FOLDER:
                if (node.getChildCount() == 1) {
                    return evaluator.inFolder(
                            null,
                            walkExpr(evaluator.op(), node.getChild(0)));
                }
                else {
                    return evaluator.inFolder(
                            walkExpr(evaluator.op(), node.getChild(0)),
                            walkExpr(evaluator.op(), node.getChild(1)));
                }
            case CmisQlStrictLexer.IN_TREE:
                if (node.getChildCount() == 1) {
                    return evaluator.inTree(
                            null,
                            walkExpr(evaluator.op(), node.getChild(0)));
                }
                else {
                    return evaluator.inTree(
                            walkExpr(evaluator.op(), node.getChild(0)),
                            walkExpr(evaluator.op(), node.getChild(1)));
                }
            default:
                return walkOtherPredicate(evaluator, node);
        }
    }

    private T walkExpr(Evaluator<T> evaluator, Tree node) {
        switch (node.getType()) {
            case CmisQlStrictLexer.BOOL_LIT:
                return walkBoolean(evaluator, node);
            case CmisQlStrictLexer.NUM_LIT:
                return walkNumber(evaluator, node);
            case CmisQlStrictLexer.STRING_LIT:
                return walkString(evaluator, node);
            case CmisQlStrictLexer.TIME_LIT:
                return walkTimestamp(evaluator, node);
            case CmisQlStrictLexer.IN_LIST:
                return evaluator.list(walkList(evaluator, node));
            case CmisQlStrictLexer.COL:
                return walkCol(evaluator, node);
            default:
                return walkOtherExpr(evaluator, node);
        }
    }
   
    private T walkExprTextSearch(Evaluator<T> evaluator, Tree node) {
        switch (node.getType()) {
            case TextSearchLexer.TEXT_AND:
                return walkTextAnd(evaluator, node);
            case TextSearchLexer.TEXT_OR:
                return walkTextOr(evaluator, node);
            case TextSearchLexer.TEXT_MINUS:
                return walkTextMinus(evaluator, node);
            case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
                return walkTextWord(evaluator, node);
            case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
                return walkTextPhrase(evaluator, node);
            default:
                return walkOtherExpr(evaluator, node);
        }
    }

    private List<T> walkList(Evaluator<T> evaluator, Tree node) {
        int n = node.getChildCount();
        List<T> result = new ArrayList<T>(n);
        for (int i = 0; i < n; i++) {
            result.add(walkExpr(evaluator.op(), node.getChild(i)));
        }
        return result;
    }

    private T walkBoolean(Evaluator<T> evaluator, Tree node) {
        String s = node.getText();

        if ("true".equalsIgnoreCase(s)) {
            return evaluator.value(true);
        }
        else if ("false".equalsIgnoreCase(s)) {
            return evaluator.value(false);
        }
        else {
            throw new CmisInvalidArgumentException("Not a boolean: " + s);
        }
    }

    private T walkNumber(Evaluator<T> evaluator, Tree node) {
        String s = node.getText();
        try {
            return s.contains(".") || s.contains("e") || s.contains("E")
                    ? evaluator.value(Double.valueOf(s))
                    : evaluator.value(Long.valueOf(s));
        }
        catch (NumberFormatException e) {
            throw new CmisInvalidArgumentException("Not a number: " + s);
        }
    }

    private T walkString(Evaluator<T> evaluator, Tree node) {
        String s = node.getText();
        s = s.substring(1, s.length() - 1);
        return evaluator.value(s.replace("''", "'"))// un-escape quotes
    }

    private T walkTimestamp(Evaluator<T> evaluator, Tree node) {
        String s = node.getText();
        s = s.substring(s.indexOf('\'') + 1, s.length() - 1);
        try {
            return evaluator.value(CalendarHelper.fromString(s));
        }
        catch (IllegalArgumentException e) {
            throw new CmisInvalidArgumentException("Not a date time value: " + s);
        }
    }

    private T walkCol(Evaluator<T> evaluator, Tree node) {
        return evaluator.col(node.getChild(0).getText());
    }

    private T walkTextAnd(Evaluator<T> evaluator2, Tree node) {
        // TODO Auto-generated method stub
        return null;
    }
   
    private T walkTextOr(Evaluator<T> evaluator2, Tree node) {
        // TODO Auto-generated method stub
        return null;
    }
   
    private T walkTextMinus(Evaluator<T> evaluator2, Tree node) {
        // TODO Auto-generated method stub
        return null;
    }
   
    private T walkTextWord(Evaluator<T> evaluator2, Tree node) {
        // TODO Auto-generated method stub
        return null;
    }
   
    private T walkTextPhrase(Evaluator<T> evaluator2, Tree node) {
        // TODO Auto-generated method stub
        return null;
    }

}
TOP

Related Classes of org.apache.chemistry.opencmis.jcr.query.ParseTreeWalker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.