View Javadoc

1   /*
2    * Copyright 2005-2010 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.server.endpoint.adapter.method.dom;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.IOException;
21  import javax.xml.parsers.DocumentBuilder;
22  import javax.xml.parsers.DocumentBuilderFactory;
23  import javax.xml.parsers.ParserConfigurationException;
24  import javax.xml.transform.Source;
25  import javax.xml.transform.TransformerException;
26  import javax.xml.transform.dom.DOMSource;
27  
28  import org.springframework.core.MethodParameter;
29  import org.springframework.ws.server.endpoint.adapter.method.AbstractPayloadSourceMethodProcessor;
30  
31  import nu.xom.Builder;
32  import nu.xom.Document;
33  import nu.xom.Element;
34  import nu.xom.ParsingException;
35  import nu.xom.converters.DOMConverter;
36  import org.w3c.dom.DOMImplementation;
37  
38  /**
39   * Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
40   * MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
41   * MethodReturnValueHandler} that supports XOM {@linkplain Element elements}.
42   *
43   * @author Arjen Poutsma
44   * @since 2.0
45   */
46  public class XomPayloadMethodProcessor extends AbstractPayloadSourceMethodProcessor {
47  
48      private DocumentBuilderFactory documentBuilderFactory = createDocumentBuilderFactory();
49  
50      @Override
51      protected boolean supportsRequestPayloadParameter(MethodParameter parameter) {
52          return supports(parameter);
53      }
54  
55      @Override
56      protected Element resolveRequestPayloadArgument(MethodParameter parameter, Source requestPayload)
57              throws TransformerException, IOException, ParsingException {
58          if (requestPayload instanceof DOMSource) {
59              org.w3c.dom.Node node = ((DOMSource) requestPayload).getNode();
60              if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
61                  return DOMConverter.convert((org.w3c.dom.Element) node);
62              }
63              else if (node.getNodeType() == org.w3c.dom.Node.DOCUMENT_NODE) {
64                  Document document = DOMConverter.convert((org.w3c.dom.Document) node);
65                  return document.getRootElement();
66              }
67          }
68          // we have no other option than to transform
69          ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
70          Builder builder = new Builder();
71          Document document = builder.build(bis);
72          return document.getRootElement();
73      }
74  
75      @Override
76      protected boolean supportsResponsePayloadReturnType(MethodParameter returnType) {
77          return supports(returnType);
78      }
79  
80      @Override
81      protected Source createResponsePayload(MethodParameter returnType, Object returnValue)
82              throws ParserConfigurationException {
83          Element returnedElement = (Element) returnValue;
84          Document document = returnedElement.getDocument();
85          if (document == null) {
86              document = new Document(returnedElement);
87          }
88          DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
89          DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
90          org.w3c.dom.Document w3cDocument = DOMConverter.convert(document, domImplementation);
91          return new DOMSource(w3cDocument);
92      }
93  
94      private boolean supports(MethodParameter parameter) {
95          return Element.class.equals(parameter.getParameterType());
96      }
97  
98      /**
99       * Create a {@code DocumentBuilderFactory} that this resolver will use to create response payloads.
100      * <p/>
101      * Can be overridden in subclasses, adding further initialization of the factory. The resulting factory is cached,
102      * so this method will only be called once.
103      *
104      * @return the created factory
105      */
106     protected DocumentBuilderFactory createDocumentBuilderFactory() {
107         return DocumentBuilderFactory.newInstance();
108     }
109 
110 }