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