KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > el > ValueExpressionImpl


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.el;
19
20 import java.io.Externalizable JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.ObjectInput JavaDoc;
23 import java.io.ObjectOutput JavaDoc;
24
25 import javax.el.ELContext;
26 import javax.el.ELException;
27 import javax.el.ELResolver;
28 import javax.el.Expression;
29 import javax.el.ExpressionFactory;
30 import javax.el.FunctionMapper;
31 import javax.el.PropertyNotFoundException;
32 import javax.el.PropertyNotWritableException;
33 import javax.el.ValueExpression;
34 import javax.el.VariableMapper;
35
36 import org.apache.el.lang.ELSupport;
37 import org.apache.el.lang.EvaluationContext;
38 import org.apache.el.lang.ExpressionBuilder;
39 import org.apache.el.parser.AstLiteralExpression;
40 import org.apache.el.parser.Node;
41 import org.apache.el.util.ReflectionUtil;
42
43
44 /**
45  * An <code>Expression</code> that can get or set a value.
46  *
47  * <p>
48  * In previous incarnations of this API, expressions could only be read.
49  * <code>ValueExpression</code> objects can now be used both to retrieve a
50  * value and to set a value. Expressions that can have a value set on them are
51  * referred to as l-value expressions. Those that cannot are referred to as
52  * r-value expressions. Not all r-value expressions can be used as l-value
53  * expressions (e.g. <code>"${1+1}"</code> or
54  * <code>"${firstName} ${lastName}"</code>). See the EL Specification for
55  * details. Expressions that cannot be used as l-values must always return
56  * <code>true</code> from <code>isReadOnly()</code>.
57  * </p>
58  *
59  * <p>
60  * <code>The {@link ExpressionFactory#createValueExpression} method
61  * can be used to parse an expression string and return a concrete instance
62  * of <code>ValueExpression</code> that encapsulates the parsed expression.
63  * The {@link FunctionMapper} is used at parse time, not evaluation time,
64  * so one is not needed to evaluate an expression using this class.
65  * However, the {@link ELContext} is needed at evaluation time.</p>
66  *
67  * <p>The {@link #getValue}, {@link #setValue}, {@link #isReadOnly} and
68  * {@link #getType} methods will evaluate the expression each time they are
69  * called. The {@link ELResolver} in the <code>ELContext</code> is used to
70  * resolve the top-level variables and to determine the behavior of the
71  * <code>.</code> and <code>[]</code> operators. For any of the four methods,
72  * the {@link ELResolver#getValue} method is used to resolve all properties
73  * up to but excluding the last one. This provides the <code>base</code>
74  * object. At the last resolution, the <code>ValueExpression</code> will
75  * call the corresponding {@link ELResolver#getValue},
76  * {@link ELResolver#setValue}, {@link ELResolver#isReadOnly} or
77  * {@link ELResolver#getType} method, depending on which was called on
78  * the <code>ValueExpression</code>.
79  * </p>
80  *
81  * <p>See the notes about comparison, serialization and immutability in
82  * the {@link Expression} javadocs.
83  *
84  * @see javax.el.ELResolver
85  * @see javax.el.Expression
86  * @see javax.el.ExpressionFactory
87  * @see javax.el.ValueExpression
88  *
89  * @author Jacob Hookom [jacob@hookom.net]
90  * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
91  */

