src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/impl/EnvelopeImpl.java

changeset 286
f50545b5e2f1
child 368
0989ad8c0860
equal deleted inserted replaced
284:88b85470e72c 286:f50545b5e2f1
1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.xml.internal.messaging.saaj.soap.impl;
27
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.io.OutputStreamWriter;
31
32 import java.util.Iterator;
33 import java.util.logging.Level;
34 import org.w3c.dom.Document;
35
36 import javax.xml.namespace.QName;
37 import javax.xml.soap.*;
38 import javax.xml.transform.*;
39 import javax.xml.transform.dom.DOMSource;
40 import javax.xml.transform.stream.StreamResult;
41 import javax.xml.transform.sax.*;
42
43 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
44 import com.sun.xml.internal.messaging.saaj.soap.Envelope;
45 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
46 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
47 import com.sun.xml.internal.messaging.saaj.util.FastInfosetReflection;
48 import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer;
49
50 /**
51 * Our implementation of the SOAP envelope.
52 *
53 * @author Anil Vijendran (anil@sun.com)
54 */
55 public abstract class EnvelopeImpl extends ElementImpl implements Envelope {
56 protected HeaderImpl header;
57 protected BodyImpl body;
58 String omitXmlDecl = "yes";
59 String charset = "utf-8";
60 String xmlDecl = null;
61
62 protected EnvelopeImpl(SOAPDocumentImpl ownerDoc, Name name) {
63 super(ownerDoc, name);
64 }
65
66 protected EnvelopeImpl(SOAPDocumentImpl ownerDoc, QName name) {
67 super(ownerDoc, name);
68 }
69
70 protected EnvelopeImpl(
71 SOAPDocumentImpl ownerDoc,
72 NameImpl name,
73 boolean createHeader,
74 boolean createBody)
75 throws SOAPException {
76 this(ownerDoc, name);
77
78 ensureNamespaceIsDeclared(
79 getElementQName().getPrefix(), getElementQName().getNamespaceURI());
80
81 // XXX
82 if (createHeader)
83 addHeader();
84
85 if (createBody)
86 addBody();
87 }
88
89 protected abstract NameImpl getHeaderName(String prefix);
90 protected abstract NameImpl getBodyName(String prefix);
91
92 public SOAPHeader addHeader() throws SOAPException {
93 return addHeader(null);
94 }
95
96 public SOAPHeader addHeader(String prefix) throws SOAPException {
97
98 if (prefix == null || prefix.equals("")) {
99 prefix = getPrefix();
100 }
101
102 NameImpl headerName = getHeaderName(prefix);
103 NameImpl bodyName = getBodyName(prefix);
104
105 HeaderImpl header = null;
106 SOAPElement firstChild = null;
107
108 Iterator eachChild = getChildElementNodes();
109 if (eachChild.hasNext()) {
110 firstChild = (SOAPElement) eachChild.next();
111 if (firstChild.getElementName().equals(headerName)) {
112 log.severe("SAAJ0120.impl.header.already.exists");
113 throw new SOAPExceptionImpl("Can't add a header when one is already present.");
114 } else if (!firstChild.getElementName().equals(bodyName)) {
115 log.severe("SAAJ0121.impl.invalid.first.child.of.envelope");
116 throw new SOAPExceptionImpl("First child of Envelope must be either a Header or Body");
117 }
118 }
119
120 header = (HeaderImpl) createElement(headerName);
121 insertBefore(header, firstChild);
122 header.ensureNamespaceIsDeclared(headerName.getPrefix(), headerName.getURI());
123
124 return header;
125 }
126
127 protected void lookForHeader() throws SOAPException {
128 NameImpl headerName = getHeaderName(null);
129
130 HeaderImpl hdr = (HeaderImpl) findChild(headerName);
131 header = hdr;
132 }
133
134 public SOAPHeader getHeader() throws SOAPException {
135 lookForHeader();
136 return header;
137 }
138
139 protected void lookForBody() throws SOAPException {
140 NameImpl bodyName = getBodyName(null);
141
142 BodyImpl bodyChildElement = (BodyImpl) findChild(bodyName);
143 body = bodyChildElement;
144 }
145
146 public SOAPBody addBody() throws SOAPException {
147 return addBody(null);
148 }
149
150 public SOAPBody addBody(String prefix) throws SOAPException {
151 lookForBody();
152
153 if (prefix == null || prefix.equals("")) {
154 prefix = getPrefix();
155 }
156
157 if (body == null) {
158 NameImpl bodyName = getBodyName(prefix);
159 body = (BodyImpl) createElement(bodyName);
160 insertBefore(body, null);
161 body.ensureNamespaceIsDeclared(bodyName.getPrefix(), bodyName.getURI());
162 } else {
163 log.severe("SAAJ0122.impl.body.already.exists");
164 throw new SOAPExceptionImpl("Can't add a body when one is already present.");
165 }
166
167 return body;
168 }
169
170 protected SOAPElement addElement(Name name) throws SOAPException {
171 if (getBodyName(null).equals(name)) {
172 return addBody(name.getPrefix());
173 }
174 if (getHeaderName(null).equals(name)) {
175 return addHeader(name.getPrefix());
176 }
177
178 return super.addElement(name);
179 }
180
181 protected SOAPElement addElement(QName name) throws SOAPException {
182 if (getBodyName(null).equals(NameImpl.convertToName(name))) {
183 return addBody(name.getPrefix());
184 }
185 if (getHeaderName(null).equals(NameImpl.convertToName(name))) {
186 return addHeader(name.getPrefix());
187 }
188
189 return super.addElement(name);
190 }
191
192 public SOAPBody getBody() throws SOAPException {
193 lookForBody();
194 return body;
195 }
196
197 public Source getContent() {
198 return new DOMSource(getOwnerDocument());
199 }
200
201 public Name createName(String localName, String prefix, String uri)
202 throws SOAPException {
203
204 // validating parameters before passing them on
205 // to make sure that the namespace specification rules are followed
206
207 // reserved xmlns prefix cannot be used.
208 if ("xmlns".equals(prefix)) {
209 log.severe("SAAJ0123.impl.no.reserved.xmlns");
210 throw new SOAPExceptionImpl("Cannot declare reserved xmlns prefix");
211 }
212 // Qualified name cannot be xmlns.
213 if ((prefix == null) && ("xmlns".equals(localName))) {
214 log.severe("SAAJ0124.impl.qualified.name.cannot.be.xmlns");
215 throw new SOAPExceptionImpl("Qualified name cannot be xmlns");
216 }
217
218 return NameImpl.create(localName, prefix, uri);
219 }
220
221 public Name createName(String localName, String prefix)
222 throws SOAPException {
223 String namespace = getNamespaceURI(prefix);
224 if (namespace == null) {
225 log.log(
226 Level.SEVERE,
227 "SAAJ0126.impl.cannot.locate.ns",
228 new String[] { prefix });
229 throw new SOAPExceptionImpl(
230 "Unable to locate namespace for prefix " + prefix);
231 }
232 return NameImpl.create(localName, prefix, namespace);
233 }
234
235 public Name createName(String localName) throws SOAPException {
236 return NameImpl.createFromUnqualifiedName(localName);
237 }
238
239 public void setOmitXmlDecl(String value) {
240 this.omitXmlDecl = value;
241 }
242
243 public void setXmlDecl(String value) {
244 this.xmlDecl = value;
245 }
246
247 private String getOmitXmlDecl() {
248 return this.omitXmlDecl;
249 }
250
251 public void setCharsetEncoding(String value) {
252 charset = value;
253 }
254
255 public void output(OutputStream out) throws IOException {
256 try {
257 Transformer transformer =
258 EfficientStreamingTransformer.newTransformer();
259
260 transformer.setOutputProperty(
261 OutputKeys.OMIT_XML_DECLARATION, "yes");
262 /*omitXmlDecl);*/
263 // no equivalent for "setExpandEmptyElements"
264 transformer.setOutputProperty(
265 OutputKeys.ENCODING,
266 charset);
267
268 if (omitXmlDecl.equals("no") && xmlDecl == null) {
269 xmlDecl = "<?xml version=\"" + getOwnerDocument().getXmlVersion() + "\" encoding=\"" +
270 charset + "\" ?>";
271 }
272
273 StreamResult result = new StreamResult(out);
274 if (xmlDecl != null) {
275 OutputStreamWriter writer = new OutputStreamWriter(out, charset);
276 writer.write(xmlDecl);
277 writer.flush();
278 result = new StreamResult(writer);
279 }
280
281
282 log.log(
283 Level.FINE,
284 "SAAJ0190.impl.set.xml.declaration",
285 new String[] { omitXmlDecl });
286 log.log(
287 Level.FINE,
288 "SAAJ0191.impl.set.encoding",
289 new String[] { charset });
290
291 //StreamResult result = new StreamResult(out);
292 transformer.transform(getContent(), result);
293 } catch (Exception ex) {
294 throw new IOException(ex.getMessage());
295 }
296 }
297
298 /**
299 * Serialize to FI if boolean parameter set.
300 */
301 public void output(OutputStream out, boolean isFastInfoset)
302 throws IOException
303 {
304 if (!isFastInfoset) {
305 output(out);
306 }
307 else {
308 try {
309 // Run transform and generate FI output from content
310 Source source = getContent();
311 Transformer transformer = EfficientStreamingTransformer.newTransformer();
312 transformer.transform(getContent(),
313 FastInfosetReflection.FastInfosetResult_new(out));
314 }
315 catch (Exception ex) {
316 throw new IOException(ex.getMessage());
317 }
318 }
319 }
320
321 // public void prettyPrint(OutputStream out) throws IOException {
322 // if (getDocument() == null)
323 // initDocument();
324 //
325 // OutputFormat format = OutputFormat.createPrettyPrint();
326 //
327 // format.setIndentSize(2);
328 // format.setNewlines(true);
329 // format.setTrimText(true);
330 // format.setPadText(true);
331 // format.setExpandEmptyElements(false);
332 //
333 // XMLWriter writer = new XMLWriter(out, format);
334 // writer.write(getDocument());
335 // }
336 //
337 // public void prettyPrint(Writer out) throws IOException {
338 // if (getDocument() == null)
339 // initDocument();
340 //
341 // OutputFormat format = OutputFormat.createPrettyPrint();
342 //
343 // format.setIndentSize(2);
344 // format.setNewlines(true);
345 // format.setTrimText(true);
346 // format.setPadText(true);
347 // format.setExpandEmptyElements(false);
348 //
349 // XMLWriter writer = new XMLWriter(out, format);
350 // writer.write(getDocument());
351 // }
352
353
354 public SOAPElement setElementQName(QName newName) throws SOAPException {
355 log.log(Level.SEVERE,
356 "SAAJ0146.impl.invalid.name.change.requested",
357 new Object[] {elementQName.getLocalPart(),
358 newName.getLocalPart()});
359 throw new SOAPException("Cannot change name for "
360 + elementQName.getLocalPart() + " to "
361 + newName.getLocalPart());
362 }
363 }

mercurial