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
197
198
199 TemplateHashModel portalTaglib =
200 FreeMarkerTaglibFactoryUtil.createTaglibFactory(servletContext);
201
202 freeMarkerContext.put("PortalJspTagLibs", portalTaglib);
203
204
205
206 TemplateHashModel themeTaglib =
207 FreeMarkerTaglibFactoryUtil.createTaglibFactory(
208 themeServletContext);
209
210 freeMarkerContext.put("ThemeJspTaglibs", themeTaglib);
211
212
213
214 final Servlet servlet = (Servlet)pageContext.getPage();
215
216 GenericServlet genericServlet = null;
217
218 if (servlet instanceof GenericServlet) {
219 genericServlet = (GenericServlet) servlet;
220 }
221 else {
222 genericServlet = new GenericServlet() {
223
224 @Override
225 public void service(
226 ServletRequest servletRequest,
227 ServletResponse servletResponse)
228 throws ServletException, IOException {
229
230 servlet.service(servletRequest, servletResponse);
231 }
232
233 };
234
235 genericServlet.init(pageContext.getServletConfig());
236 }
237
238 ServletContextHashModel servletContextHashModel =
239 new ServletContextHashModel(
240 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
241
242 freeMarkerContext.put("Application", servletContextHashModel);
243
244 HttpRequestHashModel httpRequestHashModel = new HttpRequestHashModel(
245 request, response, ObjectWrapper.DEFAULT_WRAPPER);
246
247 freeMarkerContext.put("Request", httpRequestHashModel);
248
249
250
251 FreeMarkerEngineUtil.mergeTemplate(
252 resourcePath, freeMarkerContext, writer);
253
254 if (write) {
255 return null;
256 }
257 else {
258 return writer.toString();
259 }
260 }
261
262 public static void includeJSP(
263 ServletContext servletContext, HttpServletRequest request,
264 HttpServletResponse response, String path, Theme theme)
265 throws Exception {
266
267 insertTilesVariables(request);
268
269 if (theme.isWARFile()) {
270 ServletContext themeServletContext = servletContext.getContext(
271 theme.getContextPath());
272
273 if (themeServletContext == null) {
274 _log.error(
275 "Theme " + theme.getThemeId() + " cannot find its " +
276 "servlet context at " + theme.getServletContextName());
277 }
278 else {
279 RequestDispatcher requestDispatcher =
280 themeServletContext.getRequestDispatcher(path);
281
282 if (requestDispatcher == null) {
283 _log.error(
284 "Theme " + theme.getThemeId() + " does not have " +
285 path);
286 }
287 else {
288 requestDispatcher.include(request, response);
289 }
290 }
291 }
292 else {
293 RequestDispatcher requestDispatcher =
294 servletContext.getRequestDispatcher(path);
295
296 if (requestDispatcher == null) {
297 _log.error(
298 "Theme " + theme.getThemeId() + " does not have " + path);
299 }
300 else {
301 requestDispatcher.include(request, response);
302 }
303 }
304 }
305
306 public static String includeVM(
307 ServletContext servletContext, HttpServletRequest request,
308 PageContext pageContext, String page, Theme theme, boolean write)
309 throws Exception {
310
311
312
313
314
315
316
317 String servletContextName = GetterUtil.getString(
318 theme.getServletContextName());
319
320 if (ServletContextPool.get(servletContextName) == null) {
321
322
323
324
325 ServletContextPool.put(servletContextName, servletContext);
326 }
327
328 String portletId = getPortletId(request);
329
330 String resourcePath = theme.getResourcePath(
331 servletContext, portletId, page);
332
333 boolean checkResourceExists = true;
334
335 if (Validator.isNotNull(portletId)) {
336 if (portletId.contains(PortletConstants.INSTANCE_SEPARATOR) &&
337 (checkResourceExists = !VelocityEngineUtil.resourceExists(
338 resourcePath))) {
339
340 String rootPortletId = PortletConstants.getRootPortletId(
341 portletId);
342
343 resourcePath = theme.getResourcePath(
344 servletContext, rootPortletId, page);
345 }
346
347 if (checkResourceExists &&
348 (checkResourceExists = !VelocityEngineUtil.resourceExists(
349 resourcePath))) {
350
351 resourcePath = theme.getResourcePath(
352 servletContext, null, page);
353 }
354 }
355
356 if (checkResourceExists &&
357 !VelocityEngineUtil.resourceExists(resourcePath)) {
358
359 _log.error(resourcePath + " does not exist");
360
361 return null;
362 }
363
364 VelocityContext velocityContext =
365 VelocityEngineUtil.getWrappedStandardToolsContext();
366
367
368
369 VelocityVariablesUtil.insertVariables(velocityContext, request);
370
371
372
373 velocityContext.put("pageContext", pageContext);
374
375
376
377 ServletContext themeServletContext = ServletContextPool.get(
378 servletContextName);
379
380 velocityContext.put("themeServletContext", themeServletContext);
381
382
383
384 HttpServletResponse response =
385 (HttpServletResponse)pageContext.getResponse();
386
387 Writer writer = null;
388
389 if (write) {
390 writer = pageContext.getOut();
391 }
392 else {
393 writer = new UnsyncStringWriter();
394 }
395
396 VelocityTaglib velocityTaglib = new VelocityTaglib(
397 servletContext, request,
398 new PipingServletResponse(response, writer), pageContext);
399
400 request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
401
402 velocityContext.put("taglibLiferay", velocityTaglib);
403 velocityContext.put("theme", velocityTaglib);
404 velocityContext.put("writer", writer);
405
406
407
408 VelocityEngineUtil.mergeTemplate(resourcePath, velocityContext, writer);
409
410 if (write) {
411 return null;
412 }
413 else {
414 return ((UnsyncStringWriter)writer).toString();
415 }
416 }
417
418 public static void insertTilesVariables(HttpServletRequest request) {
419 ComponentContext componentContext =
420 (ComponentContext)request.getAttribute(
421 ComponentConstants.COMPONENT_CONTEXT);
422
423 if (componentContext == null) {
424 return;
425 }
426
427 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
428 WebKeys.THEME_DISPLAY);
429
430 String tilesTitle = (String)componentContext.getAttribute("title");
431 String tilesContent = (String)componentContext.getAttribute("content");
432 boolean tilesSelectable = GetterUtil.getBoolean(
433 (String)componentContext.getAttribute("selectable"));
434
435 themeDisplay.setTilesTitle(tilesTitle);
436 themeDisplay.setTilesContent(tilesContent);
437 themeDisplay.setTilesSelectable(tilesSelectable);
438 }
439
440 private static Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
441
442 }