Save This Page
Home » groovy-src-1.6.3 » org.codehaus » groovy » reflection » [javadoc | source]
    1   /*
    2    * Copyright 2003-2007 the original author or authors.
    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 org.codehaus.groovy.reflection;
   17   
   18   import groovy.lang.MetaClassImpl;
   19   import groovy.lang.MetaMethod;
   20   import org.codehaus.groovy.classgen.BytecodeHelper;
   21   import org.codehaus.groovy.runtime.InvokerInvocationException;
   22   import org.codehaus.groovy.runtime.callsite;
   23   import org.codehaus.groovy.runtime.metaclass.MethodHelper;
   24   
   25   import java.lang.ref.SoftReference;
   26   import java.lang.reflect.Constructor;
   27   import java.lang.reflect.InvocationTargetException;
   28   import java.lang.reflect.Method;
   29   import java.util;
   30   
   31   /**
   32    * @author Alex.Tkachman
   33    */
   34   public class CachedMethod extends MetaMethod implements Comparable {
   35       public final CachedClass cachedClass;
   36   
   37       private final Method cachedMethod;
   38       private int hashCode;
   39   
   40       private static MyComparator comparator = new MyComparator();
   41   
   42       private SoftReference<Constructor> pogoCallSiteConstructor, pojoCallSiteConstructor, staticCallSiteConstructor;
   43   
   44       public CachedMethod(CachedClass clazz, Method method) {
   45           this.cachedMethod = method;
   46           this.cachedClass = clazz;
   47       }
   48   
   49       public CachedMethod(Method method) {
   50           this(ReflectionCache.getCachedClass(method.getDeclaringClass()),method);
   51       }
   52   
   53       public static CachedMethod find(Method method) {
   54           CachedMethod[] methods = ReflectionCache.getCachedClass(method.getDeclaringClass()).getMethods();
   55   //        for (int i = 0; i < methods.length; i++) {
   56   //            CachedMethod cachedMethod = methods[i];
   57   //            if (cachedMethod.cachedMethod.equals(method))
   58   //                return cachedMethod;
   59   //        }
   60   //        return null;
   61           int i = Arrays.binarySearch(methods, method, comparator);
   62           if (i < 0)
   63             return null;
   64   
   65           return methods[i];
   66       }
   67   
   68       protected Class[] getPT() {
   69           return cachedMethod.getParameterTypes();
   70       }
   71   
   72       public String getName() {
   73           return cachedMethod.getName();
   74       }
   75   
   76       public String getDescriptor() {
   77           return BytecodeHelper.getMethodDescriptor(getReturnType(), getNativeParameterTypes());
   78       }
   79   
   80       public CachedClass getDeclaringClass() {
   81           return cachedClass;
   82       }
   83   
   84       public final Object invoke(Object object, Object[] arguments) {
   85           try {
   86               return cachedMethod.invoke(object, arguments);
   87           } catch (IllegalArgumentException e) {
   88               throw new InvokerInvocationException(e);
   89           } catch (IllegalAccessException e) {
   90               throw new InvokerInvocationException(e);
   91           } catch (InvocationTargetException e) {
   92               throw new InvokerInvocationException(e);
   93           }
   94       }
   95   
   96       public ParameterTypes getParamTypes() {
   97           return null;
   98       }
   99   
  100       public Class getReturnType() {
  101           return cachedMethod.getReturnType();
  102       }
  103   
  104       public int getParamsCount() {
  105           return getParameterTypes().length;
  106       }
  107   
  108       public int getModifiers() {
  109           return cachedMethod.getModifiers();
  110       }
  111   
  112   
  113       public String getSignature() {
  114           return getName() + getDescriptor();
  115       }
  116   
  117       public final Method setAccessible() {
  118   //        if (queuedToCompile.compareAndSet(false,true)) {
  119   //            if (isCompilable())
  120   //              CompileThread.addMethod(this);
  121   //        }
  122           return cachedMethod;
  123       }
  124   
  125       public boolean isStatic() {
  126           return MethodHelper.isStatic(cachedMethod);
  127       }
  128   
  129       public int compareTo(Object o) {
  130         if (o instanceof CachedMethod)
  131           return compareToCachedMethod((CachedMethod)o);
  132         else
  133           return compareToMethod((Method)o);
  134       }
  135   
  136       private int compareToCachedMethod(CachedMethod m) {
  137           if (m == null)
  138            return -1;
  139   
  140           final int strComp = getName().compareTo(m.getName());
  141           if (strComp != 0)
  142             return strComp;
  143   
  144           final int retComp = getReturnType().getName().compareTo(m.getReturnType().getName());
  145           if (retComp != 0)
  146             return retComp;
  147   
  148           CachedClass[]  params =   getParameterTypes();
  149           CachedClass [] mparams = m.getParameterTypes();
  150   
  151           final int pd = params.length - mparams.length;
  152           if (pd != 0)
  153             return pd;
  154   
  155           for (int i = 0; i != params.length; ++i)
  156           {
  157               final int nameComp = params[i].getName().compareTo(mparams[i].getName());
  158               if (nameComp != 0)
  159                 return nameComp;
  160           }
  161   
  162           throw new RuntimeException("Should never happen");
  163       }
  164   
  165       private int compareToMethod(Method m) {
  166           if (m == null)
  167            return -1;
  168   
  169           final int strComp = getName().compareTo(m.getName());
  170           if (strComp != 0)
  171             return strComp;
  172   
  173           final int retComp = getReturnType().getName().compareTo(m.getReturnType().getName());
  174           if (retComp != 0)
  175             return retComp;
  176   
  177           CachedClass[]  params =   getParameterTypes();
  178           Class [] mparams = m.getParameterTypes();
  179   
  180           final int pd = params.length - mparams.length;
  181           if (pd != 0)
  182             return pd;
  183   
  184           for (int i = 0; i != params.length; ++i)
  185           {
  186               final int nameComp = params[i].getName().compareTo(mparams[i].getName());
  187               if (nameComp != 0)
  188                 return nameComp;
  189           }
  190   
  191           return 0;
  192       }
  193   
  194       public boolean equals(Object o) {
  195           return (o instanceof CachedMethod && cachedMethod.equals(((CachedMethod)o).cachedMethod))
  196                   || (o instanceof Method && cachedMethod.equals(o));
  197       }
  198   
  199       public int hashCode() {
  200           if (hashCode == 0) {
  201              hashCode = cachedMethod.hashCode();
  202              if (hashCode == 0)
  203                hashCode = 0xcafebebe;
  204           }
  205           return hashCode;
  206       }
  207   
  208       public String toString() {
  209           return cachedMethod.toString();
  210       }
  211   
  212       public CallSite createPogoMetaMethodSite(CallSite site, MetaClassImpl metaClass, Class[] params) {
  213           if (!hasPogoCallSiteConstructor()) {
  214             Constructor constr = null;
  215             if (CallSiteGenerator.isCompilable(this)) {
  216                 constr = CallSiteGenerator.compilePogoMethod(this);
  217   
  218                 if (constr != null)
  219                    pogoCallSiteConstructor = new SoftReference<Constructor> (constr);
  220             }
  221           }
  222   
  223           if (hasPogoCallSiteConstructor()) {
  224               final Constructor constructor = pogoCallSiteConstructor.get();
  225               if (constructor != null) {
  226                   try {
  227                   return (CallSite) constructor.newInstance(site, metaClass, this, params);
  228                   } catch (Throwable e) { //
  229                   }
  230               }
  231           }
  232   
  233           return new PogoMetaMethodSite.PogoCachedMethodSiteNoUnwrapNoCoerce(site, metaClass, this, params);
  234       }
  235   
  236       public CallSite createPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, Class[] params) {
  237           if (!hasPojoCallSiteConstructor()) {
  238             Constructor constr = null;
  239             if (CallSiteGenerator.isCompilable(this)) {
  240                 constr = CallSiteGenerator.compilePojoMethod(this);
  241   
  242                 if (constr != null)
  243                    pojoCallSiteConstructor = new SoftReference<Constructor> (constr);
  244             }
  245           }
  246   
  247           if (hasPogoCallSiteConstructor()) {
  248               final Constructor constructor = pojoCallSiteConstructor.get();
  249               if (constructor != null) {
  250                   try {
  251                   return (CallSite) constructor.newInstance(site, metaClass, this, params);
  252                   } catch (Throwable e) { //
  253                   }
  254               }
  255           }
  256   
  257           return new PojoMetaMethodSite.PojoCachedMethodSiteNoUnwrapNoCoerce(site, metaClass, this, params);
  258       }
  259   
  260       public CallSite createStaticMetaMethodSite(CallSite site, MetaClassImpl metaClass, Class[] params) {
  261           if (!hasStaticCallSiteConstructor()) {
  262             Constructor constr = null;
  263             if (CallSiteGenerator.isCompilable(this)) {
  264                 constr = CallSiteGenerator.compileStaticMethod(this);
  265   
  266                 if (constr != null)
  267                    staticCallSiteConstructor = new SoftReference<Constructor> (constr);
  268             }
  269           }
  270   
  271           if (hasStaticCallSiteConstructor()) {
  272               final Constructor constructor = staticCallSiteConstructor.get();
  273               if (constructor != null) {
  274                   try {
  275                   return (CallSite) constructor.newInstance(site, metaClass, this, params);
  276                   } catch (Throwable e) { //
  277                   }
  278               }
  279           }
  280   
  281           return new StaticMetaMethodSite.StaticMetaMethodSiteNoUnwrapNoCoerce(site, metaClass, this, params);
  282       }
  283   
  284       public boolean hasPogoCallSiteConstructor() {
  285           return pogoCallSiteConstructor != null && pogoCallSiteConstructor.get() != null;
  286       }
  287   
  288       public boolean hasPojoCallSiteConstructor() {
  289           return pojoCallSiteConstructor != null && pojoCallSiteConstructor.get() != null;
  290       }
  291   
  292       public boolean hasStaticCallSiteConstructor() {
  293           return staticCallSiteConstructor != null && staticCallSiteConstructor.get() != null;
  294       }
  295   
  296       private static class MyComparator implements Comparator {
  297           public int compare(Object o1, Object o2) {
  298               if (o1 instanceof CachedMethod)
  299                   return ((CachedMethod)o1).compareTo(o2);
  300               else if (o2 instanceof CachedMethod)
  301                   return -((CachedMethod)o2).compareTo(o1);
  302               else
  303                   // really, this should never happen, it's eveidence of corruption if it does
  304                   throw new ClassCastException("One of the two comperables must be a CachedMethod");
  305           }
  306       }
  307   
  308       public Method getCachedMethod() {
  309           return cachedMethod;
  310       }
  311   
  312   //    private static class CompileThread extends Thread {
  313   //        static final LinkedBlockingQueue queue = new LinkedBlockingQueue();
  314   //
  315   //        static {
  316   //            new CompileThread().start();
  317   //        }
  318   //
  319   //        private CompileThread() {
  320   //            setDaemon(true);
  321   //            setPriority(Thread.MAX_PRIORITY-2);
  322   //        }
  323   //
  324   //        public void run() {
  325   //            try {
  326   //                while (true) {
  327   //                    final CachedMethod method = (CachedMethod) queue.take();
  328   //                    if (method != null) {
  329   //                        CallSiteGenerator.compilePogoMethod(method);
  330   //                    }
  331   //                }
  332   //            }
  333   //            catch (InterruptedException e) {//
  334   //            }
  335   //        }
  336   //
  337   //        public static void addMethod (CachedMethod method) {
  338   //            try {
  339   //                queue.put(method);
  340   //            } catch (InterruptedException e) {
  341   //            }
  342   //        }
  343   //    }
  344   
  345   }
  346   

Save This Page
Home » groovy-src-1.6.3 » org.codehaus » groovy » reflection » [javadoc | source]