KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jga > fn > property > InvokeNoArgMethod


1 // ============================================================================
2
// $Id: InvokeNoArgMethod.java,v 1.9 2006/04/26 03:40:37 davidahall Exp $
3
// Copyright (c) 2003-2005 David A. Hall
4
// ============================================================================
5
// The contents of this file are subject to the Common Development and
6
// Distribution License (CDDL), Version 1.0 (the License); you may not use this
7
// file except in compliance with the License. You should have received a copy
8
// of the the License along with this file: if not, a copy of the License is
9
// available from Sun Microsystems, Inc.
10
//
11
// http://www.sun.com/cddl/cddl.html
12
//
13
// From time to time, the license steward (initially Sun Microsystems, Inc.) may
14
// publish revised and/or new versions of the License. You may not use,
15
// distribute, or otherwise make this file available under subsequent versions
16
// of the License.
17
//
18
// Alternatively, the contents of this file may be used under the terms of the
19
// GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
20
// case the provisions of the LGPL are applicable instead of those above. If you
21
// wish to allow use of your version of this file only under the terms of the
22
// LGPL, and not to allow others to use your version of this file under the
23
// terms of the CDDL, indicate your decision by deleting the provisions above
24
// and replace them with the notice and other provisions required by the LGPL.
25
// If you do not delete the provisions above, a recipient may use your version
26
// of this file under the terms of either the CDDL or the LGPL.
27
//
28
// This library is distributed in the hope that it will be useful,
29
// but WITHOUT ANY WARRANTY; without even the implied warranty of
30
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
// ============================================================================
32

33 package net.sf.jga.fn.property;
34
35 import java.lang.reflect.InvocationTargetException JavaDoc;
36 import java.lang.reflect.Method JavaDoc;
37 import java.text.MessageFormat JavaDoc;
38 import net.sf.jga.fn.BinaryFunctor;
39 import net.sf.jga.fn.EvaluationException;
40 import net.sf.jga.fn.UnaryFunctor;
41 import net.sf.jga.fn.adaptor.ChainBinary;
42 import net.sf.jga.fn.adaptor.ChainUnary;
43
44 /**
45  * Functor that invokes a no-arg method named at construction and returns the
46  * result or null if the result is void.
47  * <p>
48  * Note that declaring the return type incorrectly can result in
49  * ClassCastExceptions being thrown when the functor is invoked: the compiler
50  * cannot check the return type of a reflectively loaded method.
51  * <p>
52  * Copyright &copy; 2003-2005 David A. Hall
53  *
54  * @author <a HREF="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
55  **/

