1 /* 2 * Copyright (c) 1997, 2014, 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; 27 28 import java.io.*; 29 import java.util.Iterator; 30 import java.util.logging.Logger; 31 import java.util.logging.Level; 32 33 import javax.activation.DataHandler; 34 import javax.activation.DataSource; 35 import javax.xml.soap.*; 36 import javax.xml.transform.Source; 37 import javax.xml.transform.stream.StreamSource; 38 39 import org.w3c.dom.*; 40 41 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeBodyPart; 42 43 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 44 import com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl; 45 import com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl; 46 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; 47 import com.sun.xml.internal.messaging.saaj.util.*; 48 49 import javax.xml.transform.dom.DOMSource; 50 import javax.xml.transform.sax.SAXSource; 51 52 /** 53 * SOAPPartImpl is the first attachment. This contains the XML/SOAP document. 54 * 55 * @author Anil Vijendran (anil@sun.com) 56 */ 57 public abstract class SOAPPartImpl extends SOAPPart implements SOAPDocument { 58 protected static final Logger log = 59 Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, 60 "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); 61 62 protected MimeHeaders headers; 63 protected Envelope envelope; 64 protected Source source; 65 protected SOAPDocumentImpl document; 66 67 //flag to indicate if a setContent happened. 68 private boolean sourceWasSet = false; 69 70 // Records whether the input source had an xml decl or not. 71 protected boolean omitXmlDecl = true; 72 73 // Records the charset encoding of the input stream source if provided. 74 protected String sourceCharsetEncoding = null; 75 76 /** 77 * Reference to containing message (may be null) 78 */ 79 protected MessageImpl message; 80 81 static final boolean lazyContentLength; 82 static { 83 lazyContentLength = SAAJUtil.getSystemBoolean("saaj.lazy.contentlength"); 84 } 85 86 protected SOAPPartImpl() { 87 this(null); 88 } 89 90 protected SOAPPartImpl(MessageImpl message) { 91 document = new SOAPDocumentImpl(this); 92 headers = new MimeHeaders(); 93 this.message = message; 94 headers.setHeader("Content-Type", getContentType()); 95 } 96 97 protected abstract String getContentType(); 98 protected abstract Envelope createEnvelopeFromSource() 99 throws SOAPException; 100 protected abstract Envelope createEmptyEnvelope(String prefix) 101 throws SOAPException; 102 protected abstract SOAPPartImpl duplicateType(); 103 104 protected String getContentTypeString() { 105 return getContentType(); 106 } 107 108 public boolean isFastInfoset() { 109 return (message != null) ? message.isFastInfoset() : false; 110 } 111 112 public SOAPEnvelope getEnvelope() throws SOAPException { 113 114 // If there is no SOAP envelope already created, then create 115 // one from a source if one exists. If there is a newer source 116 // then use that source. 117 118 if (sourceWasSet) 119 sourceWasSet = false; 120 121 lookForEnvelope(); 122 if (envelope != null) { 123 if (source != null) { // there's a newer source, use it 124 document.removeChild(envelope); 125 envelope = createEnvelopeFromSource(); 126 } 127 } else if (source != null) { 128 envelope = createEnvelopeFromSource(); 129 } else { 130 envelope = createEmptyEnvelope(null); 131 document.insertBefore(envelope, null); 132 } 133 return envelope; 134 } 135 136 protected void lookForEnvelope() throws SOAPException { 137 Element envelopeChildElement = document.doGetDocumentElement(); 138 if (envelopeChildElement == null || envelopeChildElement instanceof Envelope) { 139 envelope = (EnvelopeImpl) envelopeChildElement; 140 } else if (!(envelopeChildElement instanceof ElementImpl)) { 141 log.severe("SAAJ0512.soap.incorrect.factory.used"); 142 throw new SOAPExceptionImpl("Unable to create envelope: incorrect factory used during tree construction"); 143 } else { 144 ElementImpl soapElement = (ElementImpl) envelopeChildElement; 145 if (soapElement.getLocalName().equalsIgnoreCase("Envelope")) { 146 String prefix = soapElement.getPrefix(); 147 String uri = (prefix == null) ? soapElement.getNamespaceURI() : soapElement.getNamespaceURI(prefix); 148 if(!uri.equals(NameImpl.SOAP11_NAMESPACE) && !uri.equals(NameImpl.SOAP12_NAMESPACE)) { 149 log.severe("SAAJ0513.soap.unknown.ns"); 150 throw new SOAPVersionMismatchException("Unable to create envelope from given source because the namespace was not recognized"); 151 } 152 } else { 153 log.severe("SAAJ0514.soap.root.elem.not.named.envelope"); 154 throw new SOAPExceptionImpl( 155 "Unable to create envelope from given source because the root element is not named \"Envelope\""); 156 } 157 } 158 } 159 160 public void removeAllMimeHeaders() { 161 headers.removeAllHeaders(); 162 } 163 164 public void removeMimeHeader(String header) { 165 headers.removeHeader(header); 166 } 167 168 public String[] getMimeHeader(String name) { 169 return headers.getHeader(name); 170 } 171 172 public void setMimeHeader(String name, String value) { 173 headers.setHeader(name, value); 174 } 175 176 public void addMimeHeader(String name, String value) { 177 headers.addHeader(name, value); 178 } 179 180 public Iterator getAllMimeHeaders() { 181 return headers.getAllHeaders(); 182 } 183 184 public Iterator getMatchingMimeHeaders(String[] names) { 185 return headers.getMatchingHeaders(names); 186 } 187 188 public Iterator getNonMatchingMimeHeaders(String[] names) { 189 return headers.getNonMatchingHeaders(names); 190 } 191 192 public Source getContent() throws SOAPException { 193 if (source != null) { 194 InputStream bis = null; 195 if (source instanceof JAXMStreamSource) { 196 StreamSource streamSource = (StreamSource)source; 197 bis = streamSource.getInputStream(); 198 } else if (FastInfosetReflection.isFastInfosetSource(source)) { 199 // FastInfosetSource inherits from SAXSource 200 SAXSource saxSource = (SAXSource)source; 201 bis = saxSource.getInputSource().getByteStream(); 202 } 203 204 if (bis != null) { 205 try { 206 bis.reset(); 207 } catch (IOException e) { 208 /* This exception will never be thrown. 209 * 210 * The setContent method will modify the source 211 * if StreamSource to JAXMStreamSource, that uses 212 * a ByteInputStream, and for a FastInfosetSource will 213 * replace the InputStream with a ByteInputStream. 214 */ 215 } 216 } 217 return source; 218 } 219 220 return ((Envelope) getEnvelope()).getContent(); 221 } 222 223 public void setContent(Source source) throws SOAPException { 224 try { 225 if (source instanceof StreamSource) { 226 InputStream is = ((StreamSource) source).getInputStream(); 227 Reader rdr = ((StreamSource) source).getReader(); 228 229 if (is != null) { 230 this.source = new JAXMStreamSource(is); 231 } else if (rdr != null) { 232 this.source = new JAXMStreamSource(rdr); 233 } else { 234 log.severe("SAAJ0544.soap.no.valid.reader.for.src"); 235 throw new SOAPExceptionImpl("Source does not have a valid Reader or InputStream"); 236 } 237 } 238 else if (FastInfosetReflection.isFastInfosetSource(source)) { 239 // InputStream is = source.getInputStream() 240 InputStream is = FastInfosetReflection.FastInfosetSource_getInputStream(source); 241 242 /* 243 * Underlying stream must be ByteInputStream for getContentAsStream(). We pay the 244 * cost of copying the underlying bytes here to avoid multiple copies every time 245 * getBytes() is called on a ByteInputStream. 246 */ 247 if (!(is instanceof ByteInputStream)) { 248 ByteOutputStream bout = null; 249 try { 250 bout = new ByteOutputStream(); 251 bout.write(is); 252 253 // source.setInputStream(new ByteInputStream(...)) 254 FastInfosetReflection.FastInfosetSource_setInputStream( 255 source, bout.newInputStream()); 256 } finally { 257 if (bout != null) 258 bout.close(); 259 } 260 } 261 this.source = source; 262 } 263 else { 264 this.source = source; 265 } 266 sourceWasSet = true; 267 } 268 catch (Exception ex) { 269 ex.printStackTrace(); 270 271 log.severe("SAAJ0545.soap.cannot.set.src.for.part"); 272 throw new SOAPExceptionImpl( 273 "Error setting the source for SOAPPart: " + ex.getMessage()); 274 } 275 } 276 277 public InputStream getContentAsStream() throws IOException { 278 if (source != null) { 279 InputStream is = null; 280 281 // Allow message to be transcode if so requested 282 if (source instanceof StreamSource && !isFastInfoset()) { 283 is = ((StreamSource) source).getInputStream(); 284 } 285 else if (FastInfosetReflection.isFastInfosetSource(source) && 286 isFastInfoset()) 287 { 288 try { 289 // InputStream is = source.getInputStream() 290 is = FastInfosetReflection.FastInfosetSource_getInputStream(source); 291 } 292 catch (Exception e) { 293 throw new IOException(e.toString()); 294 } 295 } 296 297 if (is != null) { 298 if (lazyContentLength) { 299 return is; 300 } 301 if (!(is instanceof ByteInputStream)) { 302 log.severe("SAAJ0546.soap.stream.incorrect.type"); 303 throw new IOException("Internal error: stream not of the right type"); 304 } 305 return (ByteInputStream) is; 306 } 307 // need to do something here for reader... 308 // for now we'll see if we can fallback... 309 } 310 311 ByteOutputStream b = new ByteOutputStream(); 312 313 Envelope env = null; 314 315 try { 316 env = (Envelope) getEnvelope(); 317 env.output(b, isFastInfoset()); 318 } 319 catch (SOAPException soapException) { 320 log.severe("SAAJ0547.soap.cannot.externalize"); 321 throw new SOAPIOException( 322 "SOAP exception while trying to externalize: ", 323 soapException); 324 } 325 326 return b.newInputStream(); 327 } 328 329 MimeBodyPart getMimePart() throws SOAPException { 330 try { 331 MimeBodyPart headerEnvelope = new MimeBodyPart(); 332 333 headerEnvelope.setDataHandler(getDataHandler()); 334 AttachmentPartImpl.copyMimeHeaders(headers, headerEnvelope); 335 336 return headerEnvelope; 337 } catch (SOAPException ex) { 338 throw ex; 339 } catch (Exception ex) { 340 log.severe("SAAJ0548.soap.cannot.externalize.hdr"); 341 throw new SOAPExceptionImpl("Unable to externalize header", ex); 342 } 343 } 344 345 MimeHeaders getMimeHeaders() { 346 return headers; 347 } 348 349 DataHandler getDataHandler() { 350 DataSource ds = new DataSource() { 351 public OutputStream getOutputStream() throws IOException { 352 throw new IOException("Illegal Operation"); 353 } 354 355 public String getContentType() { 356 return getContentTypeString(); 357 } 358 359 public String getName() { 360 return getContentId(); 361 } 362 363 public InputStream getInputStream() throws IOException { 364 return getContentAsStream(); 365 } 366 }; 367 return new DataHandler(ds); 368 } 369 370 public SOAPDocumentImpl getDocument() { 371 handleNewSource(); 372 return document; 373 } 374 375 public SOAPPartImpl getSOAPPart() { 376 return this; 377 } 378 379 public DocumentType getDoctype() { 380 return document.getDoctype(); 381 } 382 383 // Forward all of these calls to the document to ensure that they work the 384 // same way whether they are called from here or directly from the document. 385 // If the document needs any help from this SOAPPart then 386 // Make it use a call-back as in doGetDocumentElement() below 387 public DOMImplementation getImplementation() { 388 return document.getImplementation(); 389 } 390 391 public Element getDocumentElement() { 392 // If there is no SOAP envelope already created, then create 393 // one from a source if one exists. If there is a newer source 394 // then use that source. 395 try { 396 getEnvelope(); 397 } catch (SOAPException e) { 398 } 399 return document.getDocumentElement(); 400 } 401 402 protected void doGetDocumentElement() { 403 handleNewSource(); 404 try { 405 lookForEnvelope(); 406 } catch (SOAPException e) { 407 } 408 } 409 410 public Element createElement(String tagName) throws DOMException { 411 return document.createElement(tagName); 412 } 413 414 public DocumentFragment createDocumentFragment() { 415 return document.createDocumentFragment(); 416 } 417 418 public org.w3c.dom.Text createTextNode(String data) { 419 return document.createTextNode(data); 420 } 421 422 public Comment createComment(String data) { 423 return document.createComment(data); 424 } 425 426 public CDATASection createCDATASection(String data) throws DOMException { 427 return document.createCDATASection(data); 428 } 429 430 public ProcessingInstruction createProcessingInstruction( 431 String target, 432 String data) 433 throws DOMException { 434 return document.createProcessingInstruction(target, data); 435 } 436 437 public Attr createAttribute(String name) throws DOMException { 438 return document.createAttribute(name); 439 } 440 441 public EntityReference createEntityReference(String name) 442 throws DOMException { 443 return document.createEntityReference(name); 444 } 445 446 public NodeList getElementsByTagName(String tagname) { 447 handleNewSource(); 448 return document.getElementsByTagName(tagname); 449 } 450 451 public org.w3c.dom.Node importNode( 452 org.w3c.dom.Node importedNode, 453 boolean deep) 454 throws DOMException { 455 handleNewSource(); 456 return document.importNode(importedNode, deep); 457 } 458 459 public Element createElementNS(String namespaceURI, String qualifiedName) 460 throws DOMException { 461 return document.createElementNS(namespaceURI, qualifiedName); 462 } 463 464 public Attr createAttributeNS(String namespaceURI, String qualifiedName) 465 throws DOMException { 466 return document.createAttributeNS(namespaceURI, qualifiedName); 467 } 468 469 public NodeList getElementsByTagNameNS( 470 String namespaceURI, 471 String localName) { 472 handleNewSource(); 473 return document.getElementsByTagNameNS(namespaceURI, localName); 474 } 475 476 public Element getElementById(String elementId) { 477 handleNewSource(); 478 return document.getElementById(elementId); 479 } 480 public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild) 481 throws DOMException { 482 handleNewSource(); 483 return document.appendChild(newChild); 484 } 485 486 public org.w3c.dom.Node cloneNode(boolean deep) { 487 handleNewSource(); 488 return document.cloneNode(deep); 489 } 490 491 protected SOAPPartImpl doCloneNode() { 492 handleNewSource(); 493 SOAPPartImpl newSoapPart = duplicateType(); 494 495 newSoapPart.headers = MimeHeadersUtil.copy(this.headers); 496 newSoapPart.source = this.source; 497 return newSoapPart; 498 } 499 500 public NamedNodeMap getAttributes() { 501 return document.getAttributes(); 502 } 503 504 public NodeList getChildNodes() { 505 handleNewSource(); 506 return document.getChildNodes(); 507 } 508 509 public org.w3c.dom.Node getFirstChild() { 510 handleNewSource(); 511 return document.getFirstChild(); 512 } 513 514 public org.w3c.dom.Node getLastChild() { 515 handleNewSource(); 516 return document.getLastChild(); 517 } 518 519 public String getLocalName() { 520 return document.getLocalName(); 521 } 522 523 public String getNamespaceURI() { 524 return document.getNamespaceURI(); 525 } 526 527 public org.w3c.dom.Node getNextSibling() { 528 handleNewSource(); 529 return document.getNextSibling(); 530 } 531 532 public String getNodeName() { 533 return document.getNodeName(); 534 } 535 536 public short getNodeType() { 537 return document.getNodeType(); 538 } 539 540 public String getNodeValue() throws DOMException { 541 return document.getNodeValue(); 542 } 543 544 public Document getOwnerDocument() { 545 return document.getOwnerDocument(); 546 } 547 548 public org.w3c.dom.Node getParentNode() { 549 return document.getParentNode(); 550 } 551 552 public String getPrefix() { 553 return document.getPrefix(); 554 } 555 556 public org.w3c.dom.Node getPreviousSibling() { 557 return document.getPreviousSibling(); 558 } 559 560 public boolean hasAttributes() { 561 return document.hasAttributes(); 562 } 563 564 public boolean hasChildNodes() { 565 handleNewSource(); 566 return document.hasChildNodes(); 567 } 568 569 public org.w3c.dom.Node insertBefore( 570 org.w3c.dom.Node arg0, 571 org.w3c.dom.Node arg1) 572 throws DOMException { 573 handleNewSource(); 574 return document.insertBefore(arg0, arg1); 575 } 576 577 public boolean isSupported(String arg0, String arg1) { 578 return document.isSupported(arg0, arg1); 579 } 580 581 public void normalize() { 582 handleNewSource(); 583 document.normalize(); 584 } 585 586 public org.w3c.dom.Node removeChild(org.w3c.dom.Node arg0) 587 throws DOMException { 588 handleNewSource(); 589 return document.removeChild(arg0); 590 } 591 592 public org.w3c.dom.Node replaceChild( 593 org.w3c.dom.Node arg0, 594 org.w3c.dom.Node arg1) 595 throws DOMException { 596 handleNewSource(); 597 return document.replaceChild(arg0, arg1); 598 } 599 600 public void setNodeValue(String arg0) throws DOMException { 601 document.setNodeValue(arg0); 602 } 603 604 public void setPrefix(String arg0) throws DOMException { 605 document.setPrefix(arg0); 606 } 607 608 private void handleNewSource() { 609 if (sourceWasSet) { 610 // There is a newer source use that source. 611 try { 612 getEnvelope(); 613 } catch (SOAPException e) { 614 } 615 } 616 } 617 618 protected XMLDeclarationParser lookForXmlDecl() throws SOAPException { 619 if ((source != null) && (source instanceof StreamSource)) { 620 621 Reader reader = null; 622 623 InputStream inputStream = ((StreamSource) source).getInputStream(); 624 if (inputStream != null) { 625 if (getSourceCharsetEncoding() == null) { 626 reader = new InputStreamReader(inputStream); 627 } else { 628 try { 629 reader = 630 new InputStreamReader( 631 inputStream, getSourceCharsetEncoding()); 632 } catch (UnsupportedEncodingException uee) { 633 log.log( 634 Level.SEVERE, 635 "SAAJ0551.soap.unsupported.encoding", 636 new Object[] {getSourceCharsetEncoding()}); 637 throw new SOAPExceptionImpl( 638 "Unsupported encoding " + getSourceCharsetEncoding(), 639 uee); 640 } 641 } 642 } else { 643 reader = ((StreamSource) source).getReader(); 644 } 645 if (reader != null) { 646 PushbackReader pushbackReader = 647 new PushbackReader(reader, 4096); //some size to unread <?xml ....?> 648 XMLDeclarationParser ev = 649 new XMLDeclarationParser(pushbackReader); 650 try { 651 ev.parse(); 652 } catch (Exception e) { 653 log.log( 654 Level.SEVERE, 655 "SAAJ0552.soap.xml.decl.parsing.failed"); 656 throw new SOAPExceptionImpl( 657 "XML declaration parsing failed", e); 658 } 659 String xmlDecl = ev.getXmlDeclaration(); 660 if ((xmlDecl != null) && (xmlDecl.length() > 0)) { 661 this.omitXmlDecl = false; 662 } 663 if (lazyContentLength) { 664 source = new StreamSource(pushbackReader); 665 } 666 return ev; 667 } 668 } else if ((source != null) && (source instanceof DOMSource)) { 669 //TODO: A Domsource maynot contain XMLDecl ?. 670 } 671 return null; 672 } 673 674 public void setSourceCharsetEncoding(String charset) { 675 this.sourceCharsetEncoding = charset; 676 } 677 678 public org.w3c.dom.Node renameNode(org.w3c.dom.Node n, String namespaceURI, String qualifiedName) 679 throws DOMException { 680 handleNewSource(); 681 return document.renameNode(n, namespaceURI, qualifiedName); 682 } 683 684 public void normalizeDocument() { 685 document.normalizeDocument(); 686 } 687 688 public DOMConfiguration getDomConfig() { 689 return document.getDomConfig(); 690 } 691 692 public org.w3c.dom.Node adoptNode(org.w3c.dom.Node source) throws DOMException { 693 handleNewSource(); 694 return document.adoptNode(source); 695 } 696 697 public void setDocumentURI(String documentURI) { 698 document.setDocumentURI(documentURI); 699 } 700 701 public String getDocumentURI() { 702 return document.getDocumentURI(); 703 } 704 705 public void setStrictErrorChecking(boolean strictErrorChecking) { 706 document.setStrictErrorChecking(strictErrorChecking); 707 } 708 709 public String getInputEncoding() { 710 return document.getInputEncoding(); 711 } 712 713 public String getXmlEncoding() { 714 return document.getXmlEncoding(); 715 } 716 717 public boolean getXmlStandalone() { 718 return document.getXmlStandalone(); 719 } 720 721 public void setXmlStandalone(boolean xmlStandalone) throws DOMException { 722 document.setXmlStandalone(xmlStandalone); 723 } 724 725 public String getXmlVersion() { 726 return document.getXmlVersion(); 727 } 728 729 public void setXmlVersion(String xmlVersion) throws DOMException { 730 document.setXmlVersion(xmlVersion); 731 } 732 733 public boolean getStrictErrorChecking() { 734 return document.getStrictErrorChecking(); 735 } 736 737 // DOM L3 methods from org.w3c.dom.Node 738 public String getBaseURI() { 739 return document.getBaseURI(); 740 } 741 742 public short compareDocumentPosition(org.w3c.dom.Node other) 743 throws DOMException { 744 return document.compareDocumentPosition(other); 745 } 746 747 public String getTextContent() 748 throws DOMException { 749 return document.getTextContent(); 750 } 751 752 public void setTextContent(String textContent) throws DOMException { 753 document.setTextContent(textContent); 754 } 755 756 public boolean isSameNode(org.w3c.dom.Node other) { 757 return document.isSameNode(other); 758 } 759 760 public String lookupPrefix(String namespaceURI) { 761 return document.lookupPrefix(namespaceURI); 762 } 763 764 public boolean isDefaultNamespace(String namespaceURI) { 765 return document.isDefaultNamespace(namespaceURI); 766 } 767 768 public String lookupNamespaceURI(String prefix) { 769 return document.lookupNamespaceURI(prefix); 770 } 771 772 public boolean isEqualNode(org.w3c.dom.Node arg) { 773 return document.isEqualNode(arg); 774 } 775 776 public Object getFeature(String feature, 777 String version) { 778 return document.getFeature(feature,version); 779 } 780 781 public Object setUserData(String key, 782 Object data, 783 UserDataHandler handler) { 784 return document.setUserData(key, data, handler); 785 } 786 787 public Object getUserData(String key) { 788 return document.getUserData(key); 789 } 790 791 public void recycleNode() { 792 // Nothing seems to be required to be done here 793 } 794 795 public String getValue() { 796 return null; 797 } 798 799 public void setValue(String value) { 800 log.severe("SAAJ0571.soappart.setValue.not.defined"); 801 throw new IllegalStateException("Setting value of a soap part is not defined"); 802 } 803 804 public void setParentElement(SOAPElement parent) throws SOAPException { 805 log.severe("SAAJ0570.soappart.parent.element.not.defined"); 806 throw new SOAPExceptionImpl("The parent element of a soap part is not defined"); 807 } 808 809 public SOAPElement getParentElement() { 810 return null; 811 } 812 813 public void detachNode() { 814 // Nothing seems to be required to be done here 815 } 816 817 public String getSourceCharsetEncoding() { 818 return sourceCharsetEncoding; 819 } 820 821 public abstract String getSOAPNamespace(); 822 }