1 /*
2 * Copyright 2003-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.codehaus.groovy.runtime;
17
18 import groovy.lang;
19 import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
20 import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
21 import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack;
22 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
23 import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
24 import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
25 import org.codehaus.groovy.runtime.wrappers.Wrapper;
26
27 import java.util;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 /**
32 * A static helper class to interface bytecode and runtime
33 *
34 * @author Jochen Theodorou
35 * @version $Revision: 17783 $
36 */
37 public class ScriptBytecodeAdapter {
38 public static final Object[] EMPTY_ARGS = {};
39 private static final Integer ZERO = Integer.valueOf(0);
40 private static final Integer MINUS_ONE = Integer.valueOf(-1);
41 private static final Integer ONE = Integer.valueOf(1);
42
43 // --------------------------------------------------------
44 // exception handling
45 // --------------------------------------------------------
46 public static Throwable unwrap(GroovyRuntimeException gre) {
47 if (gre instanceof MissingPropertyExceptionNoStack) {
48 MissingPropertyExceptionNoStack noStack = (MissingPropertyExceptionNoStack) gre;
49 return new MissingPropertyException(noStack.getProperty(), noStack.getType());
50 }
51
52 if (gre instanceof MissingMethodExceptionNoStack) {
53 MissingMethodExceptionNoStack noStack = (MissingMethodExceptionNoStack) gre;
54 return new MissingMethodException(noStack.getMethod(), noStack.getType(), noStack.getArguments(), noStack.isStatic());
55 }
56
57 Throwable th = gre;
58 if (th.getCause() != null && th.getCause() != gre) th = th.getCause();
59 if (th != gre && (th instanceof GroovyRuntimeException)) return unwrap((GroovyRuntimeException) th);
60 return th;
61 }
62
63 // --------------------------------------------------------
64 // methods for this
65 // --------------------------------------------------------
66 public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
67 Object result = null;
68 boolean intercepting = receiver instanceof GroovyInterceptable;
69 try {
70 try {
71 // if it's a pure interceptable object (even intercepting toString(), clone(), ...)
72 if (intercepting) {
73 result = receiver.invokeMethod(messageName, messageArguments);
74 }
75 //else if there's a statically typed method or a GDK method
76 else {
77 result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true);
78 }
79 } catch (MissingMethodException e) {
80 if (e instanceof MissingMethodExecutionFailed) {
81 throw (MissingMethodException)e.getCause();
82 } else if (!intercepting && receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) {
83 // in case there's nothing else, invoke the object's own invokeMethod()
84 result = receiver.invokeMethod(messageName, messageArguments);
85 } else {
86 throw e;
87 }
88 }
89 } catch (GroovyRuntimeException gre) {
90 throw unwrap(gre);
91 }
92 return result;
93 }
94
95 public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
96 return invokeMethodOnCurrentN(senderClass, receiver, messageName, messageArguments);
97 }
98
99 public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
100 List answer = new ArrayList();
101 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
102 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
103 }
104 return answer;
105 }
106
107 public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
108 return invokeMethodOnCurrentN(senderClass, receiver, messageName, EMPTY_ARGS);
109 }
110
111 public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
112 return invokeMethodOnCurrentNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
113 }
114
115 public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
116 return invokeMethodOnCurrentNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
117 }
118
119 // --------------------------------------------------------
120 // methods for super
121 // --------------------------------------------------------
122 public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
123 MetaClass metaClass = receiver.getMetaClass();
124 // ignore interception and missing method fallback
125 Object result = null;
126 try {
127 result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
128 } catch (GroovyRuntimeException gre) {
129 throw unwrap(gre);
130 }
131 return result;
132 }
133
134 public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
135 return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments);
136 }
137
138 public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
139 List answer = new ArrayList();
140 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
141 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
142 }
143 return answer;
144 }
145
146 public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
147 return invokeMethodOnSuperN(senderClass, receiver, messageName, EMPTY_ARGS);
148 }
149
150 public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
151 return invokeMethodOnSuperNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
152 }
153
154 public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
155 return invokeMethodOnSuperNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
156 }
157
158 // --------------------------------------------------------
159 // normal method invocation
160 // --------------------------------------------------------
161 public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
162 try {
163 return InvokerHelper.invokeMethod(receiver, messageName, messageArguments);
164 } catch (GroovyRuntimeException gre) {
165 throw unwrap(gre);
166 }
167 }
168
169 public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
170 if (receiver == null) return null;
171 return invokeMethodN(senderClass, receiver, messageName, messageArguments);
172 }
173
174 public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
175 if (receiver == null) return null;
176 List answer = new ArrayList();
177 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
178 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
179 }
180 return answer;
181 }
182
183 private static Object[] getBoxedItems(Object receiver) {
184 return DefaultTypeTransformation.primitiveArrayToList(receiver).toArray();
185 }
186
187 public static Object invokeMethod0(Class senderClass, Object receiver, String messageName) throws Throwable {
188 return invokeMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
189 }
190
191 public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable {
192 if (receiver == null) return null;
193 return invokeMethodNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
194 }
195
196 public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
197 return invokeMethodNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
198 }
199
200 // --------------------------------------------------------
201 // static normal method invocation
202 // --------------------------------------------------------
203 public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable {
204 try {
205 return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments);
206 } catch (GroovyRuntimeException gre) {
207 throw unwrap(gre);
208 }
209 }
210
211 public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName) throws Throwable {
212 return invokeStaticMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
213 }
214
215 // --------------------------------------------------------
216 // normal constructor invocation (via new)
217 // --------------------------------------------------------
218 public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable {
219 try {
220 return InvokerHelper.invokeConstructorOf(receiver, arguments);
221 } catch (GroovyRuntimeException gre) {
222 throw unwrap(gre);
223 }
224 }
225
226 public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable {
227 return invokeNewN(senderClass, receiver, EMPTY_ARGS);
228 }
229
230 // --------------------------------------------------------
231 // special constructor invocation (via this/super)
232 // --------------------------------------------------------
233
234 public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfConstructors, Class which) throws Throwable {
235 MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(which);
236 try {
237 return metaClass.selectConstructorAndTransformArguments(numberOfConstructors, arguments);
238 } catch (GroovyRuntimeException gre) {
239 throw unwrap(gre);
240 }
241 }
242
243 // --------------------------------------------------------
244 // field handling super: get
245 // --------------------------------------------------------
246
247 public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable {
248 try {
249 if (receiver instanceof Class) {
250 return InvokerHelper.getAttribute(receiver, messageName);
251 } else {
252 MetaClass mc = ((GroovyObject) receiver).getMetaClass();
253 return mc.getAttribute(senderClass, receiver, messageName, true);
254 }
255 } catch (GroovyRuntimeException gre) {
256 throw unwrap(gre);
257 }
258 }
259
260 public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
261 return getFieldOnSuper(senderClass, receiver, messageName);
262 }
263
264 public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
265 List answer = new ArrayList();
266 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
267 answer.add(getFieldOnSuper(senderClass, it.next(), messageName));
268 }
269 return answer;
270 }
271
272 // --------------------------------------------------------
273 // field handling super: set
274 // --------------------------------------------------------
275
276 public static void setFieldOnSuper(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
277 try {
278 if (receiver instanceof Class) {
279 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
280 } else {
281 MetaClass mc = ((GroovyObject) receiver).getMetaClass();
282 mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true);
283 }
284 } catch (GroovyRuntimeException gre) {
285 throw unwrap(gre);
286 }
287 }
288
289 public static void setFieldOnSuperSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
290 setFieldOnSuper(messageArgument, senderClass, receiver, messageName);
291 }
292
293 public static void setFieldOnSuperSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
294 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
295 setFieldOnSuper(messageArgument, senderClass, it.next(), messageName);
296 }
297 }
298
299 // --------------------------------------------------------
300 // normal field handling : get
301 // --------------------------------------------------------
302
303 public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable {
304 try {
305 return InvokerHelper.getAttribute(receiver, messageName);
306 } catch (GroovyRuntimeException gre) {
307 throw unwrap(gre);
308 }
309 }
310
311 public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
312 if (receiver == null) return null;
313 return getField(senderClass, receiver, messageName);
314 }
315
316 public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
317 if (receiver == null) return null;
318 List answer = new ArrayList();
319 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
320 answer.add(getFieldSafe(senderClass, it.next(), messageName));
321 }
322 return answer;
323 }
324
325 // --------------------------------------------------------
326 // normal field handling : set
327 // --------------------------------------------------------
328
329 public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
330 try {
331 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
332 } catch (GroovyRuntimeException gre) {
333 throw unwrap(gre);
334 }
335 }
336
337 public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
338 if (receiver == null) return;
339 setField(messageArgument, senderClass, receiver, messageName);
340 }
341
342 public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
343 if (receiver == null) return;
344 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
345 setFieldSafe(messageArgument, senderClass, it.next(), messageName);
346 }
347 }
348
349 // --------------------------------------------------------
350 // normal GroovyObject field handling : get
351 // --------------------------------------------------------
352
353 public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
354 try {
355 return receiver.getMetaClass().getAttribute(receiver, messageName);
356 } catch (GroovyRuntimeException gre) {
357 throw unwrap(gre);
358 }
359 }
360
361 public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
362 if (receiver == null) return null;
363 try {
364 return receiver.getMetaClass().getAttribute(receiver, messageName);
365 } catch (GroovyRuntimeException gre) {
366 throw unwrap(gre);
367 }
368 }
369
370 public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
371 if (receiver == null) return null;
372 List answer = new ArrayList();
373 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
374 answer.add(getFieldSafe(senderClass, it.next(), messageName));
375 }
376 return answer;
377 }
378
379 // --------------------------------------------------------
380 // normal field handling : set
381 // --------------------------------------------------------
382
383 public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
384 try {
385 receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
386 } catch (GroovyRuntimeException gre) {
387 throw unwrap(gre);
388 }
389 }
390
391 public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
392 if (receiver == null) return;
393 try {
394 receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
395 } catch (GroovyRuntimeException gre) {
396 throw unwrap(gre);
397 }
398 }
399
400 public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
401 if (receiver == null) return;
402 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
403 setFieldSafe(messageArgument, senderClass, it.next(), messageName);
404 }
405 }
406
407 // --------------------------------------------------------
408 // Property handling super: get
409 // --------------------------------------------------------
410
411 public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
412 return invokeMethodOnSuperN(senderClass, receiver, "getProperty", new Object[]{messageName});
413 }
414
415 public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
416 return getPropertyOnSuper(senderClass, receiver, messageName);
417 }
418
419 public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
420 List answer = new ArrayList();
421 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
422 answer.add(getPropertySafe(senderClass, it.next(), messageName));
423 }
424 return answer;
425 }
426
427 // --------------------------------------------------------
428 // Property handling super: set
429 // --------------------------------------------------------
430
431 public static void setPropertyOnSuper(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
432 try {
433 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
434 } catch (GroovyRuntimeException gre) {
435 throw unwrap(gre);
436 }
437 }
438
439 public static void setPropertyOnSuperSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
440 setPropertyOnSuper(messageArgument, senderClass, receiver, messageName);
441 }
442
443 public static void setPropertyOnSuperSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
444 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
445 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
446 }
447 }
448
449 // --------------------------------------------------------
450 // normal Property handling : get
451 // --------------------------------------------------------
452
453 public static Object getProperty(Class senderClass, Object receiver, String messageName) throws Throwable {
454 try {
455 return InvokerHelper.getProperty(receiver, messageName);
456 } catch (GroovyRuntimeException gre) {
457 throw unwrap(gre);
458 }
459 }
460
461 public static Object getPropertySafe(Class senderClass, Object receiver, String messageName) throws Throwable {
462 if (receiver == null) return null;
463 return getProperty(senderClass, receiver, messageName);
464 }
465
466 public static Object getPropertySpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
467 if (receiver == null) return null;
468
469 List answer = new ArrayList();
470 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
471 answer.add(getPropertySafe(senderClass, it.next(), messageName));
472 }
473 return answer;
474 }
475
476 // --------------------------------------------------------
477 // normal Property handling : set
478 // --------------------------------------------------------
479
480 public static void setProperty(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
481 try {
482 if (receiver==null) receiver=NullObject.getNullObject();
483 InvokerHelper.setProperty(receiver, messageName, messageArgument);
484 } catch (GroovyRuntimeException gre) {
485 throw unwrap(gre);
486 }
487 }
488
489 public static void setPropertySafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
490 if (receiver == null) return;
491 setProperty(messageArgument, senderClass, receiver, messageName);
492 }
493
494 public static void setPropertySpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
495 if (receiver == null) return;
496
497 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
498 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
499 }
500 }
501
502 // --------------------------------------------------------
503 // normal GroovyObject Property handling : get
504 // --------------------------------------------------------
505
506 public static Object getGroovyObjectProperty(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
507 return receiver.getProperty(messageName);
508 }
509
510 public static Object getGroovyObjectPropertySafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
511 if (receiver == null) return null;
512 return getGroovyObjectProperty(senderClass, receiver, messageName);
513 }
514
515 public static Object getGroovyObjectPropertySpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
516 if (receiver == null) return null;
517
518 List answer = new ArrayList();
519 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
520 answer.add(getPropertySafe(senderClass, it.next(), messageName));
521 }
522 return answer;
523 }
524
525 // --------------------------------------------------------
526 // normal GroovyObject Property handling : set
527 // --------------------------------------------------------
528
529 public static void setGroovyObjectProperty(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
530 try {
531 receiver.setProperty(messageName, messageArgument);
532 } catch (GroovyRuntimeException gre) {
533 throw unwrap(gre);
534 }
535 }
536
537 public static void setGroovyObjectPropertySafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
538 if (receiver == null) return;
539 receiver.setProperty(messageName, messageArgument);
540 }
541
542 public static void setGroovyObjectPropertySpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
543 if (receiver == null) return;
544
545 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
546 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
547 }
548 }
549
550 // **********************************************************************************
551 // **********************************************************************************
552 // ************** methods not covered by the new MOP **************
553 // **********************************************************************************
554 // **********************************************************************************
555
556 // --------------------------------------------------------
557 // Closures
558 // --------------------------------------------------------
559
560 /**
561 * Returns the method pointer for the given object name
562 *
563 * @param object the object containing the method
564 * @param methodName the name of the method of interest
565 * @return the resulting Closure
566 */
567 public static Closure getMethodPointer(Object object, String methodName) {
568 return InvokerHelper.getMethodPointer(object, methodName);
569 }
570
571 // TODO: set sender class
572 public static Object invokeClosure(Object closure, Object[] arguments) throws Throwable {
573 return invokeMethodN(closure.getClass(), closure, "call", arguments);
574 }
575
576 // --------------------------------------------------------
577 // type conversion
578 // --------------------------------------------------------
579
580 /**
581 * Provides a hook for type coercion of the given object to the required type
582 *
583 * @param type of object to convert the given object to
584 * @param object the object to be converted
585 * @return the original object or a new converted value
586 * @throws Throwable if the coercion fails
587 */
588 public static Object asType(Object object, Class type) throws Throwable {
589 if (object == null) object = NullObject.getNullObject();
590 return invokeMethodN(object.getClass(), object, "asType", new Object[]{type});
591 }
592
593 /**
594 * Provides a hook for type casting of the given object to the required type
595 *
596 * @param type of object to convert the given object to
597 * @param object the object to be converted
598 * @return the original object or a new converted value
599 * @throws Throwable if the type casting fails
600 */
601 public static Object castToType(Object object, Class type) throws Throwable {
602 return DefaultTypeTransformation.castToType(object, type);
603 }
604
605 public static Tuple createTuple(Object[] array) {
606 return new Tuple(array);
607 }
608
609 public static List createList(Object[] values) {
610 return InvokerHelper.createList(values);
611 }
612
613 public static Wrapper createPojoWrapper(Object val, Class clazz) {
614 return new PojoWrapper(val, clazz);
615 }
616
617 public static Wrapper createGroovyObjectWrapper(GroovyObject val, Class clazz) {
618 return new GroovyObjectWrapper(val, clazz);
619 }
620
621 public static Map createMap(Object[] values) {
622 return InvokerHelper.createMap(values);
623 }
624
625
626 //TODO: refactor
627 public static List createRange(Object from, Object to, boolean inclusive) throws Throwable {
628 if (from instanceof Integer && to instanceof Integer) {
629 int ito = (Integer) to;
630 int ifrom = (Integer) from;
631 if (!inclusive) {
632 if (ifrom == ito) {
633 return new EmptyRange((Comparable) from);
634 }
635 if (ifrom > ito) {
636 ito++;
637 } else {
638 ito--;
639 }
640 }
641 return new IntRange(ifrom, ito);
642 }
643 if (!inclusive) {
644 if (compareEqual(from, to)) {
645 return new EmptyRange((Comparable) from);
646 }
647 if (compareGreaterThan(from, to)) {
648 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next");
649 } else {
650 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous");
651 }
652 }
653
654 if (from instanceof Integer && to instanceof Integer)
655 return new IntRange(DefaultTypeTransformation.intUnbox(from), DefaultTypeTransformation.intUnbox(to));
656 else
657 return new ObjectRange((Comparable) from, (Comparable) to);
658 }
659
660 //assert
661 public static void assertFailed(Object expression, Object message) {
662 InvokerHelper.assertFailed(expression, message);
663 }
664
665 //isCase
666 //TODO: set sender class
667 public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable {
668 if (caseExpression == null) {
669 return switchValue == null;
670 }
671 return DefaultTypeTransformation.castToBoolean(invokeMethodN(caseExpression.getClass(), caseExpression, "isCase", new Object[]{switchValue}));
672 }
673
674 //compare
675 public static boolean compareIdentical(Object left, Object right) {
676 return left == right;
677 }
678
679 public static boolean compareEqual(Object left, Object right) {
680 return DefaultTypeTransformation.compareEqual(left, right);
681 }
682
683 public static boolean compareNotEqual(Object left, Object right) {
684 return !compareEqual(left, right);
685 }
686
687 public static Integer compareTo(Object left, Object right) {
688 int answer = DefaultTypeTransformation.compareTo(left, right);
689 if (answer == 0) {
690 return ZERO;
691 } else {
692 return answer > 0 ? ONE : MINUS_ONE;
693 }
694 }
695
696 public static boolean compareLessThan(Object left, Object right) {
697 return compareTo(left, right).intValue() < 0;
698 }
699
700 public static boolean compareLessThanEqual(Object left, Object right) {
701 return compareTo(left, right).intValue() <= 0;
702 }
703
704 public static boolean compareGreaterThan(Object left, Object right) {
705 return compareTo(left, right).intValue() > 0;
706 }
707
708 public static boolean compareGreaterThanEqual(Object left, Object right) {
709 return compareTo(left, right).intValue() >= 0;
710 }
711
712 //regexpr
713 public static Pattern regexPattern(Object regex) {
714 return DefaultGroovyMethods.bitwiseNegate(regex.toString());
715 }
716
717 public static Matcher findRegex(Object left, Object right) throws Throwable {
718 return InvokerHelper.findRegex(left, right);
719 }
720
721 public static boolean matchRegex(Object left, Object right) {
722 return InvokerHelper.matchRegex(left, right);
723 }
724
725
726 //spread expressions
727 public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) {
728 List ret = new ArrayList();
729 int argsPos = 0;
730 int spreadPos = 0;
731 for (int pos = 0; pos < positions.length; pos++) {
732 for (; argsPos < positions[pos]; argsPos++) {
733 ret.add(args[argsPos]);
734 }
735 Object value = spreads[spreadPos];
736 if (value == null) {
737 ret.add(null);
738 } else if (value instanceof List) {
739 ret.addAll((List) value);
740 } else if (value.getClass().isArray()) {
741 ret.addAll(DefaultTypeTransformation.primitiveArrayToList(value));
742 } else {
743 throw new IllegalArgumentException("cannot spread the type " + value.getClass().getName() + " with value " + value);
744 }
745 spreadPos++;
746 }
747 for (; argsPos < args.length; argsPos++) {
748 ret.add(args[argsPos]);
749 }
750 return ret.toArray();
751 }
752
753 public static Object spreadMap(Object value) {
754 return InvokerHelper.spreadMap(value);
755 }
756
757 public static Object unaryMinus(Object value) throws Throwable {
758 return InvokerHelper.unaryMinus(value);
759 }
760
761 public static Object unaryPlus(Object value) throws Throwable {
762 try {
763 return InvokerHelper.unaryPlus(value);
764 } catch (GroovyRuntimeException gre) {
765 throw unwrap(gre);
766 }
767 }
768
769 public static Object bitwiseNegate(Object value) throws Throwable {
770 try {
771 return InvokerHelper.bitwiseNegate(value);
772 } catch (GroovyRuntimeException gre) {
773 throw unwrap(gre);
774 }
775 }
776
777 public static MetaClass initMetaClass(Object object) {
778 return InvokerHelper.getMetaClass(object.getClass());
779 }
780 }