001
014
015 package com.liferay.taglib.util;
016
017 import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
018 import com.liferay.portal.kernel.freemarker.FreeMarkerEngineUtil;
019 import com.liferay.portal.kernel.freemarker.FreeMarkerVariablesUtil;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.servlet.PipingServletResponse;
024 import com.liferay.portal.kernel.servlet.ServletContextPool;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.ThemeHelper;
028 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.util.WebKeys;
031 import com.liferay.portal.kernel.velocity.VelocityContext;
032 import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
033 import com.liferay.portal.kernel.velocity.VelocityVariablesUtil;
034 import com.liferay.portal.model.PortletConstants;
035 import com.liferay.portal.model.Theme;
036 import com.liferay.portal.theme.PortletDisplay;
037 import com.liferay.portal.theme.ThemeDisplay;
038
039 import freemarker.ext.jsp.TaglibFactory;
040 import freemarker.ext.servlet.HttpRequestHashModel;
041 import freemarker.ext.servlet.ServletContextHashModel;
042
043 import freemarker.template.ObjectWrapper;
044
045 import java.io.IOException;
046 import java.io.Writer;
047
048 import javax.servlet.GenericServlet;
049 import javax.servlet.RequestDispatcher;
050 import javax.servlet.Servlet;
051 import javax.servlet.ServletContext;
052 import javax.servlet.ServletException;
053 import javax.servlet.ServletRequest;
054 import javax.servlet.ServletResponse;
055 import javax.servlet.http.HttpServletRequest;
056 import javax.servlet.http.HttpServletResponse;
057 import javax.servlet.jsp.PageContext;
058
059 import org.apache.struts.taglib.tiles.ComponentConstants;
060 import org.apache.struts.tiles.ComponentContext;
061
062
069 public class ThemeUtil {
070
071 public static String getPortletId(HttpServletRequest request) {
072 String portletId = null;
073
074 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
075 WebKeys.THEME_DISPLAY);
076
077 if (themeDisplay != null) {
078 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
079
080 portletId = portletDisplay.getId();
081 }
082
083 return portletId;
084 }
085
086 public static void include(
087 ServletContext servletContext, HttpServletRequest request,
088 HttpServletResponse response, PageContext pageContext, String page,
089 Theme theme)
090 throws Exception {
091
092 String extension = theme.getTemplateExtension();
093
094 if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_FTL)) {
095 includeFTL(servletContext, request, pageContext, page, theme, true);
096 }
097 else if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_VM)) {
098 includeVM(servletContext, request, pageContext, page, theme, true);
099 }
100 else {
101 String path = theme.getTemplatesPath() + StringPool.SLASH + page;
102
103 includeJSP(servletContext, request, response, path, theme);
104 }
105 }
106
107 public static String includeFTL(
108 ServletContext servletContext, HttpServletRequest request,
109 PageContext pageContext, String path, Theme theme, boolean write)
110 throws Exception {
111
112
113
114
115
116
117
118 String servletContextName = GetterUtil.getString(
119 theme.getServletContextName());
120
121 if (ServletContextPool.get(servletContextName) == null) {
122
123
124
125
126 ServletContextPool.put(servletContextName, servletContext);
127 }
128
129 String portletId = getPortletId(request);
130
131 String resourcePath = theme.getResourcePath(
132 servletContext, portletId, path);
133
134 if (Validator.isNotNull(portletId) &&
135 !FreeMarkerEngineUtil.resourceExists(resourcePath) &&
136 portletId.contains(PortletConstants.INSTANCE_SEPARATOR)) {
137
138 String rootPortletId = PortletConstants.getRootPortletId(
139 portletId);
140
141 resourcePath = theme.getResourcePath(
142 servletContext, rootPortletId, path);
143 }
144
145 if (Validator.isNotNull(portletId) &&
146 !FreeMarkerEngineUtil.resourceExists(resourcePath)) {
147
148 resourcePath = theme.getResourcePath(servletContext, null, path);
149 }
150
151 if (!FreeMarkerEngineUtil.resourceExists(resourcePath)) {
152 _log.error(resourcePath + " does not exist");
153
154 return null;
155 }
156
157 FreeMarkerContext freeMarkerContext =
158 FreeMarkerEngineUtil.getWrappedStandardToolsContext();
159
160
161
162 FreeMarkerVariablesUtil.insertVariables(freeMarkerContext, request);
163
164
165
166 ServletContext themeServletContext = ServletContextPool.get(
167 servletContextName);
168
169 freeMarkerContext.put("themeServletContext", themeServletContext);
170
171
172
173 HttpServletResponse response =
174 (HttpServletResponse)pageContext.getResponse();
175
176 Writer writer = null;
177
178 if (write) {
179
180
181
182 writer = UnsyncPrintWriterPool.borrow(pageContext.getOut());
183 }
184 else {
185 writer = new UnsyncStringWriter();
186 }
187
188 VelocityTaglib velocityTaglib = new VelocityTaglib(
189 servletContext, request,
190 new PipingServletResponse(response, writer), pageContext);
191
192 request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
193
194 freeMarkerContext.put("taglibLiferay", velocityTaglib);
195 freeMarkerContext.put("theme", velocityTaglib);
196
197
198
199 TaglibFactory portalTaglib = new TaglibFactory(servletContext);
200
201 freeMarkerContext.put("PortalJspTagLibs", portalTaglib);
202
203
204
205 TaglibFactory themeTaglib = new TaglibFactory(themeServletContext);
206
207 freeMarkerContext.put("ThemeJspTaglibs", themeTaglib);
208
209
210
211 final Servlet servlet = (Servlet)pageContext.getPage();
212
213 GenericServlet genericServlet = null;
214
215 if (servlet instanceof GenericServlet) {
216 genericServlet = (GenericServlet) servlet;
217 }
218 else {
219 genericServlet = new GenericServlet() {
220
221 @Override
222 public void service(
223 ServletRequest servletRequest,
224 ServletResponse servletResponse)
225 throws ServletException, IOException {
226
227 servlet.service(servletRequest, servletResponse);
228 }
229
230 };
231
232 genericServlet.init(pageContext.getServletConfig());
233 }
234
235 ServletContextHashModel servletContextHashModel =
236 new ServletContextHashModel(
237 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
238
239 freeMarkerContext.put("Application", servletContextHashModel);
240
241 HttpRequestHashModel httpRequestHashModel = new HttpRequestHashModel(
242 request, response, ObjectWrapper.DEFAULT_WRAPPER);
243
244 freeMarkerContext.put("Request", httpRequestHashModel);
245
246
247
248 FreeMarkerEngineUtil.mergeTemplate(
249 resourcePath, freeMarkerContext, writer);
250
251 if (write) {
252 return null;
253 }
254 else {
255 return writer.toString();
256 }
257 }
258
259 public static void includeJSP(
260 ServletContext servletContext, HttpServletRequest request,
261 HttpServletResponse response, String path, Theme theme)
262 throws Exception {
263
264 insertTilesVariables(request);
265
266 if (theme.isWARFile()) {
267 ServletContext themeServletContext = servletContext.getContext(
268 theme.getContextPath());
269
270 if (themeServletContext == null) {
271 _log.error(
272 "Theme " + theme.getThemeId() + " cannot find its " +
273 "servlet context at " + theme.getServletContextName());
274 }
275 else {
276 RequestDispatcher requestDispatcher =
277 themeServletContext.getRequestDispatcher(path);
278
279 if (requestDispatcher == null) {
280 _log.error(
281 "Theme " + theme.getThemeId() + " does not have " +
282 path);
283 }
284 else {
285 requestDispatcher.include(request, response);
286 }
287 }
288 }
289 else {
290 RequestDispatcher requestDispatcher =
291 servletContext.getRequestDispatcher(path);
292
293 if (requestDispatcher == null) {
294 _log.error(
295 "Theme " + theme.getThemeId() + " does not have " + path);
296 }
297 else {
298 requestDispatcher.include(request, response);
299 }
300 }
301 }
302
303 public static String includeVM(
304 ServletContext servletContext, HttpServletRequest request,
305 PageContext pageContext, String page, Theme theme, boolean write)
306 throws Exception {
307
308
309
310
311
312
313
314 String servletContextName = GetterUtil.getString(
315 theme.getServletContextName());
316
317 if (ServletContextPool.get(servletContextName) == null) {
318
319
320
321
322 ServletContextPool.put(servletContextName, servletContext);
323 }
324
325 String portletId = getPortletId(request);
326
327 String resourcePath = theme.getResourcePath(
328 servletContext, portletId, page);
329
330 boolean checkResourceExists = true;
331
332 if (Validator.isNotNull(portletId)) {
333 if (portletId.contains(PortletConstants.INSTANCE_SEPARATOR) &&
334 (checkResourceExists = !VelocityEngineUtil.resourceExists(
335 resourcePath))) {
336
337 String rootPortletId = PortletConstants.getRootPortletId(
338 portletId);
339
340 resourcePath = theme.getResourcePath(
341 servletContext, rootPortletId, page);
342 }
343
344 if (checkResourceExists &&
345 (checkResourceExists = !VelocityEngineUtil.resourceExists(
346 resourcePath))) {
347
348 resourcePath = theme.getResourcePath(
349 servletContext, null, page);
350 }
351 }
352
353 if (checkResourceExists &&
354 !VelocityEngineUtil.resourceExists(resourcePath)) {
355
356 _log.error(resourcePath + " does not exist");
357
358 return null;
359 }
360
361 VelocityContext velocityContext =
362 VelocityEngineUtil.getWrappedStandardToolsContext();
363
364
365
366 VelocityVariablesUtil.insertVariables(velocityContext, request);
367
368
369
370 velocityContext.put("pageContext", pageContext);
371
372
373
374 ServletContext themeServletContext = ServletContextPool.get(
375 servletContextName);
376
377 velocityContext.put("themeServletContext", themeServletContext);
378
379
380
381 HttpServletResponse response =
382 (HttpServletResponse)pageContext.getResponse();
383
384 Writer writer = null;
385
386 if (write) {
387 writer = pageContext.getOut();
388 }
389 else {
390 writer = new UnsyncStringWriter();
391 }
392
393 VelocityTaglib velocityTaglib = new VelocityTaglib(
394 servletContext, request,
395 new PipingServletResponse(response, writer), pageContext);
396
397 request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
398
399 velocityContext.put("taglibLiferay", velocityTaglib);
400 velocityContext.put("theme", velocityTaglib);
401 velocityContext.put("writer", writer);
402
403
404
405 VelocityEngineUtil.mergeTemplate(resourcePath, velocityContext, writer);
406
407 if (write) {
408 return null;
409 }
410 else {
411 return ((UnsyncStringWriter)writer).toString();
412 }
413 }
414
415 public static void insertTilesVariables(HttpServletRequest request) {
416 ComponentContext componentContext =
417 (ComponentContext)request.getAttribute(
418 ComponentConstants.COMPONENT_CONTEXT);
419
420 if (componentContext == null) {
421 return;
422 }
423
424 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
425 WebKeys.THEME_DISPLAY);
426
427 String tilesTitle = (String)componentContext.getAttribute("title");
428 String tilesContent = (String)componentContext.getAttribute("content");
429 boolean tilesSelectable = GetterUtil.getBoolean(
430 (String)componentContext.getAttribute("selectable"));
431
432 themeDisplay.setTilesTitle(tilesTitle);
433 themeDisplay.setTilesContent(tilesContent);
434 themeDisplay.setTilesSelectable(tilesSelectable);
435 }
436
437 private static Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
438
439 }