KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > enhance > EnhanceUtils


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.enhance;
16
17 import java.lang.reflect.Modifier JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.apache.hivemind.ApplicationRuntimeException;
22 import org.apache.hivemind.service.ClassFabUtils;
23 import org.apache.hivemind.service.MethodSignature;
24 import org.apache.hivemind.util.Defense;
25 import org.apache.tapestry.IBinding;
26 import org.apache.tapestry.IRequestCycle;
27 import org.apache.tapestry.engine.IPageLoader;
28 import org.apache.tapestry.event.PageEvent;
29 import org.apache.tapestry.spec.IComponentSpecification;
30
31 /**
32  * Convienience methods needed by various parts of the enhancement subsystem.
33  *
34  * @author Howard M. Lewis Ship
35  * @since 4.0
36  */

37 public class EnhanceUtils
38 {
39     public static final MethodSignature FINISH_LOAD_SIGNATURE = new MethodSignature(void.class,
40             "finishLoad", new Class JavaDoc[]
41             { IRequestCycle.class, IPageLoader.class, IComponentSpecification.class }, null);
42
43     public static final MethodSignature PAGE_DETACHED_SIGNATURE = new MethodSignature(void.class,
44             "pageDetached", new Class JavaDoc[]
45             { PageEvent.class }, null);
46
47     public static final MethodSignature CLEANUP_AFTER_RENDER_SIGNATURE = new MethodSignature(
48             void.class, "cleanupAfterRender", new Class JavaDoc[]
49             { IRequestCycle.class }, null);
50
51     public static String JavaDoc createMutatorMethodName(String JavaDoc propertyName)
52     {
53         return "set" + upcase(propertyName);
54     }
55
56     public static String JavaDoc createAccessorMethodName(String JavaDoc propertyName)
57     {
58         return "get" + upcase(propertyName);
59     }
60
61     private static String JavaDoc upcase(String JavaDoc name)
62     {
63         return name.substring(0, 1).toUpperCase() + name.substring(1);
64     }
65
66     public static void createSimpleAccessor(EnhancementOperation op, String JavaDoc fieldName,
67             String JavaDoc propertyName, Class JavaDoc propertyType)
68     {
69         String JavaDoc methodName = op.getAccessorMethodName(propertyName);
70
71         op.addMethod(
72                 Modifier.PUBLIC,
73                 new MethodSignature(propertyType, methodName, null, null),
74                 "return " + fieldName + ";");
75     }
76
77     public static void createSimpleMutator(EnhancementOperation op, String JavaDoc fieldName,
78             String JavaDoc propertyName, Class JavaDoc propertyType)
79     {
80         String JavaDoc methodName = createMutatorMethodName(propertyName);
81
82         op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, methodName, new Class JavaDoc[]
83         { propertyType }, null), fieldName + " = $1;");
84     }
85
86     /**
87      * Returns the correct class for a property to be enhanced into a class. If a type name is
88      * non-null, then it is converted to a Class. If the class being enhanced defines a property,
89      * then the type must be an exact match (this is largely a holdover from Tapestry 3.0, where the
90      * type had to be provided in the specification). If the type name is null, then the value
91      * returned is the type of the existing property (if such a property exists), or
92      * java.lang.Object is no property exists.
93      *
94      * @param op
95      * the enhancement operation, which provides most of this logic
96      * @param propertyName
97      * the name of the property (the property may or may not exist)
98      * @param definedTypeName
99      * the type indicated for the property, may be null to make the return value match
100      * the type of an existing property.
101      */

102
103     public static Class JavaDoc extractPropertyType(EnhancementOperation op, String JavaDoc propertyName,
104             String JavaDoc definedTypeName)
105     {
106         Defense.notNull(op, "op");
107         Defense.notNull(propertyName, "propertyName");
108
109         if (definedTypeName != null)
110         {
111             Class JavaDoc propertyType = op.convertTypeName(definedTypeName);
112
113             op.validateProperty(propertyName, propertyType);
114
115             return propertyType;
116         }
117
118         Class JavaDoc propertyType = op.getPropertyType(propertyName);
119
120         return propertyType == null ? Object JavaDoc.class : propertyType;
121     }
122
123     // The following methods are actually invoked from fabricated methods in
124
// enhanced classes.
125

