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