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 }