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