001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.el;
018    
019    import javax.servlet.jsp.el.ELException;
020    import javax.servlet.jsp.el.FunctionMapper;
021    import javax.servlet.jsp.el.VariableResolver;
022    
023    /**
024     *
025     * <p>Represents a conditional expression.  I've decided not to produce an
026     * abstract base "TernaryOperatorExpression" class since (a) future ternary
027     * operators are unlikely and (b) it's not clear that there would be a
028     * meaningful way to abstract them.  (For instance, would they all be right-
029     * associative?  Would they all have two fixed operator symbols?)
030     * 
031     * @author Shawn Bayern
032     **/
033    
034    public class ConditionalExpression
035      extends Expression
036    {
037      //-------------------------------------
038      // Properties
039      //-------------------------------------
040      // property condition
041    
042      Expression mCondition;
043      public Expression getCondition ()
044      { return mCondition; }
045      public void setCondition (Expression pCondition)
046      { mCondition = pCondition; }
047    
048      //-------------------------------------
049      // property trueBranch
050    
051      Expression mTrueBranch;
052      public Expression getTrueBranch ()
053      { return mTrueBranch; }
054      public void setTrueBranch (Expression pTrueBranch)
055      { mTrueBranch = pTrueBranch; }
056    
057      //-------------------------------------
058      // property falseBranch
059    
060      Expression mFalseBranch;
061      public Expression getFalseBranch ()
062      { return mFalseBranch; }
063      public void setFalseBranch (Expression pFalseBranch)
064      { mFalseBranch = pFalseBranch; }
065    
066      //-------------------------------------
067      /**
068       *
069       * Constructor
070       **/
071      public ConditionalExpression (Expression pCondition,
072                                    Expression pTrueBranch,
073                                    Expression pFalseBranch)
074      {
075        mCondition = pCondition;
076        mTrueBranch = pTrueBranch;
077        mFalseBranch = pFalseBranch;
078      }
079    
080      //-------------------------------------
081      // Expression methods
082      //-------------------------------------
083      /**
084       *
085       * Returns the expression in the expression language syntax
086       **/
087      public String getExpressionString ()
088      {
089        return
090          "( " + mCondition.getExpressionString() + " ? " + 
091          mTrueBranch.getExpressionString() + " : " +
092          mFalseBranch.getExpressionString() + " )";
093      }
094    
095      //-------------------------------------
096      /**
097       *
098       * Evaluates the conditional expression and returns the literal result
099       **/
100      public Object evaluate (VariableResolver vr,
101                              FunctionMapper f)
102        throws ELException
103      {
104        // first, evaluate the condition (and coerce the result to a boolean value)
105        boolean condition =
106          Coercions.coerceToBoolean(
107            mCondition.evaluate(vr, f)).booleanValue();
108    
109        // then, use this boolean to branch appropriately
110        if (condition)
111          return mTrueBranch.evaluate(vr, f);
112        else
113          return mFalseBranch.evaluate(vr, f);
114      }
115    
116      public Expression bindFunctions(final FunctionMapper functions) throws ELException {
117           return new ConditionalExpression(
118                   mCondition.bindFunctions(functions),
119                   mTrueBranch.bindFunctions(functions),
120                   mFalseBranch.bindFunctions(functions));
121      }
122    
123      //-------------------------------------
124    }