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