1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.portletbridge.portlet;
17
18 import java.io.StringReader;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.security.MessageDigest;
22 import java.security.NoSuchAlgorithmException;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import javax.xml.transform.ErrorListener;
28 import javax.xml.transform.Source;
29 import javax.xml.transform.Templates;
30 import javax.xml.transform.TransformerConfigurationException;
31 import javax.xml.transform.TransformerException;
32 import javax.xml.transform.TransformerFactory;
33 import javax.xml.transform.TransformerFactoryConfigurationError;
34 import javax.xml.transform.stream.StreamSource;
35
36 import org.portletbridge.ResourceException;
37
38 /***
39 * @author JMcCrindle
40 */
41 public class DefaultTemplateFactory implements TemplateFactory {
42
43 private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
44 .getLog(DefaultTemplateFactory.class);
45
46 private Templates defaultTemplate;
47
48 private String defaultTemplateSytemId;
49
50 private Map templateCache = Collections.synchronizedMap(new HashMap());
51
52 public DefaultTemplateFactory() {
53 defaultTemplateSytemId = getClass().getResource(
54 "/org/portletbridge/xsl/default.xsl").toExternalForm();
55 Source templateSource = new StreamSource(defaultTemplateSytemId);
56 try {
57 defaultTemplate = TransformerFactory.newInstance().newTemplates(
58 templateSource);
59 log.debug("created default template");
60 } catch (TransformerConfigurationException e) {
61 throw new IllegalStateException(e.getMessage());
62 } catch (TransformerFactoryConfigurationError e) {
63 throw new IllegalStateException(e.getMessage());
64 }
65 }
66
67 /***
68 * Creates compiled templates for a particular stylesheet for performance.
69 *
70 * @param systemId
71 * the stylesheet to compile
72 * @return @throws
73 * ResourceException if the stylesheet could not be found.
74 * @throws TransformerFactoryConfigurationError
75 * if there was a problem finding a suitable transformer
76 * factory.
77 */
78 public Templates getTemplatesFromUrl(String systemId)
79 throws ResourceException, TransformerFactoryConfigurationError {
80 if (systemId == null) {
81 throw new ResourceException("error.stylesheet");
82 }
83 Templates result = null;
84 TransformerFactory factory = TransformerFactory.newInstance();
85 try {
86
87
88 Templates templates = (Templates) templateCache.get(systemId);
89 if(templates != null) {
90 return templates;
91 } else {
92 URL resourceUrl = null;
93 if (systemId.startsWith("classpath:")) {
94 String substring = systemId.substring(10);
95 resourceUrl = this.getClass().getResource(substring);
96 } else {
97 resourceUrl = new URL(systemId);
98 }
99 if (resourceUrl == null) {
100 throw new ResourceException("error.stylesheet.notfound",
101 systemId);
102 }
103 result = factory.newTemplates(new StreamSource(resourceUrl
104 .toExternalForm()));
105 templateCache.put(systemId, result);
106 }
107 } catch (TransformerConfigurationException e) {
108 throw new ResourceException("error.transformer", e.getMessage(), e);
109 } catch (MalformedURLException e) {
110 throw new ResourceException("error.stylesheet.url", e.getMessage(),
111 e);
112 }
113 return result;
114 }
115
116 /***
117 * Creates compiled templates for a particular stylesheet for performance.
118 *
119 * @param stylesheet
120 * the stylesheet to compile
121 * @return @throws
122 * ResourceException if the stylesheet could not be found.
123 * @throws TransformerFactoryConfigurationError
124 * if there was a problem finding a suitable transformer
125 * factory.
126 */
127 public Templates getTemplatesFromString(String stylesheet)
128 throws ResourceException, TransformerFactoryConfigurationError {
129
130 if (stylesheet == null || stylesheet.trim().length() == 0) {
131 return defaultTemplate;
132 }
133 Templates result = null;
134 TransformerFactory factory = TransformerFactory.newInstance();
135 final Exception[] exceptionHolder = new Exception[1];
136 factory.setErrorListener(new ErrorListener() {
137 public void error(TransformerException exception)
138 throws TransformerException {
139 exceptionHolder[0] = exception;
140 }
141
142 public void fatalError(TransformerException exception)
143 throws TransformerException {
144 exceptionHolder[0] = exception;
145 }
146
147 public void warning(TransformerException exception)
148 throws TransformerException {
149 exceptionHolder[0] = exception;
150 }
151 });
152
153 try {
154
155 MessageDigest messageDigest = MessageDigest.getInstance("MD5");
156 messageDigest.update(stylesheet.getBytes());
157 String key = new String(messageDigest.digest());
158 Templates templates = (Templates) templateCache.get(key);
159 if(templates != null) {
160 result = templates;
161 } else {
162 result = factory.newTemplates(new StreamSource(new StringReader(
163 stylesheet), defaultTemplateSytemId));
164 templateCache.put(key, result);
165 }
166 } catch (TransformerConfigurationException e) {
167 exceptionHolder[0] = e;
168 } catch (NoSuchAlgorithmException e) {
169 exceptionHolder[0] = e;
170 }
171 if (exceptionHolder[0] != null) {
172 throw new ResourceException("error.transformer", exceptionHolder[0].getMessage(), exceptionHolder[0]);
173 }
174 return result;
175 }
176
177 }