Save This Page
Home » groovy-src-1.6.3 » org.codehaus » groovy » runtime » [javadoc | source]
    1   /*
    2    * Copyright 2003-2008 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;
   17   
   18   import groovy.lang;
   19   import groovy.xml.XmlUtil;
   20   import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;
   21   import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
   22   import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
   23   import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
   24   import org.w3c.dom.Element;
   25   
   26   import java.beans.Introspector;
   27   import java.io;
   28   import java.math.BigDecimal;
   29   import java.math.BigInteger;
   30   import java.util;
   31   import java.util.regex.Matcher;
   32   import java.util.regex.Pattern;
   33   
   34   /**
   35    * A static helper class to make bytecode generation easier and act as a facade over the Invoker
   36    *
   37    * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
   38    * @version $Revision: 16276 $
   39    */
   40   public class InvokerHelper {
   41       private   static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
   42   
   43       public    static final Object[] EMPTY_ARGS = {};
   44       protected static final Object[] EMPTY_ARGUMENTS = EMPTY_ARGS;
   45       protected static final Class[]  EMPTY_TYPES = {};
   46   
   47       public static final MetaClassRegistry metaRegistry = GroovySystem.getMetaClassRegistry();
   48   
   49       public static void removeClass(Class clazz) {
   50           metaRegistry.removeMetaClass(clazz);
   51           Introspector.flushFromCaches(clazz);
   52       }
   53   
   54       public static Object invokeMethodSafe(Object object, String methodName, Object arguments) {
   55           if (object != null) {
   56               return invokeMethod(object, methodName, arguments);
   57           }
   58           return null;
   59       }
   60   
   61       public static Object invokeStaticMethod(String klass, String methodName, Object arguments) throws ClassNotFoundException {
   62           Class type = Class.forName(klass);
   63           return invokeStaticMethod(type, methodName, arguments);
   64       }
   65   
   66   
   67       public static Object invokeStaticNoArgumentsMethod(Class type, String methodName) {
   68           return invokeStaticMethod(type, methodName, EMPTY_ARGS);
   69       }
   70   
   71       public static Object invokeConstructorOf(String klass, Object arguments) throws ClassNotFoundException {
   72           Class type = Class.forName(klass);
   73           return invokeConstructorOf(type, arguments);
   74       }
   75   
   76       public static Object invokeNoArgumentsConstructorOf(Class type) {
   77           return invokeConstructorOf(type, EMPTY_ARGS);
   78       }
   79   
   80       public static Object invokeClosure(Object closure, Object arguments) {
   81           return invokeMethod(closure, "doCall", arguments);
   82       }
   83   
   84       public static List asList(Object value) {
   85           if (value == null) {
   86               return Collections.EMPTY_LIST;
   87           }
   88           if (value instanceof List) {
   89               return (List) value;
   90           }
   91           if (value.getClass().isArray()) {
   92               return Arrays.asList((Object[]) value);
   93           }
   94           if (value instanceof Enumeration) {
   95               List answer = new ArrayList();
   96               for (Enumeration e = (Enumeration) value; e.hasMoreElements();) {
   97                   answer.add(e.nextElement());
   98               }
   99               return answer;
  100           }
  101           // lets assume its a collection of 1
  102           return Collections.singletonList(value);
  103       }
  104   
  105       public static String toString(Object arguments) {
  106           if (arguments instanceof Object[])
  107               return toArrayString((Object[]) arguments);
  108           if (arguments instanceof Collection)
  109               return toListString((Collection) arguments);
  110           if (arguments instanceof Map)
  111               return toMapString((Map) arguments);
  112           return format(arguments, false);
  113       }
  114   
  115       public static String inspect(Object self) {
  116           return format(self, true);
  117       }
  118   
  119       public static Object getAttribute(Object object, String attribute) {
  120           if (object == null) {
  121               object = NullObject.getNullObject();
  122           }
  123   
  124           if (object instanceof Class) {
  125               return metaRegistry.getMetaClass((Class) object).getAttribute(object, attribute);
  126           } else if (object instanceof GroovyObject) {
  127               return ((GroovyObject) object).getMetaClass().getAttribute(object, attribute);
  128           } else {
  129               return metaRegistry.getMetaClass(object.getClass()).getAttribute(object, attribute);
  130           }
  131       }
  132   
  133       public static void setAttribute(Object object, String attribute, Object newValue) {
  134           if (object == null) {
  135               object = NullObject.getNullObject();
  136           }
  137   
  138           if (object instanceof Class) {
  139               metaRegistry.getMetaClass((Class) object).setAttribute(object, attribute, newValue);
  140           } else if (object instanceof GroovyObject) {
  141               ((GroovyObject) object).getMetaClass().setAttribute(object, attribute, newValue);
  142           } else {
  143               metaRegistry.getMetaClass(object.getClass()).setAttribute(object, attribute, newValue);
  144           }
  145       }
  146   
  147       public static Object getProperty(Object object, String property) {
  148           if (object == null) {
  149               object = NullObject.getNullObject();
  150           }
  151           
  152           if (object instanceof GroovyObject) {
  153               GroovyObject pogo = (GroovyObject) object;
  154               return pogo.getProperty(property);
  155           } else if (object instanceof Class) {
  156               Class c = (Class) object;
  157               return metaRegistry.getMetaClass(c).getProperty(object, property);
  158           } else {
  159               return ((MetaClassRegistryImpl)metaRegistry).getMetaClass(object).getProperty(object, property);
  160           }
  161       }
  162   
  163       public static Object getPropertySafe(Object object, String property) {
  164           if (object != null) {
  165               return getProperty(object, property);
  166           }
  167           return null;
  168       }
  169   
  170       public static void setProperty(Object object, String property, Object newValue) {
  171           if (object == null) {
  172               object = NullObject.getNullObject();
  173           }
  174   
  175           if (object instanceof GroovyObject) {
  176               GroovyObject pogo = (GroovyObject) object;
  177               pogo.setProperty(property, newValue);
  178           } else if (object instanceof Class) {
  179               metaRegistry.getMetaClass((Class) object).setProperty((Class) object, property, newValue);
  180           } else {
  181               ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(object).setProperty(object, property, newValue);
  182           }
  183       }
  184   
  185       /**
  186        * This is so we don't have to reorder the stack when we call this method.
  187        * At some point a better name might be in order.
  188        */
  189       public static void setProperty2(Object newValue, Object object, String property) {
  190           setProperty(object, property, newValue);
  191       }
  192   
  193   
  194       /**
  195        * This is so we don't have to reorder the stack when we call this method.
  196        * At some point a better name might be in order.
  197        */
  198       public static void setGroovyObjectProperty(Object newValue, GroovyObject object, String property) {
  199           object.setProperty(property, newValue);
  200       }
  201   
  202       public static Object getGroovyObjectProperty(GroovyObject object, String property) {
  203           return object.getProperty(property);
  204       }
  205   
  206   
  207       /**
  208        * This is so we don't have to reorder the stack when we call this method.
  209        * At some point a better name might be in order.
  210        */
  211       public static void setPropertySafe2(Object newValue, Object object, String property) {
  212           if (object != null) {
  213               setProperty2(newValue, object, property);
  214           }
  215       }
  216   
  217       /**
  218        * Returns the method pointer for the given object name
  219        */
  220       public static Closure getMethodPointer(Object object, String methodName) {
  221           if (object == null) {
  222               throw new NullPointerException("Cannot access method pointer for '" + methodName + "' on null object");
  223           }
  224           return new MethodClosure(object, methodName);
  225       }
  226   
  227       public static Object unaryMinus(Object value) {
  228           if (value instanceof Integer) {
  229               Integer number = (Integer) value;
  230               return Integer.valueOf(-number.intValue());
  231           }
  232           if (value instanceof Long) {
  233               Long number = (Long) value;
  234               return new Long(-number.longValue());
  235           }
  236           if (value instanceof BigInteger) {
  237               return ((BigInteger) value).negate();
  238           }
  239           if (value instanceof BigDecimal) {
  240               return ((BigDecimal) value).negate();
  241           }
  242           if (value instanceof Double) {
  243               Double number = (Double) value;
  244               return new Double(-number.doubleValue());
  245           }
  246           if (value instanceof Float) {
  247               Float number = (Float) value;
  248               return new Float(-number.floatValue());
  249           }
  250           if (value instanceof ArrayList) {
  251               // value is an list.
  252               List newlist = new ArrayList();
  253               Iterator it = ((ArrayList) value).iterator();
  254               for (; it.hasNext();) {
  255                   newlist.add(unaryMinus(it.next()));
  256               }
  257               return newlist;
  258           }
  259           return invokeMethod(value, "negative", EMPTY_ARGS);
  260       }
  261   
  262       public static Object unaryPlus(Object value) {
  263           if (value instanceof Integer ||
  264                   value instanceof Long ||
  265                   value instanceof BigInteger ||
  266                   value instanceof BigDecimal ||
  267                   value instanceof Double ||
  268                   value instanceof Float) {
  269               return value;
  270           }
  271           if (value instanceof ArrayList) {
  272               // value is an list.
  273               List newlist = new ArrayList();
  274               Iterator it = ((ArrayList) value).iterator();
  275               for (; it.hasNext();) {
  276                   newlist.add(unaryPlus(it.next()));
  277               }
  278               return newlist;
  279           }
  280           return invokeMethod(value, "positive", EMPTY_ARGS);
  281       }
  282   
  283       /**
  284        * Find the right hand regex within the left hand string and return a matcher.
  285        *
  286        * @param left  string to compare
  287        * @param right regular expression to compare the string to
  288        */
  289       public static Matcher findRegex(Object left, Object right) {
  290           String stringToCompare;
  291           if (left instanceof String) {
  292               stringToCompare = (String) left;
  293           } else {
  294               stringToCompare = toString(left);
  295           }
  296           String regexToCompareTo;
  297           if (right instanceof String) {
  298               regexToCompareTo = (String) right;
  299           } else if (right instanceof Pattern) {
  300               Pattern pattern = (Pattern) right;
  301               return pattern.matcher(stringToCompare);
  302           } else {
  303               regexToCompareTo = toString(right);
  304           }
  305           Matcher matcher = Pattern.compile(regexToCompareTo).matcher(stringToCompare);
  306           return matcher;
  307       }
  308   
  309   
  310       /**
  311        * Find the right hand regex within the left hand string and return a matcher.
  312        *
  313        * @param left  string to compare
  314        * @param right regular expression to compare the string to
  315        */
  316       public static boolean matchRegex(Object left, Object right) {
  317           Pattern pattern;
  318           if (right instanceof Pattern) {
  319               pattern = (Pattern) right;
  320           } else {
  321               pattern = Pattern.compile(toString(right));
  322           }
  323           String stringToCompare = toString(left);
  324           Matcher matcher = pattern.matcher(stringToCompare);
  325           RegexSupport.setLastMatcher(matcher);
  326           return matcher.matches();
  327       }
  328   
  329       public static Tuple createTuple(Object[] array) {
  330           return new Tuple(array);
  331       }
  332   
  333       public static SpreadMap spreadMap(Object value) {
  334           if (value instanceof Map) {
  335               Object[] values = new Object[((Map) value).keySet().size() * 2];
  336               int index = 0;
  337               Iterator it = ((Map) value).keySet().iterator();
  338               for (; it.hasNext();) {
  339                   Object key = it.next();
  340                   values[index++] = key;
  341                   values[index++] = ((Map) value).get(key);
  342               }
  343               return new SpreadMap(values);
  344           }
  345           throw new SpreadMapEvaluatingException("Cannot spread the map " + value.getClass().getName() + ", value " + value);
  346       }
  347   
  348       public static List createList(Object[] values) {
  349           List answer = new ArrayList(values.length);
  350           answer.addAll(Arrays.asList(values));
  351           return answer;
  352       }
  353   
  354       public static Map createMap(Object[] values) {
  355           Map answer = new LinkedHashMap(values.length / 2);
  356           int i = 0;
  357           while (i < values.length - 1) {
  358               if ((values[i] instanceof SpreadMap) && (values[i + 1] instanceof Map)) {
  359                   Map smap = (Map) values[i + 1];
  360                   Iterator iter = smap.keySet().iterator();
  361                   for (; iter.hasNext();) {
  362                       Object key = iter.next();
  363                       answer.put(key, smap.get(key));
  364                   }
  365                   i += 2;
  366               } else {
  367                   answer.put(values[i++], values[i++]);
  368               }
  369           }
  370           return answer;
  371       }
  372   
  373       public static void assertFailed(Object expression, Object message) {
  374           if (message == null || "".equals(message)) {
  375               throw new AssertionError("Expression: " + expression);
  376           }
  377           throw new AssertionError(String.valueOf(message) + ". Expression: " + expression);
  378       }
  379   
  380       public static Object runScript(Class scriptClass, String[] args) {
  381           Binding context = new Binding(args);
  382           Script script = createScript(scriptClass, context);
  383           return invokeMethod(script, "run", EMPTY_ARGS);
  384       }
  385   
  386       public static Script createScript(Class scriptClass, Binding context) {
  387           Script script = null;
  388           // for empty scripts
  389           if (scriptClass == null) {
  390               script = new Script() {
  391                   public Object run() {
  392                       return null;
  393                   }
  394               };
  395           } else {
  396               try {
  397                   final GroovyObject object = (GroovyObject) scriptClass
  398                           .newInstance();
  399                   if (object instanceof Script) {
  400                       script = (Script) object;
  401                   } else {
  402                       // it could just be a class, so lets wrap it in a Script
  403                       // wrapper
  404                       // though the bindings will be ignored
  405                       script = new Script() {
  406                           public Object run() {
  407                           	Object args = getBinding().getVariables().get("args");
  408                           	Object argsToPass = EMPTY_MAIN_ARGS;
  409                           	if(args != null && args instanceof String[]) {
  410                           		argsToPass = args;
  411                           	}
  412                               object.invokeMethod("main", argsToPass);
  413                               return null;
  414                           }
  415                       };
  416                       setProperties(object, context.getVariables());
  417                   }
  418               } catch (Exception e) {
  419                   throw new GroovyRuntimeException(
  420                           "Failed to create Script instance for class: "
  421                                   + scriptClass + ". Reason: " + e, e);
  422               }
  423           }
  424           script.setBinding(context);
  425           return script;
  426       }
  427   
  428       /**
  429        * Sets the properties on the given object
  430        */
  431       public static void setProperties(Object object, Map map) {
  432           MetaClass mc = getMetaClass(object);
  433           for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
  434               Map.Entry entry = (Map.Entry) iter.next();
  435               String key = entry.getKey().toString();
  436   
  437               Object value = entry.getValue();
  438               try {
  439                   mc.setProperty(object, key, value);
  440               } catch (MissingPropertyException mpe) {
  441                   // Ignore
  442               }
  443           }
  444       }
  445   
  446       public static String getVersion() {
  447           String version = null;
  448           Package p = Package.getPackage("groovy.lang");
  449           if (p != null) {
  450               version = p.getImplementationVersion();
  451           }
  452           if (version == null) {
  453               version = "";
  454           }
  455           return version;
  456       }
  457   
  458       /**
  459        * Writes the given object to the given stream
  460        */
  461       public static void write(Writer out, Object object) throws IOException {
  462           if (object instanceof String) {
  463               out.write((String) object);
  464           } else if (object instanceof Object[]) {
  465               out.write(toArrayString((Object[]) object));
  466           } else if (object instanceof Map) {
  467               out.write(toMapString((Map) object));
  468           } else if (object instanceof Collection) {
  469               out.write(toListString((Collection) object));
  470           } else if (object instanceof Writable) {
  471               Writable writable = (Writable) object;
  472               writable.writeTo(out);
  473           } else if (object instanceof InputStream || object instanceof Reader) {
  474               // Copy stream to stream
  475               Reader reader;
  476               if (object instanceof InputStream) {
  477                   reader = new InputStreamReader((InputStream) object);
  478               } else {
  479                   reader = (Reader) object;
  480               }
  481               char[] chars = new char[8192];
  482               int i;
  483               while ((i = reader.read(chars)) != -1) {
  484                   out.write(chars, 0, i);
  485               }
  486               reader.close();
  487           } else {
  488               out.write(toString(object));
  489           }
  490       }
  491   
  492       public static Iterator asIterator(Object o) {
  493           return (Iterator) invokeMethod(o, "iterator", EMPTY_ARGS);
  494       }
  495   
  496       protected static String format(Object arguments, boolean verbose) {
  497           if (arguments == null) {
  498               final NullObject nullObject = NullObject.getNullObject();
  499               return (String) nullObject.getMetaClass().invokeMethod(nullObject, "toString", EMPTY_ARGS);
  500           }
  501           if (arguments.getClass().isArray()) {
  502               if (arguments instanceof char[]) {
  503                   return new String((char[]) arguments);
  504               }
  505               return format(DefaultTypeTransformation.asCollection(arguments), verbose);
  506           }
  507           if (arguments instanceof Range) {
  508               Range range = (Range) arguments;
  509               if (verbose) {
  510                   return range.inspect();
  511               } else {
  512                   return range.toString();
  513               }
  514           }
  515           if (arguments instanceof Collection) {
  516               return formatList((Collection) arguments, verbose);
  517           }
  518           if (arguments instanceof Map) {
  519               return formatMap((Map) arguments, verbose);
  520           }
  521           if (arguments instanceof Element) {
  522               return XmlUtil.serialize((Element) arguments);
  523           }
  524           if (arguments instanceof String) {
  525               if (verbose) {
  526                   String arg = ((String) arguments).replaceAll("\\n", "\\\\n");    // line feed
  527                   arg = arg.replaceAll("\\r", "\\\\r");      // carriage return
  528                   arg = arg.replaceAll("\\t", "\\\\t");      // tab
  529                   arg = arg.replaceAll("\\f", "\\\\f");      // form feed
  530                   arg = arg.replaceAll("\\\"", "\\\\\"");    // double quotation mark
  531                   arg = arg.replaceAll("\\\\", "\\\\");      // backslash
  532                   return "\"" + arg + "\"";
  533               } else {
  534                   return (String) arguments;
  535               }
  536           }
  537           // TODO: For GROOVY-2599 do we need something like below but it breaks other things
  538   //        return (String) invokeMethod(arguments, "toString", EMPTY_ARGS);
  539           return arguments.toString();
  540       }
  541   
  542       private static String formatMap(Map map, boolean verbose) {
  543           if (map.isEmpty()) {
  544               return "[:]";
  545           }
  546           StringBuffer buffer = new StringBuffer("[");
  547           boolean first = true;
  548           for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
  549               if (first) {
  550                   first = false;
  551               } else {
  552                   buffer.append(", ");
  553               }
  554               Map.Entry entry = (Map.Entry) iter.next();
  555               buffer.append(format(entry.getKey(), verbose));
  556               buffer.append(":");
  557               if (entry.getValue() == map) {
  558                   buffer.append("this Map_");
  559               } else {
  560                   buffer.append(format(entry.getValue(), verbose));
  561               }
  562           }
  563           buffer.append("]");
  564           return buffer.toString();
  565       }
  566   
  567       private static String formatList(Collection list, boolean verbose) {
  568           StringBuffer buffer = new StringBuffer("[");
  569           boolean first = true;
  570           for (Iterator iter = list.iterator(); iter.hasNext();) {
  571               if (first) {
  572                   first = false;
  573               } else {
  574                   buffer.append(", ");
  575               }
  576               buffer.append(format(iter.next(), verbose));
  577           }
  578           buffer.append("]");
  579           return buffer.toString();
  580       }
  581   
  582       /**
  583        * A helper method to format the arguments types as a comma-separated list.
  584        *
  585        * @param arguments the type to process
  586        * @return the string representation of the type
  587        */
  588       public static String toTypeString(Object[] arguments) {
  589           if (arguments == null) {
  590               return "null";
  591           }
  592           StringBuffer argBuf = new StringBuffer();
  593           for (int i = 0; i < arguments.length; i++) {
  594               if (i > 0) {
  595                   argBuf.append(", ");
  596               }
  597               argBuf.append(arguments[i] != null ? arguments[i].getClass().getName() : "null");
  598           }
  599           return argBuf.toString();
  600       }
  601   
  602       /**
  603        * A helper method to return the string representation of a map with bracket boundaries "[" and "]".
  604        *
  605        * @param arg the map to process
  606        * @return the string representation of the map
  607        */
  608       public static String toMapString(Map arg) {
  609           return formatMap(arg, false);
  610       }
  611   
  612       /**
  613        * A helper method to return the string representation of a list with bracket boundaries "[" and "]".
  614        *
  615        * @param arg the collection to process
  616        * @return the string representation of the collection
  617        */
  618       public static String toListString(Collection arg) {
  619           return formatList(arg, false);
  620       }
  621   
  622       /**
  623        * A helper method to return the string representation of an array of objects
  624        * with brace boundaries "{" and "}".
  625        *
  626        * @param arguments the array to process
  627        * @return the string representation of the array
  628        */
  629       public static String toArrayString(Object[] arguments) {
  630           if (arguments == null) {
  631               return "null";
  632           }
  633           String sbdry = "[";
  634           String ebdry = "]";
  635           StringBuffer argBuf = new StringBuffer(sbdry);
  636           for (int i = 0; i < arguments.length; i++) {
  637               if (i > 0) {
  638                   argBuf.append(", ");
  639               }
  640               argBuf.append(format(arguments[i], false));
  641           }
  642           argBuf.append(ebdry);
  643           return argBuf.toString();
  644       }
  645   
  646       public static List createRange(Object from, Object to, boolean inclusive) {
  647           try {
  648               return ScriptBytecodeAdapter.createRange(from, to, inclusive);
  649           } catch (RuntimeException re) {
  650               throw re;
  651           } catch (Error e) {
  652               throw e;
  653           } catch (Throwable t) {
  654               throw new RuntimeException(t);
  655           }
  656       }
  657   
  658       public static Object bitwiseNegate(Object value) {
  659           if (value instanceof Integer) {
  660               Integer number = (Integer) value;
  661               return Integer.valueOf(~number.intValue());
  662           }
  663           if (value instanceof Long) {
  664               Long number = (Long) value;
  665               return new Long(~number.longValue());
  666           }
  667           if (value instanceof BigInteger) {
  668               return ((BigInteger) value).not();
  669           }
  670           if (value instanceof String) {
  671               // value is a regular expression.
  672               return DefaultGroovyMethods.bitwiseNegate(value.toString());
  673           }
  674           if (value instanceof GString) {
  675               // value is a regular expression.
  676               return DefaultGroovyMethods.bitwiseNegate(value.toString());
  677           }
  678           if (value instanceof ArrayList) {
  679               // value is an list.
  680               List newlist = new ArrayList();
  681               Iterator it = ((ArrayList) value).iterator();
  682               for (; it.hasNext();) {
  683                   newlist.add(bitwiseNegate(it.next()));
  684               }
  685               return newlist;
  686           }
  687           return invokeMethod(value, "bitwiseNegate", EMPTY_ARGS);
  688       }
  689   
  690       public static MetaClassRegistry getMetaRegistry() {
  691           return metaRegistry;
  692       }
  693   
  694       public static MetaClass getMetaClass(Object object) {
  695           if (object instanceof GroovyObject)
  696               return ((GroovyObject) object).getMetaClass();
  697           else
  698               return ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(object);
  699       }
  700   
  701       public static MetaClass getMetaClass(Class cls) {
  702           return metaRegistry.getMetaClass(cls);
  703       }
  704   
  705       /**
  706        * Invokes the given method on the object.
  707        */
  708       public static Object invokeMethod(Object object, String methodName, Object arguments) {
  709           if (object == null) {
  710               object = NullObject.getNullObject();
  711               //throw new NullPointerException("Cannot invoke method " + methodName + "() on null object");
  712           }
  713   
  714           // if the object is a Class, call a static method from that class
  715           if (object instanceof Class) {
  716               Class theClass = (Class) object;
  717               MetaClass metaClass = metaRegistry.getMetaClass(theClass);
  718               return metaClass.invokeStaticMethod(object, methodName, asArray(arguments));
  719           }
  720   
  721           // it's an instance; check if it's a Java one
  722           if (!(object instanceof GroovyObject)) {
  723               return invokePojoMethod(object, methodName, arguments);
  724           }
  725   
  726           // a groovy instance (including builder, closure, ...)
  727           return invokePogoMethod(object, methodName, arguments);
  728       }
  729   
  730       static Object invokePojoMethod(Object object, String methodName, Object arguments) {
  731           MetaClass metaClass = InvokerHelper.getMetaClass(object);
  732           return metaClass.invokeMethod(object, methodName, asArray(arguments));
  733       }
  734   
  735       static Object invokePogoMethod(Object object, String methodName, Object arguments) {
  736           GroovyObject groovy = (GroovyObject) object;
  737           boolean intercepting = groovy instanceof GroovyInterceptable;
  738           try {
  739               // if it's a pure interceptable object (even intercepting toString(), clone(), ...)
  740               if (intercepting) {
  741                   return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
  742               }
  743               //else try a statically typed method or a GDK method
  744               return groovy.getMetaClass().invokeMethod(object, methodName, asArray(arguments));
  745           } catch (MissingMethodException e) {
  746               if (e instanceof MissingMethodExecutionFailed) {
  747                   throw (MissingMethodException) e.getCause();
  748               } else if (!intercepting && e.getMethod().equals(methodName) && object.getClass() == e.getType()) {
  749                   // in case there's nothing else, invoke the object's own invokeMethod()
  750                   return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
  751               } else {
  752                   throw e;
  753               }
  754           }
  755       }
  756   
  757       public static Object invokeSuperMethod(Object object, String methodName, Object arguments) {
  758           if (object == null) {
  759               throw new NullPointerException("Cannot invoke method " + methodName + "() on null object");
  760           }
  761   
  762           Class theClass = object.getClass();
  763   
  764           MetaClass metaClass = metaRegistry.getMetaClass(theClass.getSuperclass());
  765           return metaClass.invokeMethod(object, methodName, asArray(arguments));
  766       }
  767   
  768       public static Object invokeStaticMethod(Class type, String method, Object arguments) {
  769           MetaClass metaClass = metaRegistry.getMetaClass(type);
  770           return metaClass.invokeStaticMethod(type, method, asArray(arguments));
  771       }
  772   
  773       public static Object invokeConstructorOf(Class type, Object arguments) {
  774           MetaClass metaClass = metaRegistry.getMetaClass(type);
  775           return metaClass.invokeConstructor(asArray(arguments));
  776       }
  777   
  778       /**
  779        * Converts the given object into an array; if its an array then just
  780        * cast otherwise wrap it in an array
  781        */
  782       public static Object[] asArray(Object arguments) {
  783   
  784       	if (arguments == null) {
  785       		return EMPTY_ARGUMENTS;
  786       	}
  787       	if (arguments instanceof Object[]) {
  788       		return  (Object[]) arguments;
  789       	}
  790       	return new Object[]{arguments};
  791       }
  792   
  793       public static Object[] asUnwrappedArray(Object arguments) {
  794   
  795           Object[] args = asArray(arguments);
  796   
  797           for (int i=0; i<args.length; i++) {
  798               if (args[i] instanceof PojoWrapper) {
  799                   args[i] = ((PojoWrapper)args[i]).unwrap();
  800               }
  801           }
  802   
  803           return args;
  804       }
  805   }

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