All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.ognl.ASTAdd Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
//--------------------------------------------------------------------------
//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
//  All rights reserved.
//
//	Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//	Redistributions of source code must retain the above copyright notice,
//  this list of conditions and the following disclaimer.
//	Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the distribution.
//	Neither the name of the Drew Davidson nor the names of its contributors
//  may be used to endorse or promote products derived from this software
//  without specific prior written permission.
//
//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//  DAMAGE.
//--------------------------------------------------------------------------
package com.feilong.lib.ognl;

import java.math.BigDecimal;
import java.math.BigInteger;

import com.feilong.lib.ognl.enhance.ExpressionCompiler;

/**
 * @author Luke Blanshard ([email protected])
 * @author Drew Davidson ([email protected])
 */
class ASTAdd extends NumericExpression{

    /**
     * 
     */
    private static final long serialVersionUID = 7539710878696139202L;

    public ASTAdd(int id){
        super(id);
    }

    public ASTAdd(OgnlParser p, int id){
        super(p, id);
    }

    @Override
    public void jjtClose(){
        flattenTree();
    }

    @Override
    protected Object getValueBody(OgnlContext context,Object source) throws OgnlException{
        Object result = _children[0].getValue(context, source);

        for (int i = 1; i < _children.length; ++i){
            result = OgnlOps.add(result, _children[i].getValue(context, source));
        }

        return result;
    }

    @Override
    public String getExpressionOperator(int index){
        return "+";
    }

    boolean isWider(NodeType type,NodeType lastType){
        if (lastType == null){
            return true;
        }

        //System.out.println("checking isWider(" + type.getGetterClass() + " , " + lastType.getGetterClass() + ")");

        if (String.class.isAssignableFrom(lastType.getGetterClass())){
            return false;
        }

        if (String.class.isAssignableFrom(type.getGetterClass())){
            return true;
        }

        if (_parent != null && String.class.isAssignableFrom(type.getGetterClass())){
            return true;
        }

        if (String.class.isAssignableFrom(lastType.getGetterClass()) && Object.class == type.getGetterClass()){
            return false;
        }

        if (_parent != null && String.class.isAssignableFrom(lastType.getGetterClass())){
            return false;
        }else if (_parent == null && String.class.isAssignableFrom(lastType.getGetterClass())){
            return true;
        }else if (_parent == null && String.class.isAssignableFrom(type.getGetterClass())){
            return false;
        }

        if (BigDecimal.class.isAssignableFrom(type.getGetterClass()) || BigInteger.class.isAssignableFrom(type.getGetterClass())){
            return true;
        }

        if (BigDecimal.class.isAssignableFrom(lastType.getGetterClass()) || BigInteger.class.isAssignableFrom(lastType.getGetterClass())){
            return false;
        }

        if (Double.class.isAssignableFrom(type.getGetterClass())){
            return true;
        }

        if (Integer.class.isAssignableFrom(type.getGetterClass()) && Double.class.isAssignableFrom(lastType.getGetterClass())){
            return false;
        }

        if (Float.class.isAssignableFrom(type.getGetterClass()) && Integer.class.isAssignableFrom(lastType.getGetterClass())){
            return true;
        }

        return true;
    }

