KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > util > DispatchMethodInvoker


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.util;
17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.springframework.binding.method.ClassMethodKey;
23 import org.springframework.binding.method.InvalidMethodSignatureException;
24 import org.springframework.core.NestedRuntimeException;
25 import org.springframework.util.Assert;
26 import org.springframework.util.CachingMapDecorator;
27 import org.springframework.util.ClassUtils;
28
29 /**
30  * Invoker and cache for dispatch methods that all share the same target object.
31  * The dispatch methods typically share the same form, but multiple exist per
32  * target object, and they only differ in name.
33  *
34  * @author Keith Donald
35  * @author Ben Hale
36  */

37 public class DispatchMethodInvoker {
38
39     /**
40      * The target object to dispatch to.
41      */

42     private Object JavaDoc target;
43
44     /**
45      * The parameter types describing the dispatch method signature.
46      */

47     private Class JavaDoc[] parameterTypes;
48
49     /**
50      * The resolved method cache.
51      */

52     private Map JavaDoc methodCache = new CachingMapDecorator() {
53         public Object JavaDoc create(Object JavaDoc key) {
54             String JavaDoc methodName = (String JavaDoc)key;
55             try {
56                 return new ClassMethodKey(target.getClass(), methodName, parameterTypes).getMethod();
57             }
58             catch (InvalidMethodSignatureException e) {
59                 throw new MethodLookupException("Unable to resolve dispatch method with name '" + methodName
60                         + "' and signature '" + getSignatureString(methodName)
61                         + "'; make sure the method name is correct and such a method is defined on targetClass "
62                         + target.getClass().getName(), e);
63             }
64         }
65     };
66
67     /**
68      * Creates a dispatch method invoker.
69      * @param target the target to dispatch to
70      * @param parameterTypes the parameter types defining the argument signature
71      * of the dispatch methods
72      */

73     public DispatchMethodInvoker(Object JavaDoc target, Class JavaDoc[] parameterTypes) {
74         Assert.notNull(target, "The target of a dispatch method invocation is required");
75         this.target = target;
76         this.parameterTypes = parameterTypes;
77     }
78     
79     /**
80      * Returns the target object method calls are dispatched to.
81      */

82     public Object JavaDoc getTarget() {
83         return target;
84     }
85     
86     /**
87      * Returns the parameter types defining the argument signature of the
88      * dispatch methods.
89      */

90     public Class JavaDoc[] getParameterTypes() {
91         return parameterTypes;
92     }
93
94     /**
95      * Dispatch a call with given arguments to named dispatcher method.
96      * @param methodName the name of the method to invoke
97      * @param arguments the arguments to pass to the method
98      * @return the result of the method invokation
99      * @throws MethodLookupException when the method cannot be resolved
100      * @throws Exception when the invoked method throws an exception
101      */

102     public Object JavaDoc invoke(String JavaDoc methodName, Object JavaDoc[] arguments) throws MethodLookupException, Exception JavaDoc {
103         try {
104             Method JavaDoc dispatchMethod = getDispatchMethod(methodName);
105             return dispatchMethod.invoke(target, arguments);
106         }
107         catch (InvocationTargetException JavaDoc e) {
108             // the invoced method threw an exception; have it propagate to the caller
109
Throwable JavaDoc t = e.getTargetException();
110             if (t instanceof Exception JavaDoc) {
111                 throw (Exception JavaDoc)e.getTargetException();
112             }
113             else {
114                 throw (Error JavaDoc)e.getTargetException();
115             }
116         }
117     }
118
119     /**
120      * Get a handle to the method of the specified name, with the signature
121      * defined by the configured parameter types and return type.
122      * @param methodName the method name
123      * @return the method
124      * @throws MethodLookupException when the method cannot be resolved
125      */

126     private Method JavaDoc getDispatchMethod(String JavaDoc methodName) throws MethodLookupException {
127         return (Method JavaDoc)methodCache.get(methodName);
128     }
129
130     /**
131      * Returns the signature of the dispatch methods invoked by this class.
132      * @param methodName name of the dispatch method
133      */

134     private String JavaDoc getSignatureString(String JavaDoc methodName) {
135         return methodName + "(" + getParameterTypesString() + ");";
136     }
137
138     /**
139      * Convenience method that returns the parameter types describing the
140      * signature of the dispatch method as a string.
141      */

142     private String JavaDoc getParameterTypesString() {
143         StringBuffer JavaDoc parameterTypesString = new StringBuffer JavaDoc();
144         for (int i = 0; i < parameterTypes.length; i++) {
145             parameterTypesString.append(ClassUtils.getShortName(parameterTypes[i]));
146             if (i < parameterTypes.length - 1) {
147                 parameterTypesString.append(',');
148             }
149         }
150         return parameterTypesString.toString();
151     }
152
153     /**
154      * Thrown when a dispatch method could not be resolved.
155      */

156     public static class MethodLookupException extends NestedRuntimeException {
157
158         /**
159          * Create a new method lookup exception.
160          * @param msg a descriptive message
161          * @param ex the underlying cause of this exception
162          */

163         public MethodLookupException(String JavaDoc msg, Throwable JavaDoc ex) {
164             super(msg, ex);
165         }
166     }
167 }
Popular Tags