Package org.xorm.query

Source Code of org.xorm.query.ExpressionValidator

/*
    $Header: /cvsroot/xorm/xorm/src/org/xorm/query/ExpressionValidator.java,v 1.9 2003/12/20 00:43:27 wbiggs Exp $

    This file is part of XORM.

    XORM is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    XORM 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 Public License for more details.

    You should have received a copy of the GNU General Public License
    along with XORM; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.xorm.query;

import java.util.Arrays;
import java.util.List;

import org.xorm.XORM;
import org.xorm.ClassMapping;
import org.xorm.ModelMapping;

/**
* Validates and normalizes expressions.
*/
public class ExpressionValidator extends ExpressionVisitor.NoOp {
    private static List ALLOWED_METHODS = Arrays.asList(new String[] {
        "contains", "isEmpty", "startsWith", "endsWith", "strstr",
        "indexOf" });

    private QueryImpl query;
    private boolean valid = true;
    private ModelMapping modelMapping;

    public ExpressionValidator(QueryImpl query) {
        this.query = query;
    }

    public boolean isValid() {
        query.getExpression().accept(this);
        return valid;
    }

    /** Lazy initialization of modelMapping. */
    private ModelMapping getModelMapping() {
        if (modelMapping == null) {
            modelMapping = XORM.getModelMapping(query.getPersistenceManager());
        }
        return modelMapping;
    }
 
    /**
     * Ensures that both sides of a comparison are valid.
     */
    public boolean visitComparison(Expression.Comparison exp) {
        exp.getLHS().accept(this);
        if (valid) {
            exp.getRHS().accept(this);
        }
        return true;
    }

    /**
     * Ensures that the method is acceptable as per the JDO spec.
     */
    public boolean visitMethodCall(Expression.MethodCall exp) {
        exp.getOwner().accept(this);

        valid &= ALLOWED_METHODS.contains(exp.getName());
        // TODO validate if owner is of correct type
 
        Expression[] params = exp.getParameters();
        for (int i = 0; i < params.length; i++) {
            params[i].accept(this);
        }
        return true;
    }

    /**
     * Ensures that the field is mapped for the owning class
     * and sets the Type field to the correct class.
     */
    public boolean visitFieldAccess(Expression.FieldAccess exp) {
  if (exp == Expression.FieldAccess.THIS) { return true; }
        Expression owner = exp.getOwner();
        ClassMapping mapping;
        if (owner != Expression.FieldAccess.THIS) {
            owner.accept(this);
            mapping = getModelMapping()
                .getClassMapping(exp.getOwner().getType());
        } else {
            mapping = getModelMapping()
                .getClassMapping(query.getCandidateClass());
        }
        //System.out.println("Setting type of field " + exp.getName() + " to " + mapping.getFieldDescriptor(exp.getName()).type + " using mapping for " + mapping.getMappedClass());
        exp.setType(mapping.getFieldDescriptor(exp.getName()).type);
        return true;
    }

    /**
     * Ensures that the named parameter has been declared.
     */
    public boolean visitParameter(Expression.Parameter exp) {
        valid &= query.getParameterType(exp.getName()) != null;
        return true;
    }

    /**
     * Ensures that the named variable has been declared.
     */
    public boolean visitVariable(Expression.Variable exp) {
        valid &= query.getVariableType(exp.getName()) != null;
        return true;
    }

    public boolean visitNot(Expression.Not exp) {
        // For AND/OR clauses, push the negation down the chain
        Expression inside = exp.getOperand();
        if (inside instanceof Expression.ConditionalAnd) {
            Expression.ConditionalAnd and = (Expression.ConditionalAnd) inside;
            exp.setOperand(new Expression.Not
                (new Expression.ConditionalOr
                    (new Expression.Not(and.getLHS()),
                     new Expression.Not(and.getRHS()))));
            inside = ((Expression.Unary) exp.getOperand()).getOperand();
        } else if (inside instanceof Expression.ConditionalOr) {
            Expression.ConditionalOr or = (Expression.ConditionalOr) inside;
            exp.setOperand(new Expression.Not
                (new Expression.ConditionalAnd
                    (new Expression.Not(or.getLHS()),
                     new Expression.Not(or.getRHS()))));
            inside = ((Expression.Unary) exp.getOperand()).getOperand();
        }
        inside.accept(this);
        return true;
    }

    public boolean visitUnary(Expression.Unary exp) {
        exp.getOperand().accept(this);
        return true;
    }
}
TOP

Related Classes of org.xorm.query.ExpressionValidator

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.