1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions 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.portal.servlet.filters.velocity;
24  
25  import com.liferay.portal.kernel.servlet.BrowserSniffer;
26  import com.liferay.portal.kernel.util.GetterUtil;
27  import com.liferay.portal.kernel.util.LocaleUtil;
28  import com.liferay.portal.kernel.util.ParamUtil;
29  import com.liferay.portal.model.ColorScheme;
30  import com.liferay.portal.model.Company;
31  import com.liferay.portal.model.Theme;
32  import com.liferay.portal.service.CompanyLocalServiceUtil;
33  import com.liferay.portal.service.impl.ThemeLocalUtil;
34  import com.liferay.portal.theme.ThemeDisplay;
35  import com.liferay.portal.theme.ThemeDisplayFactory;
36  import com.liferay.portal.util.PortalUtil;
37  import com.liferay.portal.util.WebKeys;
38  import com.liferay.portal.velocity.VelocityVariables;
39  import com.liferay.util.Http;
40  import com.liferay.util.SystemProperties;
41  import com.liferay.util.servlet.filters.CacheResponse;
42  import com.liferay.util.servlet.filters.CacheResponseData;
43  import com.liferay.util.servlet.filters.CacheResponseUtil;
44  
45  import java.io.IOException;
46  import java.io.StringReader;
47  import java.io.StringWriter;
48  
49  import java.util.Locale;
50  import java.util.regex.Matcher;
51  import java.util.regex.Pattern;
52  
53  import javax.servlet.Filter;
54  import javax.servlet.FilterChain;
55  import javax.servlet.FilterConfig;
56  import javax.servlet.ServletException;
57  import javax.servlet.ServletRequest;
58  import javax.servlet.ServletResponse;
59  import javax.servlet.http.HttpServletRequest;
60  import javax.servlet.http.HttpServletResponse;
61  
62  import org.apache.commons.logging.Log;
63  import org.apache.commons.logging.LogFactory;
64  import org.apache.velocity.VelocityContext;
65  import org.apache.velocity.app.Velocity;
66  
67  /**
68   * <a href="VelocityFilter.java.html"><b><i>View Source</i></b></a>
69   *
70   * @author Brian Wing Shun Chan
71   *
72   */
73  public class VelocityFilter implements Filter {
74  
75      public static final boolean USE_FILTER = GetterUtil.getBoolean(
76          SystemProperties.get(VelocityFilter.class.getName()), true);
77  
78      public static final String ENCODING = GetterUtil.getString(
79          SystemProperties.get("file.encoding"), "UTF-8");
80  
81      public void init(FilterConfig config) {
82          String pattern = config.getInitParameter("pattern");
83  
84          _pattern = Pattern.compile(pattern);
85      }
86  
87      public void doFilter(
88              ServletRequest req, ServletResponse res, FilterChain chain)
89          throws IOException, ServletException {
90  
91          if (_log.isDebugEnabled()) {
92              if (USE_FILTER) {
93                  _log.debug("Velocity is enabled");
94              }
95              else {
96                  _log.debug("Velocity is disabled");
97              }
98          }
99  
100         HttpServletRequest httpReq = (HttpServletRequest)req;
101         HttpServletResponse httpRes = (HttpServletResponse)res;
102 
103         String completeURL = Http.getCompleteURL(httpReq);
104 
105         if (USE_FILTER && isMatchingURL(completeURL)) {
106             if (_log.isDebugEnabled()) {
107                 _log.debug("Processing " + completeURL);
108             }
109 
110             CacheResponse cacheResponse = new CacheResponse(
111                 httpRes, ENCODING);
112 
113             chain.doFilter(req, cacheResponse);
114 
115             VelocityContext context = new VelocityContext();
116 
117             StringReader reader = new StringReader(
118                 new String(cacheResponse.getData()));
119             StringWriter writer = new StringWriter();
120 
121             ThemeDisplay themeDisplay = null;
122 
123             try {
124 
125                 // Company
126 
127                 long companyId = ParamUtil.getLong(req, "companyId");
128 
129                 Company company = CompanyLocalServiceUtil.getCompanyById(
130                     companyId);
131 
132                 // Paths
133 
134                 String contextPath = PortalUtil.getPathContext();
135 
136                 // Locale
137 
138                 String languageId = ParamUtil.getString(req, "languageId");
139 
140                 Locale locale = LocaleUtil.fromLanguageId(languageId);
141 
142                 // Theme and color scheme
143 
144                 String themeId = ParamUtil.getString(req, "themeId");
145                 String colorSchemeId = ParamUtil.getString(
146                     req, "colorSchemeId");
147 
148                 boolean wapTheme = BrowserSniffer.is_wap_xhtml(httpReq);
149 
150                 Theme theme = ThemeLocalUtil.getTheme(
151                     companyId, themeId, wapTheme);
152                 ColorScheme colorScheme = ThemeLocalUtil.getColorScheme(
153                     companyId, theme.getThemeId(), colorSchemeId, wapTheme);
154 
155                 // Theme display
156 
157                 themeDisplay = ThemeDisplayFactory.create();
158 
159                 themeDisplay.setCompany(company);
160                 themeDisplay.setLocale(locale);
161                 themeDisplay.setLookAndFeel(contextPath, theme, colorScheme);
162                 themeDisplay.setPathContext(contextPath);
163 
164                 req.setAttribute(WebKeys.THEME_DISPLAY, themeDisplay);
165 
166                 // Velocity variables
167 
168                 VelocityVariables.insertVariables(context, httpReq);
169 
170                 // Evaluate template
171 
172                 Velocity.evaluate(
173                     context, writer, VelocityFilter.class.getName(), reader);
174             }
175             catch (Exception e) {
176                 _log.error(e, e);
177             }
178             finally {
179                 try {
180                     if (themeDisplay != null) {
181                         ThemeDisplayFactory.recycle(themeDisplay);
182                     }
183                 }
184                 catch (Exception e) {
185                 }
186             }
187 
188             CacheResponseData data = new CacheResponseData(
189                 writer.toString().getBytes(ENCODING),
190                 cacheResponse.getContentType(), cacheResponse.getHeaders());
191 
192             CacheResponseUtil.write(httpRes, data);
193         }
194         else {
195             if (_log.isDebugEnabled()) {
196                 _log.debug("Not processing " + completeURL);
197             }
198 
199             chain.doFilter(req, res);
200         }
201     }
202 
203     public void destroy() {
204     }
205 
206     protected boolean isMatchingURL(String completeURL) {
207         Matcher matcher = _pattern.matcher(completeURL);
208 
209         return matcher.matches();
210     }
211 
212     private static Log _log = LogFactory.getLog(VelocityFilter.class);
213 
214     private Pattern _pattern;
215 
216 }