src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/transform/EfficientStreamingTransformer.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 1997, 2012, 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 /*
27 * EfficientStreamingTransformer.java
28 *
29 * Created on July 29, 2002, 3:49 PM
30 */
31
32 package com.sun.xml.internal.messaging.saaj.util.transform;
33
34 import java.io.*;
35
36 import java.net.URISyntaxException;
37 import javax.xml.transform.dom.DOMSource;
38 import javax.xml.transform.dom.DOMResult;
39 import javax.xml.transform.stream.StreamResult;
40 import javax.xml.transform.stream.StreamSource;
41
42 import org.w3c.dom.Document;
43
44 import com.sun.xml.internal.messaging.saaj.util.XMLDeclarationParser;
45 import com.sun.xml.internal.messaging.saaj.util.FastInfosetReflection;
46 import java.net.URI;
47 import javax.xml.transform.Transformer;
48 import javax.xml.transform.TransformerException;
49 import javax.xml.transform.TransformerFactory;
50
51 /**
52 * This class is a proxy for a Transformer object with optimizations
53 * for certain cases. If source and result are of type stream, then
54 * bytes are simply copied whenever possible (note that this assumes
55 * that the input is well formed). In addition, it provides support for
56 * FI using native DOM parsers and serializers.
57 *
58 * @author Panos Kougiouris panos@acm.org
59 * @author Santiago.PericasGeertsen@sun.com
60 *
61 */
62 public class EfficientStreamingTransformer
63 extends javax.xml.transform.Transformer {
64
65 //static final String version;
66 //static final String vendor;
67 // removing static : security issue : CR 6813167Z
68 private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
69
70 /**
71 removing support for Java 1.4 and 1.3 : CR6658158
72 static {
73 version = System.getProperty("java.vm.version");
74 vendor = System.getProperty("java.vm.vendor");
75 if (vendor.startsWith("Sun") &&
76 (version.startsWith("1.4") || version.startsWith("1.3"))) {
77 transformerFactory =
78 new com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl();
79 }
80 }*/
81
82 /**
83 * TransformerFactory instance.
84 */
85
86 /**
87 * Underlying XSLT transformer.
88 */
89 private Transformer m_realTransformer = null;
90
91 /**
92 * Undelying FI DOM parser.
93 */
94 private Object m_fiDOMDocumentParser = null;
95
96 /**
97 * Underlying FI DOM serializer.
98 */
99 private Object m_fiDOMDocumentSerializer = null;
100
101 private EfficientStreamingTransformer() {
102 }
103
104 private void materialize() throws TransformerException {
105 if (m_realTransformer == null) {
106 m_realTransformer = transformerFactory.newTransformer();
107 }
108 }
109
110 public void clearParameters() {
111 if (m_realTransformer != null)
112 m_realTransformer.clearParameters();
113 }
114
115 public javax.xml.transform.ErrorListener getErrorListener() {
116 try {
117 materialize();
118 return m_realTransformer.getErrorListener();
119 } catch (TransformerException e) {
120 // will be caught later
121 }
122 return null;
123 }
124
125 public java.util.Properties getOutputProperties() {
126 try {
127 materialize();
128 return m_realTransformer.getOutputProperties();
129 } catch (TransformerException e) {
130 // will be caught later
131 }
132 return null;
133 }
134
135 public String getOutputProperty(String str)
136 throws java.lang.IllegalArgumentException {
137 try {
138 materialize();
139 return m_realTransformer.getOutputProperty(str);
140 } catch (TransformerException e) {
141 // will be caught later
142 }
143 return null;
144 }
145
146 public Object getParameter(String str) {
147 try {
148 materialize();
149 return m_realTransformer.getParameter(str);
150 } catch (TransformerException e) {
151 // will be caught later
152 }
153 return null;
154 }
155
156 public javax.xml.transform.URIResolver getURIResolver() {
157 try {
158 materialize();
159 return m_realTransformer.getURIResolver();
160 } catch (TransformerException e) {
161 // will be caught later
162 }
163 return null;
164 }
165
166 public void setErrorListener(
167 javax.xml.transform.ErrorListener errorListener)
168 throws java.lang.IllegalArgumentException {
169 try {
170 materialize();
171 m_realTransformer.setErrorListener(errorListener);
172 } catch (TransformerException e) {
173 // will be caught later
174 }
175 }
176
177 public void setOutputProperties(java.util.Properties properties)
178 throws java.lang.IllegalArgumentException {
179 try {
180 materialize();
181 m_realTransformer.setOutputProperties(properties);
182 } catch (TransformerException e) {
183 // will be caught later
184 }
185 }
186
187 public void setOutputProperty(String str, String str1)
188 throws java.lang.IllegalArgumentException {
189 try {
190 materialize();
191 m_realTransformer.setOutputProperty(str, str1);
192 } catch (TransformerException e) {
193 // will be caught later
194 }
195 }
196
197 public void setParameter(String str, Object obj) {
198 try {
199 materialize();
200 m_realTransformer.setParameter(str, obj);
201 } catch (TransformerException e) {
202 // will be caught later
203 }
204 }
205
206 public void setURIResolver(javax.xml.transform.URIResolver uRIResolver) {
207 try {
208 materialize();
209 m_realTransformer.setURIResolver(uRIResolver);
210 } catch (TransformerException e) {
211 // will be caught later
212 }
213 }
214
215 private InputStream getInputStreamFromSource(StreamSource s)
216 throws TransformerException {
217
218 InputStream stream = s.getInputStream();
219 if (stream != null)
220 return stream;
221
222 if (s.getReader() != null)
223 return null;
224
225 String systemId = s.getSystemId();
226 if (systemId != null) {
227 try {
228 String fileURL = systemId;
229
230 if (systemId.startsWith("file:///"))
231 {
232 /*
233 systemId is:
234 file:///<drive>:/some/path/file.xml
235 or
236 file:///some/path/file.xml
237 */
238
239 String absolutePath = systemId.substring(7);
240 /*
241 /<drive>:/some/path/file.xml
242 or
243 /some/path/file.xml
244 */
245
246 boolean hasDriveDesignator = absolutePath.indexOf(":") > 0;
247 if (hasDriveDesignator) {
248 String driveDesignatedPath = absolutePath.substring(1);
249 /*
250 <drive>:/some/path/file.xml */
251 fileURL = driveDesignatedPath;
252 }
253 else {
254 /*
255 /some/path/file.xml */
256 fileURL = absolutePath;
257 }
258 }
259 //return new FileInputStream(fileURL);
260 try {
261 return new FileInputStream(new File(new URI(fileURL)));
262 } catch (URISyntaxException ex) {
263 throw new TransformerException(ex);
264 }
265 } catch (IOException e) {
266 throw new TransformerException(e.toString());
267 }
268 }
269
270 throw new TransformerException("Unexpected StreamSource object");
271 }
272
273 //------------------------------------------------------------------------
274
275 public void transform(
276 javax.xml.transform.Source source,
277 javax.xml.transform.Result result)
278 throws javax.xml.transform.TransformerException
279 {
280 // StreamSource -> StreamResult
281 if ((source instanceof StreamSource)
282 && (result instanceof StreamResult)) {
283 try {
284 StreamSource streamSource = (StreamSource) source;
285 InputStream is = getInputStreamFromSource(streamSource);
286
287 OutputStream os = ((StreamResult) result).getOutputStream();
288 if (os == null)
289 // TODO: We might want to fix this if it were to be used beyond
290 // XmlDataContentHandler that we know uses only OutputStream
291 throw new TransformerException("Unexpected StreamResult object contains null OutputStream");
292
293 if (is != null) {
294 if (is.markSupported())
295 is.mark(Integer.MAX_VALUE);
296 int num;
297 byte[] b = new byte[8192];
298 while ((num = is.read(b)) != -1) {
299 os.write(b, 0, num);
300 }
301 if (is.markSupported())
302 is.reset();
303 return;
304 }
305
306 Reader reader = streamSource.getReader();
307 if (reader != null) {
308
309 if (reader.markSupported())
310 reader.mark(Integer.MAX_VALUE);
311
312 PushbackReader pushbackReader = new PushbackReader(reader, 4096);
313 //some size to unread <?xml ....?>
314 XMLDeclarationParser ev =
315 new XMLDeclarationParser(pushbackReader);
316 try {
317 ev.parse();
318 } catch (Exception ex) {
319 throw new TransformerException(
320 "Unable to run the JAXP transformer on a stream "
321 + ex.getMessage());
322 }
323 Writer writer =
324 new OutputStreamWriter(os /*, ev.getEncoding()*/);
325 ev.writeTo(writer); // doesn't write any, if no header
326
327 int num;
328 char[] ac = new char[8192];
329 while ((num = pushbackReader.read(ac)) != -1) {
330 writer.write(ac, 0, num);
331 }
332 writer.flush();
333
334 if (reader.markSupported())
335 reader.reset();
336 return;
337 }
338 } catch (IOException e) {
339 e.printStackTrace();
340 throw new TransformerException(e.toString());
341 }
342
343 throw new TransformerException("Unexpected StreamSource object");
344 }
345 // FastInfosetSource -> DOMResult
346 else if (FastInfosetReflection.isFastInfosetSource(source)
347 && (result instanceof DOMResult))
348 {
349 try {
350 // Use reflection to avoid a static dep with FI
351 if (m_fiDOMDocumentParser == null) {
352 m_fiDOMDocumentParser = FastInfosetReflection.DOMDocumentParser_new();
353 }
354
355 // m_fiDOMDocumentParser.parse(document, source.getInputStream())
356 FastInfosetReflection.DOMDocumentParser_parse(
357 m_fiDOMDocumentParser,
358 (Document) ((DOMResult) result).getNode(),
359 FastInfosetReflection.FastInfosetSource_getInputStream(source));
360
361 // We're done!
362 return;
363 }
364 catch (Exception e) {
365 throw new TransformerException(e);
366 }
367 }
368 // DOMSource -> FastInfosetResult
369 else if ((source instanceof DOMSource)
370 && FastInfosetReflection.isFastInfosetResult(result))
371 {
372 try {
373 // Use reflection to avoid a static dep with FI
374 if (m_fiDOMDocumentSerializer == null) {
375 m_fiDOMDocumentSerializer = FastInfosetReflection.DOMDocumentSerializer_new();
376 }
377
378 // m_fiDOMDocumentSerializer.setOutputStream(result.getOutputStream())
379 FastInfosetReflection.DOMDocumentSerializer_setOutputStream(
380 m_fiDOMDocumentSerializer,
381 FastInfosetReflection.FastInfosetResult_getOutputStream(result));
382
383 // m_fiDOMDocumentSerializer.serialize(node)
384 FastInfosetReflection.DOMDocumentSerializer_serialize(
385 m_fiDOMDocumentSerializer,
386 ((DOMSource) source).getNode());
387
388 // We're done!
389 return;
390 }
391 catch (Exception e) {
392 throw new TransformerException(e);
393 }
394 }
395
396 // All other cases -- use transformer object
397
398 materialize();
399 m_realTransformer.transform(source, result);
400 }
401
402 /**
403 * Threadlocal to hold a Transformer instance for this thread.
404 * CR : 6813167
405 */
406 //private static ThreadLocal effTransformer = new ThreadLocal();
407
408 /**
409 * Return Transformer instance for this thread, allocating a new one if
410 * necessary. Note that this method does not clear global parameters,
411 * properties or any other data set on a previously used transformer.
412 */
413 public static Transformer newTransformer() {
414 //CR : 6813167
415 /*Transformer tt = (Transformer) effTransformer.get();
416 if (tt == null) {
417 effTransformer.set(tt = new EfficientStreamingTransformer());
418 }
419 return tt;*/
420 return new EfficientStreamingTransformer();
421 }
422
423 }

mercurial