View Javadoc

    1   /*
    2    $Id: InvokerHelper.java,v 1.57 2004/12/08 02:53:27 spullara Exp $
    3
    4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
    5
    6    Redistribution and use of this software and associated documentation
    7    ("Software"), with or without modification, are permitted provided
    8    that the following conditions are met:
    9
    10   1. Redistributions of source code must retain copyright
    11      statements and notices.  Redistributions must also contain a
    12      copy of this document.
    13
    14   2. Redistributions in binary form must reproduce the
    15      above copyright notice, this list of conditions and the
    16      following disclaimer in the documentation and/or other
    17      materials provided with the distribution.
    18
    19   3. The name "groovy" must not be used to endorse or promote
    20      products derived from this Software without prior written
    21      permission of The Codehaus.  For written permission,
    22      please contact info@codehaus.org.
    23
    24   4. Products derived from this Software may not be called "groovy"
    25      nor may "groovy" appear in their names without prior written
    26      permission of The Codehaus. "groovy" is a registered
    27      trademark of The Codehaus.
    28
    29   5. Due credit should be given to The Codehaus -
    30      http://groovy.codehaus.org/
    31
    32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
    33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
    34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
    36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    43   OF THE POSSIBILITY OF SUCH DAMAGE.
    44
    45   */
    46  package org.codehaus.groovy.runtime;
    47
    48  import groovy.lang.*;
    49
    50  import java.beans.Introspector;
    51  import java.io.*;
    52  import java.lang.reflect.Array;
    53  import java.math.BigDecimal;
    54  import java.math.BigInteger;
    55  import java.util.*;
    56  import java.util.regex.Matcher;
    57  import java.util.regex.Pattern;
    58
    59  /***
    60   * A static helper class to make bytecode generation easier and act as a facade over the Invoker
    61   *
    62   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    63   * @version $Revision: 1.57 $
    64   */
    65  public class InvokerHelper {
    66      public static final Object[] EMPTY_ARGS = {
    67      };
    68
    69      private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
    70
    71      private static final Invoker singleton = new Invoker();
    72
    73      private static final Integer ZERO = new Integer(0);
    74      private static final Integer MINUS_ONE = new Integer(-1);
    75      private static final Integer ONE = new Integer(1);
    76
    77      public static MetaClass getMetaClass(Object object) {
    78          return getInstance().getMetaClass(object);
    79      }
    80
    81      public static void removeClass(Class clazz) {
    82          getInstance().removeMetaClass(clazz);
    83          Introspector.flushFromCaches(clazz);
    84      }
    85
    86      public static Invoker getInstance() {
    87          return singleton;
    88      }
    89
    90      public static Object invokeNoArgumentsMethod(Object object, String methodName) {
    91          return getInstance().invokeMethod(object, methodName, EMPTY_ARGS);
    92      }
    93
    94      public static Object invokeMethod(Object object, String methodName, Object arguments) {
    95          return getInstance().invokeMethod(object, methodName, arguments);
    96      }
    97
    98      public static Object invokeSuperMethod(Object object, String methodName, Object arguments) {
    99          return getInstance().invokeSuperMethod(object, methodName, arguments);
    100     }
    101
    102     public static Object invokeMethodSafe(Object object, String methodName, Object arguments) {
    103         if (object != null) {
    104             return getInstance().invokeMethod(object, methodName, arguments);
    105         }
    106         return null;
    107     }
    108
    109     public static Object invokeStaticMethod(String type, String methodName, Object arguments) {
    110         return getInstance().invokeStaticMethod(type, methodName, arguments);
    111     }
    112
    113     public static Object invokeStaticNoArgumentsMethod(String type, String methodName) {
    114         return getInstance().invokeStaticMethod(type, methodName, EMPTY_ARGS);
    115     }
    116
    117     public static Object invokeConstructor(String type, Object arguments) {
    118         return getInstance().invokeConstructor(type, arguments);
    119     }
    120
    121     public static Object invokeConstructorOf(Class type, Object arguments) {
    122         return getInstance().invokeConstructorOf(type, arguments);
    123     }
    124
    125     public static Object invokeNoArgumentsConstructorOf(Class type) {
    126         return getInstance().invokeConstructorOf(type, EMPTY_ARGS);
    127     }
    128
    129     public static Object invokeClosure(Object closure, Object arguments) {
    130         return getInstance().invokeMethod(closure, "doCall", arguments);
    131     }
    132
    133     public static Iterator asIterator(Object collection) {
    134         return getInstance().asIterator(collection);
    135     }
    136
    137     public static Collection asCollection(Object collection) {
    138         return getInstance().asCollection(collection);
    139     }
    140
    141     public static List asList(Object args) {
    142         return getInstance().asList(args);
    143     }
    144
    145     public static String toString(Object arguments) {
    146         return getInstance().toString(arguments);
    147     }
    148
    149     public static String toTypeString(Object[] arguments) {
    150         return getInstance().toTypeString(arguments);
    151     }
    152
    153     public static String inspect(Object self) {
    154         return getInstance().inspect(self);
    155     }
    156
    157     public static Object getProperty(Object object, String property) {
    158         return getInstance().getProperty(object, property);
    159     }
    160
    161     public static Object getPropertySafe(Object object, String property) {
    162         if (object != null) {
    163             return getInstance().getProperty(object, property);
    164         }
    165         return null;
    166     }
    167
    168     public static void setProperty(Object object, String property, Object newValue) {
    169         getInstance().setProperty(object, property, newValue);
    170     }
    171
    172     /***
    173      * This is so we don't have to reorder the stack when we call this method.
    174      * At some point a better name might be in order.
    175      */
    176     public static void setProperty2(Object newValue, Object object, String property) {
    177         getInstance().setProperty(object, property, newValue);
    178     }
    179
    180
    181     /***
    182      * This is so we don't have to reorder the stack when we call this method.
    183      * At some point a better name might be in order.
    184      */
    185     public static void setGroovyObjectProperty(Object newValue, GroovyObject object, String property) {
    186         object.setProperty(property, newValue);
    187     }
    188
    189     public static Object getGroovyObjectProperty(GroovyObject object, String property) {
    190         return object.getProperty(property);
    191     }
    192
    193
    194     /***
    195      * This is so we don't have to reorder the stack when we call this method.
    196      * At some point a better name might be in order.
    197      */
    198     public static void setPropertySafe2(Object newValue, Object object, String property) {
    199         if (object != null) {
    200             setProperty2(newValue, object, property);
    201         }
    202     }
    203
    204     /***
    205      * Provides a hook for type coercion of the given object to the required type
    206      *
    207      * @param type   of object to convert the given object to
    208      * @param object the object to be converted
    209      * @return the original object or a new converted value
    210      */
    211     public static Object asType(Object object, Class type) {
    212         return getInstance().asType(object, type);
    213     }
    214
    215     public static boolean asBool(Object object) {
    216         return getInstance().asBool(object);
    217     }
    218
    219     public static boolean notObject(Object object) {
    220         return !asBool(object);
    221     }
    222
    223     public static boolean notBoolean(boolean bool) {
    224         return !bool;
    225     }
    226
    227     public static Object negate(Object value) {
    228         if (value instanceof Integer) {
    229             Integer number = (Integer) value;
    230             return integerValue(-number.intValue());
    231         } else if (value instanceof Long) {
    232             Long number = (Long) value;
    233             return new Long(-number.longValue());
    234         } else if (value instanceof BigInteger) {
    235             return ((BigInteger) value).negate();
    236         } else if (value instanceof BigDecimal) {
    237             return ((BigDecimal) value).negate();
    238         } else if (value instanceof Double) {
    239             Double number = (Double) value;
    240             return new Double(-number.doubleValue());
    241         } else if (value instanceof Float) {
    242             Float number = (Float) value;
    243             return new Float(-number.floatValue());
    244         } else {
    245             throw new GroovyRuntimeException("Cannot negate type " + value.getClass().getName() + ", value " + value);
    246         }
    247     }
    248
    249     public static boolean isCase(Object switchValue, Object caseExpression) {
    250         return asBool(invokeMethod(caseExpression, "isCase", new Object[]{switchValue}));
    251     }
    252
    253     public static boolean compareIdentical(Object left, Object right) {
    254         return left == right;
    255     }
    256
    257     public static boolean compareEqual(Object left, Object right) {
    258         return getInstance().objectsEqual(left, right);
    259     }
    260
    261     public static Matcher findRegex(Object left, Object right) {
    262         return getInstance().objectFindRegex(left, right);
    263     }
    264
    265     public static boolean matchRegex(Object left, Object right) {
    266         return getInstance().objectMatchRegex(left, right);
    267     }
    268
    269     public static Pattern regexPattern(Object regex) {
    270         return getInstance().regexPattern(regex);
    271     }
    272
    273     public static boolean compareNotEqual(Object left, Object right) {
    274         return !getInstance().objectsEqual(left, right);
    275     }
    276
    277     public static boolean compareLessThan(Object left, Object right) {
    278         return getInstance().compareTo(left, right) < 0;
    279     }
    280
    281     public static boolean compareLessThanEqual(Object left, Object right) {
    282         return getInstance().compareTo(left, right) <= 0;
    283     }
    284
    285     public static boolean compareGreaterThan(Object left, Object right) {
    286         return getInstance().compareTo(left, right) > 0;
    287     }
    288
    289     public static boolean compareGreaterThanEqual(Object left, Object right) {
    290         return getInstance().compareTo(left, right) >= 0;
    291     }
    292
    293     public static Integer compareTo(Object left, Object right) {
    294         int answer = getInstance().compareTo(left, right);
    295         if (answer == 0) {
    296             return ZERO;
    297         } else {
    298             return answer > 0 ? ONE : MINUS_ONE;
    299         }
    300     }
    301
    302     public static Tuple createTuple(Object[] array) {
    303         return new Tuple(array);
    304     }
    305
    306     public static List createList(Object[] values) {
    307         ArrayList answer = new ArrayList(values.length);
    308         for (int i = 0; i < values.length; i++) {
    309             answer.add(values[i]);
    310         }
    311         return answer;
    312     }
    313
    314     public static Map createMap(Object[] values) {
    315         Map answer = new HashMap(values.length / 2);
    316         int i = 0;
    317         while (i < values.length) {
    318             answer.put(values[i++], values[i++]);
    319         }
    320         return answer;
    321     }
    322
    323     public static List createRange(Object from, Object to, boolean inclusive) {
    324         if (!inclusive) {
    325             if (compareGreaterThan(from, to)) {
    326                 to = invokeMethod(to, "next", EMPTY_ARGS);
    327             } else {
    328                 to = invokeMethod(to, "previous", EMPTY_ARGS);
    329             }
    330         }
    331         if (from instanceof Integer && to instanceof Integer) {
    332             return new IntRange(asInt(from), asInt(to));
    333         } else {
    334             return new ObjectRange((Comparable) from, (Comparable) to);
    335         }
    336     }
    337
    338     public static int asInt(Object value) {
    339         return getInstance().asInt(value);
    340     }
    341
    342     public static void assertFailed(Object expression, Object message) {
    343         if (message == null || "".equals(message)) {
    344             throw new AssertionError("Expression: " + expression);
    345         } else {
    346             throw new AssertionError("" + message + ". Expression: " + expression);
    347         }
    348     }
    349
    350     public static Object runScript(Class scriptClass, String[] args) {
    351         Binding context = new Binding(args);
    352         Script script = createScript(scriptClass, context);
    353         return invokeMethod(script, "run", EMPTY_ARGS);
    354     }
    355
    356     public static Script createScript(Class scriptClass, Binding context) {
    357         try {
    358             final GroovyObject object = (GroovyObject) scriptClass.newInstance();
    359             Script script = null;
    360             if (object instanceof Script) {
    361                 script = (Script) object;
    362             } else {
    363                 // it could just be a class, so lets wrap it in a Script wrapper
    364                 // though the bindings will be ignored
    365                 script = new Script() {
    366                     public Object run() {
    367                         object.invokeMethod("main", EMPTY_MAIN_ARGS);
    368                         return null;
    369                     }
    370                 };
    371                 setProperties(object, context.getVariables());
    372             }
    373             script.setBinding(context);
    374             return script;
    375         } catch (Exception e) {
    376             throw new GroovyRuntimeException("Failed to create Script instance for class: " + scriptClass + ". Reason: " + e,
    377                     e);
    378         }
    379     }
    380
    381     /***
    382      * Sets the properties on the given object
    383      *
    384      * @param object
    385      * @param map
    386      */
    387     public static void setProperties(Object object, Map map) {
    388         getMetaClass(object).setProperties(object, map);
    389     }
    390
    391     public static String getVersion() {
    392         String version = null;
    393         Package p = Package.getPackage("groovy.lang");
    394         if (p != null) {
    395             version = p.getImplementationVersion();
    396         }
    397         if (version == null) {
    398             version = "";
    399         }
    400         return version;
    401     }
    402
    403     /***
    404      * Allows conversion of arrays into a mutable List
    405      *
    406      * @return the array as a List
    407      */
    408     protected static List primitiveArrayToList(Object array) {
    409         int size = Array.getLength(array);
    410         List list = new ArrayList(size);
    411         for (int i = 0; i < size; i++) {
    412             list.add(Array.get(array, i));
    413         }
    414         return list;
    415     }
    416
    417     /***
    418      * Writes the given object to the given stream
    419      */
    420     public static void write(Writer out, Object object) throws IOException {
    421         if (object instanceof String) {
    422             out.write((String) object);
    423         } else if (object instanceof Writable) {
    424             Writable writable = (Writable) object;
    425             writable.writeTo(out);
    426         } else if (object instanceof InputStream || object instanceof Reader) {
    427             // Copy stream to stream
    428             Reader reader;
    429             if (object instanceof InputStream) {
    430                 reader = new InputStreamReader((InputStream) object);
    431             } else {
    432                 reader = (Reader) object;
    433             }
    434             char[] chars = new char[8192];
    435             int i;
    436             while ((i = reader.read(chars)) != -1) {
    437                 out.write(chars, 0, i);
    438             }
    439             reader.close();
    440         } else {
    441             out.write(toString(object));
    442         }
    443     }
    444
    445     public static Object box(boolean value) {
    446         return value ? Boolean.TRUE : Boolean.FALSE;
    447     }
    448
    449     public static Object box(byte value) {
    450         return new Byte(value);
    451     }
    452
    453     public static Object box(char value) {
    454         return new Character(value);
    455     }
    456
    457     public static Object box(short value) {
    458         return new Short(value);
    459     }
    460
    461     public static Object box(int value) {
    462         return integerValue(value);
    463     }
    464
    465     public static Object box(long value) {
    466         return new Long(value);
    467     }
    468
    469     public static Object box(float value) {
    470         return new Float(value);
    471     }
    472
    473     public static Object box(double value) {
    474         return new Double(value);
    475     }
    476
    477     public static byte byteUnbox(Object value) {
    478         Number n = (Number) asType(value, Byte.class);
    479         return n.byteValue();
    480     }
    481
    482     public static char charUnbox(Object value) {
    483         Character n = (Character) asType(value, Character.class);
    484         return n.charValue();
    485     }
    486
    487     public static short shortUnbox(Object value) {
    488         Number n = (Number) asType(value, Short.class);
    489         return n.shortValue();
    490     }
    491
    492     public static int intUnbox(Object value) {
    493         Number n = (Number) asType(value, Integer.class);
    494         return n.intValue();
    495     }
    496
    497     public static boolean booleanUnbox(Object value) {
    498         Boolean n = (Boolean) asType(value, Boolean.class);
    499         return n.booleanValue();
    500     }
    501
    502     public static long longUnbox(Object value) {
    503         Number n = (Number) asType(value, Long.class);
    504         return n.longValue();
    505     }
    506
    507     public static float floatUnbox(Object value) {
    508         Number n = (Number) asType(value, Float.class);
    509         return n.floatValue();
    510     }
    511
    512     public static double doubleUnbox(Object value) {
    513         Number n = (Number) asType(value, Double.class);
    514         return n.doubleValue();
    515     }
    516
    517     /***
    518      * @param a    array of primitives
    519      * @param type component type of the array
    520      * @return
    521      */
    522     public static Object[] convertPrimitiveArray(Object a, Class type) {
    523 //        System.out.println("a.getClass() = " + a.getClass());
    524         Object[] ans = null;
    525         String elemType = type.getName();
    526         if (elemType.equals("int")) {
    527             // conservative coding
    528             if (a.getClass().getName().equals("[Ljava.lang.Integer;")) {
    529                 ans = (Integer[]) a;
    530             } else {
    531                 int[] ia = (int[]) a;
    532                 ans = new Integer[ia.length];
    533                 for (int i = 0; i < ia.length; i++) {
    534                     int e = ia[i];
    535                     ans[i] = integerValue(e);
    536                 }
    537             }
    538         } else if (elemType.equals("char")) {
    539             if (a.getClass().getName().equals("[Ljava.lang.Character;")) {
    540                 ans = (Character[]) a;
    541             } else {
    542                 char[] ia = (char[]) a;
    543                 ans = new Character[ia.length];
    544                 for (int i = 0; i < ia.length; i++) {
    545                     char e = ia[i];
    546                     ans[i] = new Character(e);
    547                 }
    548             }
    549         } else if (elemType.equals("boolean")) {
    550             if (a.getClass().getName().equals("[Ljava.lang.Boolean;")) {
    551                 ans = (Boolean[]) a;
    552             } else {
    553                 boolean[] ia = (boolean[]) a;
    554                 ans = new Boolean[ia.length];
    555                 for (int i = 0; i < ia.length; i++) {
    556                     boolean e = ia[i];
    557                     ans[i] = new Boolean(e);
    558                 }
    559             }
    560         } else if (elemType.equals("byte")) {
    561             if (a.getClass().getName().equals("[Ljava.lang.Byte;")) {
    562                 ans = (Byte[]) a;
    563             } else {
    564                 byte[] ia = (byte[]) a;
    565                 ans = new Byte[ia.length];
    566                 for (int i = 0; i < ia.length; i++) {
    567                     byte e = ia[i];
    568                     ans[i] = new Byte(e);
    569                 }
    570             }
    571         } else if (elemType.equals("short")) {
    572             if (a.getClass().getName().equals("[Ljava.lang.Short;")) {
    573                 ans = (Short[]) a;
    574             } else {
    575                 short[] ia = (short[]) a;
    576                 ans = new Short[ia.length];
    577                 for (int i = 0; i < ia.length; i++) {
    578                     short e = ia[i];
    579                     ans[i] = new Short(e);
    580                 }
    581             }
    582         } else if (elemType.equals("float")) {
    583             if (a.getClass().getName().equals("[Ljava.lang.Float;")) {
    584                 ans = (Float[]) a;
    585             } else {
    586                 float[] ia = (float[]) a;
    587                 ans = new Float[ia.length];
    588                 for (int i = 0; i < ia.length; i++) {
    589                     float e = ia[i];
    590                     ans[i] = new Float(e);
    591                 }
    592             }
    593         } else if (elemType.equals("long")) {
    594             if (a.getClass().getName().equals("[Ljava.lang.Long;")) {
    595                 ans = (Long[]) a;
    596             } else {
    597                 long[] ia = (long[]) a;
    598                 ans = new Long[ia.length];
    599                 for (int i = 0; i < ia.length; i++) {
    600                     long e = ia[i];
    601                     ans[i] = new Long(e);
    602                 }
    603             }
    604         } else if (elemType.equals("double")) {
    605             if (a.getClass().getName().equals("[Ljava.lang.Double;")) {
    606                 ans = (Double[]) a;
    607             } else {
    608                 double[] ia = (double[]) a;
    609                 ans = new Double[ia.length];
    610                 for (int i = 0; i < ia.length; i++) {
    611                     double e = ia[i];
    612                     ans[i] = new Double(e);
    613                 }
    614             }
    615         }
    616         return ans;
    617     }
    618
    619     public static int[] convertToIntArray(Object a) {
    620         int[] ans = null;
    621
    622         // conservative coding
    623         if (a.getClass().getName().equals("[I")) {
    624             ans = (int[]) a;
    625         } else {
    626             Object[] ia = (Object[]) a;
    627             ans = new int[ia.length];
    628             for (int i = 0; i < ia.length; i++) {
    629                 ans[i] = ((Number) ia[i]).intValue();
    630             }
    631         }
    632         return ans;
    633     }
    634
    635     public static boolean[] convertToBooleanArray(Object a) {
    636         boolean[] ans = null;
    637
    638         // conservative coding
    639         if (a.getClass().getName().equals("[Z")) {
    640             ans = (boolean[]) a;
    641         } else {
    642             Object[] ia = (Object[]) a;
    643             ans = new boolean[ia.length];
    644             for (int i = 0; i < ia.length; i++) {
    645                 ans[i] = ((Boolean) ia[i]).booleanValue();
    646             }
    647         }
    648         return ans;
    649     }
    650
    651     public static byte[] convertToByteArray(Object a) {
    652         byte[] ans = null;
    653
    654         // conservative coding
    655         if (a.getClass().getName().equals("[B")) {
    656             ans = (byte[]) a;
    657         } else {
    658             Object[] ia = (Object[]) a;
    659             ans = new byte[ia.length];
    660             for (int i = 0; i < ia.length; i++) {
    661                 ans[i] = ((Number) ia[i]).byteValue();
    662             }
    663         }
    664         return ans;
    665     }
    666
    667     public static short[] convertToShortArray(Object a) {
    668         short[] ans = null;
    669
    670         // conservative coding
    671         if (a.getClass().getName().equals("[S")) {
    672             ans = (short[]) a;
    673         } else {
    674             Object[] ia = (Object[]) a;
    675             ans = new short[ia.length];
    676             for (int i = 0; i < ia.length; i++) {
    677                 ans[i] = ((Number) ia[i]).shortValue();
    678             }
    679         }
    680         return ans;
    681     }
    682
    683     public static char[] convertToCharArray(Object a) {
    684         char[] ans = null;
    685
    686         // conservative coding
    687         if (a.getClass().getName().equals("[C")) {
    688             ans = (char[]) a;
    689         } else {
    690             Object[] ia = (Object[]) a;
    691             ans = new char[ia.length];
    692             for (int i = 0; i < ia.length; i++) {
    693                 ans[i] = ((Character) ia[i]).charValue();
    694             }
    695         }
    696         return ans;
    697     }
    698
    699     public static long[] convertToLongArray(Object a) {
    700         long[] ans = null;
    701
    702         // conservative coding
    703         if (a.getClass().getName().equals("[J")) {
    704             ans = (long[]) a;
    705         } else {
    706             Object[] ia = (Object[]) a;
    707             ans = new long[ia.length];
    708             for (int i = 0; i < ia.length; i++) {
    709                 ans[i] = ((Number) ia[i]).longValue();
    710             }
    711         }
    712         return ans;
    713     }
    714
    715     public static float[] convertToFloatArray(Object a) {
    716         float[] ans = null;
    717
    718         // conservative coding
    719         if (a.getClass().getName().equals("[F")) {
    720             ans = (float[]) a;
    721         } else {
    722             Object[] ia = (Object[]) a;
    723             ans = new float[ia.length];
    724             for (int i = 0; i < ia.length; i++) {
    725                 ans[i] = ((Number) ia[i]).floatValue();
    726             }
    727         }
    728         return ans;
    729     }
    730
    731     public static double[] convertToDoubleArray(Object a) {
    732         double[] ans = null;
    733
    734         // conservative coding
    735         if (a.getClass().getName().equals("[D")) {
    736             ans = (double[]) a;
    737         } else {
    738             Object[] ia = (Object[]) a;
    739             ans = new double[ia.length];
    740             for (int i = 0; i < ia.length; i++) {
    741                 ans[i] = ((Number) ia[i]).doubleValue();
    742             }
    743         }
    744         return ans;
    745     }
    746
    747     public static Object convertToPrimitiveArray(Object a, Class type) {
    748         if (type == Byte.TYPE)
    749             return convertToByteArray(a);
    750         if (type == Boolean.TYPE)
    751             return convertToBooleanArray(a);
    752         if (type == Short.TYPE)
    753             return convertToShortArray(a);
    754         if (type == Character.TYPE)
    755             return convertToCharArray(a);
    756         if (type == Integer.TYPE)
    757             return convertToIntArray(a);
    758         if (type == Long.TYPE)
    759             return convertToLongArray(a);
    760         if (type == Float.TYPE)
    761             return convertToFloatArray(a);
    762         if (type == Double.TYPE)
    763             return convertToDoubleArray(a);
    764         else
    765             return a;
    766     }
    767
    768     /***
    769      * get the Integer object from an int. Cached version is used for small ints.
    770      *
    771      * @param v
    772      * @return
    773      */
    774     public static Integer integerValue(int v) {
    775         int index = v + INT_CACHE_OFFSET;
    776         if (index >= 0 && index < INT_CACHE_LEN) {
    777             return SMALL_INTEGERS[index];
    778         } else {
    779             return new Integer(v);
    780         }
    781     }
    782
    783     private static Integer[] SMALL_INTEGERS;
    784     private static int INT_CACHE_OFFSET = 128, INT_CACHE_LEN = 256;
    785
    786     static {
    787         SMALL_INTEGERS = new Integer[INT_CACHE_LEN];
    788         for (int i = 0; i < SMALL_INTEGERS.length; i++) {
    789             SMALL_INTEGERS[i] = new Integer(i - INT_CACHE_OFFSET);
    790         }
    791     }
    792 }