Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  // Copyright 2004, 2005 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
 package org.apache.tapestry.enhance;
 
 import  org.apache.hivemind.ApplicationRuntimeException;
 import  org.apache.hivemind.Location;
 import  org.apache.hivemind.service.ClassFabUtils;
 import  org.apache.hivemind.service.MethodSignature;
 import  org.apache.hivemind.util.Defense;
 
 import java.util.Map;

Convienience methods needed by various parts of the enhancement subsystem.

Author(s):
Howard M. Lewis Ship
Since:
4.0
 
 public final class EnhanceUtils
 {
     public static final MethodSignature FINISH_LOAD_SIGNATURE = new MethodSignature(void.class,
             "finishLoad"new Class[]
             { IRequestCycle.classIPageLoader.classIComponentSpecification.class }, null);
 
     public static final MethodSignature PAGE_DETACHED_SIGNATURE = new MethodSignature(void.class,
             "pageDetached"new Class[]
             { PageEvent.class }, null);
 
     public static final MethodSignature CLEANUP_AFTER_RENDER_SIGNATURE = new MethodSignature(
             void.class"cleanupAfterRender"new Class[]
             { IRequestCycle.class }, null);
    
    
Used to unwrap primitive types inside the accessor method. In each case, the binding is in a variable named "binding", and {0} will be the actual type of the property. The Map is keyed on the primtive type.
 
 
     private static Map _unwrappers = new HashMap();
 
     static
     {
         .put(boolean.class"toBoolean");
         .put(byte.class"toByte");
         .put(char.class"toChar");
         .put(short.class"toShort");
         .put(int.class"toInt");
         .put(long.class"toLong");
         .put(float.class"toFloat");
         .put(double.class"toDouble");
     }
     
     /* defeat instantiation */
     private EnhanceUtils() { }
     
     public static String createMutatorMethodName(String propertyName)
     {
         return "set" + upcase(propertyName);
     }
 
     public static String createAccessorMethodName(String propertyName)
     {
         return "get" + upcase(propertyName);
     }
 
     private static String upcase(String name)
     {
         return name.substring(0, 1).toUpperCase() + name.substring(1);
     }
 
     public static void createSimpleAccessor(EnhancementOperation opString fieldName,
             String propertyNameClass propertyType, Location location)
     {
         String methodName = op.getAccessorMethodName(propertyName);
         
         op.addMethod.new MethodSignature(propertyTypemethodNamenullnull),
                 "return " + fieldName + ";"location);
     }
 
     public static void createSimpleMutator(EnhancementOperation opString fieldName,
            String propertyNameClass propertyType, Location location)
    {
        String methodName = createMutatorMethodName(propertyName);
        op.addMethod(.new MethodSignature(void.classmethodName
                new Class[] { propertyType }, null), fieldName + " = $1;"location);
    }

    
Returns the correct class for a property to be enhanced into a class. If a type name is non-null, then it is converted to a Class. If the class being enhanced defines a property, then the type must be an exact match (this is largely a holdover from Tapestry 3.0, where the type had to be provided in the specification). If the type name is null, then the value returned is the type of the existing property (if such a property exists), or java.lang.Object is no property exists.

Parameters:
op the enhancement operation, which provides most of this logic
propertyName the name of the property (the property may or may not exist)
definedTypeName the type indicated for the property, may be null to make the return value match the type of an existing property.
    public static Class extractPropertyType(EnhancementOperation opString propertyNameString definedTypeName)
    {
        return extractPropertyType(oppropertyNamedefinedTypeNamefalse);
    }
    
    
Does the same thing as extractPropertyType(EnhancementOperation, String, String), with the added knowledge of knowing whether or not the type is generic and thus skips over type validation operations as generic type checking can't be safely done in this jre 1.4 compatible section of the codebase.

