View Javadoc

1   /*
2    * Copyright 2008 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.soap.axiom;
18  
19  import java.io.ByteArrayOutputStream;
20  import javax.xml.namespace.NamespaceContext;
21  import javax.xml.namespace.QName;
22  import javax.xml.stream.XMLStreamException;
23  import javax.xml.stream.XMLStreamReader;
24  import javax.xml.stream.XMLStreamWriter;
25  import javax.xml.transform.Result;
26  
27  import org.apache.axiom.om.OMDataSource;
28  import org.apache.axiom.om.OMElement;
29  import org.apache.axiom.om.OMNamespace;
30  import org.apache.axiom.om.ds.ByteArrayDataSource;
31  import org.apache.axiom.om.util.StAXUtils;
32  import org.apache.axiom.soap.SOAPBody;
33  import org.apache.axiom.soap.SOAPFactory;
34  
35  import org.springframework.xml.transform.StaxResult;
36  
37  /**
38   * Non-caching payload in Axiom.
39   *
40   * @author Jim Cummings
41   * @author Arjen Poutsma
42   * @since 1.5.2
43   */
44  class NonCachingPayload extends Payload {
45  
46      private static final int BUF_SIZE = 1024;
47  
48      NonCachingPayload(SOAPBody axiomBody, SOAPFactory axiomFactory) {
49          super(axiomBody, axiomFactory);
50      }
51  
52      public Result getResultInternal() {
53          return new StaxResult(new DelegatingStreamWriter());
54      }
55  
56      protected XMLStreamReader getStreamReader(OMElement payloadElement) {
57          return payloadElement.getXMLStreamReaderWithoutCaching();
58      }
59  
60      private class DelegatingStreamWriter implements XMLStreamWriter {
61  
62          private final ByteArrayOutputStream baos = new ByteArrayOutputStream(BUF_SIZE);
63  
64          private final XMLStreamWriter delegate;
65  
66          private QName name;
67  
68          private String encoding = "UTF-8";
69  
70          private int elementDepth = 0;
71  
72          private boolean payloadAdded = false;
73  
74          private DelegatingStreamWriter() {
75              try {
76                  this.delegate = StAXUtils.createXMLStreamWriter(baos);
77              }
78              catch (XMLStreamException ex) {
79                  throw new AxiomSoapBodyException("Could not determine payload root element", ex);
80              }
81          }
82  
83          public void writeStartDocument() throws XMLStreamException {
84              // ignored
85          }
86  
87          public void writeStartDocument(String version) throws XMLStreamException {
88              // ignored
89          }
90  
91          public void writeStartDocument(String encoding, String version) throws XMLStreamException {
92              this.encoding = encoding;
93          }
94  
95          public void writeStartElement(String localName) throws XMLStreamException {
96              if (name == null) {
97                  name = new QName(localName);
98              }
99              elementDepth++;
100             delegate.writeStartElement(localName);
101         }
102 
103         public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
104             if (name == null) {
105                 name = new QName(namespaceURI, localName);
106             }
107             elementDepth++;
108             delegate.writeStartElement(namespaceURI, localName);
109         }
110 
111         public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
112             if (name == null) {
113                 name = new QName(namespaceURI, localName, prefix);
114             }
115             elementDepth++;
116             delegate.writeStartElement(prefix, localName, namespaceURI);
117         }
118 
119         public void writeEndElement() throws XMLStreamException {
120             elementDepth--;
121             delegate.writeEndElement();
122             addPayload();
123         }
124 
125         private void addPayload() throws XMLStreamException {
126             if (elementDepth <= 0 && !payloadAdded) {
127                 delegate.flush();
128                 if (baos.size() > 0) {
129                     byte[] buf = baos.toByteArray();
130                     OMDataSource dataSource = new ByteArrayDataSource(buf, encoding);
131                     OMNamespace namespace =
132                             getAxiomFactory().createOMNamespace(name.getNamespaceURI(), name.getPrefix());
133                     OMElement payloadElement =
134                             getAxiomFactory().createOMElement(dataSource, name.getLocalPart(), namespace);
135                     getAxiomBody().addChild(payloadElement);
136                     payloadAdded = true;
137                 }
138             }
139         }
140 
141         public void writeEmptyElement(String localName) throws XMLStreamException {
142             if (name == null) {
143                 name = new QName(localName);
144             }
145             delegate.writeEmptyElement(localName);
146             addPayload();
147         }
148 
149         public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
150             if (name == null) {
151                 name = new QName(namespaceURI, localName);
152             }
153             delegate.writeEmptyElement(namespaceURI, localName);
154             addPayload();
155         }
156 
157         public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
158             if (name == null) {
159                 name = new QName(namespaceURI, localName, prefix);
160             }
161             delegate.writeEmptyElement(prefix, localName, namespaceURI);
162             addPayload();
163         }
164 
165         public void writeEndDocument() throws XMLStreamException {
166             elementDepth = 0;
167             delegate.writeEndDocument();
168             addPayload();
169         }
170 
171         // Delegation
172 
173         public void close() throws XMLStreamException {
174             addPayload();
175             delegate.close();
176         }
177 
178         public void flush() throws XMLStreamException {
179             delegate.flush();
180         }
181 
182         public NamespaceContext getNamespaceContext() {
183             return delegate.getNamespaceContext();
184         }
185 
186         public String getPrefix(String uri) throws XMLStreamException {
187             return delegate.getPrefix(uri);
188         }
189 
190         public Object getProperty(String name) throws IllegalArgumentException {
191             return delegate.getProperty(name);
192         }
193 
194         public void setDefaultNamespace(String uri) throws XMLStreamException {
195             delegate.setDefaultNamespace(uri);
196         }
197 
198         public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
199             delegate.setNamespaceContext(context);
200         }
201 
202         public void setPrefix(String prefix, String uri) throws XMLStreamException {
203             delegate.setPrefix(prefix, uri);
204         }
205 
206         public void writeAttribute(String localName, String value) throws XMLStreamException {
207             delegate.writeAttribute(localName, value);
208         }
209 
210         public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
211             delegate.writeAttribute(namespaceURI, localName, value);
212         }
213 
214         public void writeAttribute(String prefix, String namespaceURI, String localName, String value)
215                 throws XMLStreamException {
216             delegate.writeAttribute(prefix, namespaceURI, localName, value);
217         }
218 
219         public void writeCData(String data) throws XMLStreamException {
220             delegate.writeCData(data);
221         }
222 
223         public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
224             delegate.writeCharacters(text, start, len);
225         }
226 
227         public void writeCharacters(String text) throws XMLStreamException {
228             delegate.writeCharacters(text);
229         }
230 
231         public void writeComment(String data) throws XMLStreamException {
232             delegate.writeComment(data);
233         }
234 
235         public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
236             delegate.writeDefaultNamespace(namespaceURI);
237         }
238 
239         public void writeDTD(String dtd) throws XMLStreamException {
240             delegate.writeDTD(dtd);
241         }
242 
243         public void writeEntityRef(String name) throws XMLStreamException {
244             delegate.writeEntityRef(name);
245         }
246 
247         public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
248             delegate.writeNamespace(prefix, namespaceURI);
249         }
250 
251         public void writeProcessingInstruction(String target) throws XMLStreamException {
252             delegate.writeProcessingInstruction(target);
253         }
254 
255         public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
256             delegate.writeProcessingInstruction(target, data);
257         }
258 
259     }
260 }