001
014
015 package com.liferay.taglib.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.servlet.JSPSupportServlet;
021 import com.liferay.portal.kernel.servlet.ServletContextPool;
022 import com.liferay.portal.kernel.servlet.taglib.DynamicIncludeUtil;
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 true);
329
330 if (theme.isWARFile()) {
331 ServletContext themeServletContext = servletContext.getContext(
332 theme.getContextPath());
333
334 if (themeServletContext == null) {
335 _log.error(
336 "Theme " + theme.getThemeId() + " cannot find its " +
337 "servlet context at " + theme.getServletContextName());
338 }
339 else {
340 RequestDispatcher requestDispatcher =
341 themeServletContext.getRequestDispatcher(path);
342
343 if (requestDispatcher == null) {
344 _log.error(
345 "Theme " + theme.getThemeId() + " does not have " +
346 path);
347 }
348 else {
349 requestDispatcher.include(request, response);
350 }
351 }
352 }
353 else {
354 RequestDispatcher requestDispatcher =
355 servletContext.getRequestDispatcher(path);
356
357 if (requestDispatcher == null) {
358 _log.error(
359 "Theme " + theme.getThemeId() + " does not have " + path);
360 }
361 else {
362 requestDispatcher.include(request, response);
363 }
364 }
365 }
366
367 protected static String doIncludeVM(
368 ServletContext servletContext, HttpServletRequest request,
369 HttpServletResponse response, String page, Theme theme,
370 boolean restricted, boolean write)
371 throws Exception {
372
373
374
375
376
377
378
379 String servletContextName = GetterUtil.getString(
380 theme.getServletContextName());
381
382 if (ServletContextPool.get(servletContextName) == null) {
383
384
385
386
387 ServletContextPool.put(servletContextName, servletContext);
388 }
389
390 String portletId = getPortletId(request);
391
392 String resourcePath = theme.getResourcePath(
393 servletContext, portletId, page);
394
395 boolean checkResourceExists = true;
396
397 if (Validator.isNotNull(portletId)) {
398 if (PortletConstants.hasInstanceId(portletId) &&
399 (checkResourceExists = !
400 TemplateResourceLoaderUtil.hasTemplateResource(
401 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
402
403 String rootPortletId = PortletConstants.getRootPortletId(
404 portletId);
405
406 resourcePath = theme.getResourcePath(
407 servletContext, rootPortletId, page);
408 }
409
410 if (checkResourceExists &&
411 (checkResourceExists = !
412 TemplateResourceLoaderUtil.hasTemplateResource(
413 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
414
415 resourcePath = theme.getResourcePath(
416 servletContext, null, page);
417 }
418 }
419
420 if (checkResourceExists &&
421 !TemplateResourceLoaderUtil.hasTemplateResource(
422 TemplateConstants.LANG_TYPE_VM, resourcePath)) {
423
424 _log.error(resourcePath + " does not exist");
425
426 return null;
427 }
428
429 TemplateResource templateResource =
430 TemplateResourceLoaderUtil.getTemplateResource(
431 TemplateConstants.LANG_TYPE_VM, resourcePath);
432
433 if (templateResource == null) {
434 throw new Exception(
435 "Unable to load template resource " + resourcePath);
436 }
437
438 Template template = TemplateManagerUtil.getTemplate(
439 TemplateConstants.LANG_TYPE_VM, templateResource, restricted);
440
441
442
443 template.prepare(request);
444
445
446
447 ServletContext themeServletContext = ServletContextPool.get(
448 servletContextName);
449
450 template.put("themeServletContext", themeServletContext);
451
452
453
454 Writer writer = null;
455
456 if (write) {
457 writer = response.getWriter();
458 }
459 else {
460 writer = new UnsyncStringWriter();
461 }
462
463 VelocityTaglib velocityTaglib = new VelocityTaglibImpl(
464 servletContext, request,
465 new PipingServletResponse(response, writer), template);
466
467 template.put(TemplateConstants.WRITER, writer);
468 template.put("pageContext", velocityTaglib.getPageContext());
469 template.put("taglibLiferay", velocityTaglib);
470 template.put("theme", velocityTaglib);
471
472
473
474 template.processTemplate(writer);
475
476 if (write) {
477 return null;
478 }
479 else {
480 return ((UnsyncStringWriter)writer).toString();
481 }
482 }
483
484 private static final Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
485
486 }