View Javadoc

1   /*
2    * Copyright 2007 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  
17  package org.springframework.ws.server.endpoint;
18  
19  import java.lang.reflect.InvocationTargetException;
20  import java.lang.reflect.Method;
21  
22  import org.springframework.beans.factory.BeanFactory;
23  import org.springframework.core.JdkVersion;
24  import org.springframework.util.Assert;
25  
26  /**
27   * Represents a bean method that will be invoked as part of an incoming Web service message.
28   * <p/>
29   * Consists of a {@link Method}, and a bean {@link Object}.
30   *
31   * @author Arjen Poutsma
32   * @since 1.0.0
33   */
34  public final class MethodEndpoint {
35  
36      private final Object bean;
37  
38      private final Method method;
39  
40      private final BeanFactory beanFactory;
41  
42      /**
43       * Constructs a new method endpoint with the given bean and method.
44       *
45       * @param bean   the object bean
46       * @param method the method
47       */
48      public MethodEndpoint(Object bean, Method method) {
49          Assert.notNull(bean, "bean must not be null");
50          Assert.notNull(method, "method must not be null");
51          this.bean = bean;
52          this.method = method;
53          this.beanFactory = null;
54      }
55  
56      /**
57       * Constructs a new method endpoint with the given bean, method name and parameters.
58       *
59       * @param bean           the object bean
60       * @param methodName     the method name
61       * @param parameterTypes the method parameter types
62       * @throws NoSuchMethodException when the method cannot be found
63       */
64      public MethodEndpoint(Object bean, String methodName, Class[] parameterTypes) throws NoSuchMethodException {
65          Assert.notNull(bean, "bean must not be null");
66          Assert.notNull(methodName, "method must not be null");
67          this.bean = bean;
68          this.method = bean.getClass().getMethod(methodName, parameterTypes);
69          this.beanFactory = null;
70      }
71  
72      /**
73       * Constructs a new method endpoint with the given bean name and method. The bean name will be lazily initized when
74       * {@link #invoke(Object[])} is called.
75       *
76       * @param beanName    the bean name
77       * @param beanFactory the bean factory to use for bean initialization
78       * @param method      the method
79       */
80      public MethodEndpoint(String beanName, BeanFactory beanFactory, Method method) {
81          Assert.hasText(beanName, "'beanName' must not be null");
82          Assert.notNull(beanFactory, "'beanFactory' must not be null");
83          Assert.notNull(method, "'method' must not be null");
84          Assert.isTrue(beanFactory.containsBean(beanName),
85                  "Bean factory [" + beanFactory + "] does not contain bean " + "with name [" + beanName + "]");
86          this.bean = beanName;
87          this.beanFactory = beanFactory;
88          this.method = method;
89      }
90  
91      /** Returns the object bean for this method endpoint. */
92      public Object getBean() {
93          return this.bean;
94      }
95  
96      /** Returns the method for this method endpoint. */
97      public Method getMethod() {
98          return this.method;
99      }
100 
101     /**
102      * Invokes this method endpoint with the given arguments.
103      *
104      * @param args the arguments
105      * @return the invocation result
106      * @throws Exception when the method invocation results in an exception
107      */
108     public Object invoke(Object[] args) throws Exception {
109         Object endpoint = bean;
110         if (endpoint instanceof String) {
111             String endpointName = (String) endpoint;
112             endpoint = beanFactory.getBean(endpointName);
113         }
114         try {
115             return this.method.invoke(endpoint, args);
116         }
117         catch (InvocationTargetException ex) {
118             handleInvocationTargetException(ex);
119             throw new IllegalStateException("Unexpected exception thrown by method - " +
120                     ex.getTargetException().getClass().getName() + ": " + ex.getTargetException().getMessage());
121         }
122     }
123 
124     private void handleInvocationTargetException(InvocationTargetException ex) throws Exception {
125         if (ex.getTargetException() instanceof RuntimeException) {
126             throw (RuntimeException) ex.getTargetException();
127         }
128         if (ex.getTargetException() instanceof Error) {
129             throw (Error) ex.getTargetException();
130         }
131         if (ex.getTargetException() instanceof Exception) {
132             throw (Exception) ex.getTargetException();
133         }
134 
135     }
136 
137     public boolean equals(Object o) {
138         if (this == o) {
139             return true;
140         }
141         if (o != null && o instanceof MethodEndpoint) {
142             MethodEndpoint other = (MethodEndpoint) o;
143             return this.bean.equals(other.bean) && this.method.equals(other.method);
144         }
145         return false;
146     }
147 
148     public int hashCode() {
149         return 31 * this.bean.hashCode() + this.method.hashCode();
150     }
151 
152     public String toString() {
153         if (JdkVersion.getMajorJavaVersion() <= JdkVersion.JAVA_14) {
154             return this.method.toString();
155         }
156         else {
157             return GenericToStringProvider.toString(method);
158         }
159     }
160 
161     /** Inner class to avoid a static JDK 1.5 dependency for generic string generation. */
162     private static class GenericToStringProvider {
163 
164         public static String toString(Method method) {
165             return method.toGenericString();
166         }
167     }
168 }