    @Override
    public String toGetSourceString(OgnlContext context,Object target){
        try{
            String result = "";
            NodeType lastType = null;

            // go through once to determine the ultimate type

            if ((_children != null) && (_children.length > 0)){
                Class currType = context.getCurrentType();
                Class currAccessor = context.getCurrentAccessor();

                Object cast = context.get(ExpressionCompiler.PRE_CAST);

                for (Node element : _children){
                    element.toGetSourceString(context, target);

                    if (NodeType.class.isInstance(element) && ((NodeType) element).getGetterClass() != null
                                    && isWider((NodeType) element, lastType)){
                        lastType = (NodeType) element;
                    }
                }

                context.put(ExpressionCompiler.PRE_CAST, cast);

                context.setCurrentType(currType);
                context.setCurrentAccessor(currAccessor);
            }

            // reset context since previous children loop would have changed it

            context.setCurrentObject(target);

            if ((_children != null) && (_children.length > 0)){

                for (int i = 0; i < _children.length; ++i){
                    if (i > 0){
                        result += " " + getExpressionOperator(i) + " ";
                    }

                    String expr = _children[i].toGetSourceString(context, target);

                    if ((expr != null && "null".equals(expr))
                                    || (!ASTConst.class.isInstance(_children[i]) && (expr == null || expr.trim().length() <= 0))){
                        expr = "null";
                    }

                    //System.out.println("astadd child class: " + _children[i].getClass().getName() + " and return expr: " + expr);

                    if (ASTProperty.class.isInstance(_children[i])){
                        expr = ExpressionCompiler.getRootExpression(_children[i], context.getRoot(), context) + expr;
                        context.setCurrentAccessor(context.getRoot().getClass());
                    }else if (ASTMethod.class.isInstance(_children[i])){
                        String chain = (String) context.get("_currentChain");
                        String rootExpr = ExpressionCompiler.getRootExpression(_children[i], context.getRoot(), context);

                        //System.out.println("astadd chains is >>" + chain + "<< and rootExpr is >>" + rootExpr + "<<");

                        // dirty fix for overly aggressive casting dot operations
                        if (rootExpr.endsWith(".") && chain != null && chain.startsWith(").")){
                            chain = chain.substring(1, chain.length());
                        }

                        expr = rootExpr + (chain != null ? chain + "." : "") + expr;
                        context.setCurrentAccessor(context.getRoot().getClass());

                    }else if (ExpressionNode.class.isInstance(_children[i])){
                        expr = "(" + expr + ")";
                    }else if ((_parent == null || !ASTChain.class.isInstance(_parent)) && ASTChain.class.isInstance(_children[i])){
                        String rootExpr = ExpressionCompiler.getRootExpression(_children[i], context.getRoot(), context);

                        if (!ASTProperty.class.isInstance(_children[i].jjtGetChild(0)) && rootExpr.endsWith(")") && expr.startsWith(")")){
                            expr = expr.substring(1, expr.length());
                        }

                        expr = rootExpr + expr;
                        context.setCurrentAccessor(context.getRoot().getClass());

                        String cast = (String) context.remove(ExpressionCompiler.PRE_CAST);
                        if (cast == null){
                            cast = "";
                        }

                        expr = cast + expr;
                    }

                    // turn quoted characters into quoted strings

                    if (context.getCurrentType() != null && context.getCurrentType() == Character.class
                                    && ASTConst.class.isInstance(_children[i])){
                        if (expr.indexOf('\'') >= 0){
                            expr = expr.replaceAll("'", "\"");
                        }
                        context.setCurrentType(String.class);
                    }else{

                        if (!ASTVarRef.class.isAssignableFrom(_children[i].getClass()) && !ASTProperty.class.isInstance(_children[i])
                                        && !ASTMethod.class.isInstance(_children[i]) && !ASTSequence.class.isInstance(_children[i])
                                        && !ASTChain.class.isInstance(_children[i])
                                        && !NumericExpression.class.isAssignableFrom(_children[i].getClass())
                                        && !ASTStaticField.class.isInstance(_children[i]) && !ASTStaticMethod.class.isInstance(_children[i])
                                        && !ASTTest.class.isInstance(_children[i])){
                            if (lastType != null && String.class.isAssignableFrom(lastType.getGetterClass())){
                                //System.out.println("Input expr >>" + expr + "<<");
                                if (expr.indexOf(""") >= 0){
                                    expr = expr.replaceAll(""", "\"");
                                }
                                if (expr.indexOf('"') >= 0){
                                    expr = expr.replaceAll("\"", "'");
                                }
                                expr = "\"" + expr + "\"";
                                //System.out.println("Expr now >>" + expr + "<<");
                            }
                        }
                    }

                    result += expr;

                    // hanlde addition for numeric types when applicable or just string concatenation

                    if ((lastType == null || !String.class.isAssignableFrom(lastType.getGetterClass()))
                                    && !ASTConst.class.isAssignableFrom(_children[i].getClass())
                                    && !NumericExpression.class.isAssignableFrom(_children[i].getClass())){
                        if (context.getCurrentType() != null && Number.class.isAssignableFrom(context.getCurrentType())
                                        && !ASTMethod.class.isInstance(_children[i])){
                            if (ASTVarRef.class.isInstance(_children[i]) || ASTProperty.class.isInstance(_children[i])
                                            || ASTChain.class.isInstance(_children[i])){
                                result += ".";
                            }

                            result += OgnlRuntime.getNumericValueGetter(context.getCurrentType());
                            context.setCurrentType(OgnlRuntime.getPrimitiveWrapperClass(context.getCurrentType()));
                        }
                    }

                    if (lastType != null){
                        context.setCurrentAccessor(lastType.getGetterClass());
                    }
                }
            }

            if (_parent == null || ASTSequence.class.isAssignableFrom(_parent.getClass())){
                if (_getterClass != null && String.class.isAssignableFrom(_getterClass)){
                    _getterClass = Object.class;
                }
            }else{
                context.setCurrentType(_getterClass);
            }

            try{
                Object contextObj = getValueBody(context, target);
                context.setCurrentObject(contextObj);
            }catch (Throwable t){
                throw OgnlOps.castToRuntime(t);
            }

            return result;

        }catch (Throwable t){
            throw OgnlOps.castToRuntime(t);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy