Mon, 20 Apr 2009 15:14:39 -0700
6831313: update jaxws in OpenJDK7 to 2.1 plus bug fixes from OpenJDK 6
6672868: Package javax.xml.ws.wsaddressing not included in make/docs/CORE_PKGS.gmk
Reviewed-by: darcy
1 /*
2 * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
27 /*
28 * EfficientStreamingTransformer.java
29 *
30 * Created on July 29, 2002, 3:49 PM
31 */
33 package com.sun.xml.internal.messaging.saaj.util.transform;
35 import java.io.*;
37 import javax.xml.parsers.DocumentBuilder;
38 import javax.xml.parsers.DocumentBuilderFactory;
40 import javax.xml.transform.*;
41 import javax.xml.transform.dom.DOMSource;
42 import javax.xml.transform.dom.DOMResult;
43 import javax.xml.transform.stream.StreamResult;
44 import javax.xml.transform.stream.StreamSource;
46 import org.w3c.dom.Document;
48 import com.sun.xml.internal.messaging.saaj.util.XMLDeclarationParser;
49 import com.sun.xml.internal.messaging.saaj.util.FastInfosetReflection;
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 {
65 static final String version;
66 static final String vendor;
68 protected static TransformerFactory transformerFactory = TransformerFactory.newInstance();
70 static {
71 version = System.getProperty("java.vm.version");
72 vendor = System.getProperty("java.vm.vendor");
73 if (vendor.startsWith("Sun") &&
74 (version.startsWith("1.4") || version.startsWith("1.3"))) {
75 transformerFactory =
76 new com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl();
77 }
78 }
80 /**
81 * TransformerFactory instance.
82 */
84 /**
85 * Underlying XSLT transformer.
86 */
87 private Transformer m_realTransformer = null;
89 /**
90 * Undelying FI DOM parser.
91 */
92 private Object m_fiDOMDocumentParser = null;
94 /**
95 * Underlying FI DOM serializer.
96 */
97 private Object m_fiDOMDocumentSerializer = null;
99 private EfficientStreamingTransformer() {
100 }
102 private void materialize() throws TransformerException {
103 if (m_realTransformer == null) {
104 m_realTransformer = transformerFactory.newTransformer();
105 }
106 }
108 public void clearParameters() {
109 if (m_realTransformer != null)
110 m_realTransformer.clearParameters();
111 }
113 public javax.xml.transform.ErrorListener getErrorListener() {
114 try {
115 materialize();
116 return m_realTransformer.getErrorListener();
117 } catch (TransformerException e) {
118 // will be caught later
119 }
120 return null;
121 }
123 public java.util.Properties getOutputProperties() {
124 try {
125 materialize();
126 return m_realTransformer.getOutputProperties();
127 } catch (TransformerException e) {
128 // will be caught later
129 }
130 return null;
131 }
133 public String getOutputProperty(String str)
134 throws java.lang.IllegalArgumentException {
135 try {
136 materialize();
137 return m_realTransformer.getOutputProperty(str);
138 } catch (TransformerException e) {
139 // will be caught later
140 }
141 return null;
142 }
144 public Object getParameter(String str) {
145 try {
146 materialize();
147 return m_realTransformer.getParameter(str);
148 } catch (TransformerException e) {
149 // will be caught later
150 }
151 return null;
152 }
154 public javax.xml.transform.URIResolver getURIResolver() {
155 try {
156 materialize();
157 return m_realTransformer.getURIResolver();
158 } catch (TransformerException e) {
159 // will be caught later
160 }
161 return null;
162 }
164 public void setErrorListener(
165 javax.xml.transform.ErrorListener errorListener)
166 throws java.lang.IllegalArgumentException {
167 try {
168 materialize();
169 m_realTransformer.setErrorListener(errorListener);
170 } catch (TransformerException e) {
171 // will be caught later
172 }
173 }
175 public void setOutputProperties(java.util.Properties properties)
176 throws java.lang.IllegalArgumentException {
177 try {
178 materialize();
179 m_realTransformer.setOutputProperties(properties);
180 } catch (TransformerException e) {
181 // will be caught later
182 }
183 }
185 public void setOutputProperty(String str, String str1)
186 throws java.lang.IllegalArgumentException {
187 try {
188 materialize();
189 m_realTransformer.setOutputProperty(str, str1);
190 } catch (TransformerException e) {
191 // will be caught later
192 }
193 }
195 public void setParameter(String str, Object obj) {
196 try {
197 materialize();
198 m_realTransformer.setParameter(str, obj);
199 } catch (TransformerException e) {
200 // will be caught later
201 }
202 }
204 public void setURIResolver(javax.xml.transform.URIResolver uRIResolver) {
205 try {
206 materialize();
207 m_realTransformer.setURIResolver(uRIResolver);
208 } catch (TransformerException e) {
209 // will be caught later
210 }
211 }
213 private InputStream getInputStreamFromSource(StreamSource s)
214 throws TransformerException {
216 InputStream stream = s.getInputStream();
217 if (stream != null)
218 return stream;
220 if (s.getReader() != null)
221 return null;
223 String systemId = s.getSystemId();
224 if (systemId != null) {
225 try {
226 String fileURL = systemId;
228 if (systemId.startsWith("file:///"))
229 {
230 /*
231 systemId is:
232 file:///<drive>:/some/path/file.xml
233 or
234 file:///some/path/file.xml
235 */
237 String absolutePath = systemId.substring(7);
238 /*
239 /<drive>:/some/path/file.xml
240 or
241 /some/path/file.xml
242 */
244 boolean hasDriveDesignator = absolutePath.indexOf(":") > 0;
245 if (hasDriveDesignator) {
246 String driveDesignatedPath = absolutePath.substring(1);
247 /*
248 <drive>:/some/path/file.xml */
249 fileURL = driveDesignatedPath;
250 }
251 else {
252 /*
253 /some/path/file.xml */
254 fileURL = absolutePath;
255 }
256 }
257 return new FileInputStream(fileURL);
258 } catch (IOException e) {
259 throw new TransformerException(e.toString());
260 }
261 }
263 throw new TransformerException("Unexpected StreamSource object");
264 }
266 //------------------------------------------------------------------------
268 public void transform(
269 javax.xml.transform.Source source,
270 javax.xml.transform.Result result)
271 throws javax.xml.transform.TransformerException
272 {
273 // StreamSource -> StreamResult
274 if ((source instanceof StreamSource)
275 && (result instanceof StreamResult)) {
276 try {
277 StreamSource streamSource = (StreamSource) source;
278 InputStream is = getInputStreamFromSource(streamSource);
280 OutputStream os = ((StreamResult) result).getOutputStream();
281 if (os == null)
282 // TODO: We might want to fix this if it were to be used beyond
283 // XmlDataContentHandler that we know uses only OutputStream
284 throw new TransformerException("Unexpected StreamResult object contains null OutputStream");
286 if (is != null) {
287 if (is.markSupported())
288 is.mark(Integer.MAX_VALUE);
289 int num;
290 byte[] b = new byte[8192];
291 while ((num = is.read(b)) != -1) {
292 os.write(b, 0, num);
293 }
294 if (is.markSupported())
295 is.reset();
296 return;
297 }
299 Reader reader = streamSource.getReader();
300 if (reader != null) {
302 if (reader.markSupported())
303 reader.mark(Integer.MAX_VALUE);
305 PushbackReader pushbackReader = new PushbackReader(reader, 4096);
306 //some size to unread <?xml ....?>
307 XMLDeclarationParser ev =
308 new XMLDeclarationParser(pushbackReader);
309 try {
310 ev.parse();
311 } catch (Exception ex) {
312 throw new TransformerException(
313 "Unable to run the JAXP transformer on a stream "
314 + ex.getMessage());
315 }
316 Writer writer =
317 new OutputStreamWriter(os /*, ev.getEncoding()*/);
318 ev.writeTo(writer); // doesn't write any, if no header
320 int num;
321 char[] ac = new char[8192];
322 while ((num = pushbackReader.read(ac)) != -1) {
323 writer.write(ac, 0, num);
324 }
325 writer.flush();
327 if (reader.markSupported())
328 reader.reset();
329 return;
330 }
331 } catch (IOException e) {
332 e.printStackTrace();
333 throw new TransformerException(e.toString());
334 }
336 throw new TransformerException("Unexpected StreamSource object");
337 }
338 // FastInfosetSource -> DOMResult
339 else if (FastInfosetReflection.isFastInfosetSource(source)
340 && (result instanceof DOMResult))
341 {
342 try {
343 // Use reflection to avoid a static dep with FI
344 if (m_fiDOMDocumentParser == null) {
345 m_fiDOMDocumentParser = FastInfosetReflection.DOMDocumentParser_new();
346 }
348 // m_fiDOMDocumentParser.parse(document, source.getInputStream())
349 FastInfosetReflection.DOMDocumentParser_parse(
350 m_fiDOMDocumentParser,
351 (Document) ((DOMResult) result).getNode(),
352 FastInfosetReflection.FastInfosetSource_getInputStream(source));
354 // We're done!
355 return;
356 }
357 catch (Exception e) {
358 throw new TransformerException(e);
359 }
360 }
361 // DOMSource -> FastInfosetResult
362 else if ((source instanceof DOMSource)
363 && FastInfosetReflection.isFastInfosetResult(result))
364 {
365 try {
366 // Use reflection to avoid a static dep with FI
367 if (m_fiDOMDocumentSerializer == null) {
368 m_fiDOMDocumentSerializer = FastInfosetReflection.DOMDocumentSerializer_new();
369 }
371 // m_fiDOMDocumentSerializer.setOutputStream(result.getOutputStream())
372 FastInfosetReflection.DOMDocumentSerializer_setOutputStream(
373 m_fiDOMDocumentSerializer,
374 FastInfosetReflection.FastInfosetResult_getOutputStream(result));
376 // m_fiDOMDocumentSerializer.serialize(node)
377 FastInfosetReflection.DOMDocumentSerializer_serialize(
378 m_fiDOMDocumentSerializer,
379 ((DOMSource) source).getNode());
381 // We're done!
382 return;
383 }
384 catch (Exception e) {
385 throw new TransformerException(e);
386 }
387 }
389 // All other cases -- use transformer object
391 materialize();
392 m_realTransformer.transform(source, result);
393 }
395 /**
396 * Threadlocal to hold a Transformer instance for this thread.
397 */
398 private static ThreadLocal effTransformer = new ThreadLocal();
400 /**
401 * Return Transformer instance for this thread, allocating a new one if
402 * necessary. Note that this method does not clear global parameters,
403 * properties or any other data set on a previously used transformer.
404 */
405 public static Transformer newTransformer() {
406 Transformer tt = (Transformer) effTransformer.get();
407 if (tt == null) {
408 effTransformer.set(tt = new EfficientStreamingTransformer());
409 }
410 return tt;
411 }
413 }