View Javadoc

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