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