001
014
015 package com.liferay.portal.servlet.filters.i18n;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.servlet.HttpMethods;
023 import com.liferay.portal.kernel.util.CookieKeys;
024 import com.liferay.portal.kernel.util.LocaleUtil;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.model.Group;
029 import com.liferay.portal.model.LayoutSet;
030 import com.liferay.portal.model.User;
031 import com.liferay.portal.service.GroupLocalServiceUtil;
032 import com.liferay.portal.servlet.filters.BasePortalFilter;
033 import com.liferay.portal.util.PortalUtil;
034 import com.liferay.portal.util.PropsValues;
035 import com.liferay.portal.util.WebKeys;
036
037 import java.util.Collections;
038 import java.util.HashSet;
039 import java.util.Locale;
040 import java.util.Set;
041
042 import javax.servlet.FilterChain;
043 import javax.servlet.http.HttpServletRequest;
044 import javax.servlet.http.HttpServletResponse;
045 import javax.servlet.http.HttpSession;
046
047 import org.apache.struts.Globals;
048
049
052 public class I18nFilter extends BasePortalFilter {
053
054 public static final String SKIP_FILTER =
055 I18nFilter.class.getName() + "SKIP_FILTER";
056
057 public static Set<String> getLanguageIds() {
058 return _languageIds;
059 }
060
061 public static void setLanguageIds(Set<String> languageIds) {
062 _languageIds = new HashSet<String>();
063
064 for (String languageId : languageIds) {
065 languageId = languageId.substring(1);
066
067 _languageIds.add(languageId);
068 }
069
070 _languageIds = Collections.unmodifiableSet(_languageIds);
071 }
072
073 @Override
074 public boolean isFilterEnabled(
075 HttpServletRequest request, HttpServletResponse response) {
076
077 if (!isAlreadyFiltered(request) && !isForwardedByI18nServlet(request) &&
078 !isWidget(request)) {
079
080 return true;
081 }
082 else {
083 return false;
084 }
085 }
086
087 protected String getDefaultLanguageId(HttpServletRequest request) {
088 String defaultLanguageId = getSiteDefaultLanguageId(request);
089
090 if (Validator.isNull(defaultLanguageId)) {
091 defaultLanguageId = LocaleUtil.toLanguageId(
092 LocaleUtil.getDefault());
093 }
094
095 return defaultLanguageId;
096 }
097
098 protected String getFriendlyURL(HttpServletRequest request) {
099 String friendlyURL = StringPool.BLANK;
100
101 String pathInfo = request.getPathInfo();
102
103 if (Validator.isNotNull(pathInfo)) {
104 String[] pathInfoElements = pathInfo.split("/");
105
106 if (Validator.isNotNull(pathInfoElements) &&
107 (pathInfoElements.length > 1)) {
108
109 friendlyURL = StringPool.SLASH + pathInfoElements[1];
110 }
111 }
112
113 return friendlyURL;
114 }
115
116 protected String getRedirect(HttpServletRequest request) throws Exception {
117 if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 0) {
118 return null;
119 }
120
121 String method = request.getMethod();
122
123 if (method.equals(HttpMethods.POST)) {
124 return null;
125 }
126
127 String contextPath = PortalUtil.getPathContext();
128
129 String requestURI = request.getRequestURI();
130
131 if (Validator.isNotNull(contextPath) &&
132 requestURI.contains(contextPath)) {
133
134 requestURI = requestURI.substring(contextPath.length());
135 }
136
137 requestURI = StringUtil.replace(
138 requestURI, StringPool.DOUBLE_SLASH, StringPool.SLASH);
139
140 String i18nLanguageId = prependI18nLanguageId(
141 request, PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE);
142
143 if (i18nLanguageId == null) {
144 return null;
145 }
146
147 Locale locale = LocaleUtil.fromLanguageId(i18nLanguageId);
148
149 if (!LanguageUtil.isAvailableLocale(locale)) {
150 return null;
151 }
152
153 String i18nPathLanguageId = PortalUtil.getI18nPathLanguageId(
154 locale, i18nLanguageId);
155
156 String i18nPath = StringPool.SLASH.concat(i18nPathLanguageId);
157
158 if (requestURI.contains(i18nPath.concat(StringPool.SLASH))) {
159 return null;
160 }
161
162 String redirect = contextPath + i18nPath + requestURI;
163
164 int[] groupFriendlyURLIndex = PortalUtil.getGroupFriendlyURLIndex(
165 requestURI);
166
167 String groupFriendlyURL = StringPool.BLANK;
168
169 int friendlyURLStart = 0;
170 int friendlyURLEnd = 0;
171
172 if (groupFriendlyURLIndex != null) {
173 friendlyURLStart = groupFriendlyURLIndex[0];
174 friendlyURLEnd = groupFriendlyURLIndex[1];
175
176 groupFriendlyURL = requestURI.substring(
177 friendlyURLStart, friendlyURLEnd);
178 }
179
180 long companyId = PortalUtil.getCompanyId(request);
181
182 Group friendlyURLGroup = GroupLocalServiceUtil.fetchFriendlyURLGroup(
183 companyId, groupFriendlyURL);
184
185 if ((friendlyURLGroup != null) &&
186 !LanguageUtil.isAvailableLocale(
187 friendlyURLGroup.getGroupId(), i18nLanguageId)) {
188
189 return null;
190 }
191
192 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
193 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
194
195 if ((layoutSet != null) &&
196 requestURI.startsWith(
197 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING)) {
198
199 Group group = layoutSet.getGroup();
200
201 if (groupFriendlyURL.equals(group.getFriendlyURL())) {
202 redirect =
203 contextPath + i18nPath +
204 requestURI.substring(friendlyURLEnd);
205 }
206 }
207
208 String queryString = request.getQueryString();
209
210 if (Validator.isNotNull(queryString)) {
211 redirect += StringPool.QUESTION + request.getQueryString();
212 }
213
214 return redirect;
215 }
216
217 protected String getRequestedLanguageId(
218 HttpServletRequest request, String userLanguageId) {
219
220 HttpSession session = request.getSession();
221
222 Locale locale = (Locale)session.getAttribute(Globals.LOCALE_KEY);
223
224 String requestedLanguageId = null;
225
226 if (Validator.isNotNull(locale)) {
227 requestedLanguageId = LocaleUtil.toLanguageId(locale);
228 }
229
230 if (Validator.isNull(requestedLanguageId)) {
231 requestedLanguageId = userLanguageId;
232 }
233
234 if (Validator.isNull(requestedLanguageId)) {
235 requestedLanguageId = CookieKeys.getCookie(
236 request, CookieKeys.GUEST_LANGUAGE_ID, false);
237 }
238
239 return requestedLanguageId;
240 }
241
242 protected String getSiteDefaultLanguageId(HttpServletRequest request) {
243 String friendlyURL = getFriendlyURL(request);
244
245 long companyId = PortalUtil.getCompanyId(request);
246
247 try {
248 Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
249 companyId, friendlyURL);
250
251 Locale siteDefaultLocale = PortalUtil.getSiteDefaultLocale(
252 group.getGroupId());
253
254 return LocaleUtil.toLanguageId(siteDefaultLocale);
255 }
256 catch (PortalException pe) {
257 if (_log.isDebugEnabled()) {
258 pe.printStackTrace();
259 }
260
261 return StringPool.BLANK;
262 }
263 catch (SystemException se) {
264 if (_log.isDebugEnabled()) {
265 se.printStackTrace();
266 }
267
268 return StringPool.BLANK;
269 }
270 }
271
272 protected boolean isAlreadyFiltered(HttpServletRequest request) {
273 if (request.getAttribute(SKIP_FILTER) != null) {
274 return true;
275 }
276 else {
277 return false;
278 }
279 }
280
281 protected boolean isForwardedByI18nServlet(HttpServletRequest request) {
282 if ((request.getAttribute(WebKeys.I18N_LANGUAGE_ID) != null) ||
283 (request.getAttribute(WebKeys.I18N_PATH) != null)) {
284
285 return true;
286 }
287 else {
288 return false;
289 }
290 }
291
292 protected boolean isWidget(HttpServletRequest request) {
293 if (request.getAttribute(WebKeys.WIDGET) != null) {
294 return true;
295 }
296 else {
297 return false;
298 }
299 }
300
301 protected String prependI18nLanguageId(
302 HttpServletRequest request, int prependFriendlyUrlStyle) {
303
304 User user = (User)request.getAttribute(WebKeys.USER);
305
306 String userLanguageId = null;
307
308 if (user != null) {
309 userLanguageId = user.getLanguageId();
310 }
311
312 String requestedLanguageId = getRequestedLanguageId(
313 request, userLanguageId);
314
315 String defaultLanguageId = getDefaultLanguageId(request);
316
317 if (Validator.isNull(requestedLanguageId)) {
318 requestedLanguageId = defaultLanguageId;
319 }
320
321 if (prependFriendlyUrlStyle == 1) {
322 return prependIfRequestedLocaleDiffersFromDefaultLocale(
323 defaultLanguageId, requestedLanguageId);
324 }
325 else if (prependFriendlyUrlStyle == 2) {
326 return requestedLanguageId;
327 }
328 else if (prependFriendlyUrlStyle == 3) {
329 if (user != null) {
330 if (userLanguageId.equals(requestedLanguageId)) {
331 return null;
332 }
333
334 return requestedLanguageId;
335 }
336 else {
337 return prependIfRequestedLocaleDiffersFromDefaultLocale(
338 defaultLanguageId, requestedLanguageId);
339 }
340 }
341
342 return null;
343 }
344
345 protected String prependIfRequestedLocaleDiffersFromDefaultLocale(
346 String defaultLanguageId, String guestLanguageId) {
347
348 if (defaultLanguageId.equals(guestLanguageId)) {
349 return null;
350 }
351
352 return guestLanguageId;
353 }
354
355 @Override
356 protected void processFilter(
357 HttpServletRequest request, HttpServletResponse response,
358 FilterChain filterChain)
359 throws Exception {
360
361 request.setAttribute(SKIP_FILTER, Boolean.TRUE);
362
363 String redirect = getRedirect(request);
364
365 if (redirect == null) {
366 processFilter(I18nFilter.class, request, response, filterChain);
367
368 return;
369 }
370
371 if (_log.isDebugEnabled()) {
372 _log.debug("Redirect " + redirect);
373 }
374
375 response.sendRedirect(redirect);
376 }
377
378 private static Log _log = LogFactoryUtil.getLog(I18nFilter.class);
379
380 private static Set<String> _languageIds;
381
382 }