1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.taglib.util;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.servlet.StringServletResponse;
21  import com.liferay.portal.kernel.util.GetterUtil;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.WebKeys;
24  import com.liferay.portal.kernel.velocity.VelocityContext;
25  import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
26  import com.liferay.portal.model.Theme;
27  import com.liferay.portal.theme.ThemeDisplay;
28  import com.liferay.portal.velocity.VelocityContextPool;
29  import com.liferay.portal.velocity.VelocityVariables;
30  
31  import javax.servlet.RequestDispatcher;
32  import javax.servlet.ServletContext;
33  import javax.servlet.http.HttpServletRequest;
34  import javax.servlet.http.HttpServletResponse;
35  import javax.servlet.jsp.PageContext;
36  
37  import org.apache.struts.taglib.tiles.ComponentConstants;
38  import org.apache.struts.tiles.ComponentContext;
39  
40  /**
41   * <a href="ThemeUtil.java.html"><b><i>View Source</i></b></a>
42   *
43   * @author Brian Wing Shun Chan
44   * @author Brian Myunghun Kim
45   * @author Raymond Augé
46   */
47  public class ThemeUtil {
48  
49      public static void include(
50              ServletContext servletContext, HttpServletRequest request,
51              HttpServletResponse response, PageContext pageContext, String page,
52              Theme theme)
53          throws Exception {
54  
55          String extension = theme.getTemplateExtension();
56  
57          if (extension.equals(_TEMPLATE_EXTENSION_VM)) {
58              includeVM(servletContext, request, pageContext, page, theme, true);
59          }
60          else {
61              String path =
62                  theme.getTemplatesPath() + StringPool.SLASH + page;
63  
64              includeJSP(servletContext, request, response, path, theme);
65          }
66      }
67  
68      public static void includeJSP(
69              ServletContext servletContext, HttpServletRequest request,
70              HttpServletResponse response, String path, Theme theme)
71          throws Exception {
72  
73          String tilesTitle = _getTilesVariables(request, "title");
74          String tilesContent = _getTilesVariables(request, "content");
75          boolean tilesSelectable = GetterUtil.getBoolean(
76              _getTilesVariables(request, "selectable"));
77  
78          ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
79              WebKeys.THEME_DISPLAY);
80  
81          themeDisplay.setTilesTitle(tilesTitle);
82          themeDisplay.setTilesContent(tilesContent);
83          themeDisplay.setTilesSelectable(tilesSelectable);
84  
85          if (theme.isWARFile()) {
86              ServletContext themeServletContext = servletContext.getContext(
87                  theme.getContextPath());
88  
89              if (themeServletContext == null) {
90                  _log.error(
91                      "Theme " + theme.getThemeId() + " cannot find its " +
92                          "servlet context at " + theme.getServletContextName());
93              }
94              else {
95                  RequestDispatcher requestDispatcher =
96                      themeServletContext.getRequestDispatcher(path);
97  
98                  if (requestDispatcher == null) {
99                      _log.error(
100                         "Theme " + theme.getThemeId() + " does not have " +
101                             path);
102                 }
103                 else {
104                     requestDispatcher.include(request, response);
105                 }
106             }
107         }
108         else {
109             RequestDispatcher requestDispatcher =
110                 servletContext.getRequestDispatcher(path);
111 
112             if (requestDispatcher == null) {
113                 _log.error(
114                     "Theme " + theme.getThemeId() + " does not have " + path);
115             }
116             else {
117                 requestDispatcher.include(request, response);
118             }
119         }
120     }
121 
122     public static String includeVM(
123             ServletContext servletContext, HttpServletRequest request,
124             PageContext pageContext, String page, Theme theme, boolean write)
125         throws Exception {
126 
127         // The servlet context name will be null when the theme is deployed to
128         // the root directory in Tomcat. See
129         // com.liferay.portal.servlet.MainServlet and
130         // com.liferay.portlet.PortletContextImpl for other cases where a null
131         // servlet context name is also converted to an empty string.
132 
133         String ctxName = GetterUtil.getString(theme.getServletContextName());
134 
135         if (VelocityContextPool.get(ctxName) == null) {
136 
137             // This should only happen if the Velocity template is the first
138             // page to be accessed in the system
139 
140             VelocityContextPool.put(ctxName, servletContext);
141         }
142 
143         int pos = page.lastIndexOf(StringPool.PERIOD);
144 
145         StringBuilder sb = new StringBuilder();
146 
147         sb.append(ctxName);
148         sb.append(theme.getVelocityResourceListener());
149         sb.append(theme.getTemplatesPath());
150         sb.append(StringPool.SLASH);
151         sb.append(page.substring(0, pos));
152         sb.append(StringPool.PERIOD);
153         sb.append(_TEMPLATE_EXTENSION_VM);
154 
155         String source = sb.toString();
156 
157         if (!VelocityEngineUtil.resourceExists(source)) {
158             _log.error(source + " does not exist");
159 
160             return null;
161         }
162 
163         UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter(true);
164 
165         VelocityContext velocityContext =
166             VelocityEngineUtil.getWrappedStandardToolsContext();
167 
168         // Velocity variables
169 
170         VelocityVariables.insertVariables(velocityContext, request);
171 
172         // Theme servlet context
173 
174         ServletContext themeServletContext = VelocityContextPool.get(ctxName);
175 
176         // liferay:include tag library
177 
178         StringServletResponse stringResponse = new StringServletResponse(
179             (HttpServletResponse)pageContext.getResponse());
180 
181         VelocityTaglib velocityTaglib = new VelocityTaglib(
182             servletContext, request, stringResponse, pageContext);
183 
184         request.setAttribute(WebKeys.VELOCITY_TAGLIB, velocityTaglib);
185 
186         velocityContext.put("themeServletContext", themeServletContext);
187         velocityContext.put("taglibLiferay", velocityTaglib);
188         velocityContext.put("theme", velocityTaglib);
189 
190         // Merge templates
191 
192         VelocityEngineUtil.mergeTemplate(
193             source, velocityContext, unsyncStringWriter);
194 
195         // Print output
196 
197         String output = unsyncStringWriter.toString();
198 
199         if (write) {
200             pageContext.getOut().print(output);
201 
202             return null;
203         }
204         else {
205             return output;
206         }
207     }
208 
209     private static String _getTilesVariables(
210         HttpServletRequest request, String attributeName) {
211 
212         ComponentContext componentContext =
213             (ComponentContext)request.getAttribute(
214                 ComponentConstants.COMPONENT_CONTEXT);
215 
216         String value = null;
217 
218         if (componentContext != null) {
219             value = (String)componentContext.getAttribute(attributeName);
220         }
221 
222         return value;
223     }
224 
225     private static final String _TEMPLATE_EXTENSION_VM = "vm";
226 
227     private static Log _log = LogFactoryUtil.getLog(ThemeUtil.class);
228 
229 }