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.Closure;
49 import groovy.lang.GroovyObject;
50 import groovy.lang.GroovyRuntimeException;
51 import groovy.lang.MetaClass;
52 import groovy.lang.MetaClassRegistry;
53 import groovy.lang.MissingMethodException;
54 import groovy.lang.Range;
55 import groovy.lang.Tuple;
56 import org.apache.xml.serialize.OutputFormat;
57 import org.apache.xml.serialize.XMLSerializer;
58 import org.w3c.dom.Element;
59 import org.w3c.dom.Node;
60 import org.w3c.dom.NodeList;
61
62 import java.io.File;
63 import java.io.IOException;
64 import java.io.StringWriter;
65 import java.lang.reflect.Array;
66 import java.lang.reflect.Method;
67 import java.security.AccessController;
68 import java.security.PrivilegedAction;
69 import java.util.ArrayList;
70 import java.util.Arrays;
71 import java.util.Collection;
72 import java.util.Collections;
73 import java.util.Enumeration;
74 import java.util.Iterator;
75 import java.util.List;
76 import java.util.Map;
77 import java.util.NoSuchElementException;
78 import java.util.regex.Matcher;
79 import java.util.regex.Pattern;
80 import java.math.BigDecimal;
81
82 /***
83 * A helper class to invoke methods or extract properties on arbitrary Java objects dynamically
84 *
85 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
86 * @version $Revision: 1.67 $
87 */
88 public class Invoker {
89
90 protected static final Object[] EMPTY_ARGUMENTS = {
91 };
92 protected static final Class[] EMPTY_TYPES = {
93 };
94
95 public MetaClassRegistry getMetaRegistry() {
96 return metaRegistry;
97 }
98
99 private MetaClassRegistry metaRegistry = new MetaClassRegistry();
100
101 public MetaClass getMetaClass(Object object) {
102 return metaRegistry.getMetaClass(object.getClass());
103 }
104
105 /***
106 * Invokes the given method on the object.
107 *
108 * @param object
109 * @param methodName
110 * @param arguments
111 * @return
112 */
113 public Object invokeMethod(Object object, String methodName, Object arguments) {
114
115
116
117
118
119
120
121
122
123
124
125
126 if (object == null) {
127 throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
128 }
129
130
131 if (object instanceof Class) {
132 Class theClass = (Class) object;
133 MetaClass metaClass = metaRegistry.getMetaClass(theClass);
134 return metaClass.invokeStaticMethod(object, methodName, asArray(arguments));
135 }
136 else
137 {
138
139 if (!(object instanceof GroovyObject)) {
140 Class theClass = object.getClass();
141 MetaClass metaClass = metaRegistry.getMetaClass(theClass);
142 return metaClass.invokeMethod(object, methodName, asArray(arguments));
143 }
144
145 else {
146
147 if (object instanceof Closure) {
148 Closure closure = (Closure) object;
149 return closure.invokeMethod(methodName, arguments);
150 }
151
152
153 else {
154 GroovyObject groovy = (GroovyObject) object;
155 try {
156
157 return groovy.getMetaClass().invokeMethod(object, methodName, arguments);
158 }
159 catch (MissingMethodException e) {
160 if (e.getMethod().equals(methodName) && object.getClass() == e.getType()) {
161
162 return groovy.invokeMethod(methodName, arguments);
163 }
164 else {
165 throw e;
166 }
167 }
168 }
169 }
170 }
171 }
172
173 public Object invokeSuperMethod(Object object, String methodName, Object arguments) {
174 if (object == null) {
175 throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
176 }
177
178 Class theClass = object.getClass();
179
180 MetaClass metaClass = metaRegistry.getMetaClass(theClass.getSuperclass());
181 return metaClass.invokeMethod(object, methodName, asArray(arguments));
182 }
183
184 public Object invokeStaticMethod(String type, String method, Object arguments) {
185 MetaClass metaClass = metaRegistry.getMetaClass(loadClass(type));
186 List argumentList = asList(arguments);
187 return metaClass.invokeStaticMethod(null, method, asArray(arguments));
188 }
189
190 public Object invokeConstructor(String type, Object arguments) {
191
192 return invokeConstructorOf(loadClass(type), arguments);
193 }
194
195 public Object invokeConstructorOf(Class type, Object arguments) {
196 MetaClass metaClass = metaRegistry.getMetaClass(type);
197 return metaClass.invokeConstructor(asArray(arguments));
198 }
199
200 /***
201 * Converts the given object into an array; if its an array then just
202 * cast otherwise wrap it in an array
203 */
204 public Object[] asArray(Object arguments) {
205 if (arguments == null) {
206 return EMPTY_ARGUMENTS;
207 }
208 if (arguments instanceof Tuple) {
209 Tuple tuple = (Tuple) arguments;
210 return tuple.toArray();
211 }
212 if (arguments instanceof Object[]) {
213 return (Object[]) arguments;
214 }
215 else {
216 return new Object[]{arguments};
217 }
218 }
219
220 public List asList(Object value) {
221 if (value == null) {
222 return Collections.EMPTY_LIST;
223 }
224 else if (value instanceof List) {
225 return (List) value;
226 }
227 else if (value.getClass().isArray()) {
228 return Arrays.asList((Object[]) value);
229 }
230 else if (value instanceof Enumeration) {
231 List answer = new ArrayList();
232 for (Enumeration e = (Enumeration) value; e.hasMoreElements();) {
233 answer.add(e.nextElement());
234 }
235 return answer;
236 }
237 else {
238
239 return Collections.singletonList(value);
240 }
241 }
242
243 /***
244 * @param arguments
245 * @return
246 */
247 public Collection asCollection(Object value) {
248 if (value == null) {
249 return Collections.EMPTY_LIST;
250 }
251 else if (value instanceof Collection) {
252 return (Collection) value;
253 }
254 else if (value instanceof Map) {
255 Map map = (Map) value;
256 return map.entrySet();
257 }
258 else if (value.getClass().isArray()) {
259 if (value.getClass().getComponentType().isPrimitive()) {
260 return InvokerHelper.primitiveArrayToList(value);
261 }
262 return Arrays.asList((Object[]) value);
263 }
264 else if (value instanceof MethodClosure) {
265 MethodClosure method = (MethodClosure) value;
266 IteratorClosureAdapter adapter = new IteratorClosureAdapter(method.getDelegate());
267 method.call(adapter);
268 return adapter.asList();
269 }
270 else if (value instanceof String) {
271 return DefaultGroovyMethods.toList((String) value);
272 }
273 else if (value instanceof File) {
274 try {
275 return DefaultGroovyMethods.readLines((File) value);
276 }
277 catch (IOException e) {
278 throw new GroovyRuntimeException("Error reading file: " + value, e);
279 }
280 }
281 else {
282
283 return Collections.singletonList(value);
284 }
285 }
286
287 public Iterator asIterator(Object value) {
288 if (value == null) {
289 return Collections.EMPTY_LIST.iterator();
290 }
291 if (value instanceof Iterator) {
292 return (Iterator) value;
293 }
294 if (value instanceof NodeList) {
295 final NodeList nodeList = (NodeList) value;
296 return new Iterator() {
297 private int current = 0;
298
299 public boolean hasNext() {
300 return current < nodeList.getLength();
301 }
302
303 public Object next() {
304 Node node = nodeList.item(current++);
305 return node;
306 }
307
308 public void remove() {
309 throw new UnsupportedOperationException("Cannot remove() from an Enumeration");
310 }
311 };
312 }
313 else if (value instanceof Enumeration) {
314 final Enumeration enumeration = (Enumeration) value;
315 return new Iterator() {
316 private Object last;
317
318 public boolean hasNext() {
319 return enumeration.hasMoreElements();
320 }
321
322 public Object next() {
323 last = enumeration.nextElement();
324 return last;
325 }
326
327 public void remove() {
328 throw new UnsupportedOperationException("Cannot remove() from an Enumeration");
329 }
330 };
331 }
332 else if (value instanceof Matcher) {
333 final Matcher matcher = (Matcher) value;
334 return new Iterator() {
335 private boolean found = false;
336 private boolean done = false;
337
338 public boolean hasNext() {
339 if (done) {
340 return false;
341 }
342 if (!found) {
343 found = matcher.find();
344 if (!found) {
345 done = true;
346 }
347 }
348 return found;
349 }
350
351 public Object next() {
352 if (!found) {
353 if (!hasNext()) {
354 throw new NoSuchElementException();
355 }
356 }
357 found = false;
358 return matcher.group();
359 }
360
361 public void remove() {
362 throw new UnsupportedOperationException();
363 }
364 };
365 }
366 else {
367 try {
368
369 final Method method = value.getClass().getMethod("iterator", EMPTY_TYPES);
370
371 if (method != null) {
372 AccessController.doPrivileged(new PrivilegedAction() {
373 public Object run() {
374 method.setAccessible(true);
375 return null;
376 }
377 });
378
379 return (Iterator) method.invoke(value, EMPTY_ARGUMENTS);
380 }
381 }
382 catch (Exception e) {
383
384 }
385 }
386 return asCollection(value).iterator();
387 }
388
389 /***
390 * @return true if the two objects are null or the objects are equal
391 */
392 public boolean objectsEqual(Object left, Object right) {
393 if (left == right) {
394 return true;
395 }
396 if (left != null) {
397 if (right == null) {
398 return false;
399 }
400 if (left instanceof Comparable) {
401 return compareTo(left, right) == 0;
402 }
403 else {
404 return left.equals(right);
405 }
406 }
407 return false;
408 }
409
410 public String inspect(Object self) {
411 return format(self, true);
412 }
413
414 /***
415 * Compares the two objects handling nulls gracefully and performing numeric type coercion if required
416 */
417 public int compareTo(Object left, Object right) {
418
419 if (left == right) {
420 return 0;
421 }
422 if (left == null) {
423 return -1;
424 }
425 else if (right == null) {
426 return 1;
427 }
428 if (left instanceof Comparable) {
429 if (left instanceof Number) {
430 if (isValidCharacterString(right)) {
431 return asCharacter((Number) left).compareTo(asCharacter((String) right));
432 }
433 return DefaultGroovyMethods.compareTo((Number) left, asNumber(right));
434 }
435 else if (left instanceof Character) {
436 if (isValidCharacterString(right)) {
437 return ((Character) left).compareTo(asCharacter((String) right));
438 }
439 else if (right instanceof Number) {
440 return ((Character) left).compareTo(asCharacter((Number) right));
441 }
442 }
443 else if (right instanceof Number) {
444 if (isValidCharacterString(left)) {
445 return asCharacter((String) left).compareTo(asCharacter((Number) right));
446 }
447 return DefaultGroovyMethods.compareTo(asNumber(left), (Number) right);
448 }
449 else if (left instanceof String && right instanceof Character) {
450 return ((String) left).compareTo(right.toString());
451 }
452 Comparable comparable = (Comparable) left;
453 return comparable.compareTo(right);
454 }
455 if (left.getClass().isArray()) {
456 Collection leftList = asCollection(left);
457 if (right.getClass().isArray()) {
458 right = asCollection(right);
459 }
460 return ((Comparable) leftList).compareTo(right);
461 }
462 /*** todo we might wanna do some type conversion here */
463 throw new GroovyRuntimeException("Cannot compare values: " + left + " and " + right);
464 }
465
466 /***
467 * A helper method to provide some better toString() behaviour such as turning arrays
468 * into tuples
469 */
470 public String toString(Object arguments) {
471 return format(arguments, false);
472 }
473
474 /***
475 * A helper method to format the arguments types as a comma-separated list
476 */
477 public String toTypeString(Object[] arguments) {
478 if (arguments == null) {
479 return "null";
480 }
481 StringBuffer argBuf = new StringBuffer();
482 for (int i = 0; i < arguments.length; i++) {
483 if (i > 0) {
484 argBuf.append(", ");
485 }
486 argBuf.append(arguments[i] != null ? arguments[i].getClass().getName() : "null");
487 }
488 return argBuf.toString();
489 }
490
491 protected String format(Object arguments, boolean verbose) {
492 if (arguments == null) {
493 return "null";
494 }
495 else if (arguments.getClass().isArray()) {
496 return format(asCollection(arguments), verbose);
497 }
498 else if (arguments instanceof Range) {
499 Range range = (Range) arguments;
500 if (verbose) {
501 return range.inspect();
502 }
503 else {
504 return range.toString();
505 }
506 }
507 else if (arguments instanceof List) {
508 List list = (List) arguments;
509 StringBuffer buffer = new StringBuffer("[");
510 boolean first = true;
511 for (Iterator iter = list.iterator(); iter.hasNext();) {
512 if (first) {
513 first = false;
514 }
515 else {
516 buffer.append(", ");
517 }
518 buffer.append(format(iter.next(), verbose));
519 }
520 buffer.append("]");
521 return buffer.toString();
522 }
523 else if (arguments instanceof Map) {
524 Map map = (Map) arguments;
525 if (map.isEmpty()) {
526 return "[:]";
527 }
528 StringBuffer buffer = new StringBuffer("[");
529 boolean first = true;
530 for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
531 if (first) {
532 first = false;
533 }
534 else {
535 buffer.append(", ");
536 }
537 Map.Entry entry = (Map.Entry) iter.next();
538 buffer.append(format(entry.getKey(), verbose));
539 buffer.append(":");
540 buffer.append(format(entry.getValue(), verbose));
541 }
542 buffer.append("]");
543 return buffer.toString();
544 }
545 else if (arguments instanceof Element) {
546 Element node = (Element) arguments;
547 OutputFormat format = new OutputFormat(node.getOwnerDocument());
548 format.setOmitXMLDeclaration(true);
549 format.setIndenting(true);
550 format.setLineWidth(0);
551 format.setPreserveSpace(true);
552 StringWriter sw = new StringWriter();
553 XMLSerializer serializer = new XMLSerializer(sw, format);
554 try {
555 serializer.asDOMSerializer();
556 serializer.serialize(node);
557 }
558 catch (IOException e) {
559 }
560 return sw.toString();
561 }
562 else if (arguments instanceof String) {
563 if (verbose) {
564 return "\"" + arguments + "\"";
565 }
566 else {
567 return (String) arguments;
568 }
569 }
570 else {
571 return arguments.toString();
572 }
573 }
574
575 /***
576 * Looks up the given property of the given object
577 */
578 public Object getProperty(Object object, String property) {
579 if (object == null) {
580 throw new NullPointerException("Cannot get property: " + property + " on null object");
581 }
582 else if (object instanceof GroovyObject) {
583 GroovyObject pogo = (GroovyObject) object;
584 return pogo.getProperty(property);
585 }
586 else if (object instanceof Map) {
587 Map map = (Map) object;
588 return map.get(property);
589 }
590 else {
591 return metaRegistry.getMetaClass(object.getClass()).getProperty(object, property);
592 }
593 }
594
595 /***
596 * Sets the property on the given object
597 */
598 public void setProperty(Object object, String property, Object newValue) {
599 if (object == null) {
600 throw new GroovyRuntimeException("Cannot set property on null object");
601 }
602 else if (object instanceof GroovyObject) {
603 GroovyObject pogo = (GroovyObject) object;
604 pogo.setProperty(property, newValue);
605 }
606 else if (object instanceof Map) {
607 Map map = (Map) object;
608 map.put(property, newValue);
609 }
610 else {
611 metaRegistry.getMetaClass(object.getClass()).setProperty(object, property, newValue);
612 }
613 }
614
615 /***
616 * Looks up the given attribute (field) on the given object
617 */
618 public Object getAttribute(Object object, String attribute) {
619 if (object == null) {
620 throw new NullPointerException("Cannot get attribute: " + attribute + " on null object");
621
622 /***
623 } else if (object instanceof GroovyObject) {
624 GroovyObject pogo = (GroovyObject) object;
625 return pogo.getAttribute(attribute);
626 } else if (object instanceof Map) {
627 Map map = (Map) object;
628 return map.get(attribute);
629 */
630 }
631 else {
632 return metaRegistry.getMetaClass(object.getClass()).getAttribute(object, attribute);
633 }
634 }
635
636 /***
637 * Sets the given attribute (field) on the given object
638 */
639 public void setAttribute(Object object, String attribute, Object newValue) {
640 if (object == null) {
641 throw new GroovyRuntimeException("Cannot set attribute on null object");
642
643
644
645
646
647
648
649
650 }
651 else {
652 metaRegistry.getMetaClass(object.getClass()).setAttribute(object, attribute, newValue);
653 }
654 }
655
656 /***
657 * Attempts to load the given class via name using the current class loader
658 * for this code or the thread context class loader
659 */
660 protected Class loadClass(String type) {
661 try {
662 return getClass().getClassLoader().loadClass(type);
663 }
664 catch (ClassNotFoundException e) {
665 try {
666 return Thread.currentThread().getContextClassLoader().loadClass(type);
667 }
668 catch (ClassNotFoundException e2) {
669 try {
670 return Class.forName(type);
671 }
672 catch (ClassNotFoundException e3) {
673 }
674 }
675 throw new GroovyRuntimeException("Could not load type: " + type, e);
676 }
677 }
678
679 /***
680 * Find the right hand regex within the left hand string and return a matcher.
681 *
682 * @param left string to compare
683 * @param right regular expression to compare the string to
684 * @return
685 */
686 public Matcher objectFindRegex(Object left, Object right) {
687 String stringToCompare;
688 if (left instanceof String) {
689 stringToCompare = (String) left;
690 }
691 else {
692 stringToCompare = toString(left);
693 }
694 String regexToCompareTo;
695 if (right instanceof String) {
696 regexToCompareTo = (String) right;
697 }
698 else if (right instanceof Pattern) {
699 Pattern pattern = (Pattern) right;
700 return pattern.matcher(stringToCompare);
701 }
702 else {
703 regexToCompareTo = toString(right);
704 }
705 Matcher matcher = Pattern.compile(regexToCompareTo).matcher(stringToCompare);
706 return matcher;
707 }
708
709 /***
710 * Find the right hand regex within the left hand string and return a matcher.
711 *
712 * @param left string to compare
713 * @param right regular expression to compare the string to
714 * @return
715 */
716 public boolean objectMatchRegex(Object left, Object right) {
717 Pattern pattern;
718 if (right instanceof Pattern) {
719 pattern = (Pattern) right;
720 }
721 else {
722 pattern = Pattern.compile(toString(right));
723 }
724 String stringToCompare = toString(left);
725 Matcher matcher = pattern.matcher(stringToCompare);
726 RegexSupport.setLastMatcher(matcher);
727 return matcher.matches();
728 }
729
730 /***
731 * Compile a regular expression from a string.
732 *
733 * @param regex
734 * @return
735 */
736 public Pattern regexPattern(Object regex) {
737 return Pattern.compile(regex.toString());
738 }
739
740 public Object asType(Object object, Class type) {
741 if (object == null) {
742 return null;
743 }
744
745
746 if (type.isArray()) {
747 return asArray(object, type);
748
749 }
750 if (type.isInstance(object)) {
751 return object;
752 }
753 if (type.isAssignableFrom(Collection.class)) {
754 if (object.getClass().isArray()) {
755
756
757 Collection answer = null;
758 try {
759 answer = (Collection) type.newInstance();
760 }
761 catch (Exception e) {
762 throw new ClassCastException("Could not instantiate instance of: " + type.getName() + ". Reason: " + e);
763 }
764
765
766 int length = Array.getLength(object);
767 for (int i = 0; i < length; i++) {
768 Object element = Array.get(object, i);
769 answer.add(element);
770 }
771 return answer;
772 }
773 }
774 if (type.equals(String.class)) {
775 return object.toString();
776 }
777 if (type.equals(Character.class)) {
778 if (object instanceof Number) {
779 return asCharacter((Number) object);
780 }
781 else {
782 String text = object.toString();
783 if (text.length() == 1) {
784 return new Character(text.charAt(0));
785 }
786 else {
787 throw new ClassCastException("Cannot cast: " + text + " to a Character");
788 }
789 }
790 }
791 if (Number.class.isAssignableFrom(type)) {
792 if (object instanceof Character) {
793 return new Integer(((Character) object).charValue());
794 }
795 else if (object instanceof String) {
796 String c = (String) object;
797 if (c.length() == 1) {
798 return new Integer(c.charAt(0));
799 }
800 else {
801 throw new ClassCastException("Cannot cast: '" + c + "' to an Integer");
802 }
803 }
804 }
805 if (object instanceof Number) {
806 Number n = (Number) object;
807 if (type.isPrimitive()) {
808 if (type == byte.class) {
809 return new Byte(n.byteValue());
810 }
811 if (type == char.class) {
812 return new Character((char) n.intValue());
813 }
814 if (type == short.class) {
815 return new Short(n.shortValue());
816 }
817 if (type == int.class) {
818 return new Integer(n.intValue());
819 }
820 if (type == long.class) {
821 return new Long(n.longValue());
822 }
823 if (type == float.class) {
824 return new Float(n.floatValue());
825 }
826 if (type == double.class) {
827 Double answer = new Double(n.doubleValue());
828
829 if (!(n instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
830 || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
831 throw new GroovyRuntimeException("Automatic coercion of " + n.getClass().getName()
832 + " value " + n + " to double failed. Value is out of range.");
833 }
834 return answer;
835 }
836 }
837 else {
838 if (Number.class.isAssignableFrom(type)) {
839 if (type == Byte.class) {
840 return new Byte(n.byteValue());
841 }
842 if (type == Character.class) {
843 return new Character((char) n.intValue());
844 }
845 if (type == Short.class) {
846 return new Short(n.shortValue());
847 }
848 if (type == Integer.class) {
849 return new Integer(n.intValue());
850 }
851 if (type == Long.class) {
852 return new Long(n.longValue());
853 }
854 if (type == Float.class) {
855 return new Float(n.floatValue());
856 }
857 if (type == Double.class) {
858 Double answer = new Double(n.doubleValue());
859
860 if (!(n instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
861 || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
862 throw new GroovyRuntimeException("Automatic coercion of " + n.getClass().getName()
863 + " value " + n + " to double failed. Value is out of range.");
864 }
865 return answer;
866 }
867
868 }
869 }
870 }
871 if (type == Boolean.class) {
872 return asBool(object) ? Boolean.TRUE : Boolean.FALSE;
873 }
874 return object;
875 }
876
877 public Object asArray(Object object, Class type) {
878 Collection list = asCollection(object);
879 int size = list.size();
880 Class elementType = type.getComponentType();
881 Object array = Array.newInstance(elementType, size);
882 int idx = 0;
883
884 if (boolean.class.equals(elementType)) {
885 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
886 Object element = iter.next();
887 Array.setBoolean(array, idx, asBool(element));
888 }
889 }
890 else if (byte.class.equals(elementType)) {
891 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
892 Object element = iter.next();
893 Array.setByte(array, idx, asByte(element));
894 }
895 }
896 else if (char.class.equals(elementType)) {
897 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
898 Object element = iter.next();
899 Array.setChar(array, idx, asChar(element));
900 }
901 }
902 else if (double.class.equals(elementType)) {
903 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
904 Object element = iter.next();
905 Array.setDouble(array, idx, asDouble(element));
906 }
907 }
908 else if (float.class.equals(elementType)) {
909 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
910 Object element = iter.next();
911 Array.setFloat(array, idx, asFloat(element));
912 }
913 }
914 else if (int.class.equals(elementType)) {
915 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
916 Object element = iter.next();
917 Array.setInt(array, idx, asInt(element));
918 }
919 }
920 else if (long.class.equals(elementType)) {
921 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
922 Object element = iter.next();
923 Array.setLong(array, idx, asLong(element));
924 }
925 }
926 else if (short.class.equals(elementType)) {
927 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
928 Object element = iter.next();
929 Array.setShort(array, idx, asShort(element));
930 }
931 }
932 else {
933 for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
934 Object element = iter.next();
935 Object coercedElement = asType(element, elementType);
936 Array.set(array, idx, coercedElement);
937 }
938 }
939 return array;
940 }
941
942 public Number asNumber(Object value) {
943 if (value instanceof Number) {
944 return (Number) value;
945 }
946 else if (value instanceof String) {
947 String s = (String) value;
948
949 if (s.length() == 1) {
950 return new Integer(s.charAt(0));
951 }
952 else {
953 return new BigDecimal(s);
954 }
955 }
956 else if (value instanceof Character) {
957 return new Integer(((Character) value).charValue());
958 }
959 else {
960 throw new GroovyRuntimeException("Could not convert object: " + value + " into a Number");
961 }
962 }
963
964 public byte asByte(Object element) {
965 return asNumber(element).byteValue();
966 }
967
968 public char asChar(Object element) {
969 if (element instanceof String) {
970 return asCharacter((String) element).charValue();
971 }
972 return asCharacter(asNumber(element)).charValue();
973 }
974
975 public float asFloat(Object element) {
976 return asNumber(element).floatValue();
977 }
978
979 public double asDouble(Object element) {
980 return asNumber(element).doubleValue();
981 }
982
983 public short asShort(Object element) {
984 return asNumber(element).shortValue();
985 }
986
987 public int asInt(Object element) {
988 return asNumber(element).intValue();
989 }
990
991 public long asLong(Object element) {
992 return asNumber(element).longValue();
993 }
994
995 public boolean asBool(Object object) {
996 if (object instanceof Boolean) {
997 Boolean booleanValue = (Boolean) object;
998 return booleanValue.booleanValue();
999 }
1000 else if (object instanceof Matcher) {
1001 Matcher matcher = (Matcher) object;
1002 RegexSupport.setLastMatcher(matcher);
1003 return matcher.find();
1004 }
1005 else if (object instanceof Collection) {
1006 Collection collection = (Collection) object;
1007 return !collection.isEmpty();
1008 }
1009 else if (object instanceof Number) {
1010 Number n = (Number) object;
1011 return n.doubleValue() != 0;
1012 }
1013 else {
1014 return object != null;
1015 }
1016 }
1017
1018 protected Character asCharacter(Number value) {
1019 return new Character((char) value.intValue());
1020 }
1021
1022 protected Character asCharacter(String text) {
1023 return new Character(text.charAt(0));
1024 }
1025
1026 /***
1027 * @return true if the given value is a valid character string (i.e. has length of 1)
1028 */
1029 protected boolean isValidCharacterString(Object value) {
1030 if (value instanceof String) {
1031 String s = (String) value;
1032 if (s.length() == 1) {
1033 return true;
1034 }
1035 }
1036 return false;
1037 }
1038
1039 public void removeMetaClass(Class clazz) {
1040 getMetaRegistry().removeMetaClass(clazz);
1041 }
1042 }