0001: /*
0002: $Id: ScriptBytecodeAdapter.java 4294 2006-12-02 19:31:27Z blackdrag $
0003:
0004: Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
0005:
0006: Redistribution and use of this software and associated documentation
0007: ("Software"), with or without modification, are permitted provided
0008: that the following conditions are met:
0009:
0010: 1. Redistributions of source code must retain copyright
0011: statements and notices. Redistributions must also contain a
0012: copy of this document.
0013:
0014: 2. Redistributions in binary form must reproduce the
0015: above copyright notice, this list of conditions and the
0016: following disclaimer in the documentation and/or other
0017: materials provided with the distribution.
0018:
0019: 3. The name "groovy" must not be used to endorse or promote
0020: products derived from this Software without prior written
0021: permission of The Codehaus. For written permission,
0022: please contact info@codehaus.org.
0023:
0024: 4. Products derived from this Software may not be called "groovy"
0025: nor may "groovy" appear in their names without prior written
0026: permission of The Codehaus. "groovy" is a registered
0027: trademark of The Codehaus.
0028:
0029: 5. Due credit should be given to The Codehaus -
0030: http://groovy.codehaus.org/
0031:
0032: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
0033: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
0034: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
0035: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
0036: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
0037: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0038: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
0039: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0040: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0041: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0042: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
0043: OF THE POSSIBILITY OF SUCH DAMAGE.
0044:
0045: */
0046: package org.codehaus.groovy.runtime;
0047:
0048: import groovy.lang.*;
0049:
0050: import java.util.Iterator;
0051: import java.util.List;
0052: import java.util.ArrayList;
0053: import java.util.Map;
0054: import java.util.regex.Matcher;
0055: import java.util.regex.Pattern;
0056:
0057: import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
0058: import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
0059: import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
0060: import org.codehaus.groovy.runtime.wrappers.Wrapper;
0061:
0062: /**
0063: * A static helper class to interface bytecode and runtime
0064: *
0065: * @author Jochen Theodorou
0066: * @version $Revision: 4294 $
0067: */
0068: public class ScriptBytecodeAdapter {
0069: public static final Object[] EMPTY_ARGS = {};
0070: private static final Integer ZERO = new Integer(0);
0071: private static final Integer MINUS_ONE = new Integer(-1);
0072: private static final Integer ONE = new Integer(1);
0073:
0074: // --------------------------------------------------------
0075: // exception handling
0076: // --------------------------------------------------------
0077: private static Object unwrap(GroovyRuntimeException gre)
0078: throws Throwable {
0079: Throwable th = gre;
0080: if (th.getCause() != null && th.getCause() != gre)
0081: th = th.getCause();
0082: if (th != gre && (th instanceof GroovyRuntimeException))
0083: unwrap((GroovyRuntimeException) th);
0084: throw th;
0085: }
0086:
0087: // --------------------------------------------------------
0088: // methods for this
0089: // --------------------------------------------------------
0090: public static Object invokeMethodOnCurrentN(Class senderClass,
0091: GroovyObject receiver, String messageName,
0092: Object[] messageArguments) throws Throwable {
0093: Object result = null;
0094: try {
0095: try {
0096: // if it's a pure interceptable object (even intercepting toString(), clone(), ...)
0097: if (receiver instanceof GroovyInterceptable) {
0098: result = receiver.invokeMethod(messageName,
0099: messageArguments);
0100: }
0101: //else if there's a statically typed method or a GDK method
0102: else {
0103: result = receiver.getMetaClass().invokeMethod(
0104: senderClass, receiver, messageName,
0105: messageArguments, false, true);
0106: }
0107: } catch (MissingMethodException e) {
0108: if (receiver.getClass() == e.getType()
0109: && e.getMethod().equals(messageName)) {
0110: // in case there's nothing else, invoke the object's own invokeMethod()
0111: result = receiver.invokeMethod(messageName,
0112: messageArguments);
0113: } else {
0114: throw e;
0115: }
0116: }
0117: } catch (GroovyRuntimeException t) {
0118: unwrap(t);
0119: }
0120: return result;
0121: }
0122:
0123: public static Object invokeMethodOnCurrentNSafe(Class senderClass,
0124: GroovyObject receiver, String messageName,
0125: Object[] messageArguments) throws Throwable {
0126: return invokeMethodOnCurrentN(senderClass, receiver,
0127: messageName, messageArguments);
0128: }
0129:
0130: public static Object invokeMethodOnCurrentNSpreadSafe(
0131: Class senderClass, GroovyObject receiver,
0132: String messageName, Object[] messageArguments)
0133: throws Throwable {
0134: if (!(receiver instanceof List))
0135: return invokeMethodOnCurrentN(senderClass, receiver,
0136: messageName, messageArguments);
0137:
0138: List list = (List) receiver;
0139: List answer = new ArrayList();
0140: for (Iterator it = list.iterator(); it.hasNext();) {
0141: answer.add(invokeMethodNSafe(senderClass, it.next(),
0142: messageName, messageArguments));
0143: }
0144: return answer;
0145: }
0146:
0147: public static Object invokeMethodOnCurrent0(Class senderClass,
0148: GroovyObject receiver, String messageName) throws Throwable {
0149: return invokeMethodOnCurrentN(senderClass, receiver,
0150: messageName, EMPTY_ARGS);
0151: }
0152:
0153: public static Object invokeMethodOnCurrent0Safe(Class senderClass,
0154: GroovyObject receiver, String messageName,
0155: Object[] messageArguments) throws Throwable {
0156: return invokeMethodOnCurrentNSafe(senderClass, receiver,
0157: messageName, EMPTY_ARGS);
0158: }
0159:
0160: public static Object invokeMethodOnCurrent0SpreadSafe(
0161: Class senderClass, GroovyObject receiver,
0162: String messageName, Object[] messageArguments)
0163: throws Throwable {
0164: return invokeMethodOnCurrentNSpreadSafe(senderClass, receiver,
0165: messageName, EMPTY_ARGS);
0166: }
0167:
0168: // --------------------------------------------------------
0169: // methods for super
0170: // --------------------------------------------------------
0171: public static Object invokeMethodOnSuperN(Class senderClass,
0172: GroovyObject receiver, String messageName,
0173: Object[] messageArguments) throws Throwable {
0174: MetaClass metaClass = receiver.getMetaClass();
0175: // ignore interception and missing method fallback
0176: Object result = null;
0177: try {
0178: result = metaClass.invokeMethod(senderClass, receiver,
0179: messageName, messageArguments, true, true);
0180: } catch (GroovyRuntimeException t) {
0181: unwrap(t);
0182: }
0183: return result;
0184: }
0185:
0186: public static Object invokeMethodOnSuperNSafe(Class senderClass,
0187: GroovyObject receiver, String messageName,
0188: Object[] messageArguments) throws Throwable {
0189: return invokeMethodOnSuperN(senderClass, receiver, messageName,
0190: messageArguments);
0191: }
0192:
0193: public static Object invokeMethodOnSuperNSpreadSafe(
0194: Class senderClass, GroovyObject receiver,
0195: String messageName, Object[] messageArguments)
0196: throws Throwable {
0197: if (!(receiver instanceof List))
0198: return invokeMethodOnSuperN(senderClass, receiver,
0199: messageName, messageArguments);
0200:
0201: List list = (List) receiver;
0202: List answer = new ArrayList();
0203: for (Iterator it = list.iterator(); it.hasNext();) {
0204: answer.add(invokeMethodNSafe(senderClass, it.next(),
0205: messageName, messageArguments));
0206: }
0207: return answer;
0208: }
0209:
0210: public static Object invokeMethodOnSuper0(Class senderClass,
0211: GroovyObject receiver, String messageName) throws Throwable {
0212: return invokeMethodOnSuperN(senderClass, receiver, messageName,
0213: EMPTY_ARGS);
0214: }
0215:
0216: public static Object invokeMethodOnSuper0Safe(Class senderClass,
0217: GroovyObject receiver, String messageName,
0218: Object[] messageArguments) throws Throwable {
0219: return invokeMethodOnSuperNSafe(senderClass, receiver,
0220: messageName, EMPTY_ARGS);
0221: }
0222:
0223: public static Object invokeMethodOnSuper0SpreadSafe(
0224: Class senderClass, GroovyObject receiver,
0225: String messageName, Object[] messageArguments)
0226: throws Throwable {
0227: return invokeMethodOnSuperNSpreadSafe(senderClass, receiver,
0228: messageName, EMPTY_ARGS);
0229: }
0230:
0231: // --------------------------------------------------------
0232: // normal method invocation
0233: // --------------------------------------------------------
0234: public static Object invokeMethodN(Class senderClass,
0235: Object receiver, String messageName,
0236: Object[] messageArguments) throws Throwable {
0237: try {
0238: return InvokerHelper.invokeMethod(receiver, messageName,
0239: messageArguments);
0240: } catch (GroovyRuntimeException gre) {
0241: return unwrap(gre);
0242: }
0243: }
0244:
0245: public static Object invokeMethodNSafe(Class senderClass,
0246: Object receiver, String messageName,
0247: Object[] messageArguments) throws Throwable {
0248: if (receiver == null)
0249: return null;
0250: return invokeMethodN(senderClass, receiver, messageName,
0251: messageArguments);
0252: }
0253:
0254: public static Object invokeMethodNSpreadSafe(Class senderClass,
0255: Object receiver, String messageName,
0256: Object[] messageArguments) throws Throwable {
0257: if (receiver == null)
0258: return null;
0259: if (!(receiver instanceof List))
0260: return invokeMethodN(senderClass, receiver, messageName,
0261: messageArguments);
0262:
0263: List list = (List) receiver;
0264: List answer = new ArrayList();
0265: for (Iterator it = list.iterator(); it.hasNext();) {
0266: answer.add(invokeMethodNSafe(senderClass, it.next(),
0267: messageName, messageArguments));
0268: }
0269: return answer;
0270: }
0271:
0272: public static Object invokeMethod0(Class senderClass,
0273: Object receiver, String messageName) throws Throwable {
0274: return invokeMethodN(senderClass, receiver, messageName,
0275: EMPTY_ARGS);
0276: }
0277:
0278: public static Object invokeMethod0Safe(Class senderClass,
0279: Object receiver, String messageName) throws Throwable {
0280: if (receiver == null)
0281: return null;
0282: return invokeMethodNSafe(senderClass, receiver, messageName,
0283: EMPTY_ARGS);
0284: }
0285:
0286: public static Object invokeMethod0SpreadSafe(Class senderClass,
0287: Object receiver, String messageName) throws Throwable {
0288: return invokeMethodNSpreadSafe(senderClass, receiver,
0289: messageName, EMPTY_ARGS);
0290: }
0291:
0292: // --------------------------------------------------------
0293: // static normal method invocation
0294: // --------------------------------------------------------
0295: public static Object invokeStaticMethodN(Class senderClass,
0296: Class receiver, String messageName,
0297: Object[] messageArguments) throws Throwable {
0298: try {
0299: return InvokerHelper.invokeStaticMethod(receiver,
0300: messageName, messageArguments);
0301: } catch (GroovyRuntimeException gre) {
0302: return unwrap(gre);
0303: }
0304: }
0305:
0306: public static Object invokeStaticMethod0(Class senderClass,
0307: Class receiver, String messageName) throws Throwable {
0308: return invokeStaticMethodN(senderClass, receiver, messageName,
0309: EMPTY_ARGS);
0310: }
0311:
0312: // --------------------------------------------------------
0313: // normal constructor invocation (via new)
0314: // --------------------------------------------------------
0315: public static Object invokeNewN(Class senderClass, Class receiver,
0316: Object arguments) throws Throwable {
0317: try {
0318: return InvokerHelper.invokeConstructorOf(receiver,
0319: arguments);
0320: } catch (GroovyRuntimeException gre) {
0321: return unwrap(gre);
0322: }
0323: }
0324:
0325: public static Object invokeNew0(Class senderClass, Class receiver)
0326: throws Throwable {
0327: return invokeNewN(senderClass, receiver, EMPTY_ARGS);
0328: }
0329:
0330: // --------------------------------------------------------
0331: // special constructor invocation (via this/super)
0332: // --------------------------------------------------------
0333:
0334: public static int selectConstructorAndTransformArguments(
0335: Object[] arguments, int numberOfCosntructors, Class which) {
0336: MetaClassImpl metaClass = (MetaClassImpl) InvokerHelper
0337: .getInstance().getMetaRegistry().getMetaClass(which);
0338: return metaClass.selectConstructorAndTransformArguments(
0339: numberOfCosntructors, arguments);
0340: }
0341:
0342: // --------------------------------------------------------
0343: // field handling super: get
0344: // --------------------------------------------------------
0345:
0346: public static Object getFieldOnSuper(Class senderClass,
0347: Object receiver, String messageName) throws Throwable {
0348: try {
0349: if (receiver instanceof Class) {
0350: return InvokerHelper
0351: .getAttribute(receiver, messageName);
0352: } else {
0353: MetaClass mc = ((GroovyObject) receiver).getMetaClass();
0354: return mc.getAttribute(senderClass, receiver,
0355: messageName, true);
0356: }
0357: } catch (GroovyRuntimeException gre) {
0358: return unwrap(gre);
0359: }
0360: }
0361:
0362: public static Object getFieldOnSuperSafe(Class senderClass,
0363: Object receiver, String messageName) throws Throwable {
0364: return getFieldOnSuper(senderClass, receiver, messageName);
0365: }
0366:
0367: public static Object getFieldOnSuperSpreadSafe(Class senderClass,
0368: Object receiver, String messageName) throws Throwable {
0369: if (!(receiver instanceof List))
0370: return getFieldOnSuper(senderClass, receiver, messageName);
0371:
0372: List list = (List) receiver;
0373: List answer = new ArrayList();
0374: for (Iterator it = list.iterator(); it.hasNext();) {
0375: answer.add(getFieldOnSuper(senderClass, it.next(),
0376: messageName));
0377: }
0378: return answer;
0379: }
0380:
0381: // --------------------------------------------------------
0382: // field handling super: set
0383: // --------------------------------------------------------
0384:
0385: public static void setFieldOnSuper(Object messageArgument,
0386: Class senderClass, Object receiver, String messageName)
0387: throws Throwable {
0388: try {
0389: if (receiver instanceof Class) {
0390: InvokerHelper.setAttribute(receiver, messageName,
0391: messageArgument);
0392: } else {
0393: MetaClass mc = ((GroovyObject) receiver).getMetaClass();
0394: mc.setAttribute(senderClass, receiver, messageName,
0395: messageArgument, true, true);
0396: }
0397: } catch (GroovyRuntimeException gre) {
0398: unwrap(gre);
0399: }
0400: }
0401:
0402: public static void setFieldOnSuperSafe(Object messageArgument,
0403: Class senderClass, Object receiver, String messageName)
0404: throws Throwable {
0405: setFieldOnSuper(messageArgument, senderClass, receiver,
0406: messageName);
0407: }
0408:
0409: public static void setFieldOnSuperSpreadSafe(
0410: Object messageArgument, Class senderClass, Object receiver,
0411: String messageName) throws Throwable {
0412: if (!(receiver instanceof List)) {
0413: setFieldOnSuper(messageArgument, senderClass, receiver,
0414: messageName);
0415: return;
0416: }
0417:
0418: List list = (List) receiver;
0419: List answer = new ArrayList();
0420: for (Iterator it = list.iterator(); it.hasNext();) {
0421: setFieldOnSuper(messageArgument, senderClass, it.next(),
0422: messageName);
0423: }
0424: }
0425:
0426: // --------------------------------------------------------
0427: // normal field handling : get
0428: // --------------------------------------------------------
0429:
0430: public static Object getField(Class senderClass, Object receiver,
0431: String messageName) throws Throwable {
0432: try {
0433: return InvokerHelper.getAttribute(receiver, messageName);
0434: } catch (GroovyRuntimeException gre) {
0435: return unwrap(gre);
0436: }
0437: }
0438:
0439: public static Object getFieldSafe(Class senderClass,
0440: Object receiver, String messageName) throws Throwable {
0441: if (receiver == null)
0442: return null;
0443: return getField(senderClass, receiver, messageName);
0444: }
0445:
0446: public static Object getFieldSpreadSafe(Class senderClass,
0447: Object receiver, String messageName) throws Throwable {
0448: if (receiver == null)
0449: return null;
0450: if (!(receiver instanceof List))
0451: return getField(senderClass, receiver, messageName);
0452:
0453: List list = (List) receiver;
0454: List answer = new ArrayList();
0455: for (Iterator it = list.iterator(); it.hasNext();) {
0456: answer
0457: .add(getFieldSafe(senderClass, it.next(),
0458: messageName));
0459: }
0460: return answer;
0461: }
0462:
0463: // --------------------------------------------------------
0464: // normal field handling : set
0465: // --------------------------------------------------------
0466:
0467: public static void setField(Object messageArgument,
0468: Class senderClass, Object receiver, String messageName)
0469: throws Throwable {
0470: try {
0471: InvokerHelper.setAttribute(receiver, messageName,
0472: messageArgument);
0473: } catch (GroovyRuntimeException gre) {
0474: unwrap(gre);
0475: }
0476: }
0477:
0478: public static void setFieldSafe(Object messageArgument,
0479: Class senderClass, Object receiver, String messageName)
0480: throws Throwable {
0481: if (receiver == null)
0482: return;
0483: setField(messageArgument, senderClass, receiver, messageName);
0484: }
0485:
0486: public static void setFieldSpreadSafe(Object messageArgument,
0487: Class senderClass, Object receiver, String messageName)
0488: throws Throwable {
0489: if (receiver == null)
0490: return;
0491: if (!(receiver instanceof List)) {
0492: setField(messageArgument, senderClass, receiver,
0493: messageName);
0494: return;
0495: }
0496:
0497: List list = (List) receiver;
0498: List answer = new ArrayList();
0499: for (Iterator it = list.iterator(); it.hasNext();) {
0500: setFieldSafe(messageArgument, senderClass, it.next(),
0501: messageName);
0502: }
0503: }
0504:
0505: // --------------------------------------------------------
0506: // normal GroovyObject field handling : get
0507: // --------------------------------------------------------
0508:
0509: public static Object getGroovyObjectField(Class senderClass,
0510: GroovyObject receiver, String messageName) throws Throwable {
0511: return receiver.getMetaClass().getAttribute(receiver,
0512: messageName);
0513: }
0514:
0515: public static Object getGroovyObjectFieldSafe(Class senderClass,
0516: GroovyObject receiver, String messageName) throws Throwable {
0517: if (receiver == null)
0518: return null;
0519: return receiver.getMetaClass().getAttribute(receiver,
0520: messageName);
0521: }
0522:
0523: public static Object getGroovyObjectFieldSpreadSafe(
0524: Class senderClass, GroovyObject receiver, String messageName)
0525: throws Throwable {
0526: if (receiver == null)
0527: return null;
0528: if (!(receiver instanceof List))
0529: return getGroovyObjectField(senderClass, receiver,
0530: messageName);
0531:
0532: List list = (List) receiver;
0533: List answer = new ArrayList();
0534: for (Iterator it = list.iterator(); it.hasNext();) {
0535: answer
0536: .add(getFieldSafe(senderClass, it.next(),
0537: messageName));
0538: }
0539: return answer;
0540: }
0541:
0542: // --------------------------------------------------------
0543: // normal field handling : set
0544: // --------------------------------------------------------
0545:
0546: public static void setGroovyObjectField(Object messageArgument,
0547: Class senderClass, GroovyObject receiver, String messageName)
0548: throws Throwable {
0549: receiver.getMetaClass().setAttribute(receiver, messageName,
0550: messageArgument);
0551: }
0552:
0553: public static void setGroovyObjectFieldSafe(Object messageArgument,
0554: Class senderClass, GroovyObject receiver, String messageName)
0555: throws Throwable {
0556: if (receiver == null)
0557: return;
0558: receiver.getMetaClass().setAttribute(receiver, messageName,
0559: messageArgument);
0560: }
0561:
0562: public static void setGroovyObjectFieldSpreadSafe(
0563: Object messageArgument, Class senderClass,
0564: GroovyObject receiver, String messageName) throws Throwable {
0565: if (receiver == null)
0566: return;
0567: if (!(receiver instanceof List)) {
0568: setGroovyObjectField(messageArgument, senderClass,
0569: receiver, messageName);
0570: return;
0571: }
0572:
0573: List list = (List) receiver;
0574: List answer = new ArrayList();
0575: for (Iterator it = list.iterator(); it.hasNext();) {
0576: setFieldSafe(messageArgument, senderClass, it.next(),
0577: messageName);
0578: }
0579: }
0580:
0581: // --------------------------------------------------------
0582: // Property handling super: get
0583: // --------------------------------------------------------
0584:
0585: public static Object getPropertyOnSuper(Class senderClass,
0586: GroovyObject receiver, String messageName) throws Throwable {
0587: return invokeMethodOnSuperN(senderClass, receiver,
0588: "getProperty", new Object[] { messageName });
0589: }
0590:
0591: public static Object getPropertyOnSuperSafe(Class senderClass,
0592: GroovyObject receiver, String messageName) throws Throwable {
0593: return getPropertyOnSuper(senderClass, receiver, messageName);
0594: }
0595:
0596: public static Object getPropertyOnSuperSpreadSafe(
0597: Class senderClass, GroovyObject receiver, String messageName)
0598: throws Throwable {
0599: if (!(receiver instanceof List))
0600: return getPropertyOnSuper(senderClass, receiver,
0601: messageName);
0602:
0603: List list = (List) receiver;
0604: List answer = new ArrayList();
0605: for (Iterator it = list.iterator(); it.hasNext();) {
0606: answer.add(getPropertySafe(senderClass, it.next(),
0607: messageName));
0608: }
0609: return answer;
0610: }
0611:
0612: // --------------------------------------------------------
0613: // Property handling super: set
0614: // --------------------------------------------------------
0615:
0616: public static void setPropertyOnSuper(Object messageArgument,
0617: Class senderClass, GroovyObject receiver, String messageName)
0618: throws Throwable {
0619: try {
0620: InvokerHelper.setAttribute(receiver, messageName,
0621: messageArgument);
0622: } catch (GroovyRuntimeException gre) {
0623: unwrap(gre);
0624: }
0625: }
0626:
0627: public static void setPropertyOnSuperSafe(Object messageArgument,
0628: Class senderClass, GroovyObject receiver, String messageName)
0629: throws Throwable {
0630: setPropertyOnSuper(messageArgument, senderClass, receiver,
0631: messageName);
0632: }
0633:
0634: public static void setPropertyOnSuperSpreadSafe(
0635: Object messageArgument, Class senderClass,
0636: GroovyObject receiver, String messageName) throws Throwable {
0637: if (!(receiver instanceof List)) {
0638: setPropertyOnSuper(messageArgument, senderClass, receiver,
0639: messageName);
0640: return;
0641: }
0642:
0643: List list = (List) receiver;
0644: List answer = new ArrayList();
0645: for (Iterator it = list.iterator(); it.hasNext();) {
0646: setPropertySafe(messageArgument, senderClass, it.next(),
0647: messageName);
0648: }
0649: }
0650:
0651: // --------------------------------------------------------
0652: // normal Property handling : get
0653: // --------------------------------------------------------
0654:
0655: public static Object getProperty(Class senderClass,
0656: Object receiver, String messageName) throws Throwable {
0657: try {
0658: return InvokerHelper.getProperty(receiver, messageName);
0659: } catch (GroovyRuntimeException gre) {
0660: return unwrap(gre);
0661: }
0662: }
0663:
0664: public static Object getPropertySafe(Class senderClass,
0665: Object receiver, String messageName) throws Throwable {
0666: if (receiver == null)
0667: return null;
0668: return getProperty(senderClass, receiver, messageName);
0669: }
0670:
0671: public static Object getPropertySpreadSafe(Class senderClass,
0672: Object receiver, String messageName) throws Throwable {
0673: if (receiver == null)
0674: return null;
0675: if (!(receiver instanceof List))
0676: return getProperty(senderClass, receiver, messageName);
0677:
0678: List list = (List) receiver;
0679: List answer = new ArrayList();
0680: for (Iterator it = list.iterator(); it.hasNext();) {
0681: answer.add(getPropertySafe(senderClass, it.next(),
0682: messageName));
0683: }
0684: return answer;
0685: }
0686:
0687: // --------------------------------------------------------
0688: // normal Property handling : set
0689: // --------------------------------------------------------
0690:
0691: public static void setProperty(Object messageArgument,
0692: Class senderClass, Object receiver, String messageName)
0693: throws Throwable {
0694: try {
0695: InvokerHelper.setProperty(receiver, messageName,
0696: messageArgument);
0697: } catch (GroovyRuntimeException gre) {
0698: unwrap(gre);
0699: }
0700: }
0701:
0702: public static void setPropertySafe(Object messageArgument,
0703: Class senderClass, Object receiver, String messageName)
0704: throws Throwable {
0705: if (receiver == null)
0706: return;
0707: setProperty(messageArgument, senderClass, receiver, messageName);
0708: }
0709:
0710: public static void setPropertySpreadSafe(Object messageArgument,
0711: Class senderClass, Object receiver, String messageName)
0712: throws Throwable {
0713: if (receiver == null)
0714: return;
0715: if (!(receiver instanceof List)) {
0716: setProperty(messageArgument, senderClass, receiver,
0717: messageName);
0718: return;
0719: }
0720:
0721: List list = (List) receiver;
0722: List answer = new ArrayList();
0723: for (Iterator it = list.iterator(); it.hasNext();) {
0724: setPropertySafe(messageArgument, senderClass, it.next(),
0725: messageName);
0726: }
0727: }
0728:
0729: // --------------------------------------------------------
0730: // normal GroovyObject Property handling : get
0731: // --------------------------------------------------------
0732:
0733: public static Object getGroovyObjectProperty(Class senderClass,
0734: GroovyObject receiver, String messageName) throws Throwable {
0735: return receiver.getProperty(messageName);
0736: }
0737:
0738: public static Object getGroovyObjectPropertySafe(Class senderClass,
0739: GroovyObject receiver, String messageName) throws Throwable {
0740: if (receiver == null)
0741: return null;
0742: return receiver.getProperty(messageName);
0743: }
0744:
0745: public static Object getGroovyObjectPropertySpreadSafe(
0746: Class senderClass, GroovyObject receiver, String messageName)
0747: throws Throwable {
0748: if (receiver == null)
0749: return null;
0750: if (!(receiver instanceof List))
0751: return getGroovyObjectProperty(senderClass, receiver,
0752: messageName);
0753:
0754: List list = (List) receiver;
0755: List answer = new ArrayList();
0756: for (Iterator it = list.iterator(); it.hasNext();) {
0757: answer.add(getPropertySafe(senderClass, it.next(),
0758: messageName));
0759: }
0760: return answer;
0761: }
0762:
0763: // --------------------------------------------------------
0764: // normal GroovyObject Property handling : set
0765: // --------------------------------------------------------
0766:
0767: public static void setGroovyObjectProperty(Object messageArgument,
0768: Class senderClass, GroovyObject receiver, String messageName)
0769: throws Throwable {
0770: receiver.setProperty(messageName, messageArgument);
0771: }
0772:
0773: public static void setGroovyObjectPropertySafe(
0774: Object messageArgument, Class senderClass,
0775: GroovyObject receiver, String messageName) throws Throwable {
0776: if (receiver == null)
0777: return;
0778: receiver.setProperty(messageName, messageArgument);
0779: }
0780:
0781: public static void setGroovyObjectPropertySpreadSafe(
0782: Object messageArgument, Class senderClass,
0783: GroovyObject receiver, String messageName) throws Throwable {
0784: if (receiver == null)
0785: return;
0786: if (!(receiver instanceof List)) {
0787: setProperty(messageArgument, senderClass, receiver,
0788: messageName);
0789: return;
0790: }
0791:
0792: List list = (List) receiver;
0793: List answer = new ArrayList();
0794: for (Iterator it = list.iterator(); it.hasNext();) {
0795: setPropertySafe(messageArgument, senderClass, it.next(),
0796: messageName);
0797: }
0798: }
0799:
0800: // **********************************************************************************
0801: // **********************************************************************************
0802: // ************** methods not covered by the new MOP **************
0803: // **********************************************************************************
0804: // **********************************************************************************
0805:
0806: // --------------------------------------------------------
0807: // Closures
0808: // --------------------------------------------------------
0809:
0810: /**
0811: * Returns the method pointer for the given object name
0812: */
0813: public static Closure getMethodPointer(Object object,
0814: String methodName) {
0815: return InvokerHelper.getMethodPointer(object, methodName);
0816: }
0817:
0818: // TODO: set sender class
0819: public static Object invokeClosure(Object closure,
0820: Object[] arguments) throws Throwable {
0821: return invokeMethodN(closure.getClass(), closure, "doCall",
0822: arguments);
0823: }
0824:
0825: // --------------------------------------------------------
0826: // type conversion
0827: // --------------------------------------------------------
0828:
0829: /**
0830: * Provides a hook for type coercion of the given object to the required type
0831: *
0832: * @param type of object to convert the given object to
0833: * @param object the object to be converted
0834: * @return the original object or a new converted value
0835: * @throws Throwable
0836: */
0837: public static Object asType(Object object, Class type)
0838: throws Throwable {
0839: return invokeMethodN(object.getClass(), object, "asType",
0840: new Object[] { type });
0841: }
0842:
0843: /**
0844: * Provides a hook for type casting of the given object to the required type
0845: *
0846: * @param type of object to convert the given object to
0847: * @param object the object to be converted
0848: * @return the original object or a new converted value
0849: * @throws Throwable
0850: */
0851: public static Object castToType(Object object, Class type)
0852: throws Throwable {
0853: try {
0854: return DefaultTypeTransformation.castToType(object, type);
0855: } catch (GroovyRuntimeException gre) {
0856: return (Matcher) unwrap(gre);
0857: }
0858: }
0859:
0860: public static Tuple createTuple(Object[] array) {
0861: return new Tuple(array);
0862: }
0863:
0864: public static List createList(Object[] values) {
0865: return InvokerHelper.createList(values);
0866: }
0867:
0868: public static Wrapper createPojoWrapper(Object val, Class clazz) {
0869: return new PojoWrapper(val, clazz);
0870: }
0871:
0872: public static Wrapper createGroovyObjectWrapper(GroovyObject val,
0873: Class clazz) {
0874: return new GroovyObjectWrapper(val, clazz);
0875: }
0876:
0877: public static Map createMap(Object[] values) {
0878: return InvokerHelper.createMap(values);
0879: }
0880:
0881: //TODO: refactor
0882: public static List createRange(Object from, Object to,
0883: boolean inclusive) throws Throwable {
0884: if (!inclusive) {
0885: if (compareEqual(from, to)) {
0886: return new EmptyRange((Comparable) from);
0887: }
0888: if (compareGreaterThan(from, to)) {
0889: to = invokeMethod0(ScriptBytecodeAdapter.class, to,
0890: "next");
0891: } else {
0892: to = invokeMethod0(ScriptBytecodeAdapter.class, to,
0893: "previous");
0894: }
0895: }
0896: if (from instanceof Integer && to instanceof Integer) {
0897: return new IntRange(DefaultTypeTransformation
0898: .intUnbox(from), DefaultTypeTransformation
0899: .intUnbox(to));
0900: } else {
0901: return new ObjectRange((Comparable) from, (Comparable) to);
0902: }
0903: }
0904:
0905: //assert
0906: public static void assertFailed(Object expression, Object message) {
0907: InvokerHelper.assertFailed(expression, message);
0908: }
0909:
0910: //isCase
0911: //TODO: set sender class
0912: public static boolean isCase(Object switchValue,
0913: Object caseExpression) throws Throwable {
0914: if (caseExpression == null) {
0915: return switchValue == null;
0916: }
0917: return DefaultTypeTransformation.castToBoolean(invokeMethodN(
0918: caseExpression.getClass(), caseExpression, "isCase",
0919: new Object[] { switchValue }));
0920: }
0921:
0922: //compare
0923: public static boolean compareIdentical(Object left, Object right) {
0924: return left == right;
0925: }
0926:
0927: public static boolean compareEqual(Object left, Object right) {
0928: return DefaultTypeTransformation.compareEqual(left, right);
0929: }
0930:
0931: public static boolean compareNotEqual(Object left, Object right) {
0932: return !compareEqual(left, right);
0933: }
0934:
0935: public static Integer compareTo(Object left, Object right) {
0936: int answer = DefaultTypeTransformation.compareTo(left, right);
0937: if (answer == 0) {
0938: return ZERO;
0939: } else {
0940: return answer > 0 ? ONE : MINUS_ONE;
0941: }
0942: }
0943:
0944: public static boolean compareLessThan(Object left, Object right) {
0945: return compareTo(left, right).intValue() < 0;
0946: }
0947:
0948: public static boolean compareLessThanEqual(Object left, Object right) {
0949: return compareTo(left, right).intValue() <= 0;
0950: }
0951:
0952: public static boolean compareGreaterThan(Object left, Object right) {
0953: return compareTo(left, right).intValue() > 0;
0954: }
0955:
0956: public static boolean compareGreaterThanEqual(Object left,
0957: Object right) {
0958: return compareTo(left, right).intValue() >= 0;
0959: }
0960:
0961: //regexpr
0962: public static Pattern regexPattern(Object regex) {
0963: return DefaultGroovyMethods.negate(regex.toString());
0964: }
0965:
0966: public static Matcher findRegex(Object left, Object right)
0967: throws Throwable {
0968: try {
0969: return InvokerHelper.findRegex(left, right);
0970: } catch (GroovyRuntimeException gre) {
0971: return (Matcher) unwrap(gre);
0972: }
0973: }
0974:
0975: public static boolean matchRegex(Object left, Object right) {
0976: return InvokerHelper.matchRegex(left, right);
0977: }
0978:
0979: //spread expressions
0980: public static Object[] despreadList(Object[] args,
0981: Object[] spreads, int[] positions) {
0982: ArrayList ret = new ArrayList();
0983: int argsPos = 0;
0984: int spreadPos = 0;
0985: for (int pos = 0; pos < positions.length; pos++) {
0986: for (; argsPos < positions[pos]; argsPos++) {
0987: ret.add(args[argsPos]);
0988: }
0989: Object value = spreads[spreadPos];
0990: if (value == null) {
0991: ret.add(null);
0992: } else if (value instanceof List) {
0993: ret.addAll((List) value);
0994: } else if (value.getClass().isArray()) {
0995: ret.addAll(DefaultTypeTransformation
0996: .primitiveArrayToList(value));
0997: } else {
0998: throw new IllegalArgumentException(
0999: "connot spread the type "
1000: + value.getClass().getName()
1001: + " with value " + value);
1002: }
1003: spreadPos++;
1004: }
1005: for (; argsPos < args.length; argsPos++) {
1006: ret.add(args[argsPos]);
1007: }
1008: return ret.toArray();
1009: }
1010:
1011: public static Object spreadMap(Object value) {
1012: return InvokerHelper.spreadMap(value);
1013: }
1014:
1015: //negation
1016: public static Object negate(Object value) throws Throwable {
1017: try {
1018: return InvokerHelper.negate(value);
1019: } catch (GroovyRuntimeException gre) {
1020: return unwrap(gre);
1021: }
1022: }
1023:
1024: public static Object bitNegate(Object value) {
1025: return InvokerHelper.bitNegate(value);
1026: }
1027:
1028: public static MetaClass initMetaClass(Object object) {
1029: return InvokerHelper.getMetaClass(object);
1030: }
1031:
1032: private static MetaClass getMetaClassObjectNotNull(Object object) {
1033: if (!(object instanceof GroovyObject)) {
1034: return initMetaClass(object);
1035: } else {
1036: return ((GroovyObject) object).getMetaClass();
1037: }
1038: }
1039:
1040: }
|