SWS-684 - Added support for <ref> elements inside the <interceptors> element

This commit is contained in:
Tareq Abedrabbo
2011-02-03 12:35:38 +00:00
parent b1eefff62e
commit eb54ee8e7c
4 changed files with 109 additions and 7 deletions

View File

@@ -20,11 +20,14 @@ import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.ws.server.SmartEndpointInterceptor;
import org.springframework.ws.soap.server.endpoint.interceptor.DelegatingSmartSoapEndpointInterceptor;
@@ -58,7 +61,20 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
else if ("ref".equals(childElement.getLocalName())) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(DelegatingSmartSoapEndpointInterceptor.class, childElement,
parserContext);
BeanReference interceptorRef = createInterceptorReference(parserContext, childElement);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
else if ("payloadRoot".equals(childElement.getLocalName())) {
// bean elements
List<Element> beanElements = DomUtils.getChildElementsByTagName(childElement, "bean");
for (Element beanElement : beanElements) {
RootBeanDefinition smartInterceptorDef =
@@ -75,8 +91,27 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
// ref elements
List<Element> refElements = DomUtils.getChildElementsByTagName(childElement, "ref");
for (Element refElement : refElements) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class, childElement,
parserContext);
BeanReference interceptorRef = createInterceptorReference(parserContext, refElement);
String namespaceUri = childElement.getAttribute("namespaceUri");
String localPart = childElement.getAttribute("localPart");
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
}
else if ("soapAction".equals(childElement.getLocalName())) {
// bean elements
List<Element> beanElements = DomUtils.getChildElementsByTagName(childElement, "bean");
for (Element beanElement : beanElements) {
RootBeanDefinition smartInterceptorDef =
@@ -91,6 +126,22 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
// ref elements
List<Element> refElements = DomUtils.getChildElementsByTagName(childElement, "ref");
for (Element refElement : refElements) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement,
parserContext);
BeanReference interceptorRef = createInterceptorReference(parserContext, refElement);
String soapAction = childElement.getAttribute("value");
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
}
}
@@ -113,6 +164,26 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
return interceptorDef;
}
private BeanReference createInterceptorReference(ParserContext parserContext, Element element) {
// A generic reference to any name of any bean.
String refName = element.getAttribute("bean");
if (!StringUtils.hasLength(refName)) {
// A reference to the id of another bean in the same XML file.
refName = element.getAttribute("local");
if (!StringUtils.hasLength(refName)) {
error(parserContext, "Either 'bean' or 'local' is required for <ref> element", element);
return null;
}
}
if (!StringUtils.hasText(refName)) {
error(parserContext, "<ref> element contains empty target attribute", element);
return null;
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(parserContext.extractSource(element));
return ref;
}
private RootBeanDefinition createSmartInterceptorDefinition(Class<? extends SmartEndpointInterceptor> interceptorClass,
Element element,
ParserContext parserContext) {
@@ -122,4 +193,7 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
return smartInterceptorDef;
}
private void error(ParserContext parserContext, String message, Object source) {
parserContext.getDelegate().getReaderContext().error(message, source);
}
}

View File

@@ -71,6 +71,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor">
Registers a reference to an interceptor that intercepts every request.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="payloadRoot">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor"><![CDATA[
@@ -79,13 +86,20 @@
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation>The interceptor's bean definition.</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation>
The interceptor's bean reference.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:attribute name="namespaceUri" type="xsd:anyURI" use="required" />
<xsd:attribute name="localPart" type="xsd:anyURI" />
</xsd:complexType>
@@ -97,13 +111,20 @@
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation>The interceptor's bean definition.</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation>
The interceptor's bean reference.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:attribute name="value" type="xsd:anyURI" use="required" />
</xsd:complexType>
</xsd:element>

View File

@@ -41,13 +41,13 @@ public class InterceptorsBeanDefinitionParserTest {
@Test
public void namespace() throws Exception {
Map<String, ?> result = applicationContext.getBeansOfType(DelegatingSmartEndpointInterceptor.class);
assertEquals("no smart interceptors found", 5, result.size());
assertEquals("no smart interceptors found", 8, result.size());
result = applicationContext.getBeansOfType(PayloadRootSmartSoapEndpointInterceptor.class);
assertEquals("no interceptors found", 2, result.size());
assertEquals("no interceptors found", 3, result.size());
result = applicationContext.getBeansOfType(SoapActionSmartEndpointInterceptor.class);
assertEquals("no interceptors found", 2, result.size());
assertEquals("no interceptors found", 3, result.size());
}
}

View File

@@ -7,16 +7,23 @@
<sws:interceptors>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<ref bean="externalGlobalInterceptor"/>
<sws:payloadRoot namespaceUri="http://www.springframework.org/spring-ws">
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<ref bean="externalPayloadRootInterceptor"/>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</sws:payloadRoot>
<sws:soapAction value="mySoapAction">
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<ref local="externalSoapActionInterceptor"/>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</sws:soapAction>
</sws:interceptors>
<bean id="externalGlobalInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean id="externalPayloadRootInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean id="externalSoapActionInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</beans>