KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > binding > ExpressionBinding


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

15 package org.apache.tapestry.binding;
16
17 import org.apache.hivemind.Location;
18 import org.apache.tapestry.BindingException;
19 import org.apache.tapestry.IComponent;
20 import org.apache.tapestry.coerce.ValueConverter;
21 import org.apache.tapestry.services.ExpressionCache;
22 import org.apache.tapestry.services.ExpressionEvaluator;
23
24 /**
25  * Implements a dynamic binding, based on evaluating an expression using an expression language.
26  * Tapestry's default expression language is the <a HREF="http://www.ognl.org/">Object Graph
27  * Navigation Language </a>.
28  *
29  * @see org.apache.tapestry.services.ExpressionEvaluator
30  * @author Howard Lewis Ship
31  * @since 2.2
32  */

33
34 public class ExpressionBinding extends AbstractBinding
35 {
36     /**
37      * The root object against which the nested property name is evaluated.
38      */

39
40     private final IComponent _root;
41
42     /**
43      * The OGNL expression, as a string.
44      */

45
46     private String JavaDoc _expression;
47
48     /**
49      * If true, then the binding is invariant.
50      */

51
52     private boolean _invariant = false;
53
54     /**
55      * Parsed OGNL expression.
56      */

57
58     private Object JavaDoc _parsedExpression;
59
60     /**
61      * Flag set to true once the binding has initialized.
62      */

63
64     private boolean _initialized;
65
66     /**
67      * @since 4.0
68      */

69
70     private ExpressionEvaluator _evaluator;
71
72     /** @since 4.0 */
73
74     private ExpressionCache _cache;
75
76     /**
77      * Creates a {@link ExpressionBinding}from the root object and an OGNL expression.
78      */

79
80     public ExpressionBinding(String JavaDoc description, Location location, ValueConverter valueConverter,
81             IComponent root, String JavaDoc expression, ExpressionEvaluator evaluator,
82             ExpressionCache cache)
83     {
84         super(description, valueConverter, location);
85
86         _root = root;
87         _expression = expression;
88         _evaluator = evaluator;
89         _cache = cache;
90     }
91
92     /**
93      * Gets the value of the property path, with the assistance of the {@link ExpressionEvaluator}.
94      *
95      * @throws BindingException
96      * if an exception is thrown accessing the property.
97      */

98
99     public Object JavaDoc getObject()
100     {
101         initialize();
102
103         return resolveExpression();
104     }
105
106     private Object JavaDoc resolveExpression()
107     {
108         try
109         {
110             return _evaluator.readCompiled(_root, _parsedExpression);
111         }
112         catch (Throwable JavaDoc t)
113         {
114             throw new BindingException(t.getMessage(), this, t);
115         }
116     }
117
118     /**
119      * Returns true if the binding is expected to always return the same value.
120      */

121
122     public boolean isInvariant()
123     {
124         initialize();
125
126         return _invariant;
127     }
128
129     /**
130      * Sets up the helper object, but also optimizes the property path and determines if the binding
131      * is invarant.
132      */

133
134     private void initialize()
135     {
136         if (_initialized)
137             return;
138
139         _initialized = true;
140
141         try
142         {
143             _parsedExpression = _cache.getCompiledExpression(_expression);
144
145             _invariant = _evaluator.isConstant(_expression);
146         }
147         catch (Exception JavaDoc ex)
148         {
149             throw new BindingException(ex.getMessage(), this, ex);
150         }
151     }
152
153     /**
154      * Updates the property for the binding to the given value.
155      *
156      * @throws BindingException
157      * if the property can't be updated (typically due to an security problem, or a
158      * missing mutator method).
159      * @throws ReadOnlyBindingException
160      * if the binding is invariant.
161      */

162
163     public void setObject(Object JavaDoc value)
164     {
165         initialize();
166
167         if (_invariant)
168             throw createReadOnlyBindingException(this);
169
170         try
171         {
172             _evaluator.writeCompiled(_root, _parsedExpression, value);
173         }
174         catch (Throwable JavaDoc ex)
175         {
176             throw new BindingException(ex.getMessage(), this, ex);
177         }
178     }
179
180     /**
181      * Returns the a String representing the property path. This includes the
182      * {@link IComponent#getExtendedId() extended id}of the root component and the property path
183      * ... once the binding is used, these may change due to optimization of the property path.
184      */

185
186     public String JavaDoc toString()
187     {
188         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
189
190         buffer.append("ExpressionBinding[");
191         buffer.append(_root.getExtendedId());
192
193         if (_expression != null)
194         {
195             buffer.append(' ');
196             buffer.append(_expression);
197         }
198
199         buffer.append(']');
200
201         return buffer.toString();
202     }
203
204     /** @since 4.0 */
205     public Object JavaDoc getComponent()
206     {
207         return _root;
208     }
209 }
Popular Tags