001 /* 002 $Id: ScriptBytecodeAdapter.java 4294 2006-12-02 19:31:27Z blackdrag $ 003 004 Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved. 005 006 Redistribution and use of this software and associated documentation 007 ("Software"), with or without modification, are permitted provided 008 that the following conditions are met: 009 010 1. Redistributions of source code must retain copyright 011 statements and notices. Redistributions must also contain a 012 copy of this document. 013 014 2. Redistributions in binary form must reproduce the 015 above copyright notice, this list of conditions and the 016 following disclaimer in the documentation and/or other 017 materials provided with the distribution. 018 019 3. The name "groovy" must not be used to endorse or promote 020 products derived from this Software without prior written 021 permission of The Codehaus. For written permission, 022 please contact info@codehaus.org. 023 024 4. Products derived from this Software may not be called "groovy" 025 nor may "groovy" appear in their names without prior written 026 permission of The Codehaus. "groovy" is a registered 027 trademark of The Codehaus. 028 029 5. Due credit should be given to The Codehaus - 030 http://groovy.codehaus.org/ 031 032 THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS 033 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 034 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 035 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 036 THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 037 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 038 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 039 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 040 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 041 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 042 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 043 OF THE POSSIBILITY OF SUCH DAMAGE. 044 045 */ 046 package org.codehaus.groovy.runtime; 047 048 import groovy.lang.*; 049 050 import java.util.Iterator; 051 import java.util.List; 052 import java.util.ArrayList; 053 import java.util.Map; 054 import java.util.regex.Matcher; 055 import java.util.regex.Pattern; 056 057 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; 058 import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper; 059 import org.codehaus.groovy.runtime.wrappers.PojoWrapper; 060 import org.codehaus.groovy.runtime.wrappers.Wrapper; 061 062 /** 063 * A static helper class to interface bytecode and runtime 064 * 065 * @author Jochen Theodorou 066 * @version $Revision: 4294 $ 067 */ 068 public class ScriptBytecodeAdapter { 069 public static final Object[] EMPTY_ARGS = {}; 070 private static final Integer ZERO = new Integer(0); 071 private static final Integer MINUS_ONE = new Integer(-1); 072 private static final Integer ONE = new Integer(1); 073 074 // -------------------------------------------------------- 075 // exception handling 076 // -------------------------------------------------------- 077 private static Object unwrap(GroovyRuntimeException gre) throws Throwable{ 078 Throwable th = gre; 079 if (th.getCause()!=null && th.getCause()!=gre) th=th.getCause(); 080 if (th!=gre && (th instanceof GroovyRuntimeException)) unwrap((GroovyRuntimeException) th); 081 throw th; 082 } 083 084 // -------------------------------------------------------- 085 // methods for this 086 // -------------------------------------------------------- 087 public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 088 Object result=null; 089 try { 090 try { 091 // if it's a pure interceptable object (even intercepting toString(), clone(), ...) 092 if (receiver instanceof GroovyInterceptable) { 093 result = receiver.invokeMethod(messageName, messageArguments); 094 } 095 //else if there's a statically typed method or a GDK method 096 else { 097 result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true); 098 } 099 } catch (MissingMethodException e) { 100 if (receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) { 101 // in case there's nothing else, invoke the object's own invokeMethod() 102 result = receiver.invokeMethod(messageName, messageArguments); 103 } else { 104 throw e; 105 } 106 } 107 } catch (GroovyRuntimeException t) { 108 unwrap(t); 109 } 110 return result; 111 } 112 113 public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 114 return invokeMethodOnCurrentN(senderClass,receiver,messageName,messageArguments); 115 } 116 117 public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 118 if (! (receiver instanceof List)) return invokeMethodOnCurrentN(senderClass,receiver,messageName, messageArguments); 119 120 List list = (List) receiver; 121 List answer = new ArrayList(); 122 for (Iterator it = list.iterator(); it.hasNext();) { 123 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments)); 124 } 125 return answer; 126 } 127 128 public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 129 return invokeMethodOnCurrentN(senderClass,receiver,messageName,EMPTY_ARGS); 130 } 131 132 public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 133 return invokeMethodOnCurrentNSafe(senderClass,receiver,messageName,EMPTY_ARGS); 134 } 135 136 public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 137 return invokeMethodOnCurrentNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS); 138 } 139 140 // -------------------------------------------------------- 141 // methods for super 142 // -------------------------------------------------------- 143 public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 144 MetaClass metaClass = receiver.getMetaClass(); 145 // ignore interception and missing method fallback 146 Object result=null; 147 try { 148 result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true); 149 } catch (GroovyRuntimeException t) { 150 unwrap(t); 151 } 152 return result; 153 } 154 155 public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 156 return invokeMethodOnSuperN(senderClass,receiver,messageName,messageArguments); 157 } 158 159 public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 160 if (! (receiver instanceof List)) return invokeMethodOnSuperN(senderClass,receiver,messageName, messageArguments); 161 162 List list = (List) receiver; 163 List answer = new ArrayList(); 164 for (Iterator it = list.iterator(); it.hasNext();) { 165 answer.add(invokeMethodNSafe(senderClass,it.next(), messageName, messageArguments)); 166 } 167 return answer; 168 } 169 170 public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 171 return invokeMethodOnSuperN(senderClass,receiver,messageName,EMPTY_ARGS); 172 } 173 174 public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 175 return invokeMethodOnSuperNSafe(senderClass,receiver,messageName,EMPTY_ARGS); 176 } 177 178 public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{ 179 return invokeMethodOnSuperNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS); 180 } 181 182 // -------------------------------------------------------- 183 // normal method invocation 184 // -------------------------------------------------------- 185 public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{ 186 try { 187 return InvokerHelper.invokeMethod(receiver, messageName, messageArguments); 188 } catch (GroovyRuntimeException gre) { 189 return unwrap(gre); 190 } 191 } 192 193 public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{ 194 if (receiver==null) return null; 195 return invokeMethodN(senderClass,receiver,messageName,messageArguments); 196 } 197 198 public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{ 199 if (receiver==null) return null; 200 if (! (receiver instanceof List)) return invokeMethodN(senderClass,receiver,messageName, messageArguments); 201 202 List list = (List) receiver; 203 List answer = new ArrayList(); 204 for (Iterator it = list.iterator(); it.hasNext();) { 205 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments)); 206 } 207 return answer; 208 } 209 210 public static Object invokeMethod0(Class senderClass, Object receiver, String messageName) throws Throwable{ 211 return invokeMethodN(senderClass,receiver,messageName,EMPTY_ARGS); 212 } 213 214 public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable{ 215 if (receiver==null) return null; 216 return invokeMethodNSafe(senderClass,receiver,messageName,EMPTY_ARGS); 217 } 218 219 public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 220 return invokeMethodNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS); 221 } 222 223 // -------------------------------------------------------- 224 // static normal method invocation 225 // -------------------------------------------------------- 226 public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable{ 227 try { 228 return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments); 229 } catch (GroovyRuntimeException gre) { 230 return unwrap(gre); 231 } 232 } 233 234 public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName) throws Throwable{ 235 return invokeStaticMethodN(senderClass,receiver,messageName,EMPTY_ARGS); 236 } 237 238 // -------------------------------------------------------- 239 // normal constructor invocation (via new) 240 // -------------------------------------------------------- 241 public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable{ 242 try { 243 return InvokerHelper.invokeConstructorOf(receiver, arguments); 244 } catch (GroovyRuntimeException gre) { 245 return unwrap(gre); 246 } 247 } 248 249 public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable { 250 return invokeNewN(senderClass, receiver, EMPTY_ARGS); 251 } 252 253 // -------------------------------------------------------- 254 // special constructor invocation (via this/super) 255 // -------------------------------------------------------- 256 257 public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfCosntructors, Class which) { 258 MetaClassImpl metaClass = (MetaClassImpl) InvokerHelper.getInstance().getMetaRegistry().getMetaClass(which); 259 return metaClass.selectConstructorAndTransformArguments(numberOfCosntructors, arguments); 260 } 261 262 // -------------------------------------------------------- 263 // field handling super: get 264 // -------------------------------------------------------- 265 266 public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable{ 267 try { 268 if (receiver instanceof Class) { 269 return InvokerHelper.getAttribute(receiver,messageName); 270 } else { 271 MetaClass mc = ((GroovyObject) receiver).getMetaClass(); 272 return mc.getAttribute(senderClass, receiver, messageName, true); 273 } 274 } catch (GroovyRuntimeException gre) { 275 return unwrap(gre); 276 } 277 } 278 279 public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 280 return getFieldOnSuper(senderClass,receiver,messageName); 281 } 282 283 public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 284 if (! (receiver instanceof List)) return getFieldOnSuper(senderClass,receiver,messageName); 285 286 List list = (List) receiver; 287 List answer = new ArrayList(); 288 for (Iterator it = list.iterator(); it.hasNext();) { 289 answer.add(getFieldOnSuper(senderClass, it.next(), messageName)); 290 } 291 return answer; 292 } 293 294 // -------------------------------------------------------- 295 // field handling super: set 296 // -------------------------------------------------------- 297 298 public static void setFieldOnSuper(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{ 299 try { 300 if (receiver instanceof Class) { 301 InvokerHelper.setAttribute(receiver,messageName,messageArgument); 302 } else { 303 MetaClass mc = ((GroovyObject) receiver).getMetaClass(); 304 mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true); 305 } 306 } catch (GroovyRuntimeException gre) { 307 unwrap(gre); 308 } 309 } 310 311 public static void setFieldOnSuperSafe(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{ 312 setFieldOnSuper(messageArgument,senderClass,receiver,messageName); 313 } 314 315 public static void setFieldOnSuperSpreadSafe(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{ 316 if (! (receiver instanceof List)) { 317 setFieldOnSuper(messageArgument,senderClass,receiver,messageName); 318 return; 319 } 320 321 List list = (List) receiver; 322 List answer = new ArrayList(); 323 for (Iterator it = list.iterator(); it.hasNext();) { 324 setFieldOnSuper(messageArgument,senderClass, it.next(), messageName); 325 } 326 } 327 328 329 // -------------------------------------------------------- 330 // normal field handling : get 331 // -------------------------------------------------------- 332 333 public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable{ 334 try { 335 return InvokerHelper.getAttribute(receiver, messageName); 336 } catch (GroovyRuntimeException gre) { 337 return unwrap(gre); 338 } 339 } 340 341 public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 342 if (receiver==null) return null; 343 return getField(senderClass,receiver,messageName); 344 } 345 346 public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 347 if (receiver==null) return null; 348 if (! (receiver instanceof List)) return getField(senderClass,receiver,messageName); 349 350 List list = (List) receiver; 351 List answer = new ArrayList(); 352 for (Iterator it = list.iterator(); it.hasNext();) { 353 answer.add(getFieldSafe(senderClass, it.next(), messageName)); 354 } 355 return answer; 356 } 357 358 // -------------------------------------------------------- 359 // normal field handling : set 360 // -------------------------------------------------------- 361 362 public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 363 try { 364 InvokerHelper.setAttribute(receiver, messageName,messageArgument); 365 } catch (GroovyRuntimeException gre) { 366 unwrap(gre); 367 } 368 } 369 370 public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 371 if (receiver==null) return; 372 setField(messageArgument,senderClass,receiver,messageName); 373 } 374 375 public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 376 if (receiver==null) return; 377 if (! (receiver instanceof List)) { 378 setField(messageArgument,senderClass,receiver,messageName); 379 return; 380 } 381 382 List list = (List) receiver; 383 List answer = new ArrayList(); 384 for (Iterator it = list.iterator(); it.hasNext();) { 385 setFieldSafe(messageArgument,senderClass, it.next(), messageName); 386 } 387 } 388 389 // -------------------------------------------------------- 390 // normal GroovyObject field handling : get 391 // -------------------------------------------------------- 392 393 public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 394 return receiver.getMetaClass().getAttribute(receiver,messageName); 395 } 396 397 public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 398 if (receiver==null) return null; 399 return receiver.getMetaClass().getAttribute(receiver,messageName); 400 } 401 402 public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 403 if (receiver==null) return null; 404 if (! (receiver instanceof List)) return getGroovyObjectField(senderClass,receiver,messageName); 405 406 List list = (List) receiver; 407 List answer = new ArrayList(); 408 for (Iterator it = list.iterator(); it.hasNext();) { 409 answer.add(getFieldSafe(senderClass, it.next(), messageName)); 410 } 411 return answer; 412 } 413 414 // -------------------------------------------------------- 415 // normal field handling : set 416 // -------------------------------------------------------- 417 418 public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 419 receiver.getMetaClass().setAttribute(receiver,messageName,messageArgument); 420 } 421 422 public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 423 if (receiver==null) return; 424 receiver.getMetaClass().setAttribute(receiver,messageName,messageArgument); 425 } 426 427 public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 428 if (receiver==null) return; 429 if (! (receiver instanceof List)) { 430 setGroovyObjectField(messageArgument,senderClass,receiver,messageName); 431 return; 432 } 433 434 List list = (List) receiver; 435 List answer = new ArrayList(); 436 for (Iterator it = list.iterator(); it.hasNext();) { 437 setFieldSafe(messageArgument,senderClass, it.next(), messageName); 438 } 439 } 440 441 // -------------------------------------------------------- 442 // Property handling super: get 443 // -------------------------------------------------------- 444 445 public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 446 return invokeMethodOnSuperN(senderClass, receiver, "getProperty", new Object[]{messageName}); 447 } 448 449 public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 450 return getPropertyOnSuper(senderClass,receiver,messageName); 451 } 452 453 public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 454 if (! (receiver instanceof List)) return getPropertyOnSuper(senderClass,receiver,messageName); 455 456 List list = (List) receiver; 457 List answer = new ArrayList(); 458 for (Iterator it = list.iterator(); it.hasNext();) { 459 answer.add(getPropertySafe(senderClass, it.next(), messageName)); 460 } 461 return answer; 462 } 463 464 // -------------------------------------------------------- 465 // Property handling super: set 466 // -------------------------------------------------------- 467 468 public static void setPropertyOnSuper(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 469 try { 470 InvokerHelper.setAttribute(receiver, messageName,messageArgument); 471 } catch (GroovyRuntimeException gre) { 472 unwrap(gre); 473 } 474 } 475 476 public static void setPropertyOnSuperSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 477 setPropertyOnSuper(messageArgument, senderClass,receiver,messageName); 478 } 479 480 public static void setPropertyOnSuperSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 481 if (! (receiver instanceof List)) { 482 setPropertyOnSuper(messageArgument, senderClass,receiver,messageName); 483 return; 484 } 485 486 List list = (List) receiver; 487 List answer = new ArrayList(); 488 for (Iterator it = list.iterator(); it.hasNext();) { 489 setPropertySafe(messageArgument, senderClass, it.next(), messageName); 490 } 491 } 492 493 494 // -------------------------------------------------------- 495 // normal Property handling : get 496 // -------------------------------------------------------- 497 498 public static Object getProperty(Class senderClass, Object receiver, String messageName) throws Throwable{ 499 try { 500 return InvokerHelper.getProperty(receiver, messageName); 501 } catch (GroovyRuntimeException gre) { 502 return unwrap(gre); 503 } 504 } 505 506 public static Object getPropertySafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 507 if (receiver==null) return null; 508 return getProperty(senderClass,receiver,messageName); 509 } 510 511 public static Object getPropertySpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{ 512 if (receiver==null) return null; 513 if (! (receiver instanceof List)) return getProperty(senderClass,receiver,messageName); 514 515 List list = (List) receiver; 516 List answer = new ArrayList(); 517 for (Iterator it = list.iterator(); it.hasNext();) { 518 answer.add(getPropertySafe(senderClass, it.next(), messageName)); 519 } 520 return answer; 521 } 522 523 // -------------------------------------------------------- 524 // normal Property handling : set 525 // -------------------------------------------------------- 526 527 public static void setProperty(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 528 try { 529 InvokerHelper.setProperty(receiver, messageName,messageArgument); 530 } catch (GroovyRuntimeException gre) { 531 unwrap(gre); 532 } 533 } 534 535 public static void setPropertySafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 536 if (receiver==null) return; 537 setProperty(messageArgument,senderClass,receiver,messageName); 538 } 539 540 public static void setPropertySpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{ 541 if (receiver==null) return; 542 if (! (receiver instanceof List)) { 543 setProperty(messageArgument, senderClass, receiver, messageName); 544 return; 545 } 546 547 List list = (List) receiver; 548 List answer = new ArrayList(); 549 for (Iterator it = list.iterator(); it.hasNext();) { 550 setPropertySafe(messageArgument, senderClass, it.next(), messageName); 551 } 552 } 553 554 555 // -------------------------------------------------------- 556 // normal GroovyObject Property handling : get 557 // -------------------------------------------------------- 558 559 public static Object getGroovyObjectProperty(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 560 return receiver.getProperty(messageName); 561 } 562 563 public static Object getGroovyObjectPropertySafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 564 if (receiver==null) return null; 565 return receiver.getProperty(messageName); 566 } 567 568 public static Object getGroovyObjectPropertySpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 569 if (receiver==null) return null; 570 if (! (receiver instanceof List)) return getGroovyObjectProperty(senderClass,receiver,messageName); 571 572 List list = (List) receiver; 573 List answer = new ArrayList(); 574 for (Iterator it = list.iterator(); it.hasNext();) { 575 answer.add(getPropertySafe(senderClass, it.next(), messageName)); 576 } 577 return answer; 578 } 579 580 // -------------------------------------------------------- 581 // normal GroovyObject Property handling : set 582 // -------------------------------------------------------- 583 584 public static void setGroovyObjectProperty(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 585 receiver.setProperty(messageName,messageArgument); 586 } 587 588 public static void setGroovyObjectPropertySafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 589 if (receiver==null) return; 590 receiver.setProperty(messageName,messageArgument); 591 } 592 593 public static void setGroovyObjectPropertySpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{ 594 if (receiver==null) return; 595 if (! (receiver instanceof List)) { 596 setProperty(messageArgument, senderClass, receiver, messageName); 597 return; 598 } 599 600 List list = (List) receiver; 601 List answer = new ArrayList(); 602 for (Iterator it = list.iterator(); it.hasNext();) { 603 setPropertySafe(messageArgument, senderClass, it.next(), messageName); 604 } 605 } 606 607 // ********************************************************************************** 608 // ********************************************************************************** 609 // ************** methods not covered by the new MOP ************** 610 // ********************************************************************************** 611 // ********************************************************************************** 612 613 // -------------------------------------------------------- 614 // Closures 615 // -------------------------------------------------------- 616 617 /** 618 * Returns the method pointer for the given object name 619 */ 620 public static Closure getMethodPointer(Object object, String methodName) { 621 return InvokerHelper.getMethodPointer(object, methodName); 622 } 623 624 // TODO: set sender class 625 public static Object invokeClosure(Object closure, Object[] arguments) throws Throwable { 626 return invokeMethodN(closure.getClass(), closure, "doCall", arguments); 627 } 628 629 630 // -------------------------------------------------------- 631 // type conversion 632 // -------------------------------------------------------- 633 634 /** 635 * Provides a hook for type coercion of the given object to the required type 636 * 637 * @param type of object to convert the given object to 638 * @param object the object to be converted 639 * @return the original object or a new converted value 640 * @throws Throwable 641 */ 642 public static Object asType(Object object, Class type) throws Throwable { 643 return invokeMethodN(object.getClass(),object,"asType",new Object[]{type}); 644 } 645 646 /** 647 * Provides a hook for type casting of the given object to the required type 648 * 649 * @param type of object to convert the given object to 650 * @param object the object to be converted 651 * @return the original object or a new converted value 652 * @throws Throwable 653 */ 654 public static Object castToType(Object object, Class type) throws Throwable{ 655 try { 656 return DefaultTypeTransformation.castToType(object,type); 657 } catch (GroovyRuntimeException gre) { 658 return (Matcher) unwrap(gre); 659 } 660 } 661 662 public static Tuple createTuple(Object[] array) { 663 return new Tuple(array); 664 } 665 666 public static List createList(Object[] values) { 667 return InvokerHelper.createList(values); 668 } 669 670 public static Wrapper createPojoWrapper(Object val, Class clazz) { 671 return new PojoWrapper(val,clazz); 672 } 673 674 public static Wrapper createGroovyObjectWrapper(GroovyObject val, Class clazz) { 675 return new GroovyObjectWrapper(val,clazz); 676 } 677 678 public static Map createMap(Object[] values) { 679 return InvokerHelper.createMap(values); 680 } 681 682 683 //TODO: refactor 684 public static List createRange(Object from, Object to, boolean inclusive) throws Throwable { 685 if (!inclusive) { 686 if (compareEqual(from,to)){ 687 return new EmptyRange((Comparable)from); 688 } 689 if (compareGreaterThan(from, to)) { 690 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next"); 691 } 692 else { 693 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous"); 694 } 695 } 696 if (from instanceof Integer && to instanceof Integer) { 697 return new IntRange(DefaultTypeTransformation.intUnbox(from), DefaultTypeTransformation.intUnbox(to)); 698 } 699 else { 700 return new ObjectRange((Comparable) from, (Comparable) to); 701 } 702 } 703 704 //assert 705 public static void assertFailed(Object expression, Object message) { 706 InvokerHelper.assertFailed(expression,message); 707 } 708 709 //isCase 710 //TODO: set sender class 711 public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable{ 712 if (caseExpression == null) { 713 return switchValue == null; 714 } 715 return DefaultTypeTransformation.castToBoolean(invokeMethodN(caseExpression.getClass(), caseExpression, "isCase", new Object[]{switchValue})); 716 } 717 718 //compare 719 public static boolean compareIdentical(Object left, Object right) { 720 return left == right; 721 } 722 723 public static boolean compareEqual(Object left, Object right) { 724 return DefaultTypeTransformation.compareEqual(left, right); 725 } 726 727 public static boolean compareNotEqual(Object left, Object right) { 728 return !compareEqual(left, right); 729 } 730 731 public static Integer compareTo(Object left, Object right) { 732 int answer = DefaultTypeTransformation.compareTo(left, right); 733 if (answer == 0) { 734 return ZERO; 735 } 736 else { 737 return answer > 0 ? ONE : MINUS_ONE; 738 } 739 } 740 741 public static boolean compareLessThan(Object left, Object right) { 742 return compareTo(left, right).intValue() < 0; 743 } 744 745 public static boolean compareLessThanEqual(Object left, Object right){ 746 return compareTo(left, right).intValue() <= 0; 747 } 748 749 public static boolean compareGreaterThan(Object left, Object right){ 750 return compareTo(left, right).intValue() > 0; 751 } 752 753 public static boolean compareGreaterThanEqual(Object left, Object right){ 754 return compareTo(left, right).intValue() >= 0; 755 } 756 757 //regexpr 758 public static Pattern regexPattern(Object regex) { 759 return DefaultGroovyMethods.negate(regex.toString()); 760 } 761 762 public static Matcher findRegex(Object left, Object right) throws Throwable{ 763 try { 764 return InvokerHelper.findRegex(left, right); 765 } catch (GroovyRuntimeException gre) { 766 return (Matcher) unwrap(gre); 767 } 768 } 769 770 public static boolean matchRegex(Object left, Object right) { 771 return InvokerHelper.matchRegex(left, right); 772 } 773 774 775 //spread expressions 776 public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) { 777 ArrayList ret = new ArrayList(); 778 int argsPos = 0; 779 int spreadPos = 0; 780 for (int pos = 0; pos<positions.length; pos++) { 781 for (;argsPos<positions[pos];argsPos++) { 782 ret.add(args[argsPos]); 783 } 784 Object value = spreads[spreadPos]; 785 if (value==null) { 786 ret.add(null); 787 } else if (value instanceof List) { 788 ret.addAll((List) value); 789 } else if (value.getClass().isArray()) { 790 ret.addAll(DefaultTypeTransformation.primitiveArrayToList(value)); 791 } else { 792 throw new IllegalArgumentException("connot spread the type "+ value.getClass().getName()+" with value "+value); 793 } 794 spreadPos++; 795 } 796 for (;argsPos<args.length;argsPos++) { 797 ret.add(args[argsPos]); 798 } 799 return ret.toArray(); 800 } 801 802 public static Object spreadMap(Object value) { 803 return InvokerHelper.spreadMap(value); 804 } 805 806 //negation 807 public static Object negate(Object value) throws Throwable { 808 try { 809 return InvokerHelper.negate(value); 810 } catch (GroovyRuntimeException gre) { 811 return unwrap(gre); 812 } 813 } 814 815 public static Object bitNegate(Object value) { 816 return InvokerHelper.bitNegate(value); 817 } 818 819 public static MetaClass initMetaClass(Object object) { 820 return InvokerHelper.getMetaClass(object); 821 } 822 823 private static MetaClass getMetaClassObjectNotNull(Object object) { 824 if (!(object instanceof GroovyObject)) { 825 return initMetaClass(object); 826 } else { 827 return ((GroovyObject) object).getMetaClass(); 828 } 829 } 830 831 832 833 }