1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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 }