KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > groovy > runtime > Invoker


1 /*
2  $Id: Invoker.java,v 1.65 2004/12/27 21:38:38 spullara Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11     statements and notices. Redistributions must also contain a
12     copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15     above copyright notice, this list of conditions and the
16     following disclaimer in the documentation and/or other
17     materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20     products derived from this Software without prior written
21     permission of The Codehaus. For written permission,
22     please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25     nor may "groovy" appear in their names without prior written
26     permission of The Codehaus. "groovy" is a registered
27     trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30     http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46 package org.codehaus.groovy.runtime;
47
48 import groovy.lang.*;
49 import org.apache.xml.serialize.OutputFormat;
50 import org.apache.xml.serialize.XMLSerializer;
51 import org.w3c.dom.Element JavaDoc;
52 import org.w3c.dom.Node JavaDoc;
53 import org.w3c.dom.NodeList JavaDoc;
54
55 import java.io.File JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.io.StringWriter JavaDoc;
58 import java.lang.reflect.Method JavaDoc;
59 import java.security.AccessController JavaDoc;
60 import java.security.PrivilegedAction JavaDoc;
61 import java.util.*;
62 import java.util.regex.Matcher JavaDoc;
63 import java.util.regex.Pattern JavaDoc;
64
65 /**
66  * A helper class to invoke methods or extract properties on arbitrary Java objects dynamically
67  *
68  * @author <a HREF="mailto:james@coredevelopers.net">James Strachan</a>
69  * @version $Revision: 1.65 $
70  */

