001
014
015 package com.liferay.taglib.util;
016
017 import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
018 import com.liferay.portal.kernel.freemarker.FreeMarkerEngineUtil;
019 import com.liferay.portal.kernel.freemarker.FreeMarkerVariablesUtil;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.servlet.PipingServletResponse;
024 import com.liferay.portal.kernel.servlet.ServletContextPool;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.ThemeHelper;
028 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.util.WebKeys;
031 import com.liferay.portal.kernel.velocity.VelocityContext;
032 import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
033 import com.liferay.portal.kernel.velocity.VelocityVariablesUtil;
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.util.freemarker.FreeMarkerTaglibFactoryUtil;
039
040 import freemarker.ext.servlet.HttpRequestHashModel;
041 import freemarker.ext.servlet.ServletContextHashModel;
042
043 import freemarker.template.ObjectWrapper;
044 import freemarker.template.TemplateHashModel;
045
046 import java.io.IOException;
047 import java.io.Writer;
048
049 import javax.servlet.GenericServlet;
050 import javax.servlet.RequestDispatcher;
051 import javax.servlet.Servlet;
052 import javax.servlet.ServletContext;
053 import javax.servlet.ServletException;
054 import javax.servlet.ServletRequest;
055 import javax.servlet.ServletResponse;
056 import javax.servlet.http.HttpServletRequest;
057 import javax.servlet.http.HttpServletResponse;
058 import javax.servlet.jsp.PageContext;
059
060 import org.apache.struts.taglib.tiles.ComponentConstants;
061 import org.apache.struts.tiles.ComponentContext;
062
063
070 public class ThemeUtil {
071
072 public static String getPortletId(HttpServletRequest request) {
073 String portletId = null;
074
075 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
076 WebKeys.THEME_DISPLAY);
077
078 if (themeDisplay != null) {
079 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
080
081 portletId = portletDisplay.getId();
082 }
083
084 return portletId;
085 }
086
087 public static void include(
088 ServletContext servletContext, HttpServletRequest request,
089 HttpServletResponse response, PageContext pageContext, String page,
090 Theme theme)
091 throws Exception {
092
093 String extension = theme.getTemplateExtension();
094
095 if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_FTL)) {
096 includeFTL(servletContext, request, pageContext, page, theme, true);
097 }
098 else if (extension.equals(ThemeHelper.TEMPLATE_EXTENSION_VM)) {
099 includeVM(servletContext, request, pageContext, page, theme, true);
100 }
101 else {
102 String path = theme.getTemplatesPath() + StringPool.SLASH + page;
103
104 includeJSP(servletContext, request, response, path, theme);
105 }
106 }
107
108 public static String includeFTL(
109 ServletContext servletContext, HttpServletRequest request,
110 PageContext pageContext, String path, Theme theme, boolean write)
111 throws Exception {
112
113
114
115
116
117
118
119 String servletContextName = GetterUtil.getString(
120 theme.getServletContextName());
121
122 if (ServletContextPool.get(servletContextName) == null) {
123
124
125
126
127 ServletContextPool.put(servletContextName, servletContext);
128 }
129
130 String portletId = getPortletId(request);
131
132 String resourcePath = theme.getResourcePath(
133 servletContext, portletId, path);
134
135 if (Validator.isNotNull(portletId) &&
136 !FreeMarkerEngineUtil.resourceExists(resourcePath) &&
137 portletId.contains(PortletConstants.INSTANCE_SEPARATOR)) {
138
139 String rootPortletId = PortletConstants.getRootPortletId(portletId);
140
141 resourcePath = theme.getResourcePath(
142 servletContext, rootPortletId, path);
143 }
144
145 if (Validator.isNotNull(portletId) &&
146 !FreeMarkerEngineUtil.resourceExists(resourcePath)) {
147
148 resourcePath = theme.getResourcePath(servletContext, null, path);
149 }
150
151 if (!FreeMarkerEngineUtil.resourceExists(resourcePath)) {
152 _log.error(resourcePath + " does not exist");
153
154 return null;
155 }
156
157 FreeMarkerContext freeMarkerContext =
158 FreeMarkerEngineUtil.getWrappedStandardToolsContext();
159
160
161
162 FreeMarkerVariablesUtil.insertVariables(freeMarkerContext, request);
163
164
165
166 ServletContext themeServletContext = ServletContextPool.get(
167 servletContextName);
168
169 freeMarkerContext.put("themeServletContext", themeServletContext);
170
171
172
173 HttpServletResponse response =
174 (HttpServletResponse)pageContext.getResponse();
175
176 Writer writer = null;
177
178 if (write) {
179
180
181
182 writer = UnsyncPrintWriterPool.borrow(pageContext.getOut());
183 }
184 else {
185 writer = new UnsyncStringWriter();
186 }
187
188 VelocityTaglib velocityTaglib = new VelocityTaglib(
189 servletContext, request,
190 new PipingServletResponse(response, writer), pageContext);
191
192 request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
193
194 freeMarkerContext.put("taglibLiferay", velocityTaglib);
195 freeMarkerContext.put("theme", velocityTaglib);
196 freeMarkerContext.put("writer", writer);
197
198
199
200 TemplateHashModel portalTaglib =
201 FreeMarkerTaglibFactoryUtil.createTaglibFactory(servletContext);
202
203 freeMarkerContext.put("PortalJspTagLibs", portalTaglib);
204
205
206
207 TemplateHashModel themeTaglib =
208 FreeMarkerTaglibFactoryUtil.createTaglibFactory(
209 themeServletContext);
210
211 freeMarkerContext.put("ThemeJspTaglibs", themeTaglib);
212
213
214
215 final Servlet servlet = (Servlet)pageContext.getPage();
216
217 GenericServlet genericServlet = null;
218
219 if (servlet instanceof GenericServlet) {
220 genericServlet = (GenericServlet) servlet;
221 }
222 else {
223 genericServlet = new GenericServlet() {
224
225 @Override
226 public void service(
227 ServletRequest servletRequest,
228 ServletResponse servletResponse)
229 throws ServletException, IOException {
230
231 servlet.service(servletRequest, servletResponse);
232 }
233
234 };
235
236 genericServlet.init(pageContext.getServletConfig());
237 }
238
239 ServletContextHashModel servletContextHashModel =
240 new ServletContextHashModel(
241 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
242
243 freeMarkerContext.put("Application", servletContextHashModel);
244
245 HttpRequestHashModel httpRequestHashModel = new HttpRequestHashModel(
246 request, response, ObjectWrapper.DEFAULT_WRAPPER);
247
248 freeMarkerContext.put("Request", httpRequestHashModel);
249
250
251
252 FreeMarkerEngineUtil.mergeTemplate(
253 resourcePath, freeMarkerContext, writer);
254
255 if (write) {
256 return null;
257 }
258 else {
259 return writer.toString();
260 }
261 }
262
263 public static void includeJSP(
264 ServletContext servletContext, HttpServletRequest request,
265 HttpServletResponse response, String path, Theme theme)
266 throws Exception {
267
268 insertTilesVariables(request);
269
270 if (theme.isWARFile()) {
271 ServletContext themeServletContext = servletContext.getContext(
272 theme.getContextPath());
273
274 if (themeServletContext == null) {
275 _log.error(
276 "Theme " + theme.getThemeId() + " cannot find its " +
277 "servlet context at " + theme.getServletContextName());
278 }
279 else {
280 RequestDispatcher requestDispatcher =
281 themeServletContext.getRequestDispatcher(path);
282
283 if (requestDispatcher == null) {
284 _log.error(
285 "Theme " + theme.getThemeId() + " does not have " +
286 path);
287 }
288 else {
289 requestDispatcher.include(request, response);
290 }
291 }
292 }
293 else {
294 RequestDispatcher requestDispatcher =
295 servletContext.getRequestDispatcher(path);
296
297 if (requestDispatcher == null) {
298 _log.error(
299 "Theme " + theme.getThemeId() + " does not have " + path);
300 }
301 else {
302 requestDispatcher.include(request, response);
303 }
304 }
305 }
306
307 public static String includeVM(
308 ServletContext servletContext, HttpServletRequest request,
309 PageContext pageContext, String page, Theme theme, boolean write)
310 throws Exception {
311
312
313
314
315
316
317
318 String servletContextName = GetterUtil.getString(
319 theme.getServletContextName());
320
321 if (ServletContextPool.get(servletContextName) == null) {
322
323
324
325
326 ServletContextPool.put(servletContextName, servletContext);
327 }
328
329 String portletId = getPortletId(request);
330
331 String resourcePath = theme.getResourcePath(
332 servletContext, portletId, page);
333
334 boolean checkResourceExists = true;
335
336 if (Validator.isNotNull(portletId)) {
337 if (portletId.contains(PortletConstants.INSTANCE_SEPARATOR) &&
338 (checkResourceExists = !VelocityEngineUtil.resourceExists(
339 resourcePath))) {
340
341 String rootPortletId = PortletConstants.getRootPortletId(
342 portletId);
343
344 resourcePath = theme.getResourcePath(
345 servletContext, rootPortletId, page);
346 }
347
348 if (checkResourceExists &&
349 (checkResourceExists = !VelocityEngineUtil.resourceExists(
350 resourcePath))) {
351
352 resourcePath = theme.getResourcePath(
353 servletContext, null, page);
354 }
355 }
356
357 if (checkResourceExists &&
358 !VelocityEngineUtil.resourceExists(resourcePath)) {
359
360 _log.error(resourcePath + " does not exist");
361
362 return null;
363 }
364
365 VelocityContext velocityContext =
366 VelocityEngineUtil.getWrappedStandardToolsContext();
367
368
369
370 VelocityVariablesUtil.insertVariables(velocityContext, request);
371
372
373
374 velocityContext.put("pageContext", pageContext);
375
376
377
378 ServletContext themeServletContext = ServletContextPool.get(
379 servletContextName);
380
381 velocityContext.put("themeServletContext", themeServletContext);
382
383
384
385 HttpServletResponse response =
386 (HttpServletResponse)pageContext.getResponse();
387
388 Writer writer = null;
389
390 if (write) {
391 writer = pageContext.getOut();
392 }
393 else {
394 writer = new UnsyncStringWriter();
395 }
396
397 VelocityTaglib velocityTaglib = new VelocityTaglib(
398 servletContext, request,
399 new PipingServletResponse(response, writer), pageContext);
400
401 request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
402
403 velocityContext.put("taglibLiferay", velocityTaglib);
404 velocityContext.put("theme", velocityTaglib);
405 velocityContext.put("writer", writer);
406
407
408
409 VelocityEngineUtil.mergeTemplate(resourcePath, velocityContext, writer);
410
411 if (write) {
412 return null;
413 }
414 else {
415 return ((UnsyncStringWriter)writer).toString();
416 }
417 }
418
419 public static void insertTilesVariables(HttpServletRequest request) {
420 ComponentContext componentContext =
421 (ComponentContext)request.getAttribute(
422 ComponentConstants.COMPONENT_CONTEXT);
423
424 if (componentContext == null) {
425 return;
426 }
427
428 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
429 WebKeys.THEME_DISPLAY);
430
431 String tilesTitle = (String)componentContext.getAttribute("title");
432 String tilesContent = (String)componentContext.getAttribute("content");
433 boolean tilesSelectable = GetterUtil.getBoolean(
434 (String)componentContext.getAttribute("selectable"));
435
436 themeDisplay.setTilesTitle(tilesTitle);
437 themeDisplay.setTilesContent(tilesContent);
438 themeDisplay.setTilesSelectable(tilesSelectable);
439 }
440
441 private static Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
442
443 }