001
014
015 package com.liferay.portal.xsl;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
018 import com.liferay.portal.kernel.template.StringTemplateResource;
019 import com.liferay.portal.kernel.template.Template;
020 import com.liferay.portal.kernel.template.TemplateException;
021 import com.liferay.portal.kernel.template.TemplateResource;
022 import com.liferay.portal.kernel.util.LocaleUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.template.TemplateContextHelper;
025
026 import java.io.Writer;
027
028 import java.util.HashMap;
029 import java.util.Locale;
030 import java.util.Map;
031
032 import javax.servlet.http.HttpServletRequest;
033
034 import javax.xml.transform.Transformer;
035 import javax.xml.transform.TransformerFactory;
036 import javax.xml.transform.stream.StreamResult;
037 import javax.xml.transform.stream.StreamSource;
038
039
042 public class XSLTemplate implements Template {
043
044 public XSLTemplate(
045 XSLTemplateResource xslTemplateResource,
046 TemplateResource errorTemplateResource, Map<String, Object> context,
047 TemplateContextHelper templateContextHelper) {
048
049 if (xslTemplateResource == null) {
050 throw new IllegalArgumentException("XSL template resource is null");
051 }
052
053 if (templateContextHelper == null) {
054 throw new IllegalArgumentException(
055 "Template context helper is null");
056 }
057
058 _xslTemplateResource = xslTemplateResource;
059 _errorTemplateResource = errorTemplateResource;
060 _templateContextHelper = templateContextHelper;
061
062 _context = new HashMap<String, Object>();
063
064 if (context != null) {
065 for (Map.Entry<String, Object> entry : context.entrySet()) {
066 put(entry.getKey(), entry.getValue());
067 }
068 }
069 }
070
071 public Object get(String key) {
072 return _context.get(key);
073 }
074
075 public void prepare(HttpServletRequest request) {
076 _templateContextHelper.prepare(this, request);
077 }
078
079 public boolean processTemplate(Writer writer) throws TemplateException {
080 TransformerFactory transformerFactory =
081 TransformerFactory.newInstance();
082
083 String languageId = null;
084
085 XSLURIResolver xslURIResolver =
086 _xslTemplateResource.getXSLURIResolver();
087
088 if (xslURIResolver != null) {
089 languageId = xslURIResolver.getLanguageId();
090 }
091
092 Locale locale = LocaleUtil.fromLanguageId(languageId);
093
094 XSLErrorListener xslErrorListener = new XSLErrorListener(locale);
095
096 transformerFactory.setErrorListener(xslErrorListener);
097
098 transformerFactory.setURIResolver(xslURIResolver);
099
100 StreamSource xmlSource = new StreamSource(
101 _xslTemplateResource.getXMLReader());
102
103 Transformer transformer = _getTransformer(
104 transformerFactory, _xslTemplateResource);
105
106 if (_errorTemplateResource == null) {
107 try {
108 transformer.transform(xmlSource, new StreamResult(writer));
109
110 return true;
111 }
112 catch (Exception e) {
113 throw new TemplateException(
114 "Unable to process XSL template " +
115 _xslTemplateResource.getTemplateId(),
116 e);
117 }
118 }
119
120 try {
121 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
122
123 transformer.setParameter(WRITER, unsyncStringWriter);
124
125 transformer.transform(
126 xmlSource, new StreamResult(unsyncStringWriter));
127
128 StringBundler sb = unsyncStringWriter.getStringBundler();
129
130 sb.writeTo(writer);
131
132 return true;
133 }
134 catch (Exception e1) {
135 Transformer errorTransformer = _getTransformer(
136 transformerFactory, _errorTemplateResource);
137
138 errorTransformer.setParameter(WRITER, writer);
139 errorTransformer.setParameter(
140 "exception", xslErrorListener.getMessageAndLocation());
141
142 if (_errorTemplateResource instanceof StringTemplateResource) {
143 StringTemplateResource stringTemplateResource =
144 (StringTemplateResource)_errorTemplateResource;
145
146 errorTransformer.setParameter(
147 "script", stringTemplateResource.getContent());
148 }
149
150 if (xslErrorListener.getLocation() != null) {
151 errorTransformer.setParameter(
152 "column", new Integer(xslErrorListener.getColumnNumber()));
153 errorTransformer.setParameter(
154 "line", new Integer(xslErrorListener.getLineNumber()));
155 }
156
157 try {
158 errorTransformer.transform(xmlSource, new StreamResult(writer));
159 }
160 catch (Exception e2) {
161 throw new TemplateException(
162 "Unable to process XSL template " +
163 _errorTemplateResource.getTemplateId(),
164 e2);
165 }
166
167 return false;
168 }
169 }
170
171 public void put(String key, Object value) {
172 if (value == null) {
173 return;
174 }
175
176 _context.put(key, value);
177 }
178
179 private Transformer _getTransformer(
180 TransformerFactory transformerFactory,
181 TemplateResource templateResource)
182 throws TemplateException {
183
184 try {
185 StreamSource scriptSource = new StreamSource(
186 templateResource.getReader());
187
188 Transformer transformer = transformerFactory.newTransformer(
189 scriptSource);
190
191 for (Map.Entry<String, Object> entry : _context.entrySet()) {
192 transformer.setParameter(entry.getKey(), entry.getValue());
193 }
194
195 return transformer;
196 }
197 catch (Exception e) {
198 throw new TemplateException(
199 "Unable to get Transformer for template " +
200 templateResource.getTemplateId(),
201 e);
202 }
203 }
204
205 private Map<String, Object> _context;
206 private TemplateResource _errorTemplateResource;
207 private TemplateContextHelper _templateContextHelper;
208 private XSLTemplateResource _xslTemplateResource;
209
210 }