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