71 public class Invoker {
72
73     protected static final Object JavaDoc[] EMPTY_ARGUMENTS = {
74     };
75     protected static final Class JavaDoc[] EMPTY_TYPES = {
76     };
77
78     public MetaClassRegistry getMetaRegistry() {
79         return metaRegistry;
80     }
81
82     private MetaClassRegistry metaRegistry = new MetaClassRegistry();
83
84     public MetaClass getMetaClass(Object JavaDoc object) {
85         return metaRegistry.getMetaClass(object.getClass());
86     }
87
88     /**
89      * Invokes the given method on the object.
90      *
91      * @param object
92      * @param methodName
93      * @param arguments
94      * @return
95      */

96     public Object JavaDoc invokeMethod(Object JavaDoc object, String JavaDoc methodName, Object JavaDoc arguments) {
97         /*
98         System
99             .out
100             .println(
101                 "Invoker - Invoking method on object: "
102                     + object
103                     + " method: "
104                     + methodName
105                     + " arguments: "
106                     + InvokerHelper.toString(arguments));
107                     */

108
109         if (object == null) {
110             throw new NullPointerException JavaDoc("Cannot invoke method: " + methodName + " on null object");
111         }
112
113         // if the object is a Class, call a static method from that class
114
if (object instanceof Class JavaDoc) {
115             Class JavaDoc theClass = (Class JavaDoc) object;
116             MetaClass metaClass = metaRegistry.getMetaClass(theClass);
117             return metaClass.invokeStaticMethod(object, methodName, asArray(arguments));
118         }
119         else // it's an instance
120
{
121             // if it's not an object implementing GroovyObject (thus not builder, nor a closure)
122
if (!(object instanceof GroovyObject)) {
123                 Class JavaDoc theClass = object.getClass();
124                 MetaClass metaClass = metaRegistry.getMetaClass(theClass);
125                 return metaClass.invokeMethod(object, methodName, asArray(arguments));
126             }
127             // it's an object implementing GroovyObject
128
else
129             {
130                 // if it's a closure, use the closure's invokeMethod()
131
if (object instanceof Closure) {
132                     Closure closure = (Closure) object;
133                     return closure.invokeMethod(methodName, arguments);
134                 }
135                 // it's some kind of wacky object that overrides invokeMethod() to do some groovy stuff
136
// (like a proxy, a builder, some custom funny object which controls the invokation mechanism)
137
else
138                 {
139                     GroovyObject groovy = (GroovyObject) object;
140                     try
141                     {
142                         // if there's a statically typed method or a GDK method
143
return groovy.getMetaClass().invokeMethod(object, methodName, arguments);
144                     }
145                     catch (MissingMethodException e)
146                     {
147                         if (e.getMethod().equals(methodName) && object.getClass() == e.getType()) {
148                             // in case there's nothing else, invoke the object's own invokeMethod()
149
return groovy.invokeMethod(methodName, arguments);
150                         } else {
151                             throw e;
152                         }
153                     }
154                 }
155             }
156         }
157     }
158
159     public Object JavaDoc invokeSuperMethod(Object JavaDoc object, String JavaDoc methodName, Object JavaDoc arguments) {
160         if (object == null) {
161             throw new NullPointerException JavaDoc("Cannot invoke method: " + methodName + " on null object");
162         }
163
164         Class JavaDoc theClass = object.getClass();
165
166         MetaClass metaClass = metaRegistry.getMetaClass(theClass.getSuperclass());
167         return metaClass.invokeMethod(object, methodName, asArray(arguments));
168     }
169
170     public Object JavaDoc invokeStaticMethod(String JavaDoc type, String JavaDoc method, Object JavaDoc arguments) {
171         MetaClass metaClass = metaRegistry.getMetaClass(loadClass(type));
172         List JavaDoc argumentList = asList(arguments);
173         return metaClass.invokeStaticMethod(null, method, asArray(arguments));
174     }
175
176     public Object JavaDoc invokeConstructor(String JavaDoc type, Object JavaDoc arguments) {
177         //System.out.println("Invoking constructor of type: " + type);
178
return invokeConstructorOf(loadClass(type), arguments);
179     }
180
181     public Object JavaDoc invokeConstructorOf(Class JavaDoc type, Object JavaDoc arguments) {
182         MetaClass metaClass = metaRegistry.getMetaClass(type);
183         return metaClass.invokeConstructor(asArray(arguments));
184     }
185
186     /**
187      * Converts the given object into an array; if its an array then just
188      * cast otherwise wrap it in an array
189      */

190     public Object JavaDoc[] asArray(Object JavaDoc arguments) {
191         if (arguments == null) {
192             return EMPTY_ARGUMENTS;
193         }
194         if (arguments instanceof Tuple) {
195             Tuple tuple = (Tuple) arguments;
196             return tuple.toArray();
197         }
198         if (arguments instanceof Object JavaDoc[]) {
199             return (Object JavaDoc[]) arguments;
200         } else {
201             return new Object JavaDoc[]{arguments};
202         }
203     }
204
205     public List JavaDoc asList(Object JavaDoc value) {
206         if (value == null) {
207             return Collections.EMPTY_LIST;
208         } else if (value instanceof List JavaDoc) {
209             return (List JavaDoc) value;
210         } else if (value.getClass().isArray()) {
211             return Arrays.asList((Object JavaDoc[]) value);
212         } else if (value instanceof Enumeration) {
213             List JavaDoc answer = new ArrayList();
214             for (Enumeration e = (Enumeration) value; e.hasMoreElements();) {
215                 answer.add(e.nextElement());
216             }
217             return answer;
218         } else {
219             // lets assume its a collection of 1
220
return Collections.singletonList(value);
221         }
222     }
223
224     /**
225      * @param arguments
226      * @return
227      */

228     public Collection asCollection(Object JavaDoc value) {
229         if (value == null) {
230             return Collections.EMPTY_LIST;
231         } else if (value instanceof Collection) {
232             return (Collection) value;
233         } else if (value instanceof Map) {
234             Map map = (Map) value;
235             return map.entrySet();
236         } else if (value.getClass().isArray()) {
237             if (value.getClass().getComponentType().isPrimitive()) {
238                 return InvokerHelper.primitiveArrayToList(value);
239             }
240             return Arrays.asList((Object JavaDoc[]) value);
241         } else if (value instanceof MethodClosure) {
242             MethodClosure method = (MethodClosure) value;
243             IteratorClosureAdapter adapter = new IteratorClosureAdapter(method.getDelegate());
244             method.call(adapter);
245             return adapter.asList();
246         } else if (value instanceof String JavaDoc) {
247             return DefaultGroovyMethods.toList((String JavaDoc) value);
248         } else if (value instanceof File JavaDoc) {
249             try {
250                 return DefaultGroovyMethods.readLines((File JavaDoc) value);
251             } catch (IOException JavaDoc e) {
252                 throw new GroovyRuntimeException("Error reading file: " + value, e);
253             }
254         } else {
255             // lets assume its a collection of 1
256
return Collections.singletonList(value);
257         }
258     }
259
260     public Iterator asIterator(Object JavaDoc value) {
261         if (value == null) {
262             return Collections.EMPTY_LIST.iterator();
263         }
264         if (value instanceof Iterator) {
265             return (Iterator) value;
266         }
267         if (value instanceof NodeList JavaDoc) {
268             final NodeList JavaDoc nodeList = (NodeList JavaDoc) value;
269             return new Iterator() {
270                 private int current = 0;
271
272                 public boolean hasNext() {
273                     return current < nodeList.getLength();
274                 }
275
276                 public Object JavaDoc next() {
277                     Node JavaDoc node = nodeList.item(current++);
278                     return node;
279                 }
280
281                 public void remove() {
282                     throw new UnsupportedOperationException JavaDoc("Cannot remove() from an Enumeration");
283                 }
284             };
285         } else if (value instanceof Enumeration) {
286             final Enumeration enumeration = (Enumeration) value;
287             return new Iterator() {
288                 private Object JavaDoc last;
289
290                 public boolean hasNext() {
291                     return enumeration.hasMoreElements();
292                 }
293
294                 public Object JavaDoc next() {
295                     last = enumeration.nextElement();
296                     return last;
297                 }
298
299                 public void remove() {
300                     throw new UnsupportedOperationException JavaDoc("Cannot remove() from an Enumeration");
301                 }
302             };
303         } else if (value instanceof Matcher JavaDoc) {
304             final Matcher JavaDoc matcher = (Matcher JavaDoc) value;
305             return new Iterator() {
306                 private boolean found = false;
307                 private boolean done = false;
308
309                 public boolean hasNext() {
310                     if (done)
311                         return false;
312                     if (!found) {
313                         found = matcher.find();
314                         if (!found)
315                             done = true;
316                     }
317                     return found;
318                 }
319
320                 public Object JavaDoc next() {
321                     if (!found) {
322                         if (!hasNext()) {
323                             throw new NoSuchElementException();
324                         }
325                     }
326                     found = false;
327                     return matcher.group();
328                 }
329
330                 public void remove() {
331                     throw new UnsupportedOperationException JavaDoc();
332                 }
333             };
334         } else {
335             try {
336                 // lets try see if there's an iterator() method
337
final Method JavaDoc method = value.getClass().getMethod("iterator", EMPTY_TYPES);
338
339                 if (method != null) {
340                     AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
341                         public Object JavaDoc run() {
342                             method.setAccessible(true);
343                             return null;
344                         }
345                     });
346
347                     return (Iterator) method.invoke(value, EMPTY_ARGUMENTS);
348                 }
349             } catch (Exception JavaDoc e) {
350                 // ignore
351
}
352         }
353         return asCollection(value).iterator();
354     }
355
356     /**
357      * @return true if the two objects are null or the objects are equal
358      */

