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 }