Both "source-endpoint" and "target-endpoint" elements are now configured as <channel-adapter/>. That element requires exactly one of "source" or "target" and optionally accepts a "method" attribute for creating either a MethodInvokingSource or a MethodInvokingTarget (INT-277).
This commit is contained in:
@@ -18,26 +18,38 @@ package org.springframework.integration.config;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
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.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.endpoint.SourceEndpoint;
|
||||
import org.springframework.integration.endpoint.TargetEndpoint;
|
||||
import org.springframework.integration.handler.MethodInvokingTarget;
|
||||
import org.springframework.integration.message.MethodInvokingSource;
|
||||
import org.springframework.integration.scheduling.PollingSchedule;
|
||||
import org.springframework.integration.scheduling.Schedule;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <source-endpoint/> element.
|
||||
* Parser for the <channel-adapter/> element.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class ChannelAdapterParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
protected final Class<?> getBeanClass(Element element) {
|
||||
return SourceEndpoint.class;
|
||||
boolean hasSource = StringUtils.hasText(element.getAttribute("source"));
|
||||
boolean hasTarget = StringUtils.hasText(element.getAttribute("target"));
|
||||
if (!(hasSource ^ hasTarget)) {
|
||||
throw new ConfigurationException("exactly one of 'source' or 'target' is required");
|
||||
}
|
||||
return hasSource ? SourceEndpoint.class : TargetEndpoint.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
@@ -49,21 +61,31 @@ public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser {
|
||||
}
|
||||
|
||||
protected boolean isEligibleAttribute(String name) {
|
||||
return (!"source".equals(name) && !"channel".equals(name) && super.isEligibleAttribute(name));
|
||||
return (!"source".equals(name)
|
||||
&& !"target".equals(name)
|
||||
&& !"channel".equals(name)
|
||||
&& super.isEligibleAttribute(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String source = element.getAttribute("source");
|
||||
if (!StringUtils.hasText(source)) {
|
||||
throw new ConfigurationException("'source' is required");
|
||||
}
|
||||
String output = element.getAttribute("channel");
|
||||
if (!StringUtils.hasText(output)) {
|
||||
String target = element.getAttribute("target");
|
||||
String channel = element.getAttribute("channel");
|
||||
if (!StringUtils.hasText(channel)) {
|
||||
throw new ConfigurationException("'channel' is required");
|
||||
}
|
||||
builder.addConstructorArgReference(source);
|
||||
builder.addPropertyValue("outputChannelName", output);
|
||||
boolean isSource = StringUtils.hasText(source);
|
||||
if (isSource) {
|
||||
builder.addConstructorArgReference(this.resolveConstructorArgument(
|
||||
source, MethodInvokingSource.class, element, parserContext));
|
||||
builder.addPropertyValue("outputChannelName", channel);
|
||||
}
|
||||
else {
|
||||
builder.addConstructorArgReference(this.resolveConstructorArgument(
|
||||
target, MethodInvokingTarget.class, element, parserContext));
|
||||
builder.addPropertyValue("inputChannelName", channel);
|
||||
}
|
||||
Element scheduleElement = DomUtils.getChildElementByTagName(element, "schedule");
|
||||
if (scheduleElement != null) {
|
||||
builder.addPropertyValue("schedule", this.parseSchedule(scheduleElement));
|
||||
@@ -76,6 +98,19 @@ public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveConstructorArgument(String ref, Class<?> targetClass, Element element, ParserContext parserContext) {
|
||||
String method = element.getAttribute("method");
|
||||
if (StringUtils.hasText(method)) {
|
||||
BeanDefinition adapterDef = new RootBeanDefinition(targetClass);
|
||||
adapterDef.getPropertyValues().addPropertyValue("object", new RuntimeBeanReference(ref));
|
||||
adapterDef.getPropertyValues().addPropertyValue("methodName", method);
|
||||
String adapterBeanName = parserContext.getReaderContext().generateBeanName(adapterDef);
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(adapterDef, adapterBeanName));
|
||||
return adapterBeanName;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to control the creation of the {@link Schedule}. The default
|
||||
* implementation creates a {@link PollingSchedule} instance based on the provided "period" attribute.
|
||||
@@ -64,11 +64,8 @@ public class IntegrationNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("priority-channel", new PriorityChannelParser());
|
||||
registerBeanDefinitionParser("rendezvous-channel", new RendezvousChannelParser());
|
||||
registerBeanDefinitionParser("thread-local-channel", new ThreadLocalChannelParser());
|
||||
registerBeanDefinitionParser("source-adapter", new MethodInvokingAdapterParser());
|
||||
registerBeanDefinitionParser("target-adapter", new MethodInvokingAdapterParser());
|
||||
registerBeanDefinitionParser("source-endpoint", new SourceEndpointParser());
|
||||
registerBeanDefinitionParser("handler-endpoint", new HandlerEndpointParser());
|
||||
registerBeanDefinitionParser("target-endpoint", new TargetEndpointParser());
|
||||
registerBeanDefinitionParser("channel-adapter", new ChannelAdapterParser());
|
||||
registerBeanDefinitionParser("gateway", new GatewayParser());
|
||||
registerBeanDefinitionParser("handler", new HandlerParser());
|
||||
registerBeanDefinitionParser("handler-chain", new HandlerParser());
|
||||
|
||||
@@ -168,58 +168,30 @@
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="source-endpoint">
|
||||
<xsd:element name="channel-adapter">
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a source endpoint.
|
||||
Defines a Channel Adapter that is capable of either receiving from a MessageSource and sending
|
||||
the result to a MessageChannel or receiving from a MessageChannel and sending the result to a
|
||||
MessageTarget. Therefore, either "source" or "target" should be provided (but never both).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="schedule" minOccurs="1" maxOccurs="1"/>
|
||||
<xsd:all>
|
||||
<xsd:element ref="schedule" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="interceptors" type="interceptorsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="source" type="xsd:string" use="required"/>
|
||||
</xsd:all>
|
||||
<xsd:attribute name="source" type="xsd:string"/>
|
||||
<xsd:attribute name="target" type="xsd:string"/>
|
||||
<xsd:attribute name="method" type="xsd:string"/>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="source-adapter" type="methodInvokingAdapterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a MethodInvokingSource.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="target-endpoint">
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a target endpoint.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="targetEndpointType">
|
||||
<xsd:attribute name="target" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="method" type="xsd:string"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="target-adapter" type="methodInvokingAdapterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a MethodInvokingTarget.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="handler-endpoint">
|
||||
<xsd:complexType>
|
||||
<xsd:annotation>
|
||||
@@ -228,10 +200,16 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="targetEndpointType">
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:all>
|
||||
<xsd:element ref="schedule" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="interceptors" type="interceptorsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:all>
|
||||
<xsd:attribute name="handler" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="method" type="xsd:string"/>
|
||||
<xsd:attribute name="input-channel" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="output-channel" type="xsd:string"/>
|
||||
<xsd:attribute name="selector" type="xsd:string"/>
|
||||
<xsd:attribute name="reply-handler" type="xsd:string"/>
|
||||
<xsd:attribute name="return-address-overrides" type="xsd:boolean" default="false"/>
|
||||
</xsd:extension>
|
||||
@@ -417,38 +395,6 @@
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="targetEndpointType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines common configuration properties of target message endpoints.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:all>
|
||||
<xsd:element ref="schedule" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="interceptors" type="interceptorsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:all>
|
||||
<xsd:attribute name="input-channel" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="selector" type="xsd:string"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="methodInvokingAdapterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Base type for method-invoking adapters.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:attribute name="ref" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="method" type="xsd:string" use="required"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="interceptorsType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
Reference in New Issue
Block a user