001 /* 002 $Id: InvokerHelper.java,v 1.73 2005/10/03 18:07:36 tug Exp $ 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.beans.Introspector; 051 import java.io.IOException; 052 import java.io.InputStream; 053 import java.io.InputStreamReader; 054 import java.io.Reader; 055 import java.io.Writer; 056 import java.lang.reflect.Array; 057 import java.math.BigDecimal; 058 import java.math.BigInteger; 059 import java.util.ArrayList; 060 import java.util.Collection; 061 import java.util.HashMap; 062 import java.util.Iterator; 063 import java.util.List; 064 import java.util.Map; 065 import java.util.regex.Matcher; 066 import java.util.regex.Pattern; 067 068 /** 069 * A static helper class to make bytecode generation easier and act as a facade over the Invoker 070 * 071 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a> 072 * @version $Revision: 1.73 $ 073 */ 074 public class InvokerHelper { 075 public static final Object[] EMPTY_ARGS = { 076 }; 077 078 private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]}; 079 080 private static final Invoker singleton = new Invoker(); 081 082 private static final Integer ZERO = new Integer(0); 083 private static final Integer MINUS_ONE = new Integer(-1); 084 private static final Integer ONE = new Integer(1); 085 086 public static MetaClass getMetaClass(Object object) { 087 return getInstance().getMetaClass(object); 088 } 089 090 public static void removeClass(Class clazz) { 091 getInstance().removeMetaClass(clazz); 092 Introspector.flushFromCaches(clazz); 093 } 094 095 public static Invoker getInstance() { 096 return singleton; 097 } 098 099 public static Object invokeNoArgumentsMethod(Object object, String methodName) { 100 return getInstance().invokeMethod(object, methodName, EMPTY_ARGS); 101 } 102 103 public static Object invokeMethod(Object object, String methodName, Object arguments) { 104 return getInstance().invokeMethod(object, methodName, arguments); 105 } 106 107 public static Object invokeSuperMethod(Object object, String methodName, Object arguments) { 108 return getInstance().invokeSuperMethod(object, methodName, arguments); 109 } 110 111 public static Object invokeMethodSafe(Object object, String methodName, Object arguments) { 112 if (object != null) { 113 return getInstance().invokeMethod(object, methodName, arguments); 114 } 115 return null; 116 } 117 118 public static Object invokeStaticMethod(String type, String methodName, Object arguments) { 119 return getInstance().invokeStaticMethod(type, methodName, arguments); 120 } 121 122 public static Object invokeStaticNoArgumentsMethod(String type, String methodName) { 123 return getInstance().invokeStaticMethod(type, methodName, EMPTY_ARGS); 124 } 125 126 public static Object invokeConstructorAt(Class at, Class type, Object arguments) { 127 return getInstance().invokeConstructorAt(at, type, arguments); 128 } 129 130 public static Object invokeConstructorAt(Class at, String type, Object arguments) { 131 return getInstance().invokeConstructorAt(at, type, arguments); 132 } 133 134 public static Object invokeNoArgumentsConstructorAt(Class at, Class type) { 135 return getInstance().invokeConstructorAt(at, type, EMPTY_ARGS); 136 } 137 138 public static Object invokeConstructorOf(String type, Object arguments) { 139 return getInstance().invokeConstructorOf(type, arguments); 140 } 141 142 public static Object invokeConstructorOf(Class type, Object arguments) { 143 return getInstance().invokeConstructorOf(type, arguments); 144 } 145 146 public static Object invokeNoArgumentsConstructorOf(Class type) { 147 return getInstance().invokeConstructorOf(type, EMPTY_ARGS); 148 } 149 150 public static Object invokeClosure(Object closure, Object arguments) { 151 return getInstance().invokeMethod(closure, "doCall", arguments); 152 } 153 154 public static Iterator asIterator(Object collection) { 155 return getInstance().asIterator(collection); 156 } 157 158 public static Collection asCollection(Object collection) { 159 return getInstance().asCollection(collection); 160 } 161 162 public static List asList(Object args) { 163 return getInstance().asList(args); 164 } 165 166 public static String toString(Object arguments) { 167 if (arguments instanceof Object[]) 168 return getInstance().toArrayString((Object[])arguments); 169 else if (arguments instanceof Collection) 170 return getInstance().toListString((Collection)arguments); 171 else if (arguments instanceof Map) 172 return getInstance().toMapString((Map)arguments); 173 else 174 return getInstance().toString(arguments); 175 } 176 177 public static String toTypeString(Object[] arguments) { 178 return getInstance().toTypeString(arguments); 179 } 180 181 public static String toMapString(Map arg) { 182 return getInstance().toMapString(arg); 183 } 184 185 public static String toListString(Collection arg) { 186 return getInstance().toListString(arg); 187 } 188 189 public static String toArrayString(Object[] arguments) { 190 return getInstance().toArrayString(arguments); 191 } 192 193 public static String inspect(Object self) { 194 return getInstance().inspect(self); 195 } 196 197 public static Object getAttribute(Object object, String attribute) { 198 return getInstance().getAttribute(object, attribute); 199 } 200 201 public static void setAttribute(Object object, String attribute, Object newValue) { 202 getInstance().setAttribute(object, attribute, newValue); 203 } 204 205 public static Object getProperty(Object object, String property) { 206 return getInstance().getProperty(object, property); 207 } 208 209 public static Object getPropertySafe(Object object, String property) { 210 if (object != null) { 211 return getInstance().getProperty(object, property); 212 } 213 return null; 214 } 215 216 public static void setProperty(Object object, String property, Object newValue) { 217 getInstance().setProperty(object, property, newValue); 218 } 219 220 /** 221 * This is so we don't have to reorder the stack when we call this method. 222 * At some point a better name might be in order. 223 */ 224 public static void setProperty2(Object newValue, Object object, String property) { 225 getInstance().setProperty(object, property, newValue); 226 } 227 228 229 /** 230 * This is so we don't have to reorder the stack when we call this method. 231 * At some point a better name might be in order. 232 */ 233 public static void setGroovyObjectProperty(Object newValue, GroovyObject object, String property) { 234 object.setProperty(property, newValue); 235 } 236 237 public static Object getGroovyObjectProperty(GroovyObject object, String property) { 238 return object.getProperty(property); 239 } 240 241 242 /** 243 * This is so we don't have to reorder the stack when we call this method. 244 * At some point a better name might be in order. 245 */ 246 public static void setPropertySafe2(Object newValue, Object object, String property) { 247 if (object != null) { 248 setProperty2(newValue, object, property); 249 } 250 } 251 252 /** 253 * Returns the method pointer for the given object name 254 */ 255 public static Closure getMethodPointer(Object object, String methodName) { 256 return getInstance().getMethodPointer(object, methodName); 257 } 258 259 /** 260 * Provides a hook for type coercion of the given object to the required type 261 * 262 * @param type of object to convert the given object to 263 * @param object the object to be converted 264 * @return the original object or a new converted value 265 */ 266 public static Object asType(Object object, Class type) { 267 return getInstance().asType(object, type); 268 } 269 270 public static boolean asBool(Object object) { 271 return getInstance().asBool(object); 272 } 273 274 public static boolean notObject(Object object) { 275 return !asBool(object); 276 } 277 278 public static boolean notBoolean(boolean bool) { 279 return !bool; 280 } 281 282 public static Object negate(Object value) { 283 if (value instanceof Integer) { 284 Integer number = (Integer) value; 285 return integerValue(-number.intValue()); 286 } 287 else if (value instanceof Long) { 288 Long number = (Long) value; 289 return new Long(-number.longValue()); 290 } 291 else if (value instanceof BigInteger) { 292 return ((BigInteger) value).negate(); 293 } 294 else if (value instanceof BigDecimal) { 295 return ((BigDecimal) value).negate(); 296 } 297 else if (value instanceof Double) { 298 Double number = (Double) value; 299 return new Double(-number.doubleValue()); 300 } 301 else if (value instanceof Float) { 302 Float number = (Float) value; 303 return new Float(-number.floatValue()); 304 } 305 else if (value instanceof ArrayList) { 306 // value is an list. 307 ArrayList newlist = new ArrayList(); 308 Iterator it = ((ArrayList) value).iterator(); 309 for (; it.hasNext();) { 310 newlist.add(negate(it.next())); 311 } 312 return newlist; 313 } 314 else { 315 throw new GroovyRuntimeException("Cannot negate type " + value.getClass().getName() + ", value " + value); 316 } 317 } 318 319 public static Object bitNegate(Object value) { 320 if (value instanceof Integer) { 321 Integer number = (Integer) value; 322 return integerValue(~number.intValue()); 323 } 324 else if (value instanceof Long) { 325 Long number = (Long) value; 326 return new Long(~number.longValue()); 327 } 328 else if (value instanceof BigInteger) { 329 return ((BigInteger) value).not(); 330 } 331 else if (value instanceof String) { 332 // value is a regular expression. 333 return getInstance().regexPattern(value); 334 } 335 else if (value instanceof GString) { 336 // value is a regular expression. 337 return getInstance().regexPattern(value.toString()); 338 } 339 else if (value instanceof ArrayList) { 340 // value is an list. 341 ArrayList newlist = new ArrayList(); 342 Iterator it = ((ArrayList) value).iterator(); 343 for (; it.hasNext();) { 344 newlist.add(bitNegate(it.next())); 345 } 346 return newlist; 347 } 348 else { 349 throw new BitwiseNegateEvaluatingException("Cannot bitwise negate type " + value.getClass().getName() + ", value " + value); 350 } 351 } 352 353 public static boolean isCase(Object switchValue, Object caseExpression) { 354 return asBool(invokeMethod(caseExpression, "isCase", new Object[]{switchValue})); 355 } 356 357 public static boolean compareIdentical(Object left, Object right) { 358 return left == right; 359 } 360 361 public static boolean compareEqual(Object left, Object right) { 362 return getInstance().objectsEqual(left, right); 363 } 364 365 public static Matcher findRegex(Object left, Object right) { 366 return getInstance().objectFindRegex(left, right); 367 } 368 369 public static boolean matchRegex(Object left, Object right) { 370 return getInstance().objectMatchRegex(left, right); 371 } 372 373 public static Pattern regexPattern(Object regex) { 374 return getInstance().regexPattern(regex); 375 } 376 377 public static boolean compareNotEqual(Object left, Object right) { 378 return !getInstance().objectsEqual(left, right); 379 } 380 381 public static boolean compareLessThan(Object left, Object right) { 382 return getInstance().compareTo(left, right) < 0; 383 } 384 385 public static boolean compareLessThanEqual(Object left, Object right) { 386 return getInstance().compareTo(left, right) <= 0; 387 } 388 389 public static boolean compareGreaterThan(Object left, Object right) { 390 return getInstance().compareTo(left, right) > 0; 391 } 392 393 public static boolean compareGreaterThanEqual(Object left, Object right) { 394 return getInstance().compareTo(left, right) >= 0; 395 } 396 397 public static Integer compareTo(Object left, Object right) { 398 int answer = getInstance().compareTo(left, right); 399 if (answer == 0) { 400 return ZERO; 401 } 402 else { 403 return answer > 0 ? ONE : MINUS_ONE; 404 } 405 } 406 407 public static Tuple createTuple(Object[] array) { 408 return new Tuple(array); 409 } 410 411 public static SpreadList spreadList(Object value) { 412 if (value instanceof List) { 413 // value is a list. 414 Object[] values = new Object[((List) value).size()]; 415 int index = 0; 416 Iterator it = ((List) value).iterator(); 417 for (; it.hasNext();) { 418 values[index++] = it.next(); 419 } 420 return new SpreadList(values); 421 } 422 else { 423 throw new SpreadListEvaluatingException("Cannot spread the type " + value.getClass().getName() + ", value " + value); 424 } 425 } 426 427 public static SpreadMap spreadMap(Object value) { 428 if (value instanceof Map) { 429 Object[] values = new Object[((Map) value).keySet().size() * 2]; 430 int index = 0; 431 Iterator it = ((Map) value).keySet().iterator(); 432 for (; it.hasNext();) { 433 Object key = it.next(); 434 values[index++] = key; 435 values[index++] = ((Map) value).get(key); 436 } 437 return new SpreadMap(values); 438 } 439 else { 440 throw new SpreadMapEvaluatingException("Cannot spread the map " + value.getClass().getName() + ", value " + value); 441 } 442 } 443 444 public static List createList(Object[] values) { 445 ArrayList answer = new ArrayList(values.length); 446 for (int i = 0; i < values.length; i++) { 447 if (values[i] instanceof SpreadList) { 448 SpreadList slist = (SpreadList) values[i]; 449 for (int j = 0; j < slist.size(); j++) { 450 answer.add(slist.get(j)); 451 } 452 } 453 else { 454 answer.add(values[i]); 455 } 456 } 457 return answer; 458 } 459 460 public static Map createMap(Object[] values) { 461 Map answer = new HashMap(values.length / 2); 462 int i = 0; 463 while (i < values.length - 1) { 464 if ((values[i] instanceof SpreadMap) && (values[i+1] instanceof Map)) { 465 Map smap = (Map) values[i+1]; 466 Iterator iter = smap.keySet().iterator(); 467 for (; iter.hasNext(); ) { 468 Object key = (Object) iter.next(); 469 answer.put(key, smap.get(key)); 470 } 471 i+=2; 472 } 473 else { 474 answer.put(values[i++], values[i++]); 475 } 476 } 477 return answer; 478 } 479 480 public static List createRange(Object from, Object to, boolean inclusive) { 481 if (!inclusive) { 482 if (compareEqual(from,to)){ 483 return new EmptyRange((Comparable)from); 484 } 485 if (compareGreaterThan(from, to)) { 486 to = invokeMethod(to, "next", EMPTY_ARGS); 487 } 488 else { 489 to = invokeMethod(to, "previous", EMPTY_ARGS); 490 } 491 } 492 if (from instanceof Integer && to instanceof Integer) { 493 return new IntRange(asInt(from), asInt(to)); 494 } 495 else { 496 return new ObjectRange((Comparable) from, (Comparable) to); 497 } 498 } 499 500 public static int asInt(Object value) { 501 return getInstance().asInt(value); 502 } 503 504 public static void assertFailed(Object expression, Object message) { 505 if (message == null || "".equals(message)) { 506 throw new AssertionError("Expression: " + expression); 507 } 508 else { 509 throw new AssertionError("" + message + ". Expression: " + expression); 510 } 511 } 512 513 public static Object runScript(Class scriptClass, String[] args) { 514 Binding context = new Binding(args); 515 Script script = createScript(scriptClass, context); 516 return invokeMethod(script, "run", EMPTY_ARGS); 517 } 518 519 public static Script createScript(Class scriptClass, Binding context) { 520 // for empty scripts 521 if (scriptClass == null) { 522 return new Script() { 523 public Object run() { 524 return null; 525 } 526 }; 527 } 528 try { 529 final GroovyObject object = (GroovyObject) scriptClass.newInstance(); 530 Script script = null; 531 if (object instanceof Script) { 532 script = (Script) object; 533 } 534 else { 535 // it could just be a class, so lets wrap it in a Script wrapper 536 // though the bindings will be ignored 537 script = new Script() { 538 public Object run() { 539 object.invokeMethod("main", EMPTY_MAIN_ARGS); 540 return null; 541 } 542 }; 543 setProperties(object, context.getVariables()); 544 } 545 script.setBinding(context); 546 return script; 547 } 548 catch (Exception e) { 549 throw new GroovyRuntimeException("Failed to create Script instance for class: " + scriptClass + ". Reason: " + e, 550 e); 551 } 552 } 553 554 /** 555 * Sets the properties on the given object 556 * 557 * @param object 558 * @param map 559 */ 560 public static void setProperties(Object object, Map map) { 561 getMetaClass(object).setProperties(object, map); 562 } 563 564 public static String getVersion() { 565 String version = null; 566 Package p = Package.getPackage("groovy.lang"); 567 if (p != null) { 568 version = p.getImplementationVersion(); 569 } 570 if (version == null) { 571 version = ""; 572 } 573 return version; 574 } 575 576 /** 577 * Allows conversion of arrays into a mutable List 578 * 579 * @return the array as a List 580 */ 581 protected static List primitiveArrayToList(Object array) { 582 int size = Array.getLength(array); 583 List list = new ArrayList(size); 584 for (int i = 0; i < size; i++) { 585 list.add(Array.get(array, i)); 586 } 587 return list; 588 } 589 590 /** 591 * Writes the given object to the given stream 592 */ 593 public static void write(Writer out, Object object) throws IOException { 594 if (object instanceof String) { 595 out.write((String) object); 596 } 597 else if (object instanceof Object[]) { 598 out.write(toArrayString((Object[]) object)); 599 } 600 else if (object instanceof Map) { 601 out.write(toMapString((Map) object)); 602 } 603 else if (object instanceof Collection) { 604 out.write(toListString((Collection) object)); 605 } 606 else if (object instanceof Writable) { 607 Writable writable = (Writable) object; 608 writable.writeTo(out); 609 } 610 else if (object instanceof InputStream || object instanceof Reader) { 611 // Copy stream to stream 612 Reader reader; 613 if (object instanceof InputStream) { 614 reader = new InputStreamReader((InputStream) object); 615 } 616 else { 617 reader = (Reader) object; 618 } 619 char[] chars = new char[8192]; 620 int i; 621 while ((i = reader.read(chars)) != -1) { 622 out.write(chars, 0, i); 623 } 624 reader.close(); 625 } 626 else { 627 out.write(toString(object)); 628 } 629 } 630 631 public static Object box(boolean value) { 632 return value ? Boolean.TRUE : Boolean.FALSE; 633 } 634 635 public static Object box(byte value) { 636 return new Byte(value); 637 } 638 639 public static Object box(char value) { 640 return new Character(value); 641 } 642 643 public static Object box(short value) { 644 return new Short(value); 645 } 646 647 public static Object box(int value) { 648 return integerValue(value); 649 } 650 651 public static Object box(long value) { 652 return new Long(value); 653 } 654 655 public static Object box(float value) { 656 return new Float(value); 657 } 658 659 public static Object box(double value) { 660 return new Double(value); 661 } 662 663 public static byte byteUnbox(Object value) { 664 Number n = (Number) asType(value, Byte.class); 665 return n.byteValue(); 666 } 667 668 public static char charUnbox(Object value) { 669 Character n = (Character) asType(value, Character.class); 670 return n.charValue(); 671 } 672 673 public static short shortUnbox(Object value) { 674 Number n = (Number) asType(value, Short.class); 675 return n.shortValue(); 676 } 677 678 public static int intUnbox(Object value) { 679 Number n = (Number) asType(value, Integer.class); 680 return n.intValue(); 681 } 682 683 public static boolean booleanUnbox(Object value) { 684 Boolean n = (Boolean) asType(value, Boolean.class); 685 return n.booleanValue(); 686 } 687 688 public static long longUnbox(Object value) { 689 Number n = (Number) asType(value, Long.class); 690 return n.longValue(); 691 } 692 693 public static float floatUnbox(Object value) { 694 Number n = (Number) asType(value, Float.class); 695 return n.floatValue(); 696 } 697 698 public static double doubleUnbox(Object value) { 699 Number n = (Number) asType(value, Double.class); 700 return n.doubleValue(); 701 } 702 703 /** 704 * @param a array of primitives 705 * @param type component type of the array 706 * @return 707 */ 708 public static Object[] convertPrimitiveArray(Object a, Class type) { 709 // System.out.println("a.getClass() = " + a.getClass()); 710 Object[] ans = null; 711 String elemType = type.getName(); 712 if (elemType.equals("int")) { 713 // conservative coding 714 if (a.getClass().getName().equals("[Ljava.lang.Integer;")) { 715 ans = (Integer[]) a; 716 } 717 else { 718 int[] ia = (int[]) a; 719 ans = new Integer[ia.length]; 720 for (int i = 0; i < ia.length; i++) { 721 int e = ia[i]; 722 ans[i] = integerValue(e); 723 } 724 } 725 } 726 else if (elemType.equals("char")) { 727 if (a.getClass().getName().equals("[Ljava.lang.Character;")) { 728 ans = (Character[]) a; 729 } 730 else { 731 char[] ia = (char[]) a; 732 ans = new Character[ia.length]; 733 for (int i = 0; i < ia.length; i++) { 734 char e = ia[i]; 735 ans[i] = new Character(e); 736 } 737 } 738 } 739 else if (elemType.equals("boolean")) { 740 if (a.getClass().getName().equals("[Ljava.lang.Boolean;")) { 741 ans = (Boolean[]) a; 742 } 743 else { 744 boolean[] ia = (boolean[]) a; 745 ans = new Boolean[ia.length]; 746 for (int i = 0; i < ia.length; i++) { 747 boolean e = ia[i]; 748 ans[i] = new Boolean(e); 749 } 750 } 751 } 752 else if (elemType.equals("byte")) { 753 if (a.getClass().getName().equals("[Ljava.lang.Byte;")) { 754 ans = (Byte[]) a; 755 } 756 else { 757 byte[] ia = (byte[]) a; 758 ans = new Byte[ia.length]; 759 for (int i = 0; i < ia.length; i++) { 760 byte e = ia[i]; 761 ans[i] = new Byte(e); 762 } 763 } 764 } 765 else if (elemType.equals("short")) { 766 if (a.getClass().getName().equals("[Ljava.lang.Short;")) { 767 ans = (Short[]) a; 768 } 769 else { 770 short[] ia = (short[]) a; 771 ans = new Short[ia.length]; 772 for (int i = 0; i < ia.length; i++) { 773 short e = ia[i]; 774 ans[i] = new Short(e); 775 } 776 } 777 } 778 else if (elemType.equals("float")) { 779 if (a.getClass().getName().equals("[Ljava.lang.Float;")) { 780 ans = (Float[]) a; 781 } 782 else { 783 float[] ia = (float[]) a; 784 ans = new Float[ia.length]; 785 for (int i = 0; i < ia.length; i++) { 786 float e = ia[i]; 787 ans[i] = new Float(e); 788 } 789 } 790 } 791 else if (elemType.equals("long")) { 792 if (a.getClass().getName().equals("[Ljava.lang.Long;")) { 793 ans = (Long[]) a; 794 } 795 else { 796 long[] ia = (long[]) a; 797 ans = new Long[ia.length]; 798 for (int i = 0; i < ia.length; i++) { 799 long e = ia[i]; 800 ans[i] = new Long(e); 801 } 802 } 803 } 804 else if (elemType.equals("double")) { 805 if (a.getClass().getName().equals("[Ljava.lang.Double;")) { 806 ans = (Double[]) a; 807 } 808 else { 809 double[] ia = (double[]) a; 810 ans = new Double[ia.length]; 811 for (int i = 0; i < ia.length; i++) { 812 double e = ia[i]; 813 ans[i] = new Double(e); 814 } 815 } 816 } 817 return ans; 818 } 819 820 public static int[] convertToIntArray(Object a) { 821 int[] ans = null; 822 823 // conservative coding 824 if (a.getClass().getName().equals("[I")) { 825 ans = (int[]) a; 826 } 827 else { 828 Object[] ia = (Object[]) a; 829 ans = new int[ia.length]; 830 for (int i = 0; i < ia.length; i++) { 831 if (ia[i] == null) { 832 continue; 833 } 834 ans[i] = ((Number) ia[i]).intValue(); 835 } 836 } 837 return ans; 838 } 839 840 public static boolean[] convertToBooleanArray(Object a) { 841 boolean[] ans = null; 842 843 // conservative coding 844 if (a.getClass().getName().equals("[Z")) { 845 ans = (boolean[]) a; 846 } 847 else { 848 Object[] ia = (Object[]) a; 849 ans = new boolean[ia.length]; 850 for (int i = 0; i < ia.length; i++) { 851 if (ia[i] == null) { 852 continue; 853 } 854 ans[i] = ((Boolean) ia[i]).booleanValue(); 855 } 856 } 857 return ans; 858 } 859 860 public static byte[] convertToByteArray(Object a) { 861 byte[] ans = null; 862 863 // conservative coding 864 if (a.getClass().getName().equals("[B")) { 865 ans = (byte[]) a; 866 } 867 else { 868 Object[] ia = (Object[]) a; 869 ans = new byte[ia.length]; 870 for (int i = 0; i < ia.length; i++) { 871 if (ia[i] != null) { 872 ans[i] = ((Number) ia[i]).byteValue(); 873 } 874 } 875 } 876 return ans; 877 } 878 879 public static short[] convertToShortArray(Object a) { 880 short[] ans = null; 881 882 // conservative coding 883 if (a.getClass().getName().equals("[S")) { 884 ans = (short[]) a; 885 } 886 else { 887 Object[] ia = (Object[]) a; 888 ans = new short[ia.length]; 889 for (int i = 0; i < ia.length; i++) { 890 ans[i] = ((Number) ia[i]).shortValue(); 891 } 892 } 893 return ans; 894 } 895 896 public static char[] convertToCharArray(Object a) { 897 char[] ans = null; 898 899 // conservative coding 900 if (a.getClass().getName().equals("[C")) { 901 ans = (char[]) a; 902 } 903 else { 904 Object[] ia = (Object[]) a; 905 ans = new char[ia.length]; 906 for (int i = 0; i < ia.length; i++) { 907 if (ia[i] == null) { 908 continue; 909 } 910 ans[i] = ((Character) ia[i]).charValue(); 911 } 912 } 913 return ans; 914 } 915 916 public static long[] convertToLongArray(Object a) { 917 long[] ans = null; 918 919 // conservative coding 920 if (a.getClass().getName().equals("[J")) { 921 ans = (long[]) a; 922 } 923 else { 924 Object[] ia = (Object[]) a; 925 ans = new long[ia.length]; 926 for (int i = 0; i < ia.length; i++) { 927 if (ia[i] == null) { 928 continue; 929 } 930 ans[i] = ((Number) ia[i]).longValue(); 931 } 932 } 933 return ans; 934 } 935 936 public static float[] convertToFloatArray(Object a) { 937 float[] ans = null; 938 939 // conservative coding 940 if (a.getClass().getName().equals("[F")) { 941 ans = (float[]) a; 942 } 943 else { 944 Object[] ia = (Object[]) a; 945 ans = new float[ia.length]; 946 for (int i = 0; i < ia.length; i++) { 947 if (ia[i] == null) { 948 continue; 949 } 950 ans[i] = ((Number) ia[i]).floatValue(); 951 } 952 } 953 return ans; 954 } 955 956 public static double[] convertToDoubleArray(Object a) { 957 double[] ans = null; 958 959 // conservative coding 960 if (a.getClass().getName().equals("[D")) { 961 ans = (double[]) a; 962 } 963 else { 964 Object[] ia = (Object[]) a; 965 ans = new double[ia.length]; 966 for (int i = 0; i < ia.length; i++) { 967 if (ia[i] == null) { 968 continue; 969 } 970 ans[i] = ((Number) ia[i]).doubleValue(); 971 } 972 } 973 return ans; 974 } 975 976 public static Object convertToPrimitiveArray(Object a, Class type) { 977 if (type == Byte.TYPE) { 978 return convertToByteArray(a); 979 } 980 if (type == Boolean.TYPE) { 981 return convertToBooleanArray(a); 982 } 983 if (type == Short.TYPE) { 984 return convertToShortArray(a); 985 } 986 if (type == Character.TYPE) { 987 return convertToCharArray(a); 988 } 989 if (type == Integer.TYPE) { 990 return convertToIntArray(a); 991 } 992 if (type == Long.TYPE) { 993 return convertToLongArray(a); 994 } 995 if (type == Float.TYPE) { 996 return convertToFloatArray(a); 997 } 998 if (type == Double.TYPE) { 999 return convertToDoubleArray(a); 1000 } 1001 else { 1002 return a; 1003 } 1004 } 1005 1006 /** 1007 * get the Integer object from an int. Cached version is used for small ints. 1008 * 1009 * @param v 1010 * @return 1011 */ 1012 public static Integer integerValue(int v) { 1013 int index = v + INT_CACHE_OFFSET; 1014 if (index >= 0 && index < INT_CACHE_LEN) { 1015 return SMALL_INTEGERS[index]; 1016 } 1017 else { 1018 return new Integer(v); 1019 } 1020 } 1021 1022 private static Integer[] SMALL_INTEGERS; 1023 private static int INT_CACHE_OFFSET = 128, INT_CACHE_LEN = 256; 1024 1025 static { 1026 SMALL_INTEGERS = new Integer[INT_CACHE_LEN]; 1027 for (int i = 0; i < SMALL_INTEGERS.length; i++) { 1028 SMALL_INTEGERS[i] = new Integer(i - INT_CACHE_OFFSET); 1029 } 1030 } 1031 }