Save This Page
Home » Groovy-1.7.0 » org.codehaus » groovy » runtime » callsite » [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.runtime.callsite;
   17   
   18   import groovy.lang;
   19   
   20   import org.codehaus.groovy.reflection.CachedClass;
   21   import org.codehaus.groovy.reflection.CachedField;
   22   import org.codehaus.groovy.reflection.ParameterTypes;
   23   import org.codehaus.groovy.runtime.ArrayUtil;
   24   import org.codehaus.groovy.runtime.GroovyCategorySupport;
   25   import org.codehaus.groovy.runtime.InvokerHelper;
   26   import org.codehaus.groovy.runtime.wrappers.Wrapper;
   27   
   28   import java.lang.reflect.Method;
   29   import java.util.concurrent.atomic.AtomicInteger;
   30   
   31   /**
   32    * Base class for all call sites
   33    *
   34    * @author Alex Tkachman
   35    */
   36   public class AbstractCallSite implements CallSite {
   37       protected final int index;
   38       protected final String name;
   39       protected final CallSiteArray array;
   40       protected final AtomicInteger usage;
   41   
   42       public AbstractCallSite(CallSiteArray array, int index, String name) {
   43           this.name = name;
   44           this.index = index;
   45           this.array = array;
   46           this.usage = GroovyCategorySupport.getCategoryNameUsage(name);
   47       }
   48   
   49       public AbstractCallSite(CallSite prev) {
   50           this.name = prev.getName();
   51           this.index = prev.getIndex();
   52           this.array = prev.getArray();
   53           this.usage = prev.getUsage();
   54       }
   55   
   56       public int getIndex() {
   57           return index;
   58       }
   59   
   60       public CallSiteArray getArray() {
   61           return array;
   62       }
   63   
   64       public String getName() {
   65           return name;
   66       }
   67   
   68       public AtomicInteger getUsage() {
   69           return usage;
   70       }
   71   
   72       public final Object callSafe(Object receiver, Object[] args) throws Throwable {
   73           if (receiver == null)
   74               return null;
   75   
   76           return call (receiver, args);
   77       }
   78   
   79       public final Object callSafe (Object receiver) throws Throwable {
   80           if (receiver == null)
   81               return null;
   82   
   83           return call(receiver);
   84       }
   85   
   86       public final Object callSafe (Object receiver, Object arg1) throws Throwable {
   87           if (receiver == null)
   88               return null;
   89   
   90           return call(receiver, arg1);
   91       }
   92   
   93       public final Object callSafe (Object receiver, Object arg1, Object arg2) throws Throwable {
   94           if (receiver == null)
   95               return null;
   96   
   97           return call(receiver, arg1, arg2);
   98       }
   99   
  100       public final Object callSafe (Object receiver, Object arg1, Object arg2, Object arg3) throws Throwable {
  101           if (receiver == null)
  102               return null;
  103   
  104           return call(receiver, arg1, arg2, arg3);
  105       }
  106   
  107       public Object callSafe (Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) throws Throwable {
  108           if (receiver == null)
  109               return null;
  110   
  111           return call(receiver, arg1, arg2, arg3, arg4);
  112       }
  113   
  114   
  115   
  116       public Object call(Object receiver, Object[] args) throws Throwable {
  117           return CallSiteArray.defaultCall(this, receiver, args);
  118       }
  119   
  120       public Object call (Object receiver) throws Throwable {
  121           return call(receiver, CallSiteArray.NOPARAM);
  122       }
  123   
  124       public Object call (Object receiver, Object arg1) throws Throwable {
  125           return call(receiver, ArrayUtil.createArray(arg1));
  126       }
  127   
  128       public Object call (Object receiver, Object arg1, Object arg2) throws Throwable {
  129           return call(receiver, ArrayUtil.createArray(arg1, arg2));
  130       }
  131   
  132       public Object call (Object receiver, Object arg1, Object arg2, Object arg3) throws Throwable {
  133           return call(receiver, ArrayUtil.createArray(arg1, arg2, arg3));
  134       }
  135   
  136       public Object call (Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) throws Throwable {
  137           return call(receiver, ArrayUtil.createArray(arg1, arg2, arg3, arg4));
  138       }
  139   
  140   
  141   
  142       public Object callCurrent (GroovyObject receiver, Object [] args) throws Throwable {
  143           return CallSiteArray.defaultCallCurrent(this, receiver, args);
  144       }
  145   
  146       public Object callCurrent (GroovyObject receiver) throws Throwable {
  147           return callCurrent(receiver, CallSiteArray.NOPARAM);
  148       }
  149   
  150       public Object callCurrent (GroovyObject receiver, Object arg1) throws Throwable {
  151           return callCurrent(receiver, ArrayUtil.createArray(arg1));
  152       }
  153   
  154       public Object callCurrent (GroovyObject receiver, Object arg1, Object arg2) throws Throwable {
  155           return callCurrent(receiver, ArrayUtil.createArray(arg1, arg2));
  156       }
  157   
  158       public Object callCurrent (GroovyObject receiver, Object arg1, Object arg2, Object arg3) throws Throwable {
  159           return callCurrent(receiver, ArrayUtil.createArray(arg1, arg2, arg3));
  160       }
  161   
  162       public Object callCurrent (GroovyObject receiver, Object arg1, Object arg2, Object arg3, Object arg4) throws Throwable {
  163           return callCurrent(receiver, ArrayUtil.createArray(arg1, arg2, arg3, arg4));
  164       }
  165   
  166       public Object callStatic (Class receiver, Object [] args) throws Throwable {
  167           return CallSiteArray.defaultCallStatic(this, receiver, args);
  168       }
  169   
  170       public Object callStatic (Class receiver) throws Throwable {
  171           return callStatic(receiver, CallSiteArray.NOPARAM);
  172       }
  173   
  174       public Object callStatic (Class receiver, Object arg1) throws Throwable {
  175           return callStatic(receiver, ArrayUtil.createArray(arg1));
  176       }
  177   
  178       public Object callStatic (Class receiver, Object arg1, Object arg2) throws Throwable {
  179           return callStatic(receiver, ArrayUtil.createArray(arg1, arg2));
  180       }
  181   
  182       public Object callStatic (Class receiver, Object arg1, Object arg2, Object arg3) throws Throwable {
  183           return callStatic(receiver, ArrayUtil.createArray(arg1, arg2, arg3));
  184       }
  185   
  186       public Object callStatic (Class receiver, Object arg1, Object arg2, Object arg3, Object arg4) throws Throwable {
  187           return callStatic(receiver, ArrayUtil.createArray(arg1, arg2, arg3, arg4));
  188       }
  189   
  190   
  191       public Object callConstructor (Object receiver, Object [] args) throws Throwable {
  192           return CallSiteArray.defaultCallConstructor(this, receiver, args);
  193       }
  194   
  195       public Object callConstructor (Object receiver) throws Throwable {
  196           return callConstructor(receiver, CallSiteArray.NOPARAM);
  197       }
  198   
  199       public Object callConstructor (Object receiver, Object arg1) throws Throwable {
  200           return callConstructor(receiver, ArrayUtil.createArray(arg1));
  201       }
  202   
  203       public Object callConstructor (Object receiver, Object arg1, Object arg2) throws Throwable {
  204           return callConstructor(receiver, ArrayUtil.createArray(arg1, arg2));
  205       }
  206   
  207       public Object callConstructor (Object receiver, Object arg1, Object arg2, Object arg3) throws Throwable {
  208           return callConstructor(receiver, ArrayUtil.createArray(arg1, arg2, arg3));
  209       }
  210   
  211       public Object callConstructor (Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) throws Throwable {
  212           return callConstructor(receiver, ArrayUtil.createArray(arg1, arg2, arg3, arg4));
  213       }
  214   
  215       static boolean noCoerce(ParameterTypes metaMethod, Object[] args) {
  216           final CachedClass[] paramClasses = metaMethod.getParameterTypes();
  217           if (paramClasses.length != args.length)
  218             return false;
  219   
  220           for (int i = 0; i < paramClasses.length; i++) {
  221               CachedClass paramClass = paramClasses[i];
  222               if (args[i] != null && !paramClass.isDirectlyAssignable(args[i]))
  223                 return true;
  224           }
  225           return false;
  226       }
  227   
  228       static boolean noWrappers(Object[] args) {
  229           for (int i = 0; i != args.length; ++i)
  230             if (args [i] instanceof Wrapper)
  231               return false;
  232           return true;
  233       }
  234   
  235   
  236       public Object callGetProperty (Object receiver) throws Throwable {
  237           return acceptGetProperty(receiver).getProperty(receiver);
  238       }
  239   
  240       public Object callGroovyObjectGetProperty (Object receiver) throws Throwable {
  241           return acceptGroovyObjectGetProperty(receiver).getProperty(receiver);
  242       }
  243   
  244       public CallSite acceptGetProperty(Object receiver) {
  245           return createGetPropertySite(receiver);
  246       }
  247   
  248       public CallSite acceptGroovyObjectGetProperty(Object receiver) {
  249           return createGroovyObjectGetPropertySite(receiver);
  250       }
  251   
  252       protected final CallSite createGetPropertySite(Object receiver) {
  253           if (receiver==null) {
  254               return new NullCallSite(this);
  255           } else if (receiver instanceof GroovyObject) {
  256               return createGroovyObjectGetPropertySite(receiver);
  257           } else if (receiver instanceof Class) {
  258               return createClassMetaClassGetPropertySite ((Class) receiver);
  259           }
  260           return createPojoMetaClassGetPropertySite(receiver);
  261       }
  262   
  263       protected final CallSite createGroovyObjectGetPropertySite(Object receiver) {
  264           Class aClass = receiver.getClass();
  265           try {
  266               final Method method = aClass.getMethod("getProperty", String.class);
  267               if (method != null && method.isSynthetic() && ((GroovyObject)receiver).getMetaClass() instanceof MetaClassImpl)
  268                 return createPogoMetaClassGetPropertySite ((GroovyObject)receiver);
  269           } catch (NoSuchMethodException e) {
  270               // fall threw
  271           }
  272           return createPogoGetPropertySite (aClass);
  273       }
  274   
  275       public Object getProperty(Object receiver) throws Throwable {
  276           throw new UnsupportedOperationException();
  277       }
  278   
  279       private CallSite createPojoMetaClassGetPropertySite(Object receiver) {
  280           final MetaClass metaClass = InvokerHelper.getMetaClass(receiver);
  281   
  282           CallSite site;
  283           if (metaClass.getClass() != MetaClassImpl.class || GroovyCategorySupport.hasCategoryInCurrentThread()) {
  284               site = new PojoMetaClassGetPropertySite(this);
  285           }
  286           else {
  287               final MetaProperty effective = ((MetaClassImpl) metaClass).getEffectiveGetMetaProperty(receiver.getClass(), receiver, name, false);
  288               if (effective != null) {
  289                   if (effective instanceof CachedField)
  290                       site = new GetEffectivePojoFieldSite(this, (MetaClassImpl) metaClass, (CachedField) effective);
  291                   else
  292                       site = new GetEffectivePojoPropertySite(this, (MetaClassImpl) metaClass, effective);
  293               }
  294               else {
  295                   site = new PojoMetaClassGetPropertySite(this);
  296               }
  297           }
  298   
  299           array.array[index] = site;
  300           return site;
  301       }
  302   
  303       private CallSite createClassMetaClassGetPropertySite(Class aClass) {
  304           CallSite site = new ClassMetaClassGetPropertySite(this, aClass);
  305           array.array[index] = site;
  306           return site;
  307       }
  308   
  309       private CallSite createPogoMetaClassGetPropertySite(GroovyObject receiver) {
  310           MetaClass metaClass = receiver.getMetaClass();
  311   
  312           CallSite site;
  313           if (metaClass.getClass() != MetaClassImpl.class || GroovyCategorySupport.hasCategoryInCurrentThread()) {
  314               site = new PogoMetaClassGetPropertySite(this, metaClass);
  315           }
  316           else {
  317               final MetaProperty effective = ((MetaClassImpl) metaClass).getEffectiveGetMetaProperty(metaClass.getClass(), receiver, name, false);
  318               if (effective != null) {
  319                   if (effective instanceof CachedField)
  320                       site = new GetEffectivePogoFieldSite(this, metaClass, (CachedField) effective);
  321                   else
  322                       site = new GetEffectivePogoPropertySite(this, metaClass, effective);
  323               }
  324               else {
  325                   site = new PogoMetaClassGetPropertySite(this, metaClass);
  326               }
  327           }
  328   
  329           array.array[index] = site;
  330           return site;
  331       }
  332   
  333       private CallSite createPogoGetPropertySite(Class aClass) {
  334           CallSite site = new PogoGetPropertySite(this, aClass);
  335           array.array[index] = site;
  336           return site;
  337       }
  338   
  339       public final Object callGetPropertySafe (Object receiver) throws Throwable {
  340           if (receiver == null)
  341             return null;
  342           else
  343             return callGetProperty(receiver);
  344       }
  345   
  346       public final Object callGroovyObjectGetPropertySafe (Object receiver) throws Throwable {
  347           if (receiver == null)
  348             return null;
  349           else
  350             return callGroovyObjectGetProperty(receiver);
  351       }
  352   
  353   }
  354   

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