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

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