View Javadoc

    1   /*
    2    * Copyright 2002,2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package org.apache.commons.jexl;
    18
    19  import java.util.ArrayList;
    20  import java.util.List;
    21
    22  import org.apache.commons.jexl.parser.SimpleNode;
    23
    24  /***
    25   * Instances of ExpressionImpl are created by the {@link ExpressionFactory},
    26   * and this is the default implementation of the {@link Expression} interface.
    27   *
    28   *  @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
    29   *  @version $Id: ExpressionImpl.java,v 1.11 2004/08/23 14:00:11 dion Exp $
    30   */
    31  class ExpressionImpl implements Expression
    32  {
    33
    34      protected List preResolvers;
    35      protected List postResolvers;
    36
    37      /***
    38       *  Original expression - this is just a 'snippet', not a valid
    39       *  statement (i.e.  foo.bar() vs foo.bar();
    40       */
    41      protected String expression;
    42
    43      /***
    44       *  The resulting AST we can call value() on
    45       */
    46      protected SimpleNode node;
    47
    48      /***
    49       *  do not let this be generally instantiated with a 'new'
    50       */
    51      ExpressionImpl(String expr, SimpleNode ref)
    52      {
    53          expression = expr;
    54          node = ref;
    55      }
    56
    57      /***
    58       *  Evaluate the expression and return the value.
    59       *
    60       * Before JEXL evaluates the expression, any pre-resolvers will be called.
    61       * If the pre-resolver provides a value, it is returned.
    62       * If JEXL evaluates the expression as null, post-resolvers are called
    63       * and any resulting value returned.
    64       *
    65       *  @param context Context containing objects/data used for evaluation
    66       *  @return value of expression
    67       */
    68      public Object evaluate(JexlContext context)
    69          throws Exception
    70      {
    71          Object val = null;
    72
    73          /*
    74           * if we have pre resolvers, give them a wack
    75           */
    76          if (preResolvers != null)
    77          {
    78              val = tryResolver(preResolvers, context);
    79
    80              if (val != JexlExprResolver.NO_VALUE)
    81              {
    82                  return val;
    83              }
    84          }
    85
    86          val = node.value(context);
    87
    88          /*
    89           * if null, call post resolvers
    90           */
    91          if (val == null && postResolvers != null)
    92          {
    93              val = tryResolver(postResolvers, context);
    94
    95              if (val != JexlExprResolver.NO_VALUE)
    96              {
    97                  return val;
    98              }
    99          }
    100
    101         return val;
    102     }
    103
    104     /***
    105      *  Tries the resolvers in the given resolverlist against the context
    106      *
    107      *  @param resolverList list of JexlExprResolvers
    108      *  @param context JexlContext to use for evauluation
    109      *  @return value (including null) or JexlExprResolver.NO_VALUE
    110      */
    111     protected Object tryResolver(List resolverList, JexlContext context)
    112     {
    113         Object val = JexlExprResolver.NO_VALUE;
    114         String expr = getExpression();
    115
    116         for (int i = 0; i < resolverList.size(); i++)
    117         {
    118             JexlExprResolver jer = (JexlExprResolver) resolverList.get(i);
    119
    120             val = jer.evaluate(context, expr);
    121
    122             /*
    123             * as long as it's not NO_VALUE, return it
    124             */
    125             if (val != JexlExprResolver.NO_VALUE)
    126             {
    127                return val;
    128             }
    129         }
    130
    131         return val;
    132     }
    133
    134     /***
    135      *  returns original expression string
    136      */
    137     public String getExpression()
    138     {
    139         return expression;
    140     }
    141
    142     public void addPreResolver(JexlExprResolver resolver)
    143     {
    144         if (preResolvers == null)
    145         {
    146             preResolvers = new ArrayList();
    147         }
    148         preResolvers.add(resolver);
    149     }
    150
    151     /***
    152      *  allows addition of a resolver to allow custom interdiction of
    153      *  expression evaluation
    154      *
    155      *  @param resolver resolver to be called if Jexl expression evaluated to null
    156      */
    157     public void addPostResolver(JexlExprResolver resolver)
    158     {
    159         if (postResolvers == null)
    160         {
    161             postResolvers = new ArrayList();
    162         }
    163         postResolvers.add(resolver);
    164     }
    165
    166 }