359     public boolean objectsEqual(Object JavaDoc left, Object JavaDoc right) {
360         if (left == right) {
361             return true;
362         }
363         if (left != null) {
364             if (right == null) {
365                 return false;
366             }
367             if (left instanceof Comparable JavaDoc) {
368                 return compareTo(left, right) == 0;
369             } else {
370                 return left.equals(right);
371             }
372         }
373         return false;
374     }
375
376     public String JavaDoc inspect(Object JavaDoc self) {
377         return format(self, true);
378     }
379
380     /**
381      * Compares the two objects handling nulls gracefully and performing numeric type coercion if required
382      */

383     public int compareTo(Object JavaDoc left, Object JavaDoc right) {
384         //System.out.println("Comparing: " + left + " to: " + right);
385
if (left == right) {
386             return 0;
387         }
388         if (left == null) {
389             return -1;
390         } else if (right == null) {
391             return 1;
392         }
393         if (left instanceof Comparable JavaDoc) {
394             if (left instanceof Number JavaDoc) {
395                 if (isValidCharacterString(right)) {
396                     return asCharacter((Number JavaDoc) left).compareTo(asCharacter((String JavaDoc) right));
397                 }
398                 return DefaultGroovyMethods.compareTo((Number JavaDoc) left, asNumber(right));
399             } else if (left instanceof Character JavaDoc) {
400                 if (isValidCharacterString(right)) {
401                     return ((Character JavaDoc) left).compareTo(asCharacter((String JavaDoc) right));
402                 } else if (right instanceof Number JavaDoc) {
403                     return ((Character JavaDoc) left).compareTo(asCharacter((Number JavaDoc) right));
404                 }
405             } else if (right instanceof Number JavaDoc) {
406                 if (isValidCharacterString(left)) {
407                     return asCharacter((String JavaDoc) left).compareTo(asCharacter((Number JavaDoc) right));
408                 }
409                 return DefaultGroovyMethods.compareTo(asNumber(left), (Number JavaDoc) right);
410             } else if (left instanceof String JavaDoc && right instanceof Character JavaDoc) {
411                 return ((String JavaDoc) left).compareTo(right.toString());
412             }
413             Comparable JavaDoc comparable = (Comparable JavaDoc) left;
414             return comparable.compareTo(right);
415         }
416         if (left.getClass().isArray()) {
417             Collection leftList = asCollection(left);
418             if (right.getClass().isArray()) {
419                 right = asCollection(right);
420             }
421             return ((Comparable JavaDoc) leftList).compareTo(right);
422         }
423         /** todo we might wanna do some type conversion here */
424         throw new GroovyRuntimeException("Cannot compare values: " + left + " and " + right);
425     }
426
427     /**
428      * A helper method to provide some better toString() behaviour such as turning arrays
429      * into tuples
430      */

