View Javadoc

1   /*
2    * Copyright 2005-2011 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.config;
18  
19  import java.util.List;
20  
21  import org.springframework.beans.factory.config.BeanDefinition;
22  import org.springframework.beans.factory.config.BeanDefinitionHolder;
23  import org.springframework.beans.factory.config.BeanReference;
24  import org.springframework.beans.factory.config.RuntimeBeanReference;
25  import org.springframework.beans.factory.parsing.BeanComponentDefinition;
26  import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
27  import org.springframework.beans.factory.support.RootBeanDefinition;
28  import org.springframework.beans.factory.xml.BeanDefinitionParser;
29  import org.springframework.beans.factory.xml.ParserContext;
30  import org.springframework.util.StringUtils;
31  import org.springframework.util.xml.DomUtils;
32  import org.springframework.ws.server.SmartEndpointInterceptor;
33  import org.springframework.ws.soap.server.endpoint.interceptor.DelegatingSmartSoapEndpointInterceptor;
34  import org.springframework.ws.soap.server.endpoint.interceptor.PayloadRootSmartSoapEndpointInterceptor;
35  import org.springframework.ws.soap.server.endpoint.interceptor.SoapActionSmartEndpointInterceptor;
36  
37  import org.w3c.dom.Element;
38  
39  /**
40   * Parser for the {@code <sws:interceptors/>} element.
41   *
42   * @author Arjen Poutsma
43   * @since 2.0
44   */
45  class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
46  
47      public BeanDefinition parse(Element element, ParserContext parserContext) {
48          CompositeComponentDefinition compDefinition =
49                  new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
50          parserContext.pushContainingComponent(compDefinition);
51  
52          List<Element> childElements = DomUtils.getChildElements(element);
53          for (Element childElement : childElements) {
54              if ("bean".equals(childElement.getLocalName())) {
55                  RootBeanDefinition smartInterceptorDef =
56                          createSmartInterceptorDefinition(DelegatingSmartSoapEndpointInterceptor.class, childElement,
57                                  parserContext);
58                  BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, childElement);
59  
60                  smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
61  
62                  registerSmartInterceptor(parserContext, smartInterceptorDef);
63              }
64              else if ("ref".equals(childElement.getLocalName())) {
65                  RootBeanDefinition smartInterceptorDef =
66                          createSmartInterceptorDefinition(DelegatingSmartSoapEndpointInterceptor.class, childElement,
67                                  parserContext);
68  
69                  BeanReference interceptorRef = createInterceptorReference(parserContext, childElement);
70  
71                  smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
72  
73                  registerSmartInterceptor(parserContext, smartInterceptorDef);
74  
75              }
76              else if ("payloadRoot".equals(childElement.getLocalName())) {
77                  List<Element> payloadRootChildren = DomUtils.getChildElements(childElement);
78                  for (Element payloadRootChild : payloadRootChildren) {
79                      if ("bean".equals(payloadRootChild.getLocalName())) {
80                          RootBeanDefinition smartInterceptorDef =
81                                  createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class,
82                                          childElement, parserContext);
83                          BeanDefinitionHolder interceptorDef =
84                                  createInterceptorDefinition(parserContext, payloadRootChild);
85  
86                          String namespaceUri = childElement.getAttribute("namespaceUri");
87                          String localPart = childElement.getAttribute("localPart");
88  
89                          smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
90                          smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri);
91                          smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart);
92  
93                          registerSmartInterceptor(parserContext, smartInterceptorDef);
94                      }
95                      else if ("ref".equals(payloadRootChild.getLocalName())) {
96                          RootBeanDefinition smartInterceptorDef =
97                                  createSmartInterceptorDefinition(PayloadRootSmartSoapEndpointInterceptor.class,
98                                          childElement, parserContext);
99                          BeanReference interceptorRef = createInterceptorReference(parserContext, payloadRootChild);
100 
101                         String namespaceUri = childElement.getAttribute("namespaceUri");
102                         String localPart = childElement.getAttribute("localPart");
103 
104                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
105                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri);
106                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart);
107 
108                         registerSmartInterceptor(parserContext, smartInterceptorDef);
109                     }
110                 }
111             }
112             else if ("soapAction".equals(childElement.getLocalName())) {
113                 List<Element> soapActionChildren = DomUtils.getChildElements(childElement);
114                 for (Element soapActionChild : soapActionChildren) {
115                     if ("bean".equals(soapActionChild.getLocalName())) {
116                         RootBeanDefinition smartInterceptorDef =
117                                 createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement,
118                                         parserContext);
119                         BeanDefinitionHolder interceptorDef =
120                                 createInterceptorDefinition(parserContext, soapActionChild);
121 
122                         String soapAction = childElement.getAttribute("value");
123 
124                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
125                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction);
126 
127                         registerSmartInterceptor(parserContext, smartInterceptorDef);
128                     }
129                     else if ("ref".equals(soapActionChild.getLocalName())) {
130                         RootBeanDefinition smartInterceptorDef =
131                                 createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement,
132                                         parserContext);
133                         BeanReference interceptorRef = createInterceptorReference(parserContext, soapActionChild);
134 
135                         String soapAction = childElement.getAttribute("value");
136 
137                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorRef);
138                         smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction);
139 
140                         registerSmartInterceptor(parserContext, smartInterceptorDef);
141                     }
142                 }
143             }
144         }
145 
146         parserContext.popAndRegisterContainingComponent();
147         return null;
148     }
149 
150     private void registerSmartInterceptor(ParserContext parserContext, RootBeanDefinition smartInterceptorDef) {
151         String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(smartInterceptorDef);
152         parserContext.registerComponent(new BeanComponentDefinition(smartInterceptorDef, mappedInterceptorName));
153     }
154 
155     private BeanDefinitionHolder createInterceptorDefinition(ParserContext parserContext, Element element) {
156         BeanDefinitionHolder interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(element);
157         interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(element, interceptorDef);
158         return interceptorDef;
159     }
160 
161     private BeanReference createInterceptorReference(ParserContext parserContext, Element element) {
162         // A generic reference to any name of any bean.
163         String refName = element.getAttribute("bean");
164         if (!StringUtils.hasLength(refName)) {
165             // A reference to the id of another bean in the same XML file.
166             refName = element.getAttribute("local");
167             if (!StringUtils.hasLength(refName)) {
168                 error(parserContext, "Either 'bean' or 'local' is required for <ref> element", element);
169                 return null;
170             }
171         }
172         if (!StringUtils.hasText(refName)) {
173             error(parserContext, "<ref> element contains empty target attribute", element);
174             return null;
175         }
176         RuntimeBeanReference ref = new RuntimeBeanReference(refName);
177         ref.setSource(parserContext.extractSource(element));
178         return ref;
179     }
180 
181     private RootBeanDefinition createSmartInterceptorDefinition(Class<? extends SmartEndpointInterceptor> interceptorClass,
182                                                                 Element element,
183                                                                 ParserContext parserContext) {
184         RootBeanDefinition smartInterceptorDef = new RootBeanDefinition(interceptorClass);
185         smartInterceptorDef.setSource(parserContext.extractSource(element));
186         smartInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
187         return smartInterceptorDef;
188     }
189 
190     private void error(ParserContext parserContext, String message, Object source) {
191         parserContext.getDelegate().getReaderContext().error(message, source);
192     }
193 }