001 /*
002 * Copyright 2005 John G. Wilson
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017
018 package groovy.lang;
019
020 import java.lang.reflect.Constructor;
021 import java.lang.reflect.Method;
022 import java.util.LinkedList;
023 import java.util.List;
024 import java.util.Map;
025 import java.util.logging.Logger;
026
027 import org.codehaus.groovy.ast.ClassNode;
028 import org.codehaus.groovy.runtime.MetaClassHelper;
029
030 /**
031 * @author John Wilson
032 *
033 */
034
035 public abstract class MetaClass {
036 protected static final Logger log = Logger.getLogger(MetaClass.class.getName());
037 protected static boolean useReflection = false;
038 public static final Object NO_METHOD_FOUND = new Object();
039
040 public static boolean isUseReflection() {
041 return MetaClass.useReflection;
042 }
043
044 /**
045 * Allows reflection to be enabled in situations where bytecode generation
046 * of method invocations causes issues.
047 *
048 * @param useReflection
049 */
050 public static void setUseReflection(boolean useReflection) {
051 MetaClass.useReflection = useReflection;
052 }
053
054 protected final Class theClass;
055
056 protected MetaClass(final Class theClass) {
057 this.theClass = theClass;
058 }
059
060 public Object invokeMethod(Object object, String methodName, Object arguments) {
061 if (arguments == null) {
062 return invokeMethod(object, methodName, MetaClassHelper.EMPTY_ARRAY);
063 }
064 if (arguments instanceof Tuple) {
065 Tuple tuple = (Tuple) arguments;
066 return invokeMethod(object, methodName, tuple.toArray());
067 }
068 if (arguments instanceof Object[]) {
069 return invokeMethod(object, methodName, (Object[])arguments);
070 }
071 else {
072 return invokeMethod(object, methodName, new Object[]{arguments});
073 }
074 }
075
076 public abstract Object invokeConstructor(Object[] arguments);
077 public abstract Object invokeMethod(Object object, String methodName, Object[] arguments);
078 public abstract Object invokeStaticMethod(Object object, String methodName, Object[] arguments);
079 public abstract Object getProperty(Object object, String property);
080 public abstract void setProperty(Object object, String property, Object newValue);
081 public abstract Object getAttribute(Object object, String attribute);
082 public abstract void setAttribute(Object object, String attribute, Object newValue);
083
084 // Possibly Temp methods
085 public abstract List getMethods();
086 protected abstract MetaMethod pickMethod(String methodName, Class[] arguments);
087 protected abstract MetaMethod pickMethod(Object object, String methodName, Object[] arguments);
088 public abstract MetaMethod retrieveMethod(Object owner, String methodName, Object[] arguments);
089 public abstract MetaMethod retrieveMethod(String methodName, Class[] arguments);
090 public abstract MetaMethod retrieveStaticMethod(String methodName, Class[] arguments);
091 public abstract Constructor retrieveConstructor(Class[] arguments);
092 protected abstract void addNewInstanceMethod(Method method);
093 protected abstract void addNewStaticMethod(Method method);
094 protected abstract void checkInitialised();
095 public abstract List getProperties();
096 public abstract void setProperties(Object bean, Map map);
097 public abstract ClassNode getClassNode();
098 public abstract List getMetaMethods();
099 public abstract Object invokeConstructorAt(Class at, Object[] arguments);
100
101 // Possibly Temp fields
102 protected List newGroovyMethodsList = new LinkedList();
103
104 }