92 public final class ValueExpressionImpl extends ValueExpression implements
93         Externalizable JavaDoc {
94
95     private Class JavaDoc expectedType;
96
97     private String JavaDoc expr;
98
99     private FunctionMapper fnMapper;
100
101     private VariableMapper varMapper;
102
103     private transient Node node;
104
105     public ValueExpressionImpl() {
106
107     }
108
109     /**
110      *
111      */

112     public ValueExpressionImpl(String JavaDoc expr, Node node, FunctionMapper fnMapper,
113             VariableMapper varMapper, Class JavaDoc expectedType) {
114         this.expr = expr;
115         this.node = node;
116         this.fnMapper = fnMapper;
117         this.varMapper = varMapper;
118         this.expectedType = expectedType;
119     }
120
121     /*
122      * (non-Javadoc)
123      *
124      * @see java.lang.Object#equals(java.lang.Object)
125      */

126     public boolean equals(Object JavaDoc obj) {
127         return (obj instanceof ValueExpressionImpl && obj.hashCode() == this
128                 .hashCode());
129     }
130
131     /*
132      * (non-Javadoc)
133      *
134      * @see javax.el.ValueExpression#getExpectedType()
135      */

136     public Class JavaDoc getExpectedType() {
137         return this.expectedType;
138     }
139
140     /**
141      * Returns the type the result of the expression will be coerced to after
142      * evaluation.
143      *
144      * @return the <code>expectedType</code> passed to the
145      * <code>ExpressionFactory.createValueExpression</code> method
146      * that created this <code>ValueExpression</code>.
147      *
148      * @see javax.el.Expression#getExpressionString()
149      */

150     public String JavaDoc getExpressionString() {
151         return this.expr;
152     }
153
154     /**
155      * @return
156      * @throws ELException
157      */

158     private Node getNode() throws ELException {
159         if (this.node == null) {
160             this.node = ExpressionBuilder.createNode(this.expr);
161         }
162         return this.node;
163     }
164
165     /*
166      * (non-Javadoc)
167      *
168      * @see javax.el.ValueExpression#getType(javax.el.ELContext)
169      */

170     public Class JavaDoc getType(ELContext context) throws PropertyNotFoundException,
171             ELException {
172         EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
173                 this.varMapper);
174         return this.getNode().getType(ctx);
175     }
176
177     /*
178      * (non-Javadoc)
179      *
180      * @see javax.el.ValueExpression#getValue(javax.el.ELContext)
181      */

182     public Object JavaDoc getValue(ELContext context) throws PropertyNotFoundException,
183             ELException {
184         EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
185                 this.varMapper);
186         Object JavaDoc value = this.getNode().getValue(ctx);
187         if (this.expectedType != null) {
188             return ELSupport.coerceToType(value, this.expectedType);
189         }
190         return value;
191     }
192
193     /*
194      * (non-Javadoc)
195      *
196      * @see java.lang.Object#hashCode()
197      */

198     public int hashCode() {
199         return this.expr.hashCode();
200     }
201
202     /*
203      * (non-Javadoc)
204      *
205      * @see javax.el.ValueExpression#isLiteralText()
206      */

207     public boolean isLiteralText() {
208         try {
209             return this.getNode() instanceof AstLiteralExpression;
210         } catch (ELException ele) {
211             return false;
212         }
213     }
214
215     /*
216      * (non-Javadoc)
217      *
218      * @see javax.el.ValueExpression#isReadOnly(javax.el.ELContext)
219      */

220     public boolean isReadOnly(ELContext context)
221             throws PropertyNotFoundException, ELException {
222         EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
223                 this.varMapper);
224         return this.getNode().isReadOnly(ctx);
225     }
226
227     public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc,
228             ClassNotFoundException JavaDoc {
229         this.expr = in.readUTF();
230         String JavaDoc type = in.readUTF();
231         if (!"".equals(type)) {
232             this.expectedType = ReflectionUtil.forName(type);
233         }
234         this.fnMapper = (FunctionMapper) in.readObject();
235         this.varMapper = (VariableMapper) in.readObject();
236     }
237
238     /*
239      * (non-Javadoc)
240      *
241      * @see javax.el.ValueExpression#setValue(javax.el.ELContext,
242      * java.lang.Object)
243      */

244     public void setValue(ELContext context, Object JavaDoc value)
245             throws PropertyNotFoundException, PropertyNotWritableException,
246             ELException {
247         EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
248                 this.varMapper);
249         this.getNode().setValue(ctx, value);
250     }
251
252     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
253         out.writeUTF(this.expr);
254         out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
255                 : "");
256         out.writeObject(this.fnMapper);
257         out.writeObject(this.varMapper);
258     }
259
260     public String JavaDoc toString() {
261         return "ValueExpression["+this.expr+"]";
262     }
263 }
264
Popular Tags