Clover coverage report - Code Coverage for tapestry release 4.0-beta-2
Coverage timestamp: Sat Jul 9 2005 22:02:17 EDT
file stats: LOC: 298   Methods: 17
NCLOC: 169   Classes: 1
30 day Evaluation License registered to hlship@comcast.net Your 30 day evaluation period has expired. Please visit http://www.cenqua.com to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
EnhanceUtils.java 100% 85.9% 70.6% 84.7%
coverage coverage
 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;
 18    import java.util.HashMap;
 19    import java.util.Map;
 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[]
 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[]
 45    { PageEvent.class }, null);
 46   
 47    public static final MethodSignature CLEANUP_AFTER_RENDER_SIGNATURE = new MethodSignature(
 48    void.class, "cleanupAfterRender", new Class[]
 49    { IRequestCycle.class }, null);
 50   
 51  2549 public static String createMutatorMethodName(String propertyName)
 52    {
 53  2549 return "set" + upcase(propertyName);
 54    }
 55   
 56  561 public static String createAccessorMethodName(String propertyName)
 57    {
 58  561 return "get" + upcase(propertyName);
 59    }
 60   
 61  3110 private static String upcase(String name)
 62    {
 63  3110 return name.substring(0, 1).toUpperCase() + name.substring(1);
 64    }
 65   
 66  1897 public static void createSimpleAccessor(EnhancementOperation op, String fieldName,
 67    String propertyName, Class propertyType)
 68    {
 69  1897 String methodName = op.getAccessorMethodName(propertyName);
 70   
 71  1897 op.addMethod(
 72    Modifier.PUBLIC,
 73    new MethodSignature(propertyType, methodName, null, null),
 74    "return " + fieldName + ";");
 75    }
 76   
 77  1342 public static void createSimpleMutator(EnhancementOperation op, String fieldName,
 78    String propertyName, Class propertyType)
 79    {
 80  1342 String methodName = createMutatorMethodName(propertyName);
 81   
 82  1342 op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, methodName, new Class[]
 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  1484 public static Class extractPropertyType(EnhancementOperation op, String propertyName,
 104    String definedTypeName)
 105    {
 106  1484 Defense.notNull(op, "op");
 107  1484 Defense.notNull(propertyName, "propertyName");
 108   
 109  1484 if (definedTypeName != null)
 110    {
 111  92 Class propertyType = op.convertTypeName(definedTypeName);
 112   
 113  90 op.validateProperty(propertyName, propertyType);
 114   
 115  90 return propertyType;
 116    }
 117   
 118  1392 Class propertyType = op.getPropertyType(propertyName);
 119   
 120  1392 return propertyType == null ? Object.class : propertyType;
 121    }
 122   
 123    // The following methods are actually invoked from fabricated methods in
 124    // enhanced classes.
 125   
 126  280 public static boolean toBoolean(IBinding binding)
 127    {
 128  280 Boolean wrapped = (Boolean) binding.getObject(Boolean.class);
 129   
 130  279 return wrapped.booleanValue();
 131    }
 132   
 133  0 public static byte toByte(IBinding binding)
 134    {
 135  0 Byte wrapped = (Byte) binding.getObject(Byte.class);
 136   
 137  0 return wrapped.byteValue();
 138    }
 139   
 140  0 public static char toChar(IBinding binding)
 141    {
 142  0 Character wrapped = (Character) binding.getObject(Character.class);
 143   
 144  0 return wrapped.charValue();
 145    }
 146   
 147  0 public static short toShort(IBinding binding)
 148    {
 149  0 Short wrapped = (Short) binding.getObject(Short.class);
 150   
 151  0 return wrapped.shortValue();
 152    }
 153   
 154  10 public static int toInt(IBinding binding)
 155    {
 156  10 Integer wrapped = (Integer) binding.getObject(Integer.class);
 157   
 158  10 return wrapped.intValue();
 159    }
 160   
 161  0 public static long toLong(IBinding binding)
 162    {
 163  0 Long wrapped = (Long) binding.getObject(Long.class);
 164   
 165  0 return wrapped.longValue();
 166    }
 167   
 168  0 public static float toFloat(IBinding binding)
 169    {
 170  0 Float wrapped = (Float) binding.getObject(Float.class);
 171   
 172  0 return wrapped.floatValue();
 173    }
 174   
 175  2 public static double toDouble(IBinding binding)
 176    {
 177  2 Double wrapped = (Double) binding.getObject(Double.class);
 178   
 179  2 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 _unwrappers = new HashMap();
 189   
 190    static
 191    {
 192  1 _unwrappers.put(boolean.class, "toBoolean");
 193  1 _unwrappers.put(byte.class, "toByte");
 194  1 _unwrappers.put(char.class, "toChar");
 195  1 _unwrappers.put(short.class, "toShort");
 196  1 _unwrappers.put(int.class, "toInt");
 197  1 _unwrappers.put(long.class, "toLong");
 198  1 _unwrappers.put(float.class, "toFloat");
 199  1 _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  1096 public static String getUnwrapperMethodName(Class type)
 208    {
 209  1096 Defense.notNull(type, "type");
 210   
 211  1096 return (String) _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  1096 public static String createUnwrapExpression(EnhancementOperation op, String bindingName,
 228    Class valueType)
 229    {
 230  1096 Defense.notNull(op, "op");
 231  1096 Defense.notNull(bindingName, "bindingName");
 232  1096 Defense.notNull(valueType, "valueType");
 233   
 234  1096 StringBuffer buffer = new StringBuffer();
 235   
 236  1096 String unwrapper = getUnwrapperMethodName(valueType);
 237   
 238  1096 if (unwrapper == null)
 239    {
 240  803 String propertyTypeRef = op.getClassReference(valueType);
 241   
 242  803 buffer.append("(");
 243  803 buffer.append(ClassFabUtils.getJavaClassName(valueType));
 244  803 buffer.append(") ");
 245  803 buffer.append(bindingName);
 246  803 buffer.append(".getObject(");
 247  803 buffer.append(propertyTypeRef);
 248  803 buffer.append(")");
 249    }
 250    else
 251    {
 252  293 buffer.append(EnhanceUtils.class.getName());
 253  293 buffer.append(".");
 254  293 buffer.append(unwrapper);
 255  293 buffer.append("(");
 256  293 buffer.append(bindingName);
 257  293 buffer.append(")");
 258    }
 259   
 260  1096 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  5 public static Class verifyPropertyType(EnhancementOperation op, String propertyName,
 275    Class requiredType)
 276    {
 277  5 Defense.notNull(op, "op");
 278  5 Defense.notNull(propertyName, "propertyName");
 279  5 Defense.notNull(requiredType, "requiredType");
 280   
 281  5 Class propertyType = op.getPropertyType(propertyName);
 282   
 283    // When the property type is not defined, it will end up being
 284  5 if (propertyType == null)
 285  1 return Object.class;
 286   
 287    // Make sure that an object of the required type is assignable
 288    // to the property type.
 289   
 290  4 if (!propertyType.isAssignableFrom(requiredType))
 291  1 throw new ApplicationRuntimeException(EnhanceMessages.wrongTypeForProperty(
 292    propertyName,
 293    propertyType,
 294    requiredType));
 295   
 296  3 return propertyType;
 297    }
 298    }