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