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