View Javadoc

1   /*
2    * Copyright 2007 Hippo
3    *
4    * Licensed under the Apache License, Version 2.0 (the  "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  package nl.hippo.client.webdav.utils;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import javax.xml.transform.ErrorListener;
26  import javax.xml.transform.Result;
27  import javax.xml.transform.Source;
28  import javax.xml.transform.Templates;
29  import javax.xml.transform.Transformer;
30  import javax.xml.transform.TransformerConfigurationException;
31  import javax.xml.transform.TransformerException;
32  import javax.xml.transform.TransformerFactory;
33  import javax.xml.transform.stream.StreamSource;
34  
35  import nl.hippo.client.api.ClientException;
36  import nl.hippo.client.webdav.WebdavResponse;
37  
38  /**
39   * Wraps an xslt transformer
40   */
41  public class XslTransformer {
42  
43      private static TransformerFactory transformerFactory = TransformerFactory.newInstance();
44      private static ErrorMultiplexer errorMultiplexer = new ErrorMultiplexer();
45      static {
46          transformerFactory.setErrorListener(errorMultiplexer);
47      }
48  
49      private XslTransformer() {
50          //This class contains only static methods and should not be instantiated
51      }
52  
53      /**
54       * A map of precompiled xslt templates
55       */
56      private static Map templates = Collections.synchronizedMap(new HashMap());
57  
58      /**
59       * Perform an xslt transformation
60       * 
61       * @param xslt IntputStream on a UTF-8 encoded valid xslt document
62       * @param source XML source
63       * @param result XML result
64       * @return A list of errors 
65       * 
66       * @throws ClientException If something went wrong.
67       */
68      public static List transform(WebdavResponse xslt, Source source, Result result) throws ClientException {
69          try {
70              
71              //Precompile the xsl to a Templates object collecting all errors/warnings.
72              Templates template;
73              ErrorHandler handler = new ErrorHandler();
74              errorMultiplexer.addListener(handler);
75              if (templates.containsKey(xslt)) {
76                  template = (Templates) templates.get(xslt);
77              } else {
78                  template = transformerFactory.newTemplates(new StreamSource(xslt.getResponseAsStream()));
79                  templates.put(xslt, template);
80              }
81              
82              Transformer transformer = template.newTransformer();            
83              transformer.transform(source, result);
84              errorMultiplexer.removeListener(handler);
85              return handler.errors();
86          } catch (TransformerConfigurationException e) {
87              throw new ClientException("transformation failed", e);
88          } catch (TransformerException e) {
89              throw new ClientException("transformation failed", e);
90          }
91      }
92  
93      /**
94       * Perform an identity xslt transformation
95       * @param source XML source
96       * @param result XML result
97       * @throws ClientException If something went wrong
98       */
99      public static void identityTransform(Source source, Result result) throws ClientException {
100         try {
101             Transformer identityTransformer = transformerFactory.newTransformer();
102             identityTransformer.transform(source, result);
103         } catch (TransformerConfigurationException e) {
104             throw new ClientException("Transformation failed.", e);
105         } catch (TransformerException e) {
106             throw new ClientException("Transformation failed.", e);
107         }
108     }
109 }
110 
111 class ErrorHandler implements ErrorListener {
112     List errors = new ArrayList();
113 
114     public void error(TransformerException exception) throws TransformerException {
115         errors.add("TransformerException, error: " + exception.toString());
116     }
117 
118     public void fatalError(TransformerException exception) throws TransformerException {
119         errors.add("TransformerException, fatal error: " + exception.toString());
120     }
121 
122     public void warning(TransformerException exception) throws TransformerException {
123         errors.add("TransformerException, warning: " + exception.toString());
124     }
125     
126     public List errors() {
127         return errors;
128     }
129 };
130 
131 class ErrorMultiplexer implements ErrorListener {
132     
133     private List listeners = Collections.synchronizedList(new ArrayList());
134 
135     void addListener(ErrorListener listener) {
136         listeners.add(listener);
137     }
138 
139     void removeListener(ErrorListener listener) {
140         listeners.remove(listener);
141     }
142 
143     public void error(TransformerException exception) throws TransformerException {
144         Iterator it = listeners.iterator();
145         while (it.hasNext()) {
146             ErrorListener listener = (ErrorListener) it.next();
147             listener.error(exception);
148         }
149     }
150 
151     public void fatalError(TransformerException exception) throws TransformerException {
152         Iterator it = listeners.iterator();
153         while (it.hasNext()) {
154             ErrorListener listener = (ErrorListener) it.next();
155             listener.error(exception);
156         }
157     }
158 
159     public void warning(TransformerException exception) throws TransformerException {
160         Iterator it = listeners.iterator();
161         while (it.hasNext()) {
162             ErrorListener listener = (ErrorListener) it.next();
163             listener.error(exception);
164         }
165     }
166 }