431     public String JavaDoc toString(Object JavaDoc arguments) {
432         return format(arguments, false);
433     }
434
435     /**
436      * A helper method to format the arguments types as a comma-separated list
437      */

438     public String JavaDoc toTypeString(Object JavaDoc[] arguments) {
439         if (arguments == null) {
440             return "null";
441         }
442         StringBuffer JavaDoc argBuf = new StringBuffer JavaDoc();
443         for (int i = 0; i < arguments.length; i++) {
444             if (i > 0)
445                 argBuf.append(", ");
446             argBuf.append(arguments[i] != null ? arguments[i].getClass().getName() : "null");
447         }
448         return argBuf.toString();
449     }
450
451     protected String JavaDoc format(Object JavaDoc arguments, boolean verbose) {
452         if (arguments == null) {
453             return "null";
454         } else if (arguments.getClass().isArray()) {
455             return format(asCollection(arguments), verbose);
456         } else if (arguments instanceof Range) {
457             Range range = (Range) arguments;
458             if (verbose) {
459                 return range.inspect();
460             } else {
461                 return range.toString();
462             }
463         } else if (arguments instanceof List JavaDoc) {
464             List JavaDoc list = (List JavaDoc) arguments;
465             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("[");
466             boolean first = true;
467             for (Iterator iter = list.iterator(); iter.hasNext();) {
468                 if (first) {
469                     first = false;
470                 } else {
471                     buffer.append(", ");
472                 }
473                 buffer.append(format(iter.next(), verbose));
474             }
475             buffer.append("]");
476             return buffer.toString();
477         } else if (arguments instanceof Map) {
478             Map map = (Map) arguments;
479             if (map.isEmpty()) {
480                 return "[:]";
481             }
482             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("[");
483             boolean first = true;
484             for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
485                 if (first) {
486                     first = false;
487                 } else {
488                     buffer.append(", ");
489                 }
490                 Map.Entry entry = (Map.Entry) iter.next();
491                 buffer.append(format(entry.getKey(), verbose));
492                 buffer.append(":");
493                 buffer.append(format(entry.getValue(), verbose));
494             }
495             buffer.append("]");
496             return buffer.toString();
497         } else if (arguments instanceof Element JavaDoc) {
498             Element JavaDoc node = (Element JavaDoc) arguments;
499             OutputFormat format = new OutputFormat(node.getOwnerDocument());
500             format.setOmitXMLDeclaration(true);
501             format.setIndenting(true);
502             format.setLineWidth(0);
503             format.setPreserveSpace(true);
504             StringWriter JavaDoc sw = new StringWriter JavaDoc();
505             XMLSerializer serializer = new XMLSerializer(sw, format);
506             try {
507                 serializer.asDOMSerializer();
508                 serializer.serialize(node);
509             } catch (IOException JavaDoc e) {
510             }
511             return sw.toString();
512         } else if (arguments instanceof String JavaDoc) {
513             if (verbose) {
514                 return "\"" + arguments + "\"";
515             } else {
516                 return (String JavaDoc) arguments;
517             }
518         } else {
519             return arguments.toString();
520         }
521     }
522
523     /**
524      * Sets the property on the given object
525      *
526      * @param object
527      * @param property
528      * @param newValue
529      * @return
530      */

