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