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 com.sun.xml.internal.messaging.saaj.LazyEnvelopeSource; 29 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 30 import com.sun.xml.internal.messaging.saaj.util.JAXMStreamSource; 31 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants; 32 import com.sun.xml.internal.messaging.saaj.util.ParserPool; 33 import com.sun.xml.internal.messaging.saaj.util.RejectDoctypeSaxFilter; 34 import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer; 35 import org.xml.sax.InputSource; 36 import org.xml.sax.XMLReader; 37 38 import javax.xml.parsers.SAXParser; 39 import javax.xml.soap.SOAPException; 40 import javax.xml.stream.XMLInputFactory; 41 import javax.xml.stream.XMLStreamException; 42 import javax.xml.stream.XMLStreamReader; 43 import javax.xml.transform.Source; 44 import javax.xml.transform.Transformer; 45 import javax.xml.transform.dom.DOMResult; 46 import javax.xml.transform.sax.SAXSource; 47 import javax.xml.transform.stax.StAXSource; 48 import javax.xml.transform.stream.StreamSource; 49 import java.util.logging.Logger; 50 51 /** 52 * EnvelopeFactory creates SOAP Envelope objects using different 53 * underlying implementations. 54 */ 55 public class EnvelopeFactory { 56 57 protected static final Logger 58 log = Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, 59 "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); 60 61 private static ContextClassloaderLocal<ParserPool> parserPool = 62 new ContextClassloaderLocal<ParserPool>() { 63 @Override 64 protected ParserPool initialValue() throws Exception { 65 return new ParserPool(5); 66 } 67 }; 68 69 public static Envelope createEnvelope(Source src, SOAPPartImpl soapPart) 70 throws SOAPException 71 { 72 if (src instanceof JAXMStreamSource) { 73 try { 74 if (!SOAPPartImpl.lazyContentLength) { 75 ((JAXMStreamSource) src).reset(); 76 } 77 } catch (java.io.IOException ioe) { 78 log.severe("SAAJ0515.source.reset.exception"); 79 throw new SOAPExceptionImpl(ioe); 80 } 81 } 82 if (src instanceof LazyEnvelopeSource) { 83 return lazy((LazyEnvelopeSource)src, soapPart); 84 } 85 if (soapPart.message.isLazySoapBodyParsing()) { 86 return parseEnvelopeStax(src, soapPart); 87 } else { 88 return parseEnvelopeSax(src, soapPart); 89 } 90 } 91 92 private static Envelope lazy(LazyEnvelopeSource src, SOAPPartImpl soapPart) throws SOAPException { 93 try { 94 StaxBridge staxBridge = new StaxLazySourceBridge(src, soapPart); 95 staxBridge.bridgeEnvelopeAndHeaders(); 96 Envelope env = (Envelope) soapPart.getEnvelope(); 97 env.setStaxBridge(staxBridge); 98 return env; 99 } catch (XMLStreamException e) { 100 throw new SOAPException(e); 101 } 102 } 103 104 static private XMLInputFactory xmlInputFactory = null; 105 106 private static Envelope parseEnvelopeStax(Source src, SOAPPartImpl soapPart) 107 throws SOAPException { 108 XMLStreamReader streamReader = null; 109 if (src instanceof StAXSource) { 110 streamReader = ((StAXSource) src).getXMLStreamReader(); 111 } 112 try { 113 if (streamReader == null) { 114 if (xmlInputFactory == null) xmlInputFactory = XMLInputFactory.newInstance(); 115 streamReader = xmlInputFactory.createXMLStreamReader(src); 116 } 117 // SaajStaxWriter saajWriter = new SaajStaxWriter(soapPart.message, soapPart.document); 118 // XMLStreamReaderToXMLStreamWriter readerWriterBridge = new XMLStreamReaderToXMLStreamWriter( 119 // streamReader, saajWriter, soapPart.getSOAPNamespace()); 120 121 StaxBridge readerWriterBridge = new StaxReaderBridge(streamReader, soapPart); 122 //bridge will stop reading at body element, and parse upon request, so save it 123 //on the envelope 124 readerWriterBridge.bridgeEnvelopeAndHeaders(); 125 126 Envelope env = (Envelope) soapPart.getEnvelope(); 127 env.setStaxBridge(readerWriterBridge); 128 return env; 129 } catch (Exception e) { 130 throw new SOAPException(e); 131 } 132 } 133 private static Envelope parseEnvelopeSax(Source src, SOAPPartImpl soapPart) 134 throws SOAPException { 135 // Insert SAX filter to disallow Document Type Declarations since 136 // they are not legal in SOAP 137 SAXParser saxParser = null; 138 if (src instanceof StreamSource) { 139 try { 140 saxParser = parserPool.get().get(); 141 } catch (Exception e) { 142 log.severe("SAAJ0601.util.newSAXParser.exception"); 143 throw new SOAPExceptionImpl( 144 "Couldn't get a SAX parser while constructing a envelope", 145 e); 146 } 147 InputSource is = SAXSource.sourceToInputSource(src); 148 if (is.getEncoding()== null && soapPart.getSourceCharsetEncoding() != null) { 149 is.setEncoding(soapPart.getSourceCharsetEncoding()); 150 } 151 XMLReader rejectFilter; 152 try { 153 rejectFilter = new RejectDoctypeSaxFilter(saxParser); 154 } catch (Exception ex) { 155 log.severe("SAAJ0510.soap.cannot.create.envelope"); 156 throw new SOAPExceptionImpl( 157 "Unable to create envelope from given source: ", 158 ex); 159 } 160 src = new SAXSource(rejectFilter, is); 161 } 162 163 try { 164 Transformer transformer = 165 EfficientStreamingTransformer.newTransformer(); 166 DOMResult result = new DOMResult(soapPart); 167 transformer.transform(src, result); 168 169 Envelope env = (Envelope) soapPart.getEnvelope(); 170 return env; 171 } catch (Exception ex) { 172 if (ex instanceof SOAPVersionMismatchException) { 173 throw (SOAPVersionMismatchException) ex; 174 } 175 log.severe("SAAJ0511.soap.cannot.create.envelope"); 176 throw new SOAPExceptionImpl( 177 "Unable to create envelope from given source: ", 178 ex); 179 } finally { 180 if (saxParser != null) { 181 parserPool.get().returnParser(saxParser); 182 } 183 } 184 } 185 }