KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > el > ValueExpressionImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  *
21  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
22  *
23  * Portions Copyright Apache Software Foundation.
24  */

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

98 public final class ValueExpressionImpl extends ValueExpression implements
99         Externalizable JavaDoc {
100
101     private Class JavaDoc expectedType;
102
103     private String JavaDoc expr;
104
105     private FunctionMapper fnMapper;
106
107     private VariableMapper varMapper;
108
109     private transient Node node;
110
111     public ValueExpressionImpl() {
112
113     }
114
115     /**
116      *
117      */

118     public ValueExpressionImpl(String JavaDoc expr, Node node, FunctionMapper fnMapper,
119             VariableMapper varMapper, Class JavaDoc expectedType) {
120         this.expr = expr;
121         this.node = node;
122         this.fnMapper = fnMapper;
123         this.varMapper = varMapper;
124         this.expectedType = expectedType;
125     }
126
127     /*
128      * (non-Javadoc)
129      *
130      * @see java.lang.Object#equals(java.lang.Object)
131      */

132     public boolean equals(Object JavaDoc obj) {
133         return (obj instanceof ValueExpressionImpl && obj.hashCode() == this
134                 .hashCode());
135     }
136
137     /*
138      * (non-Javadoc)
139      *
140      * @see javax.el.ValueExpression#getExpectedType()
141      */

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

156     public String JavaDoc getExpressionString() {
157         return this.expr;
158     }
159
160     /**
161      * @return
162      * @throws ELException
163      */

164     private Node getNode() throws ELException {
165         if (this.node == null) {
166             this.node = ExpressionBuilder.createNode(this.expr);
167         }
168         return this.node;
169     }
170
171     /*
172      * (non-Javadoc)
173      *
174      * @see javax.el.ValueExpression#getType(javax.el.ELContext)
175      */

176     public Class JavaDoc getType(ELContext context) throws PropertyNotFoundException,
177             ELException {
178         EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
179                 this.varMapper);
180         return this.getNode().getType(ctx);
181     }
182
183     /*
184      * (non-Javadoc)
185      *
186      * @see javax.el.ValueExpression#getValue(javax.el.ELContext)
187      */

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

204     public int hashCode() {
205         return this.expr.hashCode();
206     }
207
208     /*
209      * (non-Javadoc)
210      *
211      * @see javax.el.ValueExpression#isLiteralText()
212      */

213     public boolean isLiteralText() {
214         try {
215             return this.getNode() instanceof AstLiteralExpression;
216         } catch (ELException ele) {
217             return false;
218         }
219     }
220
221     /*
222      * (non-Javadoc)
223      *
224      * @see javax.el.ValueExpression#isReadOnly(javax.el.ELContext)
225      */

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

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