KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > lang > MetaMethod


1 /*
2  * $Id: MetaMethod.java,v 1.14 2004/07/10 03:31:36 bran Exp $
3  *
4  * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5  *
6  * Redistribution and use of this software and associated documentation
7  * ("Software"), with or without modification, are permitted provided that the
8  * following conditions are met:
9  * 1. Redistributions of source code must retain copyright statements and
10  * notices. Redistributions must also contain a copy of this document.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. The name "groovy" must not be used to endorse or promote products
15  * derived from this Software without prior written permission of The Codehaus.
16  * For written permission, please contact info@codehaus.org.
17  * 4. Products derived from this Software may not be called "groovy" nor may
18  * "groovy" appear in their names without prior written permission of The
19  * Codehaus. "groovy" is a registered trademark of The Codehaus.
20  * 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
23  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
26  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32  * DAMAGE.
33  *
34  */

35 package groovy.lang;
36
37 import java.lang.reflect.Method JavaDoc;
38 import java.lang.reflect.Modifier JavaDoc;
39 import java.security.AccessController JavaDoc;
40 import java.security.PrivilegedAction JavaDoc;
41 import java.util.logging.Logger JavaDoc;
42
43 import org.codehaus.groovy.runtime.InvokerHelper;
44 import org.codehaus.groovy.runtime.Reflector;
45
46 /**
47  * Represents a Method on a Java object a little like {@link java.lang.reflect.Method}
48  * except without using reflection to invoke the method
49  *
50  * @author <a HREF="mailto:james@coredevelopers.net">James Strachan</a>
51  * @version $Revision: 1.14 $
52  */

53 public class MetaMethod implements Cloneable JavaDoc {
54
55     private static final Logger JavaDoc log = Logger.getLogger(MetaMethod.class.getName());
56
57     private String JavaDoc name;
58     private Class JavaDoc declaringClass;
59     private Class JavaDoc interfaceClass;
60     private Class JavaDoc[] parameterTypes;
61     private Class JavaDoc returnType;
62     private int modifiers;
63     private Reflector reflector;
64     private int methodIndex;
65     private Method JavaDoc method;
66
67     public MetaMethod(String JavaDoc name, Class JavaDoc declaringClass, Class JavaDoc[] parameterTypes, Class JavaDoc returnType, int modifiers) {
68         this.name = name;
69         this.declaringClass = declaringClass;
70         this.parameterTypes = parameterTypes;
71         this.returnType = returnType;
72         this.modifiers = modifiers;
73     }
74
75     public MetaMethod(Method JavaDoc method) {
76         this(
77             method.getName(),
78             method.getDeclaringClass(),
79             method.getParameterTypes(),
80             method.getReturnType(),
81             method.getModifiers());
82         this.method = method;
83     }
84
85     public MetaMethod(MetaMethod metaMethod) {
86         this(metaMethod.method);
87     }
88
89     /**
90      * Checks that the given parameters are valid to call this method
91      *
92      * @param arguments
93      * @throws IllegalArgumentException if the parameters are not valid
94      */

95     public void checkParameters(Class JavaDoc[] arguments) {
96         // lets check that the argument types are valid
97
if (!MetaClass.isValidMethod(getParameterTypes(), arguments, false)) {
98             throw new IllegalArgumentException JavaDoc(
99                     "Parameters to method: "
100                     + getName()
101                     + " do not match types: "
102                     + InvokerHelper.toString(getParameterTypes())
103                     + " for arguments: "
104                     + InvokerHelper.toString(arguments));
105         }
106     }
107     
108     public Object JavaDoc invoke(Object JavaDoc object, Object JavaDoc[] arguments) throws Exception JavaDoc {
109         if (reflector != null) {
110             return reflector.invoke(this, object, arguments);
111         }
112         else {
113             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
114                     public Object JavaDoc run() {
115                         method.setAccessible(true);
116                         return null;
117                     }
118                 });
119             return method.invoke(object, arguments);
120         }
121     }
122
123     public Class JavaDoc getDeclaringClass() {
124         return declaringClass;
125     }
126
127     public int getMethodIndex() {
128         return methodIndex;
129     }
130
131     public void setMethodIndex(int methodIndex) {
132         this.methodIndex = methodIndex;
133     }
134
135     public int getModifiers() {
136         return modifiers;
137     }
138
139     public String JavaDoc getName() {
140         return name;
141     }
142
143     public Class JavaDoc[] getParameterTypes() {
144         return parameterTypes;
145     }
146
147     public Class JavaDoc getReturnType() {
148         return returnType;
149     }
150
151     public Reflector getReflector() {
152         return reflector;
153     }
154
155     public void setReflector(Reflector reflector) {
156         this.reflector = reflector;
157     }
158
159     public boolean isMethod(Method JavaDoc method) {
160         return name.equals(method.getName())
161             && modifiers == method.getModifiers()
162             && returnType.equals(method.getReturnType())
163             && equal(parameterTypes, method.getParameterTypes());
164     }
165
166     protected boolean equal(Class JavaDoc[] a, Class JavaDoc[] b) {
167         if (a.length == b.length) {
168             for (int i = 0, size = a.length; i < size; i++) {
169                 if (!a[i].equals(b[i])) {
170                     return false;
171                 }
172             }
173             return true;
174         }
175         return false;
176     }
177
178     public String JavaDoc toString() {
179         return super.toString()
180             + "[name: "
181             + name
182             + " params: "
183             + InvokerHelper.toString(parameterTypes)
184             + " returns: "
185             + returnType
186             + " owner: "
187             + declaringClass
188             + "]";
189     }
190
191     public Object JavaDoc clone() {
192         try {
193             return super.clone();
194         }
195         catch (CloneNotSupportedException JavaDoc e) {
196             throw new GroovyRuntimeException("This should never happen", e);
197         }
198     }
199
200     public boolean isStatic() {
201         return (modifiers & Modifier.STATIC) != 0;
202     }
203
204     public boolean isPrivate() {
205         return (modifiers & Modifier.PRIVATE) != 0;
206     }
207
208     public boolean isProtected() {
209         return (modifiers & Modifier.PROTECTED) != 0;
210     }
211
212     public boolean isPublic() {
213         return (modifiers & Modifier.PUBLIC) != 0;
214     }
215
216     /**
217      * @return true if the given method has the same name, parameters, return type
218      * and modifiers but may be defined on another type
219      */

220     public boolean isSame(MetaMethod method) {
221         return name.equals(method.getName())
222             && compatibleModifiers(modifiers, method.getModifiers())
223             && returnType.equals(method.getReturnType())
224             && equal(parameterTypes, method.getParameterTypes());
225     }
226
227     protected boolean compatibleModifiers(int modifiersA, int modifiersB) {
228         int mask = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC | Modifier.STATIC;
229         return (modifiersA & mask) == (modifiersB & mask);
230     }
231
232     public Class JavaDoc getInterfaceClass() {
233         return interfaceClass;
234     }
235
236     public void setInterfaceClass(Class JavaDoc interfaceClass) {
237         this.interfaceClass = interfaceClass;
238     }
239
240     public boolean isCacheable() {
241         return true;
242     }
243
244 }
245
Popular Tags