KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > faces > application > PropertyResolverImpl


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

16
17 package org.apache.struts.faces.application;
18
19
20 import java.util.Map JavaDoc;
21
22 import javax.faces.el.PropertyNotFoundException;
23 import javax.faces.el.PropertyResolver;
24
25 import org.apache.commons.beanutils.DynaBean;
26 import org.apache.commons.beanutils.DynaProperty;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.struts.action.DynaActionForm;
30
31
32
33 /**
34  * <p>Custom <code>PropertyResolver</code> implementation that adds support
35  * for <code>DynaBean</code> property access to the facilities of the default
36  * <code>PropertyResolver</code> provided by JavaServer Faces.</p>
37  *
38  * <p>This class implements the following specific rules:</p>
39  * <ul>
40  * <li>Indexed variants of each call are directly passed through to the
41  * <code>PropertyResolver</code> instance that we are wrapping.</li>
42  * <li>If the specified base object is an instance of
43  * <code>DynaActionForm</code>, and the requested property name is
44  * <code>map</code>, maintain compatibility with the way that JSP and
45  * JSTL expressions can access this property:
46  * <ul>
47  * <li><code>getValue()</code> will return the result of calling
48  * <code>getMap()</code> on the base object.</li>
49  * <li><code>setValue()</code> will throw an exception, because the
50  * map of property values is a read-only property of the
51  * <code>DynaActionForm</code> class.</li>
52  * <li><code>isReadOnly()</code> returns <code>true</code>.</li>
53  * <li><code>getType()</code> returns the <code>Class</code> object
54  * for <code>java.util.Map</code>.</li>
55  * </ul></li>
56  * <li>If the specified base object is an instance of
57  * <code>DynaBean</code>, provide access to its named properties
58  * as follows:
59  * <ul>
60  * <li><code>getValue()</code> will return the result of calling
61  * <code>get()</code> on the base object.</li>
62  * <li><code>setValue()</code> will call <code>set()</code>
63  * on the base object.</li>
64  * <li><code>isReadOnly()</code> returns <code>false</code> (because
65  * the DynaBean APIs provide no mechanism to make this determination,
66  * but most implementations will provide mutable properties).</li>
67  * <li><code>getType()</code> returns the <code>Class</code> object
68  * for the underlying dynamic property.</li>
69  * </ul></li>
70  * <li>Named variant calls with any other type of base object are
71  * passed through to the <code>PropertyResolver</code> that we
72  * are wrapping.</li>
73  * </ul>
74  *
75  * @version $Rev: 54934 $ $Date: 2004-10-16 18:07:50 +0100 (Sat, 16 Oct 2004) $
76  */

