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