Added handler parsing.

This commit is contained in:
Mark Fisher
2007-12-18 16:33:22 +00:00
parent 88482aa129
commit e0424b7f4e
4 changed files with 85 additions and 19 deletions

View File

@@ -24,6 +24,7 @@ import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.endpoint.InboundMethodInvokingChannelAdapter;
import org.springframework.integration.endpoint.OutboundMethodInvokingChannelAdapter;
import org.springframework.util.StringUtils;
@@ -62,6 +63,7 @@ public class ChannelAdapterParser implements BeanDefinitionParser {
String ref = element.getAttribute(REF_ATTRIBUTE);
String method = element.getAttribute(METHOD_ATTRIBUTE);
if (!StringUtils.hasText(ref) || !StringUtils.hasText(method)) {
throw new MessagingConfigurationException("'ref' and 'method' are both required");
}
adapterDef.getPropertyValues().addPropertyValue("object", new RuntimeBeanReference(ref));
adapterDef.getPropertyValues().addPropertyValue("method", method);

View File

@@ -16,6 +16,9 @@
package org.springframework.integration.config;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -23,12 +26,15 @@ import org.w3c.dom.NodeList;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.bus.ConsumerPolicy;
import org.springframework.integration.endpoint.GenericMessageEndpoint;
import org.springframework.integration.handler.DefaultMessageHandlerAdapter;
import org.springframework.integration.handler.MessageHandlerChain;
import org.springframework.util.StringUtils;
/**
@@ -48,6 +54,14 @@ public class EndpointParser implements BeanDefinitionParser {
private static final String DEFAULT_OUTPUT_CHANNEL_PROPERTY = "defaultOutputChannelName";
private static final String HANDLER_ELEMENT = "handler";
private static final String REF_ATTRIBUTE = "ref";
private static final String METHOD_ATTRIBUTE = "method";
private static final String HANDLERS_PROPERTY = "handlers";
private static final String HANDLER_REF_ATTRIBUTE = "handler-ref";
private static final String HANDLER_METHOD_ATTRIBUTE = "handler-method";
@@ -78,25 +92,7 @@ public class EndpointParser implements BeanDefinitionParser {
if (StringUtils.hasText(defaultOutputChannel)) {
endpointDef.getPropertyValues().addPropertyValue(DEFAULT_OUTPUT_CHANNEL_PROPERTY, defaultOutputChannel);
}
String handlerRef = element.getAttribute(HANDLER_REF_ATTRIBUTE);
if (StringUtils.hasText(handlerRef)) {
String handlerMethod = element.getAttribute(HANDLER_METHOD_ATTRIBUTE);
if (StringUtils.hasText(handlerMethod)) {
BeanDefinition handlerAdapterDef = new RootBeanDefinition(DefaultMessageHandlerAdapter.class);
handlerAdapterDef.getPropertyValues().addPropertyValue(OBJECT_PROPERTY, new RuntimeBeanReference(handlerRef));
handlerAdapterDef.getPropertyValues().addPropertyValue(METHOD_NAME_PROPERTY, handlerMethod);
String adapterBeanName = parserContext.getReaderContext().generateBeanName(handlerAdapterDef);
parserContext.registerBeanComponent(new BeanComponentDefinition(handlerAdapterDef, adapterBeanName));
endpointDef.getPropertyValues().addPropertyValue(HANDLER_PROPERTY, new RuntimeBeanReference(adapterBeanName));
}
else {
endpointDef.getPropertyValues().addPropertyValue(HANDLER_PROPERTY, new RuntimeBeanReference(handlerRef));
}
}
String beanName = element.getAttribute(ID_ATTRIBUTE);
if (!StringUtils.hasText(beanName)) {
beanName = parserContext.getReaderContext().generateBeanName(endpointDef);
}
List<String> childHandlerRefs = new ArrayList<String>();
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
@@ -107,8 +103,49 @@ public class EndpointParser implements BeanDefinitionParser {
endpointDef.getPropertyValues().addPropertyValue(
CONSUMER_POLICY_PROPERTY, new RuntimeBeanReference(consumerBeanName));
}
else if (HANDLER_ELEMENT.equals(localName)) {
String ref = ((Element) child).getAttribute(REF_ATTRIBUTE);
String method = ((Element) child).getAttribute(METHOD_ATTRIBUTE);
childHandlerRefs.add(this.parseHandlerAdapter(ref, method, parserContext));
}
}
}
if (childHandlerRefs.size() > 0) {
if (childHandlerRefs.size() == 1) {
endpointDef.getPropertyValues().addPropertyValue(
HANDLER_PROPERTY, new RuntimeBeanReference(childHandlerRefs.get(0)));
}
else {
RootBeanDefinition handlerChainDef = new RootBeanDefinition(MessageHandlerChain.class);
List handlerList = new ManagedList();
for (String ref : childHandlerRefs) {
handlerList.add(new RuntimeBeanReference(ref));
}
handlerChainDef.getPropertyValues().addPropertyValue(HANDLERS_PROPERTY, handlerList);
String chainBeanName = parserContext.getReaderContext().generateBeanName(handlerChainDef);
parserContext.registerBeanComponent(new BeanComponentDefinition(handlerChainDef, chainBeanName));
endpointDef.getPropertyValues().addPropertyValue(HANDLER_PROPERTY, new RuntimeBeanReference(chainBeanName));
}
}
String handlerRef = element.getAttribute(HANDLER_REF_ATTRIBUTE);
if (StringUtils.hasText(handlerRef)) {
if (childHandlerRefs.size() > 0) {
throw new MessagingConfigurationException(
"The 'handler-ref' attribute is only supported when no 'handler' child elements are present");
}
String handlerMethod = element.getAttribute(HANDLER_METHOD_ATTRIBUTE);
if (StringUtils.hasText(handlerMethod)) {
String adapterBeanName = this.parseHandlerAdapter(handlerRef, handlerMethod, parserContext);
endpointDef.getPropertyValues().addPropertyValue(HANDLER_PROPERTY, new RuntimeBeanReference(adapterBeanName));
}
else {
endpointDef.getPropertyValues().addPropertyValue(HANDLER_PROPERTY, new RuntimeBeanReference(handlerRef));
}
}
String beanName = element.getAttribute(ID_ATTRIBUTE);
if (!StringUtils.hasText(beanName)) {
beanName = parserContext.getReaderContext().generateBeanName(endpointDef);
}
parserContext.registerBeanComponent(new BeanComponentDefinition(endpointDef, beanName));
return endpointDef;
}
@@ -124,4 +161,13 @@ public class EndpointParser implements BeanDefinitionParser {
return beanName;
}
private String parseHandlerAdapter(String handlerRef, String handlerMethod, ParserContext parserContext) {
BeanDefinition handlerAdapterDef = new RootBeanDefinition(DefaultMessageHandlerAdapter.class);
handlerAdapterDef.getPropertyValues().addPropertyValue(OBJECT_PROPERTY, new RuntimeBeanReference(handlerRef));
handlerAdapterDef.getPropertyValues().addPropertyValue(METHOD_NAME_PROPERTY, handlerMethod);
String adapterBeanName = parserContext.getReaderContext().generateBeanName(handlerAdapterDef);
parserContext.registerBeanComponent(new BeanComponentDefinition(handlerAdapterDef, adapterBeanName));
return adapterBeanName;
}
}

View File

@@ -97,6 +97,7 @@
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element ref="consumer" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="handler" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="input-channel" type="xsd:string"/>
<xsd:attribute name="default-output-channel" type="xsd:string"/>
@@ -118,4 +119,16 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="handler">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines a handler.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="ref" type="xsd:string" use="required"/>
<xsd:attribute name="method" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -46,6 +46,11 @@ public class MessageHandlerChain implements MessageHandler {
this.handlers.add(index, handler);
}
public void setHandlers(List<MessageHandler> handlers) {
this.handlers.clear();
this.handlers.addAll(handlers);
}
public Message handle(Message message) {
for (MessageHandler next : handlers) {
message = next.handle(message);