KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > context > BeanContext


1 /*
2  * $Id: BeanContext.java,v 1.5 2002/06/06 15:02:07 valis Exp $
3  *
4  * ===========================================================================
5  *
6  * The JGenerator Software License, Version 1.0
7  *
8  * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowlegement:
23  * "This product includes software developed by Dmitry Skavish
24  * (skavish@usa.net, http://www.flashgap.com/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The name "The JGenerator" must not be used to endorse or promote
29  * products derived from this software without prior written permission.
30  * For written permission, please contact skavish@usa.net.
31  *
32  * 5. Products derived from this software may not be called "The JGenerator"
33  * nor may "The JGenerator" appear in their names without prior written
34  * permission of Dmitry Skavish.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
40  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  *
49  */

50
51 package org.openlaszlo.iv.flash.context;
52
53 import org.apache.commons.jexl.Expression;
54 import org.apache.commons.jexl.ExpressionFactory;
55 import org.apache.commons.jexl.context.HashMapContext;
56
57 import java.util.ArrayList JavaDoc;
58 import java.util.Collection JavaDoc;
59 import java.util.List JavaDoc;
60 import java.util.ListIterator JavaDoc;
61 import java.util.Map JavaDoc;
62 import java.util.Set JavaDoc;
63
64 /**
65  * A Context that provides access to a graph of objects (beans and collections)
66  * using Jexl (JSTL expression language + extenstions) syntax.
67  *
68  * Unlike the other contexts in JGen, this is not easily creatable from a
69  * datasource, and is intended to be used where JGen is embedded in another
70  * framework.
71  *
72  * @author <a HREF="james@jamestaylor.org">James Taylor</a>
73  */

