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