531     public void setProperty(Object JavaDoc object, String JavaDoc property, Object JavaDoc newValue) {
532         if (object == null) {
533             throw new GroovyRuntimeException("Cannot set property on null object");
534         } else if (object instanceof GroovyObject) {
535             GroovyObject pogo = (GroovyObject) object;
536             pogo.setProperty(property, newValue);
537         } else if (object instanceof Map) {
538             Map map = (Map) object;
539             map.put(property, newValue);
540         } else {
541             metaRegistry.getMetaClass(object.getClass()).setProperty(object, property, newValue);
542         }
543     }
544
545     /**
546      * Looks up the given property of the given object
547      *
548      * @param object
549      * @param property
550      * @return
551      */

552     public Object JavaDoc getProperty(Object JavaDoc object, String JavaDoc property) {
553         if (object == null) {
554             throw new NullPointerException JavaDoc("Cannot get property: " + property + " on null object");
555         } else if (object instanceof GroovyObject) {
556             GroovyObject pogo = (GroovyObject) object;
557             return pogo.getProperty(property);
558         } else if (object instanceof Map) {
559             Map map = (Map) object;
560             return map.get(property);
561         } else {
562             return metaRegistry.getMetaClass(object.getClass()).getProperty(object, property);
563         }
564     }
565
566     public int asInt(Object JavaDoc value) {
567         if (value instanceof Number JavaDoc) {
568             Number JavaDoc n = (Number JavaDoc) value;
569             return n.intValue();
570         }
571         throw new GroovyRuntimeException("Could not convert object: " + value + " into an int");
572     }
573
574     public Number JavaDoc asNumber(Object JavaDoc value) {
575         if (value instanceof Number JavaDoc) {
576             return (Number JavaDoc) value;
577         } else if (value instanceof String JavaDoc) {
578             String JavaDoc s = (String JavaDoc) value;
579
580             if (s.length() == 1)
581                 return new Integer JavaDoc(s.charAt(0));
582             else
583                 return Double.valueOf(s);
584         } else if (value instanceof Character JavaDoc) {
585             return new Integer JavaDoc(((Character JavaDoc) value).charValue());
586         } else {
587             throw new GroovyRuntimeException("Could not convert object: " + value + " into a Number");
588         }
589     }
590
591     /**
592      * Attempts to load the given class via name using the current class loader
593      * for this code or the thread context class loader
594      */