74 public class BeanContext extends GraphContext implements Map JavaDoc
75 {
76     /** Key used to store root object when building a context for a list item */
77     public static final String JavaDoc ROOT_ITEM_KEY = "root";
78
79     /** The JexlContext */
80     private HashMapContext jexlContext = new HashMapContext();
81
82     /**
83      * Creates empty context.
84      */

85     public BeanContext()
86     {
87     }
88
89     /**
90      * Creates context from specified hashtable.
91      *
92      * @param context parent context
93      * @param values Map of initial values to populate context with
94      */

95     public BeanContext( Context context, Map JavaDoc values )
96     {
97         setParent( context );
98
99         if ( values != null )
100         {
101             this.jexlContext.setVars( values );
102         }
103     }
104
105     /**
106      * Tries to resolve given string in this context as XPath expression,
107      * using JPath. If the XPath expression selects an object, the result
108      * of evaluating its 'toString' method is returned, otherwise the path
109      * is passed along to the parent context (if defined).
110      *
111      * @param path XPath/JPath expression
112      *
113      * @return String representation of result of xpath execution or result
114      * from the parent or null
115      */

116
117     public String JavaDoc getValue( String JavaDoc path )
118     {
119         // Evaluate path against our context
120

121         Object JavaDoc o = evaluatePath( path );
122
123         // If o is null, that indicates that the path expression did not
124
// select an object in the context. This is perfectly acceptable,
125
// and we pass the path to the parent context.
126

127         if ( o == null )
128         {
129             return getValueFromParent( path );
130         }
131
132         // If o was not null, we return it's string representation, which is
133
// hopefully something meaningfull. But even if it is not the default
134
// implementation of Object.toString() should give a value which will
135
// allow the user to see that something is wrong with the path or
136
// context.
137

138         else
139         {
140             return o.toString();
141         }
142     }
143
144     /**
145      * Tries to resolve given string in this context as Jexl expression.
146      * If the path expression evaluates to a non-empty list, a list of contexts
147      * corresponding to each value in that list will be returned. Otherwise
148      * the path is passed to the parent context. If there is no parent
149      * context, null is returned.
150      *
151      * The wrapping contexts will have the single element 'root' which is the
152      * object selected as a list item.
153      *
154      * @param path Jexl expression
155      *
156      * @return List of objects (wrapped in BeanContext) selected by path or
157      * result from the parent or null
158      */

159     public List JavaDoc getValueList( String JavaDoc path )
160     {
161         // Evaluate path against our context
162

163         Object JavaDoc o = evaluatePath( path );
164
165         // If o is null, that indicates that the path expression did not
166
// select an object in the context. This is perfectly acceptable,
167
// and we pass the path to the parent context.
168

169         if ( o == null )
170         {
171             return getValueListFromParent( path );
172         }
173
174         // If o is a list, we build a list of contexts for each object it
175
// contains. If o is a single object we'll just build a context list
176
// with one item.
177

178         ArrayList JavaDoc contextList = new ArrayList JavaDoc();
179
180         if ( o instanceof List JavaDoc )
181         {
182             ListIterator JavaDoc iter = ( ( List JavaDoc ) o ).listIterator();
183
184             while ( iter.hasNext() )
185             {
186                 addToContextList( iter.next(), contextList );
187             }
188         }
189         else
190         {
191             addToContextList( o, contextList );
192         }
193
194         return contextList;
195     }
196
197     /**
198      * Build a BeanContext around and object and add it to the provided list.
199      *
200      * @param o Object to add
201      * @param contextList List to add context to
202      */

203     private void addToContextList( Object JavaDoc o, List JavaDoc contextList )
204     {
205         BeanContext newContext = new BeanContext( this, null );
206
207         newContext.put( ROOT_ITEM_KEY, o );
208
209         contextList.add( newContext );
210     }
211
212     /**
213      * Evaluate a path as a Jexl expression on the contained context.
214      *
215      * @param path Expression to evaluate
216      * @return Object if found or null
217      */

218     private Object JavaDoc evaluatePath( String JavaDoc path )
219     {
220         try
221         {
222             // Parse the path into a Jexl Expression
223

224             Expression expr = ExpressionFactory.createExpression( path );
225
226             // Execute the expression against our context
227

228             Object JavaDoc o = expr.evaluate( jexlContext );
229
230             return o;
231         }
232         catch ( Exception JavaDoc e )
233         {
234             // Expression could not be parsed or evaluated as Jexl, so return
235
// null which will cause the path to be passed up to that parent
236

237             return null;
238         }
239     }
240
241     // ------------------------------ interface Map, delegate to HashMapContext
242

243     public int size()
244     {
245         return jexlContext.size();
246     }
247
248     public boolean isEmpty()
249     {
250         return jexlContext.isEmpty();
251     }
252
253     public boolean containsKey( Object JavaDoc key )
254     {
255         return jexlContext.containsKey( key );
256     }
257
258     public boolean containsValue( Object JavaDoc value )
259     {
260         return jexlContext.containsValue( value );
261     }
262
263     public Object JavaDoc get( Object JavaDoc key )
264     {
265         return jexlContext.get( key );
266     }
267
268     public Object JavaDoc put( Object JavaDoc key, Object JavaDoc value )
269     {
270         return jexlContext.put( key, value );
271     }
272
273     public Object JavaDoc remove( Object JavaDoc key )
274     {
275         return jexlContext.remove( key );
276     }
277
278     public void putAll( Map JavaDoc t )
279     {
280         jexlContext.putAll( t );
281     }
282
283     public void clear()
284     {
285         jexlContext.clear();
286     }
287
288     public Set JavaDoc keySet()
289     {
290         return jexlContext.keySet();
291     }
292
293     public Collection JavaDoc values()
294     {
295         return jexlContext.values();
296     }
297
298     public Set JavaDoc entrySet()
299     {
300         return jexlContext.entrySet();
301     }
302
303     public boolean equals( Object JavaDoc o )
304     {
305         return jexlContext.equals( o );
306     }
307
308     public int hashCode()
309     {
310         return jexlContext.hashCode();
311     }
312
313 }
314
Popular Tags