View Javadoc

    1   /*
    2    $Id: InvokerHelper.java,v 1.73 2005/10/03 18:07:36 tug 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.IOException;
    52  import java.io.InputStream;
    53  import java.io.InputStreamReader;
    54  import java.io.Reader;
    55  import java.io.Writer;
    56  import java.lang.reflect.Array;
    57  import java.math.BigDecimal;
    58  import java.math.BigInteger;
    59  import java.util.ArrayList;
    60  import java.util.Collection;
    61  import java.util.HashMap;
    62  import java.util.Iterator;
    63  import java.util.List;
    64  import java.util.Map;
    65  import java.util.regex.Matcher;
    66  import java.util.regex.Pattern;
    67
    68  /***
    69   * A static helper class to make bytecode generation easier and act as a facade over the Invoker
    70   *
    71   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    72   * @version $Revision: 1.73 $
    73   */
    74  public class InvokerHelper {
    75      public static final Object[] EMPTY_ARGS = {
    76      };
    77
    78      private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
    79
    80      private static final Invoker singleton = new Invoker();
    81
    82      private static final Integer ZERO = new Integer(0);
    83      private static final Integer MINUS_ONE = new Integer(-1);
    84      private static final Integer ONE = new Integer(1);
    85
    86      public static MetaClass getMetaClass(Object object) {
    87          return getInstance().getMetaClass(object);
    88      }
    89
    90      public static void removeClass(Class clazz) {
    91          getInstance().removeMetaClass(clazz);
    92          Introspector.flushFromCaches(clazz);
    93      }
    94
    95      public static Invoker getInstance() {
    96          return singleton;
    97      }
    98
    99      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 }