KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > script > el > util > ParseUtils


1 /*
2  * Copyright 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  * $Header:$
17  */

18 package org.apache.beehive.netui.script.el.util;
19
20 import java.io.StringReader JavaDoc;
21 import java.lang.reflect.Array JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.util.HashMap JavaDoc;
24
25 import org.apache.beehive.netui.script.el.parser.NetUIELParser;
26 import org.apache.beehive.netui.script.el.NetUIVariableResolver;
27 import org.apache.beehive.netui.script.el.ParsedExpression;
28 import org.apache.beehive.netui.script.el.ExpressionParseException;
29 import org.apache.beehive.netui.script.el.parser.TokenMgrError;
30 import org.apache.beehive.netui.script.el.parser.ParseException;
31 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
32 import org.apache.beehive.netui.util.internal.cache.PropertyCache;
33 import org.apache.beehive.netui.util.type.TypeUtils;
34 import org.apache.beehive.netui.util.logging.Logger;
35
36 /**
37  *
38  */

39 public class ParseUtils {
40
41     private static final Logger LOGGER = Logger.getInstance(ParseUtils.class);
42
43     private static final HashMap JavaDoc/*<String, ParsedExpression>*/ PARSED_CACHE = new HashMap JavaDoc/*<String, ParsedExpression>*/();
44
45     /* do not construct */
46     private ParseUtils() {}
47
48     public static final ParsedExpression parse(String JavaDoc exprStr) {
49         ParsedExpression pe = (ParsedExpression) PARSED_CACHE.get(exprStr);
50
51         if(pe != null)
52             return pe;
53
54         try {
55             NetUIELParser learn = new NetUIELParser(new StringReader JavaDoc(exprStr));
56
57             ParsedExpression expr = learn.parse();
58             expr.seal();
59
60             /* infrequent; this should only happen when there is a cache miss */
61             synchronized(PARSED_CACHE) {
62                 PARSED_CACHE.put(exprStr, expr);
63             }
64
65             return expr;
66         } catch(ParseException e) {
67             String JavaDoc msg = "Error occurred parsing expression \"" + exprStr + "\".";
68             LOGGER.error(msg, e);
69             throw new ExpressionParseException(msg, e);
70         } catch(TokenMgrError tm) {
71             String JavaDoc msg = "Error occurred parsing expression \"" + exprStr + "\".";
72             LOGGER.error(msg, tm);
73             throw new ExpressionParseException(msg, tm);
74         }
75     }
76
77     public static final Object JavaDoc evaluate(String JavaDoc exprStr, NetUIVariableResolver vr) {
78         ParsedExpression expr = parse(exprStr);
79         assert expr != null;
80         return expr.evaluate(vr);
81     }
82
83     public static final void update(String JavaDoc exprStr, Object JavaDoc value, NetUIVariableResolver vr) {
84         ParsedExpression expr = parse(exprStr);
85         assert expr != null;
86         expr.update(value, vr);
87     }
88
89     public static final Class JavaDoc getPropertyType(Object JavaDoc value, String JavaDoc name, PropertyCache cache) {
90         assert value != null;
91         assert cache != null;
92
93         Class JavaDoc type = value.getClass();
94
95         Method JavaDoc m = cache.getPropertySetter(type, name);
96         if(m == null) {
97             String JavaDoc msg = "Can not find setter method for property \"" + name + "\" on object of type \"" + value.getClass() + "\".";
98             LOGGER.error(msg);
99             throw new RuntimeException JavaDoc(msg);
100         }
101         // PropertyCache guarantees that props are found and match JavaBean naming rules
102
else {
103             assert m.getParameterTypes().length == 1;
104             return m.getParameterTypes()[0];
105         }
106     }
107
108     public static final Object JavaDoc getProperty(Object JavaDoc value, String JavaDoc name, PropertyCache cache) {
109         assert value != null;
110         assert cache != null;
111
112         Class JavaDoc type = value.getClass();
113
114         Method JavaDoc m = cache.getPropertyGetter(type, name);
115         if(m != null) {
116             try {
117                 return m.invoke(value, (Object JavaDoc[])null);
118             } catch(Exception JavaDoc e) {
119                 String JavaDoc msg = "An error occurred invoking a getter for the property \"" + name + "\" on an object of type \"" + type + "\".";
120                 LOGGER.error(msg, e);
121                 throw new RuntimeException JavaDoc(msg, e);
122             }
123         }
124
125         String JavaDoc msg = "Could not find JavaBean property named \"" + name + "\" on object of type \"" + type + "\"";
126         LOGGER.error(msg);
127         throw new RuntimeException JavaDoc(msg);
128     }
129
130     public static final Object JavaDoc convertType(Object JavaDoc value, Class JavaDoc toType) {
131         assert toType != null;
132
133         try {
134             boolean sourceIsArray = false;
135
136             /* only convert String types; other Object types are already assumed to be in their target types. */
137             if(value != null && !(value instanceof String JavaDoc || (sourceIsArray = (value instanceof String JavaDoc[]))))
138                 return value;
139
140             /* for a String[], convert each item in the array into its target type and return the resulting array. */
141             if(toType.isArray()) {
142                 if(value == null)
143                     return null;
144                 else {
145                     Class JavaDoc compType = toType.getComponentType();
146
147                     String JavaDoc[] strs = null;
148                     if(value.getClass().isArray())
149                         strs = (String JavaDoc[])value;
150                     else
151                         strs = new String JavaDoc[]{(String JavaDoc)value};
152
153                     Object JavaDoc tgt = Array.newInstance(compType, strs.length);
154
155                     for(int i = 0; i < strs.length; i++) {
156                         Object JavaDoc o = null;
157                         try {
158                             /* todo: support getting the Locale here in an ExpressionContext object */
159                             o = TypeUtils.convertToObject(strs[i], compType);
160                         } catch(IllegalArgumentException JavaDoc e) {
161                             String JavaDoc msg = "Can not set Object types via expressions that are not supported by the set of registered type converters. Cause: " + e;
162                             LOGGER.error(msg, e);
163                             throw new RuntimeException JavaDoc(msg, e);
164                         }
165
166                         Array.set(tgt, i, o);
167                     }
168
169                     return tgt;
170                 }
171             }
172             // convert the String into its target type and return the result
173
else {
174                 // If the "value" is multi-valued (String[]), it needs to be converted into a single-valued object.
175
// There is no policy defined for how we do this right now, so the first one will always win when
176
// multiple expressions reference the same property. When that property is a String type, the result
177
// is an HttpServletRequest that contains a String[], and here, we'll always the String[0].
178
if(sourceIsArray) {
179                     assert value instanceof String JavaDoc[];
180                     assert Array.getLength(value) > 0 && Array.getLength(value) - 1 >= 0;
181
182                     value = Array.get(value, Array.getLength(value) - 1);
183                 }
184
185                 try {
186                     assert value == null || value instanceof String JavaDoc;
187
188                     return TypeUtils.convertToObject((String JavaDoc)value, toType);
189                 } catch(IllegalArgumentException JavaDoc e) {
190                     String JavaDoc msg = "The type \"" + toType.getName() + "\" can not be set through the NetUI expression language.";
191                     LOGGER.error(msg, e);
192                     throw new RuntimeException JavaDoc(msg, e);
193                 }
194             }
195         } catch(Exception JavaDoc e) {
196             String JavaDoc msg = "Unable to convert a value of type \"" + value.getClass() + "\" to the array element type of \"" + toType + "\". Cause: " + e;
197             LOGGER.error(msg, e);
198             throw new RuntimeException JavaDoc(msg, e);
199         }
200     }
201
202     public static String JavaDoc getContextString(String JavaDoc[] contexts) {
203         InternalStringBuilder builder = new InternalStringBuilder();
204         builder.append("[");
205         if(contexts != null) {
206             for(int i = 0; i < contexts.length; i++) {
207                 if(i > 0) builder.append(", ");
208                 builder.append(contexts[i]);
209             }
210         }
211         builder.append("]");
212         return builder.toString();
213     }
214
215     public static Throwable JavaDoc getRootCause(Throwable JavaDoc t) {
216         Throwable JavaDoc root = t;
217         while(root.getCause() != null)
218             root = root.getCause();
219         return root;
220     }
221 }
222
Popular Tags