Home » cglib-src-2.2 » net.sf.cglib.reflect » [javadoc | source]

    1   /*
    2    * Copyright 2003,2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
   10    *  Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   package net.sf.cglib.reflect;
   17   
   18   import net.sf.cglib.core;
   19   import java.lang.reflect.Constructor;
   20   import java.lang.reflect.InvocationTargetException;
   21   import java.lang.reflect.Method;
   22   import org.objectweb.asm.ClassVisitor;
   23   import org.objectweb.asm.Type;
   24   
   25   abstract public class FastClass
   26   {
   27       private Class type;
   28   
   29       protected FastClass() {
   30           throw new Error("Using the FastClass empty constructor--please report to the cglib-devel mailing list");
   31       }
   32   
   33       protected FastClass(Class type) {
   34           this.type = type;
   35       }
   36   
   37       public static FastClass create(Class type) {
   38       
   39           return create(type.getClassLoader(),type);
   40           
   41       }
   42       public static FastClass create(ClassLoader loader, Class type) {
   43           Generator gen = new Generator();
   44           gen.setType(type);
   45           gen.setClassLoader(loader);
   46           return gen.create();
   47       }
   48   
   49       public static class Generator extends AbstractClassGenerator
   50       {
   51           private static final Source SOURCE = new Source(FastClass.class.getName());
   52           private Class type;
   53           
   54           public Generator() {
   55               super(SOURCE);
   56           }
   57   
   58           public void setType(Class type) {
   59               this.type = type;
   60           }
   61           
   62           public FastClass create() {
   63               setNamePrefix(type.getName());
   64               return (FastClass)super.create(type.getName());
   65           }
   66   
   67           protected ClassLoader getDefaultClassLoader() {
   68               return type.getClassLoader();
   69           }
   70   
   71           public void generateClass(ClassVisitor v) throws Exception {
   72               new FastClassEmitter(v, getClassName(), type);
   73           }
   74   
   75           protected Object firstInstance(Class type) {
   76               return ReflectUtils.newInstance(type,
   77                                               new Class[]{ Class.class },
   78                                               new Object[]{ this.type });
   79           }
   80   
   81           protected Object nextInstance(Object instance) {
   82               return instance;
   83           }
   84       }
   85       
   86       public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) throws InvocationTargetException {
   87           return invoke(getIndex(name, parameterTypes), obj, args);
   88       }
   89   
   90       public Object newInstance() throws InvocationTargetException {
   91           return newInstance(getIndex(Constants.EMPTY_CLASS_ARRAY), null);
   92       }
   93   
   94       public Object newInstance(Class[] parameterTypes, Object[] args) throws InvocationTargetException {
   95           return newInstance(getIndex(parameterTypes), args);
   96       }
   97       
   98       public FastMethod getMethod(Method method) {
   99           return new FastMethod(this, method);
  100       }
  101   
  102       public FastConstructor getConstructor(Constructor constructor) {
  103           return new FastConstructor(this, constructor);
  104       }
  105   
  106       public FastMethod getMethod(String name, Class[] parameterTypes) {
  107           try {
  108               return getMethod(type.getMethod(name, parameterTypes));
  109           } catch (NoSuchMethodException e) {
  110               throw new NoSuchMethodError(e.getMessage());
  111           }
  112       }
  113   
  114       public FastConstructor getConstructor(Class[] parameterTypes) {
  115           try {
  116               return getConstructor(type.getConstructor(parameterTypes));
  117           } catch (NoSuchMethodException e) {
  118               throw new NoSuchMethodError(e.getMessage());
  119           }
  120       }
  121   
  122       public String getName() {
  123           return type.getName();
  124       }
  125   
  126       public Class getJavaClass() {
  127           return type;
  128       }
  129   
  130       public String toString() {
  131           return type.toString();
  132       }
  133   
  134       public int hashCode() {
  135           return type.hashCode();
  136       }
  137   
  138       public boolean equals(Object o) {
  139           if (o == null || !(o instanceof FastClass)) {
  140               return false;
  141           }
  142           return type.equals(((FastClass)o).type);
  143       }
  144   
  145       /**
  146        * Return the index of the matching method. The index may be used
  147        * later to invoke the method with less overhead. If more than one
  148        * method matches (i.e. they differ by return type only), one is
  149        * chosen arbitrarily.
  150        * @see #invoke(int, Object, Object[])
  151        * @param name the method name
  152        * @param parameterTypes the parameter array
  153        * @return the index, or <code>-1</code> if none is found.
  154        */
  155       abstract public int getIndex(String name, Class[] parameterTypes);
  156   
  157       /**
  158        * Return the index of the matching constructor. The index may be used
  159        * later to create a new instance with less overhead.
  160        * @see #newInstance(int, Object[])
  161        * @param parameterTypes the parameter array
  162        * @return the constructor index, or <code>-1</code> if none is found.
  163        */
  164       abstract public int getIndex(Class[] parameterTypes);
  165   
  166       /**
  167        * Invoke the method with the specified index.
  168        * @see getIndex(name, Class[])
  169        * @param index the method index
  170        * @param obj the object the underlying method is invoked from
  171        * @param args the arguments used for the method call
  172        * @throws java.lang.reflect.InvocationTargetException if the underlying method throws an exception
  173        */
  174       abstract public Object invoke(int index, Object obj, Object[] args) throws InvocationTargetException;
  175   
  176       /**
  177        * Create a new instance using the specified constructor index and arguments.
  178        * @see getIndex(Class[])
  179        * @param index the constructor index
  180        * @param args the arguments passed to the constructor
  181        * @throws java.lang.reflect.InvocationTargetException if the constructor throws an exception
  182        */
  183       abstract public Object newInstance(int index, Object[] args) throws InvocationTargetException;
  184   
  185       abstract public int getIndex(Signature sig);
  186   
  187       /**
  188        * Returns the maximum method index for this class.
  189        */
  190       abstract public int getMaxIndex();
  191   
  192       protected static String getSignatureWithoutReturnType(String name, Class[] parameterTypes) {
  193           StringBuffer sb = new StringBuffer();
  194           sb.append(name);
  195           sb.append('(');
  196           for (int i = 0; i < parameterTypes.length; i++) {
  197               sb.append(Type.getDescriptor(parameterTypes[i]));
  198           }
  199           sb.append(')');
  200           return sb.toString();
  201       }
  202   }

Home » cglib-src-2.2 » net.sf.cglib.reflect » [javadoc | source]