001
014
015 package com.liferay.taglib.util;
016
017 import com.liferay.kernel.servlet.taglib.DynamicIncludeUtil;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.servlet.JSPSupportServlet;
022 import com.liferay.portal.kernel.servlet.ServletContextPool;
023 import com.liferay.portal.kernel.template.Template;
024 import com.liferay.portal.kernel.template.TemplateConstants;
025 import com.liferay.portal.kernel.template.TemplateManagerUtil;
026 import com.liferay.portal.kernel.template.TemplateResource;
027 import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.ThemeHelper;
031 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.kernel.util.WebKeys;
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 import com.liferay.taglib.servlet.PipingServletResponse;
039 import com.liferay.util.freemarker.FreeMarkerTaglibFactoryUtil;
040
041 import freemarker.ext.servlet.HttpRequestHashModel;
042 import freemarker.ext.servlet.ServletContextHashModel;
043
044 import freemarker.template.ObjectWrapper;
045 import freemarker.template.TemplateHashModel;
046
047 import java.io.Writer;
048
049 import javax.servlet.GenericServlet;
050 import javax.servlet.RequestDispatcher;
051 import javax.servlet.ServletContext;
052 import javax.servlet.http.HttpServletRequest;
053 import javax.servlet.http.HttpServletResponse;
054
055
062 public class ThemeUtil {
063
064 public static String getPortletId(HttpServletRequest request) {
065 String portletId = null;
066
067 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
068 WebKeys.THEME_DISPLAY);
069
070 if (themeDisplay != null) {
071 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
072
073 portletId = portletDisplay.getId();
074 }
075
076 return portletId;
077 }
078
079 public static void include(
080 ServletContext servletContext, HttpServletRequest request,
081 HttpServletResponse response, String path, Theme theme)
082 throws Exception {
083
084 String extension = theme.getTemplateExtension();
085
086 if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_FTL)) {
087 includeFTL(servletContext, request, response, path, theme, true);
088 }
089 else if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_VM)) {
090 includeVM(servletContext, request, response, path, theme, true);
091 }
092 else {
093 path = theme.getTemplatesPath() + StringPool.SLASH + path;
094
095 includeJSP(servletContext, request, response, path, theme);
096 }
097 }
098
099 public static String includeFTL(
100 ServletContext servletContext, HttpServletRequest request,
101 HttpServletResponse response, String path, Theme theme,
102 boolean write)
103 throws Exception {
104
105 return doDispatch(
106 servletContext, request, response, path, theme, write,
107 ThemeHelper.TEMPLATE_EXTENSION_FTL);
108 }
109
110 public static void includeJSP(
111 ServletContext servletContext, HttpServletRequest request,
112 HttpServletResponse response, String path, Theme theme)
113 throws Exception {
114
115 doDispatch(
116 servletContext, request, response, path, theme, true,
117 ThemeHelper.TEMPLATE_EXTENSION_JSP);
118 }
119
120 public static String includeVM(
121 ServletContext servletContext, HttpServletRequest request,
122 HttpServletResponse response, String path, Theme theme,
123 boolean write)
124 throws Exception {
125
126 return doDispatch(
127 servletContext, request, response, path, theme, write,
128 ThemeHelper.TEMPLATE_EXTENSION_VM);
129 }
130
131 protected static String doDispatch(
132 ServletContext servletContext, HttpServletRequest request,
133 HttpServletResponse response, String path, Theme theme,
134 boolean write, String extension)
135 throws Exception {
136
137 String pluginServletContextName = GetterUtil.getString(
138 theme.getServletContextName());
139
140 ServletContext pluginServletContext = ServletContextPool.get(
141 pluginServletContextName);
142
143 ClassLoader pluginClassLoader = null;
144
145 if (pluginServletContext != null) {
146 pluginClassLoader = pluginServletContext.getClassLoader();
147 }
148
149 Thread currentThread = Thread.currentThread();
150
151 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
152
153 if ((pluginClassLoader != null) &&
154 (pluginClassLoader != contextClassLoader)) {
155
156 currentThread.setContextClassLoader(pluginClassLoader);
157 }
158
159 try {
160 if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_FTL)) {
161 return doIncludeFTL(
162 servletContext, request, response, path, theme, false,
163 write);
164 }
165 else if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_JSP)) {
166 doIncludeJSP(servletContext, request, response, path, theme);
167 }
168 else if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_VM)) {
169 return doIncludeVM(
170 servletContext, request, response, path, theme, false,
171 write);
172 }
173
174 return null;
175 }
176 finally {
177 if ((pluginClassLoader != null) &&
178 (pluginClassLoader != contextClassLoader)) {
179
180 currentThread.setContextClassLoader(contextClassLoader);
181 }
182 }
183 }
184
185 protected static String doIncludeFTL(
186 ServletContext servletContext, HttpServletRequest request,
187 HttpServletResponse response, String path, Theme theme,
188 boolean restricted, boolean write)
189 throws Exception {
190
191
192
193
194
195
196
197 String servletContextName = GetterUtil.getString(
198 theme.getServletContextName());
199
200 if (ServletContextPool.get(servletContextName) == null) {
201
202
203
204
205 ServletContextPool.put(servletContextName, servletContext);
206 }
207
208 String portletId = getPortletId(request);
209
210 String resourcePath = theme.getResourcePath(
211 servletContext, portletId, path);
212
213 if (Validator.isNotNull(portletId) &&
214 PortletConstants.hasInstanceId(portletId) &&
215 !TemplateResourceLoaderUtil.hasTemplateResource(
216 TemplateConstants.LANG_TYPE_FTL, resourcePath)) {
217
218 String rootPortletId = PortletConstants.getRootPortletId(portletId);
219
220 resourcePath = theme.getResourcePath(
221 servletContext, rootPortletId, path);
222 }
223
224 if (Validator.isNotNull(portletId) &&
225 !TemplateResourceLoaderUtil.hasTemplateResource(
226 TemplateConstants.LANG_TYPE_FTL, resourcePath)) {
227
228 resourcePath = theme.getResourcePath(servletContext, null, path);
229 }
230
231 if (!TemplateResourceLoaderUtil.hasTemplateResource(
232 TemplateConstants.LANG_TYPE_FTL, resourcePath)) {
233
234 _log.error(resourcePath + " does not exist");
235
236 return null;
237 }
238
239 TemplateResource templateResource =
240 TemplateResourceLoaderUtil.getTemplateResource(
241 TemplateConstants.LANG_TYPE_FTL, resourcePath);
242
243 Template template = TemplateManagerUtil.getTemplate(
244 TemplateConstants.LANG_TYPE_FTL, templateResource, restricted);
245
246
247
248 template.prepare(request);
249
250
251
252 ServletContext themeServletContext = ServletContextPool.get(
253 servletContextName);
254
255 template.put("themeServletContext", themeServletContext);
256
257
258
259 Writer writer = null;
260
261 if (write) {
262
263
264
265 writer = UnsyncPrintWriterPool.borrow(response.getWriter());
266 }
267 else {
268 writer = new UnsyncStringWriter();
269 }
270
271 VelocityTaglib velocityTaglib = new VelocityTaglibImpl(
272 servletContext, request,
273 new PipingServletResponse(response, writer), template);
274
275 template.put(TemplateConstants.WRITER, writer);
276 template.put("taglibLiferay", velocityTaglib);
277 template.put("theme", velocityTaglib);
278
279
280
281 TemplateHashModel portalTaglib =
282 FreeMarkerTaglibFactoryUtil.createTaglibFactory(servletContext);
283
284 template.put("PortalJspTagLibs", portalTaglib);
285
286
287
288 TemplateHashModel themeTaglib =
289 FreeMarkerTaglibFactoryUtil.createTaglibFactory(
290 themeServletContext);
291
292 template.put("ThemeJspTaglibs", themeTaglib);
293
294
295
296 GenericServlet genericServlet = new JSPSupportServlet(servletContext);
297
298 ServletContextHashModel servletContextHashModel =
299 new ServletContextHashModel(
300 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
301
302 template.put("Application", servletContextHashModel);
303
304 HttpRequestHashModel httpRequestHashModel = new HttpRequestHashModel(
305 request, response, ObjectWrapper.DEFAULT_WRAPPER);
306
307 template.put("Request", httpRequestHashModel);
308
309
310
311 template.processTemplate(writer);
312
313 if (write) {
314 return null;
315 }
316 else {
317 return writer.toString();
318 }
319 }
320
321 protected static void doIncludeJSP(
322 ServletContext servletContext, HttpServletRequest request,
323 HttpServletResponse response, String path, Theme theme)
324 throws Exception {
325
326 DynamicIncludeUtil.include(
327 request, response, ThemeUtil.class.getName() + "#doIncludeJSP");
328
329 if (theme.isWARFile()) {
330 ServletContext themeServletContext = servletContext.getContext(
331 theme.getContextPath());
332
333 if (themeServletContext == null) {
334 _log.error(
335 "Theme " + theme.getThemeId() + " cannot find its " +
336 "servlet context at " + theme.getServletContextName());
337 }
338 else {
339 RequestDispatcher requestDispatcher =
340 themeServletContext.getRequestDispatcher(path);
341
342 if (requestDispatcher == null) {
343 _log.error(
344 "Theme " + theme.getThemeId() + " does not have " +
345 path);
346 }
347 else {
348 requestDispatcher.include(request, response);
349 }
350 }
351 }
352 else {
353 RequestDispatcher requestDispatcher =
354 servletContext.getRequestDispatcher(path);
355
356 if (requestDispatcher == null) {
357 _log.error(
358 "Theme " + theme.getThemeId() + " does not have " + path);
359 }
360 else {
361 requestDispatcher.include(request, response);
362 }
363 }
364 }
365
366 protected static String doIncludeVM(
367 ServletContext servletContext, HttpServletRequest request,
368 HttpServletResponse response, String page, Theme theme,
369 boolean restricted, boolean write)
370 throws Exception {
371
372
373
374
375
376
377
378 String servletContextName = GetterUtil.getString(
379 theme.getServletContextName());
380
381 if (ServletContextPool.get(servletContextName) == null) {
382
383
384
385
386 ServletContextPool.put(servletContextName, servletContext);
387 }
388
389 String portletId = getPortletId(request);
390
391 String resourcePath = theme.getResourcePath(
392 servletContext, portletId, page);
393
394 boolean checkResourceExists = true;
395
396 if (Validator.isNotNull(portletId)) {
397 if (PortletConstants.hasInstanceId(portletId) &&
398 (checkResourceExists = !
399 TemplateResourceLoaderUtil.hasTemplateResource(
400 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
401
402 String rootPortletId = PortletConstants.getRootPortletId(
403 portletId);
404
405 resourcePath = theme.getResourcePath(
406 servletContext, rootPortletId, page);
407 }
408
409 if (checkResourceExists &&
410 (checkResourceExists = !
411 TemplateResourceLoaderUtil.hasTemplateResource(
412 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
413
414 resourcePath = theme.getResourcePath(
415 servletContext, null, page);
416 }
417 }
418
419 if (checkResourceExists &&
420 !TemplateResourceLoaderUtil.hasTemplateResource(
421 TemplateConstants.LANG_TYPE_VM, resourcePath)) {
422
423 _log.error(resourcePath + " does not exist");
424
425 return null;
426 }
427
428 TemplateResource templateResource =
429 TemplateResourceLoaderUtil.getTemplateResource(
430 TemplateConstants.LANG_TYPE_VM, resourcePath);
431
432 if (templateResource == null) {
433 throw new Exception(
434 "Unable to load template resource " + resourcePath);
435 }
436
437 Template template = TemplateManagerUtil.getTemplate(
438 TemplateConstants.LANG_TYPE_VM, templateResource, restricted);
439
440
441
442 template.prepare(request);
443
444
445
446 ServletContext themeServletContext = ServletContextPool.get(
447 servletContextName);
448
449 template.put("themeServletContext", themeServletContext);
450
451
452
453 Writer writer = null;
454
455 if (write) {
456 writer = response.getWriter();
457 }
458 else {
459 writer = new UnsyncStringWriter();
460 }
461
462 VelocityTaglib velocityTaglib = new VelocityTaglibImpl(
463 servletContext, request,
464 new PipingServletResponse(response, writer), template);
465
466 template.put(TemplateConstants.WRITER, writer);
467 template.put("pageContext", velocityTaglib.getPageContext());
468 template.put("taglibLiferay", velocityTaglib);
469 template.put("theme", velocityTaglib);
470
471
472
473 template.processTemplate(writer);
474
475 if (write) {
476 return null;
477 }
478 else {
479 return ((UnsyncStringWriter)writer).toString();
480 }
481 }
482
483 private static final Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
484
485 }