001: /*
002: * $Id: EnvelopeImpl.java,v 1.1.1.1 2006/01/27 13:10:56 kumarjayanti Exp $
003: * $Revision: 1.1.1.1 $
004: * $Date: 2006/01/27 13:10:56 $
005: */
006:
007: /*
008: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
009: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
010: *
011: * This code is free software; you can redistribute it and/or modify it
012: * under the terms of the GNU General Public License version 2 only, as
013: * published by the Free Software Foundation. Sun designates this
014: * particular file as subject to the "Classpath" exception as provided
015: * by Sun in the LICENSE file that accompanied this code.
016: *
017: * This code is distributed in the hope that it will be useful, but WITHOUT
018: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
019: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
020: * version 2 for more details (a copy is included in the LICENSE file that
021: * accompanied this code).
022: *
023: * You should have received a copy of the GNU General Public License version
024: * 2 along with this work; if not, write to the Free Software Foundation,
025: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
026: *
027: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
028: * CA 95054 USA or visit www.sun.com if you need additional information or
029: * have any questions.
030: */
031: package com.sun.xml.internal.messaging.saaj.soap.impl;
032:
033: import java.io.IOException;
034: import java.io.OutputStream;
035: import java.io.OutputStreamWriter;
036:
037: import java.util.Iterator;
038: import java.util.logging.Level;
039: import org.w3c.dom.Document;
040:
041: import javax.xml.namespace.QName;
042: import javax.xml.soap.*;
043: import javax.xml.transform.*;
044: import javax.xml.transform.dom.DOMSource;
045: import javax.xml.transform.stream.StreamResult;
046: import javax.xml.transform.sax.*;
047:
048: import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
049: import com.sun.xml.internal.messaging.saaj.soap.Envelope;
050: import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
051: import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
052: import com.sun.xml.internal.messaging.saaj.util.FastInfosetReflection;
053: import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer;
054:
055: /**
056: * Our implementation of the SOAP envelope.
057: *
058: * @author Anil Vijendran (anil@sun.com)
059: */
060: public abstract class EnvelopeImpl extends ElementImpl implements
061: Envelope {
062: protected HeaderImpl header;
063: protected BodyImpl body;
064: String omitXmlDecl = "yes";
065: String charset = "utf-8";
066: String xmlDecl = null;
067:
068: protected EnvelopeImpl(SOAPDocumentImpl ownerDoc, Name name) {
069: super (ownerDoc, name);
070: }
071:
072: protected EnvelopeImpl(SOAPDocumentImpl ownerDoc, QName name) {
073: super (ownerDoc, name);
074: }
075:
076: protected EnvelopeImpl(SOAPDocumentImpl ownerDoc, NameImpl name,
077: boolean createHeader, boolean createBody)
078: throws SOAPException {
079: this (ownerDoc, name);
080:
081: ensureNamespaceIsDeclared(getElementQName().getPrefix(),
082: getElementQName().getNamespaceURI());
083:
084: // XXX
085: if (createHeader)
086: addHeader();
087:
088: if (createBody)
089: addBody();
090: }
091:
092: protected abstract NameImpl getHeaderName(String prefix);
093:
094: protected abstract NameImpl getBodyName(String prefix);
095:
096: public SOAPHeader addHeader() throws SOAPException {
097: return addHeader(null);
098: }
099:
100: public SOAPHeader addHeader(String prefix) throws SOAPException {
101:
102: if (prefix == null || prefix.equals("")) {
103: prefix = getPrefix();
104: }
105:
106: NameImpl headerName = getHeaderName(prefix);
107: NameImpl bodyName = getBodyName(prefix);
108:
109: HeaderImpl header = null;
110: SOAPElement firstChild = null;
111:
112: Iterator eachChild = getChildElementNodes();
113: if (eachChild.hasNext()) {
114: firstChild = (SOAPElement) eachChild.next();
115: if (firstChild.getElementName().equals(headerName)) {
116: log.severe("SAAJ0120.impl.header.already.exists");
117: throw new SOAPExceptionImpl(
118: "Can't add a header when one is already present.");
119: } else if (!firstChild.getElementName().equals(bodyName)) {
120: log
121: .severe("SAAJ0121.impl.invalid.first.child.of.envelope");
122: throw new SOAPExceptionImpl(
123: "First child of Envelope must be either a Header or Body");
124: }
125: }
126:
127: header = (HeaderImpl) createElement(headerName);
128: insertBefore(header, firstChild);
129: header.ensureNamespaceIsDeclared(headerName.getPrefix(),
130: headerName.getURI());
131:
132: return header;
133: }
134:
135: protected void lookForHeader() throws SOAPException {
136: NameImpl headerName = getHeaderName(null);
137:
138: HeaderImpl hdr = (HeaderImpl) findChild(headerName);
139: header = hdr;
140: }
141:
142: public SOAPHeader getHeader() throws SOAPException {
143: lookForHeader();
144: return header;
145: }
146:
147: protected void lookForBody() throws SOAPException {
148: NameImpl bodyName = getBodyName(null);
149:
150: BodyImpl bodyChildElement = (BodyImpl) findChild(bodyName);
151: body = bodyChildElement;
152: }
153:
154: public SOAPBody addBody() throws SOAPException {
155: return addBody(null);
156: }
157:
158: public SOAPBody addBody(String prefix) throws SOAPException {
159: lookForBody();
160:
161: if (prefix == null || prefix.equals("")) {
162: prefix = getPrefix();
163: }
164:
165: if (body == null) {
166: NameImpl bodyName = getBodyName(prefix);
167: body = (BodyImpl) createElement(bodyName);
168: insertBefore(body, null);
169: body.ensureNamespaceIsDeclared(bodyName.getPrefix(),
170: bodyName.getURI());
171: } else {
172: log.severe("SAAJ0122.impl.body.already.exists");
173: throw new SOAPExceptionImpl(
174: "Can't add a body when one is already present.");
175: }
176:
177: return body;
178: }
179:
180: protected SOAPElement addElement(Name name) throws SOAPException {
181: if (getBodyName(null).equals(name)) {
182: return addBody(name.getPrefix());
183: }
184: if (getHeaderName(null).equals(name)) {
185: return addHeader(name.getPrefix());
186: }
187:
188: return super .addElement(name);
189: }
190:
191: protected SOAPElement addElement(QName name) throws SOAPException {
192: if (getBodyName(null).equals(NameImpl.convertToName(name))) {
193: return addBody(name.getPrefix());
194: }
195: if (getHeaderName(null).equals(NameImpl.convertToName(name))) {
196: return addHeader(name.getPrefix());
197: }
198:
199: return super .addElement(name);
200: }
201:
202: public SOAPBody getBody() throws SOAPException {
203: lookForBody();
204: return body;
205: }
206:
207: public Source getContent() {
208: return new DOMSource(getOwnerDocument());
209: }
210:
211: public Name createName(String localName, String prefix, String uri)
212: throws SOAPException {
213:
214: // validating parameters before passing them on
215: // to make sure that the namespace specification rules are followed
216:
217: // reserved xmlns prefix cannot be used.
218: if ("xmlns".equals(prefix)) {
219: log.severe("SAAJ0123.impl.no.reserved.xmlns");
220: throw new SOAPExceptionImpl(
221: "Cannot declare reserved xmlns prefix");
222: }
223: // Qualified name cannot be xmlns.
224: if ((prefix == null) && ("xmlns".equals(localName))) {
225: log.severe("SAAJ0124.impl.qualified.name.cannot.be.xmlns");
226: throw new SOAPExceptionImpl(
227: "Qualified name cannot be xmlns");
228: }
229:
230: return NameImpl.create(localName, prefix, uri);
231: }
232:
233: public Name createName(String localName, String prefix)
234: throws SOAPException {
235: String namespace = getNamespaceURI(prefix);
236: if (namespace == null) {
237: log.log(Level.SEVERE, "SAAJ0126.impl.cannot.locate.ns",
238: new String[] { prefix });
239: throw new SOAPExceptionImpl(
240: "Unable to locate namespace for prefix " + prefix);
241: }
242: return NameImpl.create(localName, prefix, namespace);
243: }
244:
245: public Name createName(String localName) throws SOAPException {
246: return NameImpl.createFromUnqualifiedName(localName);
247: }
248:
249: public void setOmitXmlDecl(String value) {
250: this .omitXmlDecl = value;
251: }
252:
253: public void setXmlDecl(String value) {
254: this .xmlDecl = value;
255: }
256:
257: private String getOmitXmlDecl() {
258: return this .omitXmlDecl;
259: }
260:
261: public void setCharsetEncoding(String value) {
262: charset = value;
263: }
264:
265: public void output(OutputStream out) throws IOException {
266: try {
267: Transformer transformer = EfficientStreamingTransformer
268: .newTransformer();
269:
270: transformer.setOutputProperty(
271: OutputKeys.OMIT_XML_DECLARATION, "yes");
272: /*omitXmlDecl);*/
273: // no equivalent for "setExpandEmptyElements"
274: transformer.setOutputProperty(OutputKeys.ENCODING, charset);
275:
276: if (omitXmlDecl.equals("no") && xmlDecl == null) {
277: xmlDecl = "<?xml version=\""
278: + getOwnerDocument().getXmlVersion()
279: + "\" encoding=\"" + charset + "\" ?>";
280: }
281:
282: StreamResult result = new StreamResult(out);
283: if (xmlDecl != null) {
284: OutputStreamWriter writer = new OutputStreamWriter(out,
285: charset);
286: writer.write(xmlDecl);
287: writer.flush();
288: result = new StreamResult(writer);
289: }
290:
291: log.log(Level.FINE, "SAAJ0190.impl.set.xml.declaration",
292: new String[] { omitXmlDecl });
293: log.log(Level.FINE, "SAAJ0191.impl.set.encoding",
294: new String[] { charset });
295:
296: //StreamResult result = new StreamResult(out);
297: transformer.transform(getContent(), result);
298: } catch (Exception ex) {
299: throw new IOException(ex.getMessage());
300: }
301: }
302:
303: /**
304: * Serialize to FI if boolean parameter set.
305: */
306: public void output(OutputStream out, boolean isFastInfoset)
307: throws IOException {
308: if (!isFastInfoset) {
309: output(out);
310: } else {
311: try {
312: // Run transform and generate FI output from content
313: Source source = getContent();
314: Transformer transformer = EfficientStreamingTransformer
315: .newTransformer();
316: transformer.transform(getContent(),
317: FastInfosetReflection
318: .FastInfosetResult_new(out));
319: } catch (Exception ex) {
320: throw new IOException(ex.getMessage());
321: }
322: }
323: }
324:
325: // public void prettyPrint(OutputStream out) throws IOException {
326: // if (getDocument() == null)
327: // initDocument();
328: //
329: // OutputFormat format = OutputFormat.createPrettyPrint();
330: //
331: // format.setIndentSize(2);
332: // format.setNewlines(true);
333: // format.setTrimText(true);
334: // format.setPadText(true);
335: // format.setExpandEmptyElements(false);
336: //
337: // XMLWriter writer = new XMLWriter(out, format);
338: // writer.write(getDocument());
339: // }
340: //
341: // public void prettyPrint(Writer out) throws IOException {
342: // if (getDocument() == null)
343: // initDocument();
344: //
345: // OutputFormat format = OutputFormat.createPrettyPrint();
346: //
347: // format.setIndentSize(2);
348: // format.setNewlines(true);
349: // format.setTrimText(true);
350: // format.setPadText(true);
351: // format.setExpandEmptyElements(false);
352: //
353: // XMLWriter writer = new XMLWriter(out, format);
354: // writer.write(getDocument());
355: // }
356:
357: public SOAPElement setElementQName(QName newName)
358: throws SOAPException {
359: log.log(Level.SEVERE,
360: "SAAJ0146.impl.invalid.name.change.requested",
361: new Object[] { elementQName.getLocalPart(),
362: newName.getLocalPart() });
363: throw new SOAPException("Cannot change name for "
364: + elementQName.getLocalPart() + " to "
365: + newName.getLocalPart());
366: }
367: }
|