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