Package org.apache.commons.jexl.parser

Source Code of org.apache.commons.jexl.parser.ASTArrayAccess

/*
* Copyright 2002,2004 The Apache Software Foundation.
*
* Licensed 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.commons.jexl.parser;

import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.util.Coercion;
import org.apache.commons.jexl.util.Introspector;
import org.apache.commons.jexl.util.introspection.Info;
import org.apache.commons.jexl.util.introspection.VelPropertyGet;

import java.util.List;
import java.util.Map;
import java.lang.reflect.Array;


/**
*  Like an ASTIdentifier, but with array access allowed
*
*    $foo[2]
*
@author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
@version $Id: ASTArrayAccess.java,v 1.7 2004/08/22 07:42:35 dion Exp $
*/
public class ASTArrayAccess extends SimpleNode
{
    /** dummy velocity info */
    private static Info DUMMY = new Info("", 1, 1);
   
    public ASTArrayAccess(int id)
    {
        super(id);
    }

    public ASTArrayAccess(Parser p, int id)
    {
        super(p, id);
    }


    /** Accept the visitor. **/
    public Object jjtAccept(ParserVisitor visitor, Object data)
    {
        return visitor.visit(this, data);
    }

    /*
     * evaluate array access upon a base object
     *
     *   foo.bar[2]
     *
     *  makes me rethink the array operator :)
     */
    public Object execute(Object obj, JexlContext jc)
             throws Exception
     {
         ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);

         obj = base.execute(obj,jc);

         /*
          * ignore the first child - it's our identifier
          */
         for(int i=1; i<jjtGetNumChildren(); i++)
         {
             Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);

             if(loc==null)
                 return null;

             obj = evaluateExpr(obj, loc);
         }

         return obj;
     }

    /**
     *  return the value of this node
     */
    public Object value(JexlContext jc)
        throws Exception
    {
        /*
         * get the base ASTIdentifier
         */

        ASTIdentifier base = (ASTIdentifier) jjtGetChild(0);

        Object o = base.value(jc);

        /*
         * ignore the first child - it's our identifier
         */
        for(int i=1; i<jjtGetNumChildren(); i++)
        {
            Object loc = ((SimpleNode) jjtGetChild(i)).value(jc);

            if(loc==null)
                return null;

            o = evaluateExpr(o, loc);
        }

        return o;
    }

    public static Object evaluateExpr(Object o, Object loc)
        throws Exception
    {
        /*
         * following the JSTL EL rules
         */

        if (o == null)
            return null;

        if (loc == null)
            return null;

        if (o instanceof Map)
        {
            if (!((Map)o).containsKey(loc))
                return null;

            return ((Map)o).get(loc);
        }
        else if (o instanceof List)
        {
            int idx = Coercion.coerceInteger(loc).intValue();

            try
            {
                return ((List)o).get(idx);
            }
            catch(IndexOutOfBoundsException iobe)
            {
                return null;
            }
        }
        else if (o.getClass().isArray())
        {
            int idx = Coercion.coerceInteger(loc).intValue();

            try
            {
                return Array.get(o, idx);
            }
            catch(ArrayIndexOutOfBoundsException aiobe)
            {
                return null;
            }
        }
        else
        {
            /*
             *  "Otherwise (a JavaBean object)..."  huh? :)
             */

            String s = loc.toString();

            VelPropertyGet vg = Introspector.getUberspect().getPropertyGet(o, s, DUMMY);

            if (vg != null)
            {
                return vg.invoke(o);
            }
        }

        throw new Exception("Unsupported object type for array [] accessor");
    }

    public String getIdentifierString()
    {
        return ((ASTIdentifier) jjtGetChild(0)).getIdentifierString();
    }
}
TOP

Related Classes of org.apache.commons.jexl.parser.ASTArrayAccess

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.