2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.faces;
19
20 import java.beans.Beans;
21 import java.util.Map;
22 import javax.faces.el.EvaluationException;
23 import javax.faces.el.PropertyNotFoundException;
24 import javax.faces.el.PropertyResolver;
25 import javax.naming.Context;
26 import javax.naming.Name;
27 import javax.naming.NameNotFoundException;
28 import javax.naming.NamingException;
29 import org.apache.shale.util.LoadBundle;
30
31 /***
32 * <p>Shale-specific PropertyResolver for evaluating JavaServer Faces
33 * value binding and method binding expressions. The following special
34 * processing is performed, based on recognizing the type of the base
35 * object:</p>
36 * <ul>
37 * <li><strong>javax.naming.Context</strong> - Treats the property "name"
38 * as a String (or <code>javax.naming.Name</code>) suitable for passing
39 * to the <code>lookup()</code> method of the <code>Context</code>.
40 * The Context has no way to describe whether it is read only or not,
41 * so <code>isReadOnly()</code> returns <code>false</code>.</li>
42 * <li><strong>org.apache.shale.util.LoadBundle</strong> - Special handling
43 * as follows, based on the requested property name:
44 * <ul>
45 * <li><code>map</code> - Delegates to the original resolver's handling
46 * of the <code>map</code> property. This is for backwards compatibility
47 * with applications depending on this behavior from the 1.0.0
48 * version of the class.</li>
49 * <li>Any other property is considered to be a resource bundle key, which
50 * will be used to look up the corresponding value from the underlying
51 * resource bundle, using the <code>Locale</code> from the current
52 * view for selecting the appropriate translation.</li>
53 * </ul></li>
54 * </ul>
55 * <p>All other evaluations are delegated to the previous implementation
56 * that was passed to our constructor.</p>
57 *
58 * $Id: ShalePropertyResolver.java 464373 2006-10-16 04:21:54Z rahul $
59 */
60 public class ShalePropertyResolver extends PropertyResolver {
61
62
63
64
65
66 /***
67 * <p>Construct a new {@link ShalePropertyResolver} instance.</p>
68 *
69 *
70 * @param original Original resolver to delegate to.
71 */
72 public ShalePropertyResolver(PropertyResolver original) {
73
74 this.original = original;
75
76 }
77
78
79
80
81
82 /***
83 * <p>The original <code>PropertyResolver</code> passed to our constructor.</p>
84 */
85 private PropertyResolver original = null;
86
87
88
89
90
91 /***
92 * <p>For a base object of type <code>Context</code>, look up and return
93 * the named object corresponding to the specified property name from
94 * this <code>Context</code>.</p>
95 *
96 * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
97 * treat the property expression as follows:</p>
98 * <ul>
99 * <li>If the property name is <code>map</code>, call the corresponding
100 * property getter and return that value.</li>
101 * <li>Otherwise, treat the property name as a message key, and look up
102 * and return the corresponding value from the <code>Map</code> that
103 * is returned by the <code>getMap()</code> call.</li>
104 * </ul>
105 *
106 * @param base Base object from which to return a property
107 * @param property Property to be returned
108 *
109 * @exception EvaluationException if an evaluation error occurs
110 * @exception PropertyNotFoundException if there is no such named
111 * object in this context
112 */
113 public Object getValue(Object base, Object property)
114 throws EvaluationException, PropertyNotFoundException {
115
116 if (base instanceof Context) {
117 Context context = (Context) base;
118 try {
119 if (property instanceof Name) {
120 return context.lookup((Name) property);
121 } else {
122 return context.lookup(property.toString());
123 }
124 } catch (NameNotFoundException e) {
125
126
127 return null;
128 } catch (NamingException e) {
129 throw new EvaluationException(e);
130 }
131 } else if (base instanceof LoadBundle && !"basename".equals(property)) {
132 Map map = ((LoadBundle) base).getMap();
133 if ("map".equals(property)) {
134 return map;
135 } else {
136 return map.get(property);
137 }
138 } else {
139 return original.getValue(base, property);
140 }
141
142 }
143
144
145 /***
146 * <p>For a base object of type <code>Context</code>, replace any previous
147 * binding for the named object corresponding to the specified property
148 * name into this <code>Context</code>.</p>
149 *
150 * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
151 * throw an exception since all properties of this object are read only.</p>
152 *
153 * @param base Base object in which to store a property
154 * @param property Property to be stored
155 * @param value Value to be stored
156 *
157 * @exception EvaluationException if an evaluation error occurs
158 * @exception PropertyNotFoundException if there is no such named
159 * object in this context
160 */
161 public void setValue(Object base, Object property, Object value) {
162
163 if (base instanceof Context) {
164 Context context = (Context) base;
165 try {
166
167
168 if (property instanceof Name) {
169 context.rebind((Name) property, value);
170 } else {
171 context.rebind(property.toString(), value);
172 }
173 } catch (NamingException e) {
174 throw new EvaluationException(e);
175 }
176 } else if (base instanceof LoadBundle && !"basename".equals(property)) {
177 throw new PropertyNotFoundException("" + value);
178 } else {
179 original.setValue(base, property, value);
180 }
181
182 }
183
184
185 /***
186 * <p>For a <code>Context</code> base object, arbitrarily return
187 * <code>false</code> because we cannot determine if a <code>Context</code>
188 * is read only or not.</p>
189 *
190 * <p>(Since 1.0.1) For a <code>LoadBundle</code> base object,
191 * return <code>true</code> because all pseudo-properties of
192 * this bundle are considered to be read only.</p>
193 *
194 * @param base Base object from which to return read only state
195 * @param property Property to be checked
196 *
197 * @exception EvaluationException if an evaluation error occurs
198 * @exception PropertyNotFoundException if there is no such named
199 * object in this context
200 */
201 public boolean isReadOnly(Object base, Object property)
202 throws EvaluationException, PropertyNotFoundException {
203
204 if (base instanceof Context) {
205
206
207 return false;
208 } else if (base instanceof LoadBundle && !"basename".equals(property)) {
209
210 return true;
211 } else {
212 return original.isReadOnly(base, property);
213 }
214
215 }
216
217
218 /***
219 * <p>For a <code>Context</code>, look up and return the type of the
220 * named object corresponding to the specified property name from this
221 * <code>Context</code>.</p>
222 *
223 * <p>(Since 1.0.1) For a <code>LoadBundle</code>, look up and return
224 * the corresponding object type at runtime, or return <code>Object</code>
225 * for the type to be looked up at design time.</p>
226 *
227 * @param base Base object from which to return a property type
228 * @param property Property whose type is to be returned
229 *
230 * @exception EvaluationException if an evaluation error occurs
231 * @exception PropertyNotFoundException if there is no such named
232 * object in this context
233 */
234 public Class getType(Object base, Object property)
235 throws EvaluationException, PropertyNotFoundException {
236
237 if (base instanceof Context) {
238 Context context = (Context) base;
239 Object value;
240 try {
241 if (property instanceof Name) {
242 value = context.lookup((Name) property);
243 } else {
244 value = context.lookup(property.toString());
245 }
246 } catch (NameNotFoundException e) {
247
248
249 return null;
250 } catch (NamingException e) {
251 throw new EvaluationException(e);
252 }
253 if (value == null) {
254 return null;
255 } else {
256 return value.getClass();
257 }
258 } else if (base instanceof LoadBundle && !"basename".equals(property)) {
259 LoadBundle lb = (LoadBundle) base;
260 if ("map".equals(property)) {
261 return Map.class;
262 } else if (Beans.isDesignTime()) {
263 return Object.class;
264 } else {
265 Object value = lb.getMap().get(property);
266 if (value != null) {
267 return value.getClass();
268 } else {
269 return null;
270 }
271 }
272 } else {
273 return original.getType(base, property);
274 }
275
276 }
277
278
279 /***
280 * <p>Convert an index into a corresponding string, and delegate.</p>
281 *
282 * @param base Base object from which to return a property
283 * @param index Index to be returned
284 *
285 * @exception EvaluationException if an evaluation error occurs
286 * @exception PropertyNotFoundException if there is no such named
287 * object in this context
288 */
289 public Object getValue(Object base, int index)
290 throws EvaluationException, PropertyNotFoundException {
291
292 if (base instanceof Context) {
293 return getValue(base, "" + index);
294 } else if (base instanceof LoadBundle && !"basename".equals(base)) {
295 return getValue(base, "" + index);
296 } else {
297 return original.getValue(base, index);
298 }
299
300 }
301
302
303 /***
304 * <p>Convert an index into a corresponding string, and delegate.</p>
305 *
306 * @param base Base object into which to store a property
307 * @param index Index to be stored
308 * @param value Value to be stored
309 *
310 * @exception EvaluationException if an evaluation error occurs
311 * @exception PropertyNotFoundException if there is no such named
312 * object in this context
313 */
314 public void setValue(Object base, int index, Object value)
315 throws EvaluationException, PropertyNotFoundException {
316
317 if (base instanceof Context) {
318 setValue(base, "" + index, value);
319 } else if (base instanceof LoadBundle) {
320 setValue(base, "" + index, value);
321 } else {
322 original.setValue(base, index, value);
323 }
324
325 }
326
327
328 /***
329 * <p>Convert an index into a corresponding string, and delegate.</p>
330 *
331 * @param base Base object from which to check a property
332 * @param index Index to be checked
333 *
334 * @exception EvaluationException if an evaluation error occurs
335 * @exception PropertyNotFoundException if there is no such named
336 * object in this context
337 */
338 public boolean isReadOnly(Object base, int index)
339 throws EvaluationException, PropertyNotFoundException {
340
341 if (base instanceof Context) {
342 return isReadOnly(base, "" + index);
343 } else if (base instanceof LoadBundle) {
344 return isReadOnly(base, "" + index);
345 } else {
346 return original.isReadOnly(base, index);
347 }
348
349 }
350
351
352 /***
353 * <p>Convert an index into a corresponding string, and delegate.</p>
354 *
355 * @param base Base object from which to return a property type
356 * @param index Index whose type is to be returned
357 *
358 * @exception EvaluationException if an evaluation error occurs
359 * @exception PropertyNotFoundException if there is no such named
360 * object in this context
361 */
362 public Class getType(Object base, int index)
363 throws EvaluationException, PropertyNotFoundException {
364
365 if (base instanceof Context) {
366 return getType(base, "" + index);
367 } else if (base instanceof LoadBundle) {
368 return getType(base, "" + index);
369 } else {
370 return original.getType(base, index);
371 }
372
373 }
374
375
376 }