56
57 public class InvokeNoArgMethod<T,R> extends UnaryFunctor<T,R> {
58     
59     static final long serialVersionUID = -2651164047444243205L;
60
61     // The name of the method
62
private String JavaDoc _methName;
63
64     // The class on which the method is defined
65
private Class JavaDoc<T> _objclass;
66
67     // The method being called (lazily populated after deserialization)
68
private transient Method JavaDoc _meth;
69
70     /**
71      * Builds a InvokeMethod for the given method, which takes no arguments.
72      * @throws IllegalArgumentException if the method name is null or empty
73      */

74     
75     public InvokeNoArgMethod(Class JavaDoc<T> objclass, String JavaDoc methName) {
76         if (methName == null || methName.length() == 0) {
77             String JavaDoc msg = "Must supply method name";
78             throw new IllegalArgumentException JavaDoc(msg);
79         }
80
81         if (objclass == null) {
82             String JavaDoc msg = "Must supply object class";
83             throw new IllegalArgumentException JavaDoc(msg);
84         }
85
86         _methName = methName;
87         _objclass = objclass;
88         
89         try {
90             _meth = objclass.getMethod(_methName, new Class JavaDoc[0]);
91         }
92         catch (NoSuchMethodException JavaDoc x) {
93             String JavaDoc msg = "No such method: "+x.getMessage();
94             IllegalArgumentException JavaDoc iax = new IllegalArgumentException JavaDoc(msg);
95             iax.initCause(x);
96             throw iax;
97         }
98     }
99
100     /**
101      * Builds a InvokeMethod for the given method, which takes no arguments.
102      * @throws IllegalArgumentException if the method name is null or empty,
103      * or if it is not defined for the given class, or if it takes arguments
104      */

105     
106     public InvokeNoArgMethod(Class JavaDoc<T> objClass, Method JavaDoc method) {
107         if (method == null) {
108             String JavaDoc msg = "Must supply method";
109             throw new IllegalArgumentException JavaDoc(msg);
110         }
111
112         if (objClass == null) {
113             String JavaDoc msg = "Must supply object class";
114             throw new IllegalArgumentException JavaDoc(msg);
115         }
116
117         if (method.getParameterTypes().length != 0) {
118             String JavaDoc msg = "Method {0} takes arguments";
119             Object JavaDoc[] args = { method.getName() };
120             throw new IllegalArgumentException JavaDoc(MessageFormat.format(msg, args));
121         }
122         
123         if (!method.getDeclaringClass().isAssignableFrom(objClass)) {
124             String JavaDoc msg = "Method {0} not defined for class {1}";
125             Object JavaDoc[] args = { method.getName(), objClass.getName() };
126             throw new IllegalArgumentException JavaDoc(MessageFormat.format(msg, args));
127         }
128         
129         _objclass = objClass;
130         _meth = method;
131         _methName = method.getName();
132     }
133
134     /**
135      * Returns the name of the property that this functor retrieves.
136      */

137     public String JavaDoc getMethodName() {
138         return _methName;
139     }
140
141     /**
142      * Returns the type of the method
143      */

144     public Class JavaDoc<R> getReturnType() {
145         return (Class JavaDoc<R>) _meth.getReturnType();
146     }
147
148     /**
149      * Lazy loads the method
150      */

151     public synchronized Method JavaDoc getMethod() throws NoSuchMethodException JavaDoc {
152         if (_meth == null)
153             _meth = _objclass.getMethod(_methName, new Class JavaDoc[0]);
154
155         return _meth;
156     }
157
158     // Unary Functor interface
159

160     /**
161      * Invokes the method on the given object, and returns the result.
162      * @return the result of the designated method of the object
163      * @throws EvaluationException if the argument does not have the designated
164      * public property, or if it is not of the correct type.
165      */

166     public R fn(T obj) {
167         try {
168             // @SuppressWarnings
169
// There's nothing we can do about this other than warn the users
170
// to make sure that they don't use an inappropriate return type
171
return (R) getMethod().invoke(obj, new Object JavaDoc[0]);
172         }
173         catch (NoSuchMethodException JavaDoc x) {
174             String JavaDoc msg = "No method {0} for class {1} that takes no arguments";
175             Object JavaDoc[] args = new Object JavaDoc[]{_methName, _objclass.getName()};
176             throw new EvaluationException(MessageFormat.format(msg,args), x);
177         }
178         catch (ClassCastException JavaDoc x) {
179             String JavaDoc msg = "ClassCastException: " +_objclass +"." +_methName +"()";
180             throw new EvaluationException(msg, x);
181         }
182         catch (IllegalAccessException JavaDoc x) {
183             String JavaDoc msg = _objclass +"." +_methName +" is not accessible";
184             throw new EvaluationException(msg, x);
185         }
186         catch (InvocationTargetException JavaDoc x) {
187             String JavaDoc xmsg = x.getMessage();
188             String JavaDoc msg = "InvocationException: " +_objclass +"." +_methName
189                 +"()"+(xmsg != null ? (":"+xmsg) : "");
190             throw new EvaluationException(msg, x);
191         }
192     }
193
194     
195     /**
196      * Calls the Visitor's <code>visit(InvokeMethod)</code> method, if it
197      * implements the nested Visitor interface.
198      */

199     public void accept(net.sf.jga.fn.Visitor v) {
200         if (v instanceof InvokeNoArgMethod.Visitor)
201             ((InvokeNoArgMethod.Visitor)v).visit(this);
202         else
203             v.visit(this);
204     }
205     
206     // Object overrides
207

208     public String JavaDoc toString() {
209         return "InvokeNoArgMethod("+_meth+")";
210     }
211     
212    // AcyclicVisitor
213

214     /**
215      * Interface for classes that may interpret a <b>InvokeMethod</b>
216      * function.
217      */

218     public interface Visitor extends net.sf.jga.fn.Visitor {
219         public void visit(InvokeNoArgMethod host);
220     }
221 }
222
Popular Tags