595     protected Class JavaDoc loadClass(String JavaDoc type) {
596         try {
597             return getClass().getClassLoader().loadClass(type);
598         } catch (ClassNotFoundException JavaDoc e) {
599             try {
600                 return Thread.currentThread().getContextClassLoader().loadClass(type);
601             } catch (ClassNotFoundException JavaDoc e2) {
602                 try {
603                     return Class.forName(type);
604                 } catch (ClassNotFoundException JavaDoc e3) {
605                 }
606             }
607             throw new GroovyRuntimeException("Could not load type: " + type, e);
608         }
609     }
610
611     /**
612      * Find the right hand regex within the left hand string and return a matcher.
613      *
614      * @param left string to compare
615      * @param right regular expression to compare the string to
616      * @return
617      */

618     public Matcher JavaDoc objectFindRegex(Object JavaDoc left, Object JavaDoc right) {
619         String JavaDoc stringToCompare;
620         if (left instanceof String JavaDoc) {
621             stringToCompare = (String JavaDoc) left;
622         } else {
623             stringToCompare = toString(left);
624         }
625         String JavaDoc regexToCompareTo;
626         if (right instanceof String JavaDoc) {
627             regexToCompareTo = (String JavaDoc) right;
628         } else if (right instanceof Pattern JavaDoc) {
629             Pattern JavaDoc pattern = (Pattern JavaDoc) right;
630             return pattern.matcher(stringToCompare);
631         } else {
632             regexToCompareTo = toString(right);
633         }
634         Matcher JavaDoc matcher = Pattern.compile(regexToCompareTo).matcher(stringToCompare);
635         return matcher;
636     }
637
638     /**
639      * Find the right hand regex within the left hand string and return a matcher.
640      *
641      * @param left string to compare
642      * @param right regular expression to compare the string to
643      * @return
644      */

645     public boolean objectMatchRegex(Object JavaDoc left, Object JavaDoc right) {
646         Pattern JavaDoc pattern;
647         if (right instanceof Pattern JavaDoc) {
648             pattern = (Pattern JavaDoc) right;
649         } else {
650             pattern = Pattern.compile(toString(right));
651         }
652         String JavaDoc stringToCompare = toString(left);
653         Matcher JavaDoc matcher = pattern.matcher(stringToCompare);
654         RegexSupport.setLastMatcher(matcher);
655         return matcher.matches();
656     }
657
658     /**
659      * Compile a regular expression from a string.
660      *
661      * @param regex
662      * @return
663      */

