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    }