126     public static boolean toBoolean(IBinding binding)
127     {
128         Boolean JavaDoc wrapped = (Boolean JavaDoc) binding.getObject(Boolean JavaDoc.class);
129
130         return wrapped.booleanValue();
131     }
132
133     public static byte toByte(IBinding binding)
134     {
135         Byte JavaDoc wrapped = (Byte JavaDoc) binding.getObject(Byte JavaDoc.class);
136
137         return wrapped.byteValue();
138     }
139
140     public static char toChar(IBinding binding)
141     {
142         Character JavaDoc wrapped = (Character JavaDoc) binding.getObject(Character JavaDoc.class);
143
144         return wrapped.charValue();
145     }
146
147     public static short toShort(IBinding binding)
148     {
149         Short JavaDoc wrapped = (Short JavaDoc) binding.getObject(Short JavaDoc.class);
150
151         return wrapped.shortValue();
152     }
153
154     public static int toInt(IBinding binding)
155     {
156         Integer JavaDoc wrapped = (Integer JavaDoc) binding.getObject(Integer JavaDoc.class);
157
158         return wrapped.intValue();
159     }
160
161     public static long toLong(IBinding binding)
162     {
163         Long JavaDoc wrapped = (Long JavaDoc) binding.getObject(Long JavaDoc.class);
164
165         return wrapped.longValue();
166     }
167
168     public static float toFloat(IBinding binding)
169     {
170         Float JavaDoc wrapped = (Float JavaDoc) binding.getObject(Float JavaDoc.class);
171
172         return wrapped.floatValue();
173     }
174
175     public static double toDouble(IBinding binding)
176     {
177         Double JavaDoc wrapped = (Double JavaDoc) binding.getObject(Double JavaDoc.class);
178
179         return wrapped.doubleValue();
180     }
181
182     /**
183      * Used to unwrap primitive types inside the accessor method. In each case, the binding is in a
184      * variable named "binding", and {0} will be the actual type of the property. The Map is keyed
185      * on the primtive type.
186      */

187
188     private static Map JavaDoc _unwrappers = new HashMap JavaDoc();
189
190     static
191     {
192         _unwrappers.put(boolean.class, "toBoolean");
193         _unwrappers.put(byte.class, "toByte");
194         _unwrappers.put(char.class, "toChar");
195         _unwrappers.put(short.class, "toShort");
196         _unwrappers.put(int.class, "toInt");
197         _unwrappers.put(long.class, "toLong");
198         _unwrappers.put(float.class, "toFloat");
199         _unwrappers.put(double.class, "toDouble");
200     }
201
202     /**
203      * Returns the name of the static method, within EnhanceUtils, used to unwrap a binding to a
204      * primitive type. Returns null if the type is not a primitve.
205      */

206
207     public static String JavaDoc getUnwrapperMethodName(Class JavaDoc type)
208     {
209         Defense.notNull(type, "type");
210
211         return (String JavaDoc) _unwrappers.get(type);
212     }
213
214     /**
215      * Builds a Javassist expression for unwrapping a binding's value to a type (either primitive or
216      * a class type).
217      *
218      * @param op
219      * the enhancement operation
220      * @param bindingName
221      * the name of the field (or an expression) that will evaluate to the binding from
222      * which a value will be extracted.
223      * @param valueType
224      * the type of value to be extracted from the binding.
225      */

226
227     public static String JavaDoc createUnwrapExpression(EnhancementOperation op, String JavaDoc bindingName,
228             Class JavaDoc valueType)
229     {
230         Defense.notNull(op, "op");
231         Defense.notNull(bindingName, "bindingName");
232         Defense.notNull(valueType, "valueType");
233
234         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
235
236         String JavaDoc unwrapper = getUnwrapperMethodName(valueType);
237
238         if (unwrapper == null)
239         {
240             String JavaDoc propertyTypeRef = op.getClassReference(valueType);
241
242             buffer.append("(");
243             buffer.append(ClassFabUtils.getJavaClassName(valueType));
244             buffer.append(") ");
245             buffer.append(bindingName);
246             buffer.append(".getObject(");
247             buffer.append(propertyTypeRef);
248             buffer.append(")");
249         }
250         else
251         {
252             buffer.append(EnhanceUtils.class.getName());
253             buffer.append(".");
254             buffer.append(unwrapper);
255             buffer.append("(");
256             buffer.append(bindingName);
257             buffer.append(")");
258         }
259
260         return buffer.toString();
261     }
262
263     /**
264      * Verifies that a property type can be assigned a particular type of value.
265      *
266      * @param op
267      * the enhancement operation
268      * @param propertyName
269      * the name of the property to check
270      * @param requiredType
271      * the type of value that will be assigned to the property
272      * @return the property type, or java.lang.Object if the class does not define the property
273      */

274     public static Class JavaDoc verifyPropertyType(EnhancementOperation op, String JavaDoc propertyName,
275             Class JavaDoc requiredType)
276     {
277         Defense.notNull(op, "op");
278         Defense.notNull(propertyName, "propertyName");
279         Defense.notNull(requiredType, "requiredType");
280
281         Class JavaDoc propertyType = op.getPropertyType(propertyName);
282
283         // When the property type is not defined, it will end up being
284
if (propertyType == null)
285             return Object JavaDoc.class;
286
287         // Make sure that an object of the required type is assignable
288
// to the property type.
289

290         if (!propertyType.isAssignableFrom(requiredType))
291             throw new ApplicationRuntimeException(EnhanceMessages.wrongTypeForProperty(
292                     propertyName,
293                     propertyType,
294                     requiredType));
295
296         return propertyType;
297     }
298 }
Popular Tags