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