77
78 public class PropertyResolverImpl extends PropertyResolver {
79
80
81     // ------------------------------------------------------------ Constructor
82

83
84     /**
85      * <p>Construct a new <code>PropertyResolver</code> instance, wrapping the
86      * specified instance using the Decorator pattern such that this class need
87      * implement only the new functionality it supports, and not need to
88      * re-implement the basic facilities.
89      *
90      * @param resolver The original resolver to be wrapped
91      *
92      * @exception NullPointerException if <code>resolver</code>
93      * is <code>null</code>
94      */

95     public PropertyResolverImpl(PropertyResolver resolver) {
96
97         if (resolver == null) {
98             throw new NullPointerException JavaDoc();
99         }
100         if (log.isDebugEnabled()) {
101             log.debug("Creating new instance, wrapping resolver " +
102                       resolver);
103         }
104         this.resolver = resolver;
105
106     }
107
108
109     // ----------------------------------------------------- Instance Variables
110

111
112     /**
113      * <p>The <code>Log</code> instance for this class.</p>
114      */

115     private static final Log log =
116         LogFactory.getLog(PropertyResolverImpl.class);
117
118
119     /**
120      * <p>The <code>PropertyResolver</code> instance that we are wrapping,
121      * which will be used to perform operations on beans that are not
122      * recognized by this class.</p>
123      */

124     private PropertyResolver resolver = null;
125
126
127     // ----------------------------------------------- PropertyResolver Methods
128

129
130     /**
131      * <p>Return the value of the property with the specified name from
132      * the specified base object.</p>
133      *
134      * @param base The base object whose property value is to be returned
135      * @param name Name of the property to be returned
136      *
137      * @exception NullPointerException if <code>base</code> or
138      * <code>name</code> is <code>null</code>
139      * @exception PropertyNotFoundException if the specified property name
140      * does not exist, or is not readable
141      */

142     public Object JavaDoc getValue(Object JavaDoc base, Object JavaDoc name)
143         throws PropertyNotFoundException {
144
145         if ((base == null) || (name == null)) {
146             throw new NullPointerException JavaDoc();
147         } else if ((base instanceof DynaActionForm) &&
148                    ("map".equals(name))) {
149             if (log.isTraceEnabled()) {
150                 log.trace("Returning property map for DynaActionForm " + base
151                           + "'");
152             }
153             return (((DynaActionForm) base).getMap());
154         } else if (base instanceof DynaBean) {
155             if (getDynaProperty((DynaBean) base, name.toString()) == null) {
156                 throw new PropertyNotFoundException(name.toString());
157             }
158             Object JavaDoc value = ((DynaBean) base).get(name.toString());
159             if (log.isTraceEnabled()) {
160                 log.trace("Returning dynamic property '" + name +
161                           "' for DynaBean '" + base + "' value '" +
162                           value + "'");
163             }
164             return (value);
165         } else {
166             Object JavaDoc value = resolver.getValue(base, name);
167             if (log.isTraceEnabled()) {
168                 log.trace("Delegating get of property '" + name +
169                           "' for bean '" + base + "' value '" +
170                           value + "'");
171             }
172             return (value);
173         }
174
175     }
176
177
178     /**
179      * <p>Return the value at the specified index of the specified
180      * base object.</p>
181      *
182      * @param base The base object whose property value is to be returned
183      * @param index Index of the value to return
184      *
185      * @exception IndexOutOfBoundsException if thrown by the underlying
186      * access to the base object
187      * @exception NullPointerException if <code>base</code>
188      * is <code>null</code>
189      * @exception PropertyNotFoundException if some other exception occurs
190      */

191     public Object JavaDoc getValue(Object JavaDoc base, int index)
192         throws PropertyNotFoundException {
193
194         return (resolver.getValue(base, index));
195
196     }
197
198
199     /**
200      * <p>Set the specified value of the property with the specified name on
201      * the specified base object.</p>
202      *
203      * @param base The base object whose property value is to be set
204      * @param name Name of the property to be set
205      * @param value Value of the property to be set
206      *
207      * @exception NullPointerException if <code>base</code> or
208      * <code>name</code> is <code>null</code>
209      * @exception PropertyNotFoundException if the specified property name
210      * does not exist, or is not writeable
211      */

212     public void setValue(Object JavaDoc base, Object JavaDoc name, Object JavaDoc value)
213         throws PropertyNotFoundException {
214
215         if ((base == null) || (name == null)) {
216             throw new NullPointerException JavaDoc();
217         } else if ((base instanceof DynaActionForm) &&
218                    ("map".equals(name))) {
219             throw new PropertyNotFoundException(name.toString());
220         } else if (base instanceof DynaBean) {
221             if (log.isTraceEnabled()) {
222                 log.trace("setting dynamic property '" + name +
223                           "' for DynaBean '" + base +
224                           "' to '" + value + "'");
225             }
226             if (getDynaProperty((DynaBean) base, name.toString()) == null) {
227                 throw new PropertyNotFoundException(name.toString());
228             }
229             ((DynaBean) base).set(name.toString(), value);
230         } else {
231             if (log.isTraceEnabled()) {
232                 log.trace("Delegating set of property '" + name +
233                           "' for bean '" + base + "' to value '" +
234                           value + "'");
235             }
236             resolver.setValue(base, name, value);
237         }
238
239     }
240
241
242     /**
243      * <p>Set the value at the specified index of the specified
244      * base object.</p>
245      *
246      * @param base The base object whose property value is to be set
247      * @param index Index of the value to set
248      * @param value Value to be set
249      *
250      * @exception IndexOutOfBoundsException if thrown by the underlying
251      * access to the base object
252      * @exception NullPointerException if <code>base</code>
253      * is <code>null</code>
254      * @exception PropertyNotFoundException if some other exception occurs
255      */

256     public void setValue(Object JavaDoc base, int index, Object JavaDoc value)
257         throws PropertyNotFoundException {
258
259         resolver.setValue(base, index, value);
260
261     }
262
263
264     /**
265      * <p>Return <code>true</code> if the specified property of the specified
266      * base object is known to be immutable; otherwise, return
267      * <code>false</code>.</p>
268      *
269      * @param base The base object whose property is to analyzed
270      * @param name Name of the property to be analyzed
271      *
272      * @exception NullPointerException if <code>base</code> or
273      * <code>name</code> is <code>null</code>
274      * @exception PropertyNotFoundException if the specified property name
275      * does not exist
276      */

277     public boolean isReadOnly(Object JavaDoc base, Object JavaDoc name)
278         throws PropertyNotFoundException {
279
280         if ((base == null) || (name == null)) {
281             throw new NullPointerException JavaDoc();
282         } else if ((base instanceof DynaActionForm) &&
283                    ("map".equals(name))) {
284             return (true);
285         } else if (base instanceof DynaBean) {
286             if (getDynaProperty((DynaBean) base, name.toString()) == null) {
287                 throw new PropertyNotFoundException(name.toString());
288             }
289             return (false);
290         } else {
291             return (resolver.isReadOnly(base, name.toString()));
292         }
293
294     }
295
296
297     /**
298      * <p>Return <code>true</code> if the value at the specified index of
299      * the specified base object is known to be immutable; otherwise,
300      * return <code>false</code>.</p>
301      *
302      * @param base The base object whose property is to analyzed
303      * @param index Index of the value whose type is to be returned
304      *
305      * @exception IndexOutOfBoundsException if thrown by the underlying
306      * accessed to the indexed property
307      * @exception NullPointerException if <code>base</code>
308      * is <code>null</code>
309      * @exception PropertyNotFoundException if some other exception occurs
310      */

311     public boolean isReadOnly(Object JavaDoc base, int index)
312         throws PropertyNotFoundException {
313
314         return (resolver.isReadOnly(base, index));
315
316     }
317
318
319     /**
320      * <p>Return the <code>java.lang.Class</code> representing the type of
321      * the specified property of the specified base object, if it can be
322      * determined; otherwise return <code>null</code>.</p>
323      *
324      * @param base The base object whose property is to analyzed
325      * @param name Name of the property to be analyzed
326      *
327      * @exception NullPointerException if <code>base</code> or
328      * <code>name</code> is <code>null</code>
329      * @exception PropertyNotFoundException if the specified property name
330      * does not exist
331      */

332     public Class JavaDoc getType(Object JavaDoc base, Object JavaDoc name)
333         throws PropertyNotFoundException {
334
335         if ((base == null) || (name == null)) {
336             throw new NullPointerException JavaDoc();
337         } else if ((base instanceof DynaActionForm) &&
338                    ("map".equals(name))) {
339             return (Map JavaDoc.class);
340         } else if (base instanceof DynaBean) {
341             DynaProperty dynaProperty =
342                 getDynaProperty((DynaBean) base, name.toString());
343             if (dynaProperty != null) {
344                 return (dynaProperty.getType());
345             } else {
346                 throw new PropertyNotFoundException(name.toString());
347             }
348         } else {
349             return (resolver.getType(base, name));
350         }
351     }
352
353
354     /**
355      * <p>Return the <code>java.lang.Class</code> representing the type of
356      * value at the specified index of the specified base object, or
357      * <code>null</code> if this value is <code>null</code>.</p>
358      *
359      * @param base The base object whose property is to analyzed
360      * @param index Index of the value whose type is to be returned
361      *
362      * @exception IndexOutOfBoundsException if thrown by the underlying
363      * accessed to the indexed property
364      * @exception NullPointerException if <code>base</code>
365      * is <code>null</code>
366      * @exception PropertyNotFoundException if some other exception occurs
367      */

368     public Class JavaDoc getType(Object JavaDoc base, int index)
369         throws PropertyNotFoundException {
370
371         return (resolver.getType(base, index));
372
373     }
374
375
376     // -------------------------------------------------------- Private Methods
377

378
379     /**
380      * <p>Return the <code>DynaProperty</code> describing the specified
381      * property of the specified <code>DynaBean</code>, or <code>null</code>
382      * if there is no such property defined on the underlying
383      * <code>DynaClass</code>.</p>
384      *
385      * @param bean <code>DynaBean</code> to be checked
386      * @param name Name of the property to be checked
387      */

388     private DynaProperty getDynaProperty(DynaBean bean, String JavaDoc name)
389         throws PropertyNotFoundException {
390
391         DynaProperty dynaProperty = null;
392         try {
393             dynaProperty = bean.getDynaClass().getDynaProperty(name);
394         } catch (IllegalArgumentException JavaDoc e) {
395             ;
396         }
397         return (dynaProperty);
398
399     }
400
401
402
403
404 }
405
Popular Tags