664     public Pattern JavaDoc regexPattern(Object JavaDoc regex) {
665         return Pattern.compile(regex.toString());
666     }
667
668     public Object JavaDoc asType(Object JavaDoc object, Class JavaDoc type) {
669         if (object == null) {
670             return null;
671         }
672         if (type.isInstance(object)) {
673             return object;
674         }
675         if (type.equals(String JavaDoc.class)) {
676             return object.toString();
677         }
678         if (type.equals(Character JavaDoc.class)) {
679             if (object instanceof Number JavaDoc) {
680                 return asCharacter((Number JavaDoc) object);
681             } else {
682                 String JavaDoc text = object.toString();
683                 if (text.length() == 1) {
684                     return new Character JavaDoc(text.charAt(0));
685                 } else {
686                     throw new ClassCastException JavaDoc("Cannot cast: " + text + " to a Character");
687                 }
688             }
689         }
690         if (Number JavaDoc.class.isAssignableFrom(type)) {
691             if (object instanceof Character JavaDoc) {
692                 return new Integer JavaDoc(((Character JavaDoc) object).charValue());
693             } else if (object instanceof String JavaDoc) {
694                 String JavaDoc c = (String JavaDoc) object;
695                 if (c.length() == 1) {
696                     return new Integer JavaDoc(c.charAt(0));
697                 } else {
698                     throw new ClassCastException JavaDoc("Cannot cast: '" + c + "' to an Integer");
699                 }
700             }
701         }
702         if (object instanceof Number JavaDoc) {
703             Number JavaDoc n = (Number JavaDoc) object;
704             if (type.isPrimitive()) {
705                 if (type == byte.class) {
706                     return new Byte JavaDoc(n.byteValue());
707                 }
708                 if (type == char.class) {
709                     return new Character JavaDoc((char) n.intValue());
710                 }
711                 if (type == short.class) {
712                     return new Short JavaDoc(n.shortValue());
713                 }
714                 if (type == int.class) {
715                     return new Integer JavaDoc(n.intValue());
716                 }
717                 if (type == long.class) {
718                     return new Long JavaDoc(n.longValue());
719                 }
720                 if (type == float.class) {
721                     return new Float JavaDoc(n.floatValue());
722                 }
723                 if (type == double.class) {
724                     Double JavaDoc answer = new Double JavaDoc(n.doubleValue());
725                     //throw a runtime exception if conversion would be out-of-range for the type.
726
if (!(n instanceof Double JavaDoc) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
727                             || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
728                         throw new GroovyRuntimeException("Automatic coercion of " + n.getClass().getName()
729                                 + " value " + n + " to double failed. Value is out of range.");
730                     }
731                     return answer;
732                 }
733             } else {
734                 if (Number JavaDoc.class.isAssignableFrom(type)) {
735                     if (type == Byte JavaDoc.class) {
736                         return new Byte JavaDoc(n.byteValue());
737                     }
738                     if (type == Character JavaDoc.class) {
739                         return new Character JavaDoc((char) n.intValue());
740                     }
741                     if (type == Short JavaDoc.class) {
742                         return new Short JavaDoc(n.shortValue());
743                     }
744                     if (type == Integer JavaDoc.class) {
745                         return new Integer JavaDoc(n.intValue());
746                     }
747                     if (type == Long JavaDoc.class) {
748                         return new Long JavaDoc(n.longValue());
749                     }
750                     if (type == Float JavaDoc.class) {
751                         return new Float JavaDoc(n.floatValue());
752                     }
753                     if (type == Double JavaDoc.class) {
754                         Double JavaDoc answer = new Double JavaDoc(n.doubleValue());
755                         //throw a runtime exception if conversion would be out-of-range for the type.
756
if (!(n instanceof Double JavaDoc) && (answer.doubleValue() == Double.NEGATIVE_INFINITY
757                                 || answer.doubleValue() == Double.POSITIVE_INFINITY)) {
758                             throw new GroovyRuntimeException("Automatic coercion of " + n.getClass().getName()
759                                     + " value " + n + " to double failed. Value is out of range.");
760                         }
761                         return answer;
762                     }
763
764                 }
765             }
766         }
767         if (type == Boolean JavaDoc.class) {
768             return asBool(object) ? Boolean.TRUE : Boolean.FALSE;
769         }
770         return object;
771     }
772
773     public boolean asBool(Object JavaDoc object) {
774         if (object instanceof Boolean JavaDoc) {
775             Boolean JavaDoc booleanValue = (Boolean JavaDoc) object;
776             return booleanValue.booleanValue();
777         } else if (object instanceof Matcher JavaDoc) {
778             Matcher JavaDoc matcher = (Matcher JavaDoc) object;
779             RegexSupport.setLastMatcher(matcher);
780             return matcher.find();
781         } else if (object instanceof Collection) {
782             Collection collection = (Collection) object;
783             return !collection.isEmpty();
784         } else if (object instanceof Number JavaDoc) {
785             Number JavaDoc n = (Number JavaDoc) object;
786             return n.doubleValue() != 0;
787         } else {
788             return object != null;
789         }
790     }
791
792     protected Character JavaDoc asCharacter(Number JavaDoc value) {
793         return new Character JavaDoc((char) value.intValue());
794     }
795
796     protected Character JavaDoc asCharacter(String JavaDoc text) {
797         return new Character JavaDoc(text.charAt(0));
798     }
799
800     /**
801      * @return true if the given value is a valid character string (i.e. has length of 1)
802      */

803     protected boolean isValidCharacterString(Object JavaDoc value) {
804         if (value instanceof String JavaDoc) {
805             String JavaDoc s = (String JavaDoc) value;
806             if (s.length() == 1) {
807                 return true;
808             }
809         }
810         return false;
811     }
812
813     public void removeMetaClass(Class JavaDoc clazz) {
814         getMetaRegistry().removeMetaClass(clazz);
815     }
816 }
817
Popular Tags