001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: /*
021: * $Id: BodyImpl.java,v 1.2 2007/07/16 16:41:22 ofung Exp $
022: * $Revision: 1.2 $
023: * $Date: 2007/07/16 16:41:22 $
024: */
025:
026: /*
027: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
028: *
029: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
030: *
031: * The contents of this file are subject to the terms of either the GNU
032: * General Public License Version 2 only ("GPL") or the Common Development
033: * and Distribution License("CDDL") (collectively, the "License"). You
034: * may not use this file except in compliance with the License. You can obtain
035: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
036: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
037: * language governing permissions and limitations under the License.
038: *
039: * When distributing the software, include this License Header Notice in each
040: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
041: * Sun designates this particular file as subject to the "Classpath" exception
042: * as provided by Sun in the GPL Version 2 section of the License file that
043: * accompanied this code. If applicable, add the following below the License
044: * Header, with the fields enclosed by brackets [] replaced by your own
045: * identifying information: "Portions Copyrighted [year]
046: * [name of copyright owner]"
047: *
048: * Contributor(s):
049: *
050: * If you wish your version of this file to be governed by only the CDDL or
051: * only the GPL Version 2, indicate your decision by adding "[Contributor]
052: * elects to include this software in this distribution under the [CDDL or GPL
053: * Version 2] license." If you don't indicate a single choice of license, a
054: * recipient has the option to distribute your version of this file under
055: * either the CDDL, the GPL Version 2 or to extend the choice of license to
056: * its licensees as provided above. However, if you add GPL Version 2 code
057: * and therefore, elected the GPL Version 2 license, then the option applies
058: * only if the new code is made subject to such option by the copyright
059: * holder.
060: */
061: package com.sun.xml.messaging.saaj.soap.impl;
062:
063: import java.util.Iterator;
064: import java.util.Locale;
065: import java.util.logging.Level;
066:
067: import javax.xml.namespace.QName;
068: import javax.xml.soap.*;
069: import javax.xml.parsers.DocumentBuilder;
070: import javax.xml.parsers.DocumentBuilderFactory;
071:
072: import org.w3c.dom.*;
073:
074: import com.sun.xml.messaging.saaj.SOAPExceptionImpl;
075: import com.sun.xml.messaging.saaj.soap.SOAPDocument;
076: import com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl;
077: import com.sun.xml.messaging.saaj.soap.name.NameImpl;
078:
079: /**
080: * The implementation of SOAP-ENV:BODY or the SOAPBody abstraction.
081: *
082: * @author Anil Vijendran (anil@sun.com)
083: */
084: public abstract class BodyImpl extends ElementImpl implements SOAPBody {
085: private SOAPFault fault;
086:
087: protected BodyImpl(SOAPDocumentImpl ownerDoc, NameImpl bodyName) {
088: super (ownerDoc, bodyName);
089: }
090:
091: protected abstract NameImpl getFaultName(String name);
092:
093: protected abstract boolean isFault(SOAPElement child);
094:
095: protected abstract SOAPBodyElement createBodyElement(Name name);
096:
097: protected abstract SOAPBodyElement createBodyElement(QName name);
098:
099: protected abstract SOAPFault createFaultElement();
100:
101: protected abstract QName getDefaultFaultCode();
102:
103: public SOAPFault addFault() throws SOAPException {
104: if (hasFault()) {
105: log.severe("SAAJ0110.impl.fault.already.exists");
106: throw new SOAPExceptionImpl("Error: Fault already exists");
107: }
108:
109: fault = createFaultElement();
110:
111: addNode(fault);
112:
113: fault.setFaultCode(getDefaultFaultCode());
114: fault
115: .setFaultString("Fault string, and possibly fault code, not set");
116:
117: return fault;
118: }
119:
120: public SOAPFault addFault(Name faultCode, String faultString,
121: Locale locale) throws SOAPException {
122:
123: SOAPFault fault = addFault();
124: fault.setFaultCode(faultCode);
125: fault.setFaultString(faultString, locale);
126: return fault;
127: }
128:
129: public SOAPFault addFault(QName faultCode, String faultString,
130: Locale locale) throws SOAPException {
131:
132: SOAPFault fault = addFault();
133: fault.setFaultCode(faultCode);
134: fault.setFaultString(faultString, locale);
135: return fault;
136: }
137:
138: public SOAPFault addFault(Name faultCode, String faultString)
139: throws SOAPException {
140:
141: SOAPFault fault = addFault();
142: fault.setFaultCode(faultCode);
143: fault.setFaultString(faultString);
144: return fault;
145: }
146:
147: public SOAPFault addFault(QName faultCode, String faultString)
148: throws SOAPException {
149:
150: SOAPFault fault = addFault();
151: fault.setFaultCode(faultCode);
152: fault.setFaultString(faultString);
153: return fault;
154: }
155:
156: void initializeFault() {
157: FaultImpl flt = (FaultImpl) findFault();
158: fault = flt;
159: }
160:
161: protected SOAPElement findFault() {
162: Iterator eachChild = getChildElementNodes();
163: while (eachChild.hasNext()) {
164: SOAPElement child = (SOAPElement) eachChild.next();
165: if (isFault(child)) {
166: return child;
167: }
168: }
169:
170: return null;
171: }
172:
173: public boolean hasFault() {
174: initializeFault();
175: return fault != null;
176: }
177:
178: public SOAPFault getFault() {
179: if (hasFault())
180: return fault;
181: return null;
182: }
183:
184: public SOAPBodyElement addBodyElement(Name name)
185: throws SOAPException {
186: SOAPBodyElement newBodyElement = (SOAPBodyElement) ElementFactory
187: .createNamedElement(((SOAPDocument) getOwnerDocument())
188: .getDocument(), name.getLocalName(), name
189: .getPrefix(), name.getURI());
190: if (newBodyElement == null) {
191: newBodyElement = createBodyElement(name);
192: }
193: addNode(newBodyElement);
194: return newBodyElement;
195: }
196:
197: public SOAPBodyElement addBodyElement(QName qname)
198: throws SOAPException {
199: SOAPBodyElement newBodyElement = (SOAPBodyElement) ElementFactory
200: .createNamedElement(((SOAPDocument) getOwnerDocument())
201: .getDocument(), qname.getLocalPart(), qname
202: .getPrefix(), qname.getNamespaceURI());
203: if (newBodyElement == null) {
204: newBodyElement = createBodyElement(qname);
205: }
206: addNode(newBodyElement);
207: return newBodyElement;
208: }
209:
210: public void setParentElement(SOAPElement element)
211: throws SOAPException {
212:
213: if (!(element instanceof SOAPEnvelope)) {
214: log.severe("SAAJ0111.impl.body.parent.must.be.envelope");
215: throw new SOAPException(
216: "Parent of SOAPBody has to be a SOAPEnvelope");
217: }
218: super .setParentElement(element);
219: }
220:
221: protected SOAPElement addElement(Name name) throws SOAPException {
222: return addBodyElement(name);
223: }
224:
225: protected SOAPElement addElement(QName name) throws SOAPException {
226: return addBodyElement(name);
227: }
228:
229: // public Node insertBefore(Node newElement, Node ref) throws DOMException {
230: // if (!(newElement instanceof SOAPBodyElement) && (newElement instanceof SOAPElement)) {
231: // newElement = new ElementWrapper((ElementImpl) newElement);
232: // }
233: // return super.insertBefore(newElement, ref);
234: // }
235: //
236: // public Node replaceChild(Node newElement, Node ref) throws DOMException {
237: // if (!(newElement instanceof SOAPBodyElement) && (newElement instanceof SOAPElement)) {
238: // newElement = new ElementWrapper((ElementImpl) newElement);
239: // }
240: // return super.replaceChild(newElement, ref);
241: // }
242:
243: public SOAPBodyElement addDocument(Document document)
244: throws SOAPException {
245: /*
246:
247: Element rootNode =
248: document.getDocumentElement();
249: // Causes all deferred nodes to be inflated
250: rootNode.normalize();
251: adoptElement(rootNode);
252: SOAPBodyElement bodyElement = (SOAPBodyElement) convertToSoapElement(rootNode);
253: addNode(bodyElement);
254: return bodyElement;
255: */
256: ///*
257: SOAPBodyElement newBodyElement = null;
258: DocumentFragment docFrag = document.createDocumentFragment();
259: Element rootElement = document.getDocumentElement();
260: if (rootElement != null) {
261: docFrag.appendChild(rootElement);
262:
263: Document ownerDoc = getOwnerDocument();
264: // This copies the whole tree which could be very big so it's slow.
265: // However, it does have the advantage of actually working.
266: org.w3c.dom.Node replacingNode = ownerDoc.importNode(
267: docFrag, true);
268: // Adding replacingNode at the last of the children list of body
269: addNode(replacingNode);
270: Iterator i = getChildElements(NameImpl
271: .copyElementName(rootElement));
272: // Return the child element with the required name which is at the
273: // end of the list
274: while (i.hasNext())
275: newBodyElement = (SOAPBodyElement) i.next();
276: }
277: return newBodyElement;
278: //*/
279: }
280:
281: protected SOAPElement convertToSoapElement(Element element) {
282: if ((element instanceof SOAPBodyElement) &&
283: //this check is required because ElementImpl currently
284: // implements SOAPBodyElement
285: !(element.getClass().equals(ElementImpl.class))) {
286: return (SOAPElement) element;
287: } else {
288: return replaceElementWithSOAPElement(element,
289: (ElementImpl) createBodyElement(NameImpl
290: .copyElementName(element)));
291: }
292: }
293:
294: public SOAPElement setElementQName(QName newName)
295: throws SOAPException {
296: log.log(Level.SEVERE,
297: "SAAJ0146.impl.invalid.name.change.requested",
298: new Object[] { elementQName.getLocalPart(),
299: newName.getLocalPart() });
300: throw new SOAPException("Cannot change name for "
301: + elementQName.getLocalPart() + " to "
302: + newName.getLocalPart());
303: }
304:
305: public Document extractContentAsDocument() throws SOAPException {
306:
307: Iterator eachChild = getChildElements();
308: javax.xml.soap.Node firstBodyElement = null;
309:
310: while (eachChild.hasNext()
311: && !(firstBodyElement instanceof SOAPElement))
312: firstBodyElement = (javax.xml.soap.Node) eachChild.next();
313:
314: boolean exactlyOneChildElement = true;
315: if (firstBodyElement == null)
316: exactlyOneChildElement = false;
317: else {
318: for (org.w3c.dom.Node node = firstBodyElement
319: .getNextSibling(); node != null; node = node
320: .getNextSibling()) {
321:
322: if (node instanceof Element) {
323: exactlyOneChildElement = false;
324: break;
325: }
326: }
327: }
328:
329: if (!exactlyOneChildElement) {
330: log.log(Level.SEVERE,
331: "SAAJ0250.impl.body.should.have.exactly.one.child");
332: throw new SOAPException("Cannot extract Document from body");
333: }
334:
335: Document document = null;
336: try {
337: DocumentBuilderFactory factory = new com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl();
338: factory.setNamespaceAware(true);
339: DocumentBuilder builder = factory.newDocumentBuilder();
340: document = builder.newDocument();
341:
342: Element rootElement = (Element) document.importNode(
343: firstBodyElement, true);
344:
345: document.appendChild(rootElement);
346:
347: } catch (Exception e) {
348: log.log(Level.SEVERE,
349: "SAAJ0251.impl.cannot.extract.document.from.body");
350: throw new SOAPExceptionImpl(
351: "Unable to extract Document from body", e);
352: }
353:
354: firstBodyElement.detachNode();
355:
356: return document;
357: }
358:
359: }
|