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.addTaglibSupport(template, request, response);
277 templateManager.addTaglibTheme(
278 template, "taglibLiferay", request,
279 new PipingServletResponse(response, writer));
280
281 template.put(TemplateConstants.WRITER, writer);
282
283
284
285 template.processTemplate(writer);
286
287 if (write) {
288 return null;
289 }
290 else {
291 return writer.toString();
292 }
293 }
294
295 protected static void doIncludeJSP(
296 ServletContext servletContext, HttpServletRequest request,
297 HttpServletResponse response, String path, Theme theme)
298 throws Exception {
299
300 DynamicIncludeUtil.include(
301 request, response, ThemeUtil.class.getName() + "#doIncludeJSP",
302 true);
303
304 if (theme.isWARFile()) {
305 ServletContext themeServletContext = servletContext.getContext(
306 theme.getContextPath());
307
308 if (themeServletContext == null) {
309 _log.error(
310 "Theme " + theme.getThemeId() + " cannot find its " +
311 "servlet context at " + theme.getServletContextName());
312 }
313 else {
314 RequestDispatcher requestDispatcher =
315 themeServletContext.getRequestDispatcher(path);
316
317 if (requestDispatcher == null) {
318 _log.error(
319 "Theme " + theme.getThemeId() + " does not have " +
320 path);
321 }
322 else {
323 requestDispatcher.include(request, response);
324 }
325 }
326 }
327 else {
328 RequestDispatcher requestDispatcher =
329 servletContext.getRequestDispatcher(path);
330
331 if (requestDispatcher == null) {
332 _log.error(
333 "Theme " + theme.getThemeId() + " does not have " + path);
334 }
335 else {
336 requestDispatcher.include(request, response);
337 }
338 }
339 }
340
341 protected static String doIncludeVM(
342 ServletContext servletContext, HttpServletRequest request,
343 HttpServletResponse response, String page, Theme theme,
344 boolean restricted, boolean write)
345 throws Exception {
346
347
348
349
350
351
352
353 String servletContextName = GetterUtil.getString(
354 theme.getServletContextName());
355
356 if (ServletContextPool.get(servletContextName) == null) {
357
358
359
360
361 ServletContextPool.put(servletContextName, servletContext);
362 }
363
364 String portletId = getPortletId(request);
365
366 String resourcePath = theme.getResourcePath(
367 servletContext, portletId, page);
368
369 boolean checkResourceExists = true;
370
371 if (Validator.isNotNull(portletId)) {
372 if (PortletConstants.hasInstanceId(portletId) &&
373 (checkResourceExists !=
374 TemplateResourceLoaderUtil.hasTemplateResource(
375 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
376
377 String rootPortletId = PortletConstants.getRootPortletId(
378 portletId);
379
380 resourcePath = theme.getResourcePath(
381 servletContext, rootPortletId, page);
382 }
383
384 if (checkResourceExists &&
385 (checkResourceExists !=
386 TemplateResourceLoaderUtil.hasTemplateResource(
387 TemplateConstants.LANG_TYPE_VM, resourcePath))) {
388
389 resourcePath = theme.getResourcePath(
390 servletContext, null, page);
391 }
392 }
393
394 if (checkResourceExists &&
395 !TemplateResourceLoaderUtil.hasTemplateResource(
396 TemplateConstants.LANG_TYPE_VM, resourcePath)) {
397
398 _log.error(resourcePath + " does not exist");
399
400 return null;
401 }
402
403 TemplateResource templateResource =
404 TemplateResourceLoaderUtil.getTemplateResource(
405 TemplateConstants.LANG_TYPE_VM, resourcePath);
406
407 if (templateResource == null) {
408 throw new Exception(
409 "Unable to load template resource " + resourcePath);
410 }
411
412 TemplateManager templateManager =
413 TemplateManagerUtil.getTemplateManager(
414 TemplateConstants.LANG_TYPE_VM);
415
416 Template template = TemplateManagerUtil.getTemplate(
417 TemplateConstants.LANG_TYPE_VM, templateResource, restricted);
418
419
420
421 template.prepare(request);
422
423
424
425 for (TemplateContextContributor templateContextContributor :
426 _templateContextContributors) {
427
428 templateContextContributor.prepare(template, request);
429 }
430
431
432
433 ServletContext themeServletContext = ServletContextPool.get(
434 servletContextName);
435
436 template.put("themeServletContext", themeServletContext);
437
438
439
440 Writer writer = null;
441
442 if (write) {
443 writer = response.getWriter();
444 }
445 else {
446 writer = new UnsyncStringWriter();
447 }
448
449 templateManager.addTaglibTheme(
450 template, "taglibLiferay", request,
451 new PipingServletResponse(response, writer));
452
453 template.put(TemplateConstants.WRITER, writer);
454
455
456
457 template.processTemplate(writer);
458
459 if (write) {
460 return null;
461 }
462 else {
463 return ((UnsyncStringWriter)writer).toString();
464 }
465 }
466
467 private static final Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
468
469 private static final ServiceTrackerList<TemplateContextContributor>
470 _templateContextContributors = ServiceTrackerCollections.openList(
471 TemplateContextContributor.class,
472 "(type=" + TemplateContextContributor.TYPE_THEME + ")");
473
474 }