| /* |
| * Copyright 2003-2007 the original author or authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.codehaus.groovy.runtime; |
| |
| import groovy.lang.*; |
| import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; |
| import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper; |
| import org.codehaus.groovy.runtime.wrappers.PojoWrapper; |
| import org.codehaus.groovy.runtime.wrappers.Wrapper; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| /** |
| * A static helper class to interface bytecode and runtime |
| * |
| * @author Jochen Theodorou |
| * @version $Revision$ |
| */ |
| public class ScriptBytecodeAdapter { |
| public static final Object[] EMPTY_ARGS = {}; |
| private static final Integer ZERO = new Integer(0); |
| private static final Integer MINUS_ONE = new Integer(-1); |
| private static final Integer ONE = new Integer(1); |
| |
| // -------------------------------------------------------- |
| // exception handling |
| // -------------------------------------------------------- |
| private static Object unwrap(GroovyRuntimeException gre) throws Throwable { |
| Throwable th = gre; |
| if (th.getCause() != null && th.getCause() != gre) th = th.getCause(); |
| if (th != gre && (th instanceof GroovyRuntimeException)) unwrap((GroovyRuntimeException) th); |
| throw th; |
| } |
| |
| // -------------------------------------------------------- |
| // methods for this |
| // -------------------------------------------------------- |
| public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| Object result = null; |
| try { |
| try { |
| // if it's a pure interceptable object (even intercepting toString(), clone(), ...) |
| if (receiver instanceof GroovyInterceptable) { |
| result = receiver.invokeMethod(messageName, messageArguments); |
| } |
| //else if there's a statically typed method or a GDK method |
| else { |
| result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true); |
| } |
| } catch (MissingMethodException e) { |
| if (receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) { |
| // in case there's nothing else, invoke the object's own invokeMethod() |
| result = receiver.invokeMethod(messageName, messageArguments); |
| } else { |
| throw e; |
| } |
| } |
| } catch (GroovyRuntimeException t) { |
| unwrap(t); |
| } |
| return result; |
| } |
| |
| public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnCurrentN(senderClass, receiver, messageName, messageArguments); |
| } |
| |
| public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| if (!(receiver instanceof List)) |
| return invokeMethodOnCurrentN(senderClass, receiver, messageName, messageArguments); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments)); |
| } |
| return answer; |
| } |
| |
| public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return invokeMethodOnCurrentN(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnCurrentNSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnCurrentNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| // -------------------------------------------------------- |
| // methods for super |
| // -------------------------------------------------------- |
| public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| MetaClass metaClass = receiver.getMetaClass(); |
| // ignore interception and missing method fallback |
| Object result = null; |
| try { |
| result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true); |
| } catch (GroovyRuntimeException t) { |
| unwrap(t); |
| } |
| return result; |
| } |
| |
| public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments); |
| } |
| |
| public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| if (!(receiver instanceof List)) |
| return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments)); |
| } |
| return answer; |
| } |
| |
| public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return invokeMethodOnSuperN(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnSuperNSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable { |
| return invokeMethodOnSuperNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| // -------------------------------------------------------- |
| // normal method invocation |
| // -------------------------------------------------------- |
| public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable { |
| try { |
| return InvokerHelper.invokeMethod(receiver, messageName, messageArguments); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable { |
| if (receiver == null) return null; |
| return invokeMethodN(senderClass, receiver, messageName, messageArguments); |
| } |
| |
| public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable { |
| if (receiver == null) return null; |
| if (receiver.getClass().isArray()) { |
| return invokeMethodNSpreadSafeArray(senderClass, receiver, messageName, messageArguments); |
| } |
| if (receiver instanceof List) { |
| List answer = new ArrayList(); |
| for (Iterator it = ((List) receiver).iterator(); it.hasNext();) { |
| answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments)); |
| } |
| return answer; |
| } |
| return invokeMethodN(senderClass, receiver, messageName, messageArguments); |
| } |
| |
| private static Object invokeMethodNSpreadSafeArray(Class senderClass, Object receiver, String messageName, |
| Object[] messageArguments) throws Throwable { |
| List answer = new ArrayList(); |
| // assume we want to box if we are going to apply a method |
| boolean mustBox = receiver.getClass().getComponentType().isPrimitive(); |
| Object[] arrayItems = mustBox ? getBoxedItems(receiver) : (Object[]) receiver; |
| for (int i = 0; i < arrayItems.length; i++) { |
| answer.add(invokeMethodNSafe(senderClass, arrayItems[i], messageName, messageArguments)); |
| } |
| return answer; |
| } |
| |
| private static Object[] getBoxedItems(Object receiver) { |
| return DefaultTypeTransformation.primitiveArrayToList(receiver).toArray(); |
| } |
| |
| public static Object invokeMethod0(Class senderClass, Object receiver, String messageName) throws Throwable { |
| return invokeMethodN(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| return invokeMethodNSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| return invokeMethodNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| // -------------------------------------------------------- |
| // static normal method invocation |
| // -------------------------------------------------------- |
| public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable { |
| try { |
| return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName) throws Throwable { |
| return invokeStaticMethodN(senderClass, receiver, messageName, EMPTY_ARGS); |
| } |
| |
| // -------------------------------------------------------- |
| // normal constructor invocation (via new) |
| // -------------------------------------------------------- |
| public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable { |
| try { |
| return InvokerHelper.invokeConstructorOf(receiver, arguments); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable { |
| return invokeNewN(senderClass, receiver, EMPTY_ARGS); |
| } |
| |
| // -------------------------------------------------------- |
| // special constructor invocation (via this/super) |
| // -------------------------------------------------------- |
| |
| public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfCosntructors, Class which) { |
| MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(which); |
| return metaClass.selectConstructorAndTransformArguments(numberOfCosntructors, arguments); |
| } |
| |
| // -------------------------------------------------------- |
| // field handling super: get |
| // -------------------------------------------------------- |
| |
| public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| if (receiver instanceof Class) { |
| return InvokerHelper.getAttribute(receiver, messageName); |
| } else { |
| MetaClass mc = ((GroovyObject) receiver).getMetaClass(); |
| return mc.getAttribute(senderClass, receiver, messageName, true); |
| } |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| return getFieldOnSuper(senderClass, receiver, messageName); |
| } |
| |
| public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (!(receiver instanceof List)) return getFieldOnSuper(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getFieldOnSuper(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // field handling super: set |
| // -------------------------------------------------------- |
| |
| public static void setFieldOnSuper(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| if (receiver instanceof Class) { |
| InvokerHelper.setAttribute(receiver, messageName, messageArgument); |
| } else { |
| MetaClass mc = ((GroovyObject) receiver).getMetaClass(); |
| mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true); |
| } |
| } catch (GroovyRuntimeException gre) { |
| unwrap(gre); |
| } |
| } |
| |
| public static void setFieldOnSuperSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| setFieldOnSuper(messageArgument, senderClass, receiver, messageName); |
| } |
| |
| public static void setFieldOnSuperSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (!(receiver instanceof List)) { |
| setFieldOnSuper(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setFieldOnSuper(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // -------------------------------------------------------- |
| // normal field handling : get |
| // -------------------------------------------------------- |
| |
| public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| return InvokerHelper.getAttribute(receiver, messageName); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| return getField(senderClass, receiver, messageName); |
| } |
| |
| public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| if (!(receiver instanceof List)) return getField(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getFieldSafe(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // normal field handling : set |
| // -------------------------------------------------------- |
| |
| public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| InvokerHelper.setAttribute(receiver, messageName, messageArgument); |
| } catch (GroovyRuntimeException gre) { |
| unwrap(gre); |
| } |
| } |
| |
| public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| setField(messageArgument, senderClass, receiver, messageName); |
| } |
| |
| public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| if (!(receiver instanceof List)) { |
| setField(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setFieldSafe(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // -------------------------------------------------------- |
| // normal GroovyObject field handling : get |
| // -------------------------------------------------------- |
| |
| public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return receiver.getMetaClass().getAttribute(receiver, messageName); |
| } |
| |
| public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| return receiver.getMetaClass().getAttribute(receiver, messageName); |
| } |
| |
| public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| if (!(receiver instanceof List)) return getGroovyObjectField(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getFieldSafe(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // normal field handling : set |
| // -------------------------------------------------------- |
| |
| public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument); |
| } |
| |
| public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument); |
| } |
| |
| public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| if (!(receiver instanceof List)) { |
| setGroovyObjectField(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setFieldSafe(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // -------------------------------------------------------- |
| // Property handling super: get |
| // -------------------------------------------------------- |
| |
| public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return invokeMethodOnSuperN(senderClass, receiver, "getProperty", new Object[]{messageName}); |
| } |
| |
| public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return getPropertyOnSuper(senderClass, receiver, messageName); |
| } |
| |
| public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (!(receiver instanceof List)) return getPropertyOnSuper(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getPropertySafe(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // Property handling super: set |
| // -------------------------------------------------------- |
| |
| public static void setPropertyOnSuper(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| try { |
| InvokerHelper.setAttribute(receiver, messageName, messageArgument); |
| } catch (GroovyRuntimeException gre) { |
| unwrap(gre); |
| } |
| } |
| |
| public static void setPropertyOnSuperSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| setPropertyOnSuper(messageArgument, senderClass, receiver, messageName); |
| } |
| |
| public static void setPropertyOnSuperSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (!(receiver instanceof List)) { |
| setPropertyOnSuper(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setPropertySafe(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // -------------------------------------------------------- |
| // normal Property handling : get |
| // -------------------------------------------------------- |
| |
| public static Object getProperty(Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| return InvokerHelper.getProperty(receiver, messageName); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object getPropertySafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| return getProperty(senderClass, receiver, messageName); |
| } |
| |
| public static Object getPropertySpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| if (!(receiver instanceof List)) return getProperty(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getPropertySafe(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // normal Property handling : set |
| // -------------------------------------------------------- |
| |
| public static void setProperty(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| try { |
| InvokerHelper.setProperty(receiver, messageName, messageArgument); |
| } catch (GroovyRuntimeException gre) { |
| unwrap(gre); |
| } |
| } |
| |
| public static void setPropertySafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| setProperty(messageArgument, senderClass, receiver, messageName); |
| } |
| |
| public static void setPropertySpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| if (!(receiver instanceof List)) { |
| setProperty(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setPropertySafe(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // -------------------------------------------------------- |
| // normal GroovyObject Property handling : get |
| // -------------------------------------------------------- |
| |
| public static Object getGroovyObjectProperty(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| return receiver.getProperty(messageName); |
| } |
| |
| public static Object getGroovyObjectPropertySafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| return getGroovyObjectProperty(senderClass, receiver, messageName); |
| } |
| |
| public static Object getGroovyObjectPropertySpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return null; |
| if (!(receiver instanceof List)) return getGroovyObjectProperty(senderClass, receiver, messageName); |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| answer.add(getPropertySafe(senderClass, it.next(), messageName)); |
| } |
| return answer; |
| } |
| |
| // -------------------------------------------------------- |
| // normal GroovyObject Property handling : set |
| // -------------------------------------------------------- |
| |
| public static void setGroovyObjectProperty(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| receiver.setProperty(messageName, messageArgument); |
| } |
| |
| public static void setGroovyObjectPropertySafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| receiver.setProperty(messageName, messageArgument); |
| } |
| |
| public static void setGroovyObjectPropertySpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable { |
| if (receiver == null) return; |
| if (!(receiver instanceof List)) { |
| setProperty(messageArgument, senderClass, receiver, messageName); |
| return; |
| } |
| |
| List list = (List) receiver; |
| List answer = new ArrayList(); |
| for (Iterator it = list.iterator(); it.hasNext();) { |
| setPropertySafe(messageArgument, senderClass, it.next(), messageName); |
| } |
| } |
| |
| // ********************************************************************************** |
| // ********************************************************************************** |
| // ************** methods not covered by the new MOP ************** |
| // ********************************************************************************** |
| // ********************************************************************************** |
| |
| // -------------------------------------------------------- |
| // Closures |
| // -------------------------------------------------------- |
| |
| /** |
| * Returns the method pointer for the given object name |
| */ |
| public static Closure getMethodPointer(Object object, String methodName) { |
| return InvokerHelper.getMethodPointer(object, methodName); |
| } |
| |
| // TODO: set sender class |
| public static Object invokeClosure(Object closure, Object[] arguments) throws Throwable { |
| return invokeMethodN(closure.getClass(), closure, "doCall", arguments); |
| } |
| |
| // -------------------------------------------------------- |
| // type conversion |
| // -------------------------------------------------------- |
| |
| /** |
| * Provides a hook for type coercion of the given object to the required type |
| * |
| * @param type of object to convert the given object to |
| * @param object the object to be converted |
| * @return the original object or a new converted value |
| * @throws Throwable |
| */ |
| public static Object asType(Object object, Class type) throws Throwable { |
| if (object == null) object = NullObject.getNullObject(); |
| return invokeMethodN(object.getClass(), object, "asType", new Object[]{type}); |
| } |
| |
| /** |
| * Provides a hook for type casting of the given object to the required type |
| * |
| * @param type of object to convert the given object to |
| * @param object the object to be converted |
| * @return the original object or a new converted value |
| * @throws Throwable |
| */ |
| public static Object castToType(Object object, Class type) throws Throwable { |
| try { |
| return DefaultTypeTransformation.castToType(object, type); |
| } catch (GroovyRuntimeException gre) { |
| return (Matcher) unwrap(gre); |
| } |
| } |
| |
| public static Tuple createTuple(Object[] array) { |
| return new Tuple(array); |
| } |
| |
| public static List createList(Object[] values) { |
| return InvokerHelper.createList(values); |
| } |
| |
| public static Wrapper createPojoWrapper(Object val, Class clazz) { |
| return new PojoWrapper(val, clazz); |
| } |
| |
| public static Wrapper createGroovyObjectWrapper(GroovyObject val, Class clazz) { |
| return new GroovyObjectWrapper(val, clazz); |
| } |
| |
| public static Map createMap(Object[] values) { |
| return InvokerHelper.createMap(values); |
| } |
| |
| |
| //TODO: refactor |
| public static List createRange(Object from, Object to, boolean inclusive) throws Throwable { |
| if (!inclusive) { |
| if (compareEqual(from, to)) { |
| return new EmptyRange((Comparable) from); |
| } |
| if (compareGreaterThan(from, to)) { |
| to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next"); |
| } else { |
| to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous"); |
| } |
| } |
| if (from instanceof Integer && to instanceof Integer) { |
| return new IntRange(DefaultTypeTransformation.intUnbox(from), DefaultTypeTransformation.intUnbox(to)); |
| } else { |
| return new ObjectRange((Comparable) from, (Comparable) to); |
| } |
| } |
| |
| //assert |
| public static void assertFailed(Object expression, Object message) { |
| InvokerHelper.assertFailed(expression, message); |
| } |
| |
| //isCase |
| //TODO: set sender class |
| public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable { |
| if (caseExpression == null) { |
| return switchValue == null; |
| } |
| return DefaultTypeTransformation.castToBoolean(invokeMethodN(caseExpression.getClass(), caseExpression, "isCase", new Object[]{switchValue})); |
| } |
| |
| //compare |
| public static boolean compareIdentical(Object left, Object right) { |
| return left == right; |
| } |
| |
| public static boolean compareEqual(Object left, Object right) { |
| return DefaultTypeTransformation.compareEqual(left, right); |
| } |
| |
| public static boolean compareNotEqual(Object left, Object right) { |
| return !compareEqual(left, right); |
| } |
| |
| public static Integer compareTo(Object left, Object right) { |
| int answer = DefaultTypeTransformation.compareTo(left, right); |
| if (answer == 0) { |
| return ZERO; |
| } else { |
| return answer > 0 ? ONE : MINUS_ONE; |
| } |
| } |
| |
| public static boolean compareLessThan(Object left, Object right) { |
| return compareTo(left, right).intValue() < 0; |
| } |
| |
| public static boolean compareLessThanEqual(Object left, Object right) { |
| return compareTo(left, right).intValue() <= 0; |
| } |
| |
| public static boolean compareGreaterThan(Object left, Object right) { |
| return compareTo(left, right).intValue() > 0; |
| } |
| |
| public static boolean compareGreaterThanEqual(Object left, Object right) { |
| return compareTo(left, right).intValue() >= 0; |
| } |
| |
| //regexpr |
| public static Pattern regexPattern(Object regex) { |
| return DefaultGroovyMethods.negate(regex.toString()); |
| } |
| |
| public static Matcher findRegex(Object left, Object right) throws Throwable { |
| try { |
| return InvokerHelper.findRegex(left, right); |
| } catch (GroovyRuntimeException gre) { |
| return (Matcher) unwrap(gre); |
| } |
| } |
| |
| public static boolean matchRegex(Object left, Object right) { |
| return InvokerHelper.matchRegex(left, right); |
| } |
| |
| |
| //spread expressions |
| public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) { |
| List ret = new ArrayList(); |
| int argsPos = 0; |
| int spreadPos = 0; |
| for (int pos = 0; pos < positions.length; pos++) { |
| for (; argsPos < positions[pos]; argsPos++) { |
| ret.add(args[argsPos]); |
| } |
| Object value = spreads[spreadPos]; |
| if (value == null) { |
| ret.add(null); |
| } else if (value instanceof List) { |
| ret.addAll((List) value); |
| } else if (value.getClass().isArray()) { |
| ret.addAll(DefaultTypeTransformation.primitiveArrayToList(value)); |
| } else { |
| throw new IllegalArgumentException("cannot spread the type " + value.getClass().getName() + " with value " + value); |
| } |
| spreadPos++; |
| } |
| for (; argsPos < args.length; argsPos++) { |
| ret.add(args[argsPos]); |
| } |
| return ret.toArray(); |
| } |
| |
| public static Object spreadMap(Object value) { |
| return InvokerHelper.spreadMap(value); |
| } |
| |
| //negation |
| public static Object negate(Object value) throws Throwable { |
| try { |
| return InvokerHelper.negate(value); |
| } catch (GroovyRuntimeException gre) { |
| return unwrap(gre); |
| } |
| } |
| |
| public static Object bitNegate(Object value) { |
| return InvokerHelper.bitNegate(value); |
| } |
| |
| public static MetaClass initMetaClass(Object object) { |
| return InvokerHelper.getMetaClass(object); |
| } |
| |
| private static MetaClass getMetaClassObjectNotNull(Object object) { |
| if (!(object instanceof GroovyObject)) { |
| return initMetaClass(object); |
| } else { |
| return ((GroovyObject) object).getMetaClass(); |
| } |
| } |
| |
| |
| } |