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 }