Parameters:
op the enhancement operation, which provides most of this logic
propertyName the name of the property (the property may or may not exist)
definedTypeName the type indicated for the property, may be null to make the return value match the type of an existing property.
isGeneric Whether or not the type was previously discoverd and found to be generic, if true type validation is skipped.
    
    public static Class extractPropertyType(EnhancementOperation opString propertyName
            String definedTypeNameboolean isGeneric)
    {
        Defense.notNull(op"op");
        Defense.notNull(propertyName"propertyName");
        
        if (definedTypeName != null)
        {
            Class propertyType = op.convertTypeName(definedTypeName);
            
            if (!isGeneric)
                op.validateProperty(propertyNamepropertyType);
            
            return propertyType;
        }
        
        Class propertyType = op.getPropertyType(propertyName);
        return propertyType == null ? Object.class : propertyType;
    }
    // The following methods are actually invoked from fabricated methods in
    // enhanced classes.
    public static boolean toBoolean(IBinding binding)
    {
        Boolean wrapped = (Booleanbinding.getObject(Boolean.class);
        return wrapped == null ? false : wrapped.booleanValue();
    }
    public static byte toByte(IBinding binding)
    {
        Byte wrapped = (Bytebinding.getObject(Byte.class);
        return wrapped == null ? 0 : wrapped.byteValue();
    }
    public static char toChar(IBinding binding)
    {
        Character wrapped = (Characterbinding.getObject(Character.class);
        return wrapped == null ? 0 : wrapped.charValue();
    }
    public static short toShort(IBinding binding)
    {
        Short wrapped = (Shortbinding.getObject(Short.class);
        return wrapped == null ? 0 : wrapped.shortValue();
    }
    public static int toInt(IBinding binding)
    {
        Integer wrapped = (Integerbinding.getObject(Integer.class);
        return wrapped == null ? 0 : wrapped.intValue();
    }
    public static long toLong(IBinding binding)
    {
        Long wrapped = (Longbinding.getObject(Long.class);
        return wrapped == null ? 0 : wrapped.longValue();
    }
    public static float toFloat(IBinding binding)
    {
        Float wrapped = (Floatbinding.getObject(Float.class);
        return wrapped == null ? 0.0f : wrapped.floatValue();
    }
    public static double toDouble(IBinding binding)
    {
        Double wrapped = (Doublebinding.getObject(Double.class);
        return wrapped == null ? 0.0d : wrapped.doubleValue();
    }

    
Returns the name of the static method, within EnhanceUtils, used to unwrap a binding to a primitive type. Returns null if the type is not a primitve.
    public static String getUnwrapperMethodName(Class type)
    {
        Defense.notNull(type"type");
        return (String.get(type);
    }

    
Builds a Javassist expression for unwrapping a binding's value to a type (either primitive or a class type).

Parameters:
op the enhancement operation
bindingName the name of the field (or an expression) that will evaluate to the binding from which a value will be extracted.
valueType the type of value to be extracted from the binding.
    public static String createUnwrapExpression(EnhancementOperation opString bindingNameClass valueType)
    {
        Defense.notNull(op"op");
        Defense.notNull(bindingName"bindingName");
        Defense.notNull(valueType"valueType");
        StringBuffer buffer = new StringBuffer();
        String unwrapper = getUnwrapperMethodName(valueType);
        if (unwrapper == null)
        {
            String propertyTypeRef = op.getClassReference(valueType);
            buffer.append("(");
            buffer.append(ClassFabUtils.getJavaClassName(valueType));
            buffer.append(") ");
            buffer.append(bindingName);
            buffer.append(".getObject(");
            buffer.append(propertyTypeRef);
            buffer.append(")");
        }
        else
        {
            buffer.append(EnhanceUtils.class.getName());
            buffer.append(".");
            buffer.append(unwrapper);
            buffer.append("(");
            buffer.append(bindingName);
            buffer.append(")");
        }
        return buffer.toString();
    }
    
    
Verifies that a property type can be assigned a particular type of value.

Parameters:
op the enhancement operation
propertyName the name of the property to check
requiredType the type of value that will be assigned to the property
Returns:
the property type, or java.lang.Object if the class does not define the property
    public static Class verifyPropertyType(EnhancementOperation opString propertyName,
            Class requiredType)
    {
        Defense.notNull(op"op");
        Defense.notNull(propertyName"propertyName");
        Defense.notNull(requiredType"requiredType");
        Class propertyType = op.getPropertyType(propertyName);
        // When the property type is not defined, it will end up being
        if (propertyType == null)
            return Object.class;
        // Make sure that an object of the required type is assignable
        // to the property type.
        if (!propertyType.isAssignableFrom(requiredType))
            throw new ApplicationRuntimeException(EnhanceMessages.wrongTypeForProperty(
                    propertyName,
                    propertyType,
                    requiredType));
        return propertyType;
    }
    
    
Determines whether or not the specified class type is elligable for proxying. This generally means it needs a default constructor, can't be final / primitive / array.

Parameters:
type The class to check for proxying elligibility.
Returns:
True if the type can be proxied, false otherwise.
    public static boolean canProxyPropertyType(Class type)
    {
        // if it's already enhanced it must be by someone else
        
        if (type.isInterface())
            return true;
        
        if (!hasEmptyConstructor(type))
            return false;
        
        if (type.isArray() || type.isPrimitive() || Modifier.isFinal(type.getModifiers()) || Object.class == type)
            return false;
        
        return true;
    }
    
    
Checks if the specified class type has an empty constructor.

Parameters:
type The class to check, can't be null.
Returns:
True if a no args constructor exists.
    public static boolean hasEmptyConstructor(Class type)
    {
        Defense.notNull(type"type");
        
        try {
            
            return type.getConstructor(null) != null;
        } catch (Throwable t) {
            return false;
        }
    }
New to GrepCode? Check out our FAQ X