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

Mon, 20 Apr 2009 15:14:39 -0700

author
tbell
date
Mon, 20 Apr 2009 15:14:39 -0700
changeset 45
31822b475baa
parent 1
0961a4a21176
child 50
42dfec6871f6
permissions
-rw-r--r--

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 }

mercurial