001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.enhance; 016 017 import java.util.List; 018 019 import org.apache.hivemind.Location; 020 import org.apache.hivemind.service.MethodSignature; 021 022 /** 023 * A process object representing enhancements to a component class. The operation is passed to 024 * {@link org.apache.tapestry.enhance.EnhancementWorker}objects that perform enhancements. 025 * 026 * @author Howard M. Lewis Ship 027 * @since 4.0 028 */ 029 public interface EnhancementOperation 030 { 031 /** 032 * Claims a property. Most enhancements are concerned with adding properties. Some enhancement 033 * workers exist to fill in defaults, and they need to know what properties have already been 034 * spoken for by eariler enhancement works. 035 * 036 * @throws org.apache.hivemind.ApplicationRuntimeException 037 * if the property was previously claimed 038 */ 039 040 public void claimProperty(String propertyName); 041 042 /** 043 * Claims a property as read-only. This will check to see if the property has an abstract setter 044 * method. 045 * 046 * @throws org.apache.hivemind.ApplicationRuntimeException 047 * if the property was previously claimed, or if the property includes an accessor 048 * method. 049 */ 050 051 public void claimReadonlyProperty(String propertyName); 052 053 /** 054 * Returns a list of the names of existing properties that are not claimed and which have 055 * abstract accessor methods. 056 */ 057 058 public List findUnclaimedAbstractProperties(); 059 060 /** 061 * Adds a field to the enhanced class; the field will be private and use the provided name and 062 * type. 063 */ 064 065 public void addField(String name, Class type); 066 067 /** 068 * Adds a field containing an initial value, which is injected into the class via its fabricated 069 * constructor. This method may be called multiple times with the same value and will return the 070 * same variable name (an identity map is kept internally). 071 * 072 * @param fieldName 073 * The default name for the field, used if a new field (and contructor argument) is 074 * being created. Only used if a field for the value doesn't exist. 075 * @param fieldType 076 * The type of the field to be created. 077 * @param value 078 * the value to be referenced, which may not be null 079 * @return the name of the field containing the value. This may or may not match fieldName. The 080 * provided fieldName may be modified to prevent naming conflicts. 081 */ 082 083 public String addInjectedField(String fieldName, Class fieldType, Object value); 084 085 /** 086 * Converts a type name (an object class name, a primtive name, or an array) into the 087 * corresponding Class object. 088 */ 089 090 public Class convertTypeName(String type); 091 092 /** 093 * Confirms that the named property either doesn't exist (in the component base class), or that 094 * the type of the property exactly matches the indicated type. 095 */ 096 097 public void validateProperty(String name, Class expectedType); 098 099 /** 100 * Returns the name of the accessor method for the given property (if it exists in the component 101 * base class), or fabricates a new name if it does not. 102 */ 103 104 public String getAccessorMethodName(String propertyName); 105 106 /** 107 * Adds a method to the enhanced class. 108 * 109 * @param modifier 110 * as defined by {@link java.lang.reflect.Modifier}, typically 111 * {@link java.lang.reflect.Modifier#PUBLIC} 112 * @param sig 113 * the method signature (defining name, return type, etc.) 114 * @param methodBody 115 * a Javassist code snippet for the method body 116 * @param location 117 * a location used to identify "why" the method was added; the location may later be 118 * used to describe conflicts. May not be null. 119 */ 120 public void addMethod(int modifier, MethodSignature sig, String methodBody, Location location); 121 122 /** 123 * Returns the base component class, as defined in the specification (or defaulted). An enhaced 124 * subclass of the component class will usually be created. 125 */ 126 public Class getBaseClass(); 127 128 /** 129 * Returns a reference to a particular class. This will, effectively, by the name of a private 130 * field. 131 */ 132 133 public String getClassReference(Class clazz); 134 135 /** 136 * Returns the type of an existing property of the base component class. If the property does 137 * not exist, then returns null. 138 */ 139 140 public Class getPropertyType(String name); 141 142 /** 143 * Allows for a kind of distributed construction of a particular method, within a particular 144 * interface. Code can be appended to the method's implementation throughout the course of the 145 * enhancement operation. When the enhanced class is finialized, the method is added with 146 * whatever contents are in its body. If the base class implements the method, then the method 147 * body will include an initial call to that implementation. 148 * <p> 149 * At this time, this works best for void methods (since there isn't an easy way to ensure code 150 * would be inserted before a final return statement). 151 * 152 * @param interfaceClass 153 * the interface containing the method. If the base class does not implement the 154 * interface, then the enhanced class will have the interface added. 155 * @param methodSignature 156 * the signature of the method to be added. 157 * @param code 158 * the Javassist markup to be added to the body of the method. 159 */ 160 public void extendMethodImplementation(Class interfaceClass, MethodSignature methodSignature, 161 String code); 162 163 /** 164 * Returns true if the class implements the specified interface. Checks the base class (as 165 * identified in the specification), but <em>also</em> accounts for any additional interfaces 166 * that may be added by {@link #extendMethodImplementation(Class, MethodSignature, String)}. 167 */ 168 169 public boolean implementsInterface(Class interfaceClass); 170 }