renamed GatewayMethodDefinition to GatewayMethodMetadata and made it package-protected
This commit is contained in:
@@ -83,27 +83,26 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, attributeName);
|
||||
}
|
||||
List<Element> elements = DomUtils.getChildElementsByTagName(element, "method");
|
||||
|
||||
ManagedMap<String, BeanDefinition> methodToChannelMap = null;
|
||||
if (elements != null && elements.size() > 0){
|
||||
methodToChannelMap = new ManagedMap<String, BeanDefinition>();
|
||||
ManagedMap<String, BeanDefinition> methodMetadataMap = null;
|
||||
if (elements != null && elements.size() > 0) {
|
||||
methodMetadataMap = new ManagedMap<String, BeanDefinition>();
|
||||
}
|
||||
for (Element methodElement : elements) {
|
||||
String methodName = methodElement.getAttribute("name");
|
||||
BeanDefinitionBuilder gatewayDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.gateway.GatewayMethodDefinition");
|
||||
gatewayDefinitionBuilder.addPropertyValue("requestChannelName", methodElement.getAttribute("request-channel"));
|
||||
gatewayDefinitionBuilder.addPropertyValue("replyChannelName", methodElement.getAttribute("reply-channel"));
|
||||
gatewayDefinitionBuilder.addPropertyValue("requestTimeout", methodElement.getAttribute("request-timeout"));
|
||||
gatewayDefinitionBuilder.addPropertyValue("replyTimeout", methodElement.getAttribute("reply-timeout"));
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(gatewayDefinitionBuilder, methodElement, "payload-expression");
|
||||
BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.gateway.GatewayMethodMetadata");
|
||||
methodMetadataBuilder.addPropertyValue("requestChannelName", methodElement.getAttribute("request-channel"));
|
||||
methodMetadataBuilder.addPropertyValue("replyChannelName", methodElement.getAttribute("reply-channel"));
|
||||
methodMetadataBuilder.addPropertyValue("requestTimeout", methodElement.getAttribute("request-timeout"));
|
||||
methodMetadataBuilder.addPropertyValue("replyTimeout", methodElement.getAttribute("reply-timeout"));
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(methodMetadataBuilder, methodElement, "payload-expression");
|
||||
List<Element> invocationHeaders = DomUtils.getChildElementsByTagName(methodElement, "header");
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)){
|
||||
this.setMethodInvocationHeaders(gatewayDefinitionBuilder, invocationHeaders);
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)) {
|
||||
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
|
||||
}
|
||||
methodToChannelMap.put(methodName, gatewayDefinitionBuilder.getBeanDefinition());
|
||||
methodMetadataMap.put(methodName, methodMetadataBuilder.getBeanDefinition());
|
||||
}
|
||||
builder.addPropertyValue("methodToChannelMap", methodToChannelMap);
|
||||
builder.addPropertyValue("methodMetadataMap", methodMetadataMap);
|
||||
}
|
||||
|
||||
private void setMethodInvocationHeaders(BeanDefinitionBuilder gatewayDefinitionBuilder, List<Element> invocationHeaders) {
|
||||
|
||||
@@ -22,13 +22,16 @@ import java.util.Map;
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
/**
|
||||
* Represents the definition of Gateway methods, when using multiple methods per Gateway interface.
|
||||
* <si:method name="echo" request-channel="inputA" reply-timeout="2" request-timeout="200"/>
|
||||
* Represents the metadata associated with a Gateway method. This is most useful when there are
|
||||
* multiple methods per Gateway interface.
|
||||
* <p>
|
||||
* The sub-element of a <gateway> element would look like this:
|
||||
* <method name="echo" request-channel="inputA" reply-timeout="2" request-timeout="200"/>
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class GatewayMethodDefinition {
|
||||
class GatewayMethodMetadata {
|
||||
|
||||
private volatile String payloadExpression;
|
||||
|
||||
@@ -100,7 +100,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
|
||||
private final Object initializationMonitor = new Object();
|
||||
|
||||
private Map<String, GatewayMethodDefinition> methodToChannelMap;
|
||||
private Map<String, GatewayMethodMetadata> methodMetadataMap;
|
||||
|
||||
|
||||
/**
|
||||
@@ -326,24 +326,24 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
requestTimeout = gatewayAnnotation.requestTimeout();
|
||||
replyTimeout = gatewayAnnotation.replyTimeout();
|
||||
}
|
||||
else if (methodToChannelMap != null && methodToChannelMap.size() > 0) {
|
||||
GatewayMethodDefinition gatewayDefinition = methodToChannelMap.get(method.getName());
|
||||
if (gatewayDefinition != null) {
|
||||
payloadExpression = gatewayDefinition.getPayloadExpression();
|
||||
headerExpressions = gatewayDefinition.getHeaderExpressions();
|
||||
String requestChannelName = gatewayDefinition.getRequestChannelName();
|
||||
else if (methodMetadataMap != null && methodMetadataMap.size() > 0) {
|
||||
GatewayMethodMetadata methodMetadata = methodMetadataMap.get(method.getName());
|
||||
if (methodMetadata != null) {
|
||||
payloadExpression = methodMetadata.getPayloadExpression();
|
||||
headerExpressions = methodMetadata.getHeaderExpressions();
|
||||
String requestChannelName = methodMetadata.getRequestChannelName();
|
||||
if (StringUtils.hasText(requestChannelName)) {
|
||||
requestChannel = this.resolveChannelName(requestChannelName);
|
||||
}
|
||||
String replyChannelName = gatewayDefinition.getReplyChannelName();
|
||||
String replyChannelName = methodMetadata.getReplyChannelName();
|
||||
if (StringUtils.hasText(replyChannelName)) {
|
||||
replyChannel = this.resolveChannelName(replyChannelName);
|
||||
}
|
||||
String reqTimeout = gatewayDefinition.getRequestTimeout();
|
||||
String reqTimeout = methodMetadata.getRequestTimeout();
|
||||
if (StringUtils.hasText(reqTimeout)){
|
||||
requestTimeout = this.convert(reqTimeout, Long.class);
|
||||
}
|
||||
String repTimeout = gatewayDefinition.getReplyTimeout();
|
||||
String repTimeout = methodMetadata.getReplyTimeout();
|
||||
if (StringUtils.hasText(repTimeout)){
|
||||
replyTimeout = this.convert(repTimeout, Long.class);
|
||||
}
|
||||
@@ -397,12 +397,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, GatewayMethodDefinition> getMethodToChannelMap() {
|
||||
return methodToChannelMap;
|
||||
}
|
||||
|
||||
public void setMethodToChannelMap(Map<String, GatewayMethodDefinition> methodToChannelMap) {
|
||||
this.methodToChannelMap = methodToChannelMap;
|
||||
public void setMethodMetadataMap(Map<String, GatewayMethodMetadata> methodMetadataMap) {
|
||||
this.methodMetadataMap = methodMetadataMap;
|
||||
}
|
||||
|
||||
public InboundMessageMapper<Throwable> getExceptionMapper() {
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.integration.annotation.Header;
|
||||
import org.springframework.integration.annotation.Headers;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for common behavior related to Message-handling methods.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
abstract class HandlerMethodUtils {
|
||||
|
||||
/**
|
||||
* Verifies that the provided Method is capable of handling Messages.
|
||||
* It must be public, and not defined directly on Object. If it expects
|
||||
* more than one parameter, at most one of them may expect the payload
|
||||
* object. Others must be annotated for accepting Message header values.
|
||||
*/
|
||||
public static boolean isValidHandlerMethod(Method method) {
|
||||
if (isMethodDefinedOnObjectClass(method)) {
|
||||
return false;
|
||||
}
|
||||
if (!Modifier.isPublic(method.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length > 1) {
|
||||
// at most one parameter can be expecting a Message or payload.
|
||||
boolean foundPayloadParam = false;
|
||||
Annotation[][] allParamAnnotations = method.getParameterAnnotations();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
Class<?> currentType = parameterTypes[i];
|
||||
Annotation[] paramAnnotations = allParamAnnotations[i];
|
||||
// it's possible that a Map is the payload type at runtime, but we can't know that here
|
||||
if (!containsHeaderAnnotation(paramAnnotations) && !Map.class.isAssignableFrom(currentType)) {
|
||||
if (foundPayloadParam) {
|
||||
return false;
|
||||
}
|
||||
foundPayloadParam = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Method[] getCandidateHandlerMethods(Object object) {
|
||||
final List<Method> candidates = new ArrayList<Method>();
|
||||
Class<?> clazz = AopUtils.getTargetClass(object);
|
||||
if (clazz == null) {
|
||||
clazz = object.getClass();
|
||||
}
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (HandlerMethodUtils.isValidHandlerMethod(method)) {
|
||||
candidates.add(method);
|
||||
}
|
||||
}
|
||||
return candidates.toArray(new Method[candidates.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the array of Annotations for a method parameter to see if either
|
||||
* the @Header or @Headers annotation is present.
|
||||
*/
|
||||
public static boolean containsHeaderAnnotation(Annotation[] parameterAnnotations) {
|
||||
for (Annotation annotation : parameterAnnotations) {
|
||||
if (annotation.annotationType().equals(Header.class)
|
||||
|| annotation.annotationType().equals(Headers.class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isMethodDefinedOnObjectClass(Method method) {
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
if (method.getDeclaringClass().equals(Object.class)) {
|
||||
return true;
|
||||
}
|
||||
if (ReflectionUtils.isEqualsMethod(method) ||
|
||||
ReflectionUtils.isHashCodeMethod(method) ||
|
||||
ReflectionUtils.isToStringMethod(method) ||
|
||||
AopUtils.isFinalizeMethod(method)) {
|
||||
return true;
|
||||
}
|
||||
return (method.getName().equals("clone") && method.getParameterTypes().length == 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class HandlerMethodUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testNonProxyIgnoresMethodsFromObjectClass() {
|
||||
TestBean testBean = new TestBean();
|
||||
Method[] methods = HandlerMethodUtils.getCandidateHandlerMethods(testBean);
|
||||
assertEquals(2, methods.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDynamicProxyIgnoresMethodsFromObjectClass() {
|
||||
ProxyFactory pf = new ProxyFactory(TestInterface.class, new TestInterceptor());
|
||||
pf.setTarget(new TestBean());
|
||||
Object proxy = pf.getProxy();
|
||||
Method[] methods = HandlerMethodUtils.getCandidateHandlerMethods(proxy);
|
||||
assertEquals(2, methods.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCglibProxyIgnoresMethodsFromObjectClass() {
|
||||
ProxyFactory pf = new ProxyFactory(TestInterface.class, new TestInterceptor());
|
||||
pf.setTarget(new TestBean());
|
||||
pf.setProxyTargetClass(true);
|
||||
Object proxy = pf.getProxy();
|
||||
Method[] methods = HandlerMethodUtils.getCandidateHandlerMethods(proxy);
|
||||
assertEquals(2, methods.length);
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean implements TestInterface {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
|
||||
public void foo(String s) {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (this == o);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 23;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
public void finalize() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static interface TestInterface {
|
||||
void foo();
|
||||
}
|
||||
|
||||
|
||||
public static class TestInterceptor implements MethodInterceptor {
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
return invocation.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user