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