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