1
14
15 package com.liferay.portal.servlet.filters.i18n;
16
17 import com.liferay.portal.kernel.language.LanguageUtil;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.util.CharPool;
21 import com.liferay.portal.kernel.util.LocaleUtil;
22 import com.liferay.portal.kernel.util.StringPool;
23 import com.liferay.portal.kernel.util.StringUtil;
24 import com.liferay.portal.kernel.util.Validator;
25 import com.liferay.portal.model.Group;
26 import com.liferay.portal.model.LayoutSet;
27 import com.liferay.portal.servlet.filters.BasePortalFilter;
28 import com.liferay.portal.util.CookieKeys;
29 import com.liferay.portal.util.PortalUtil;
30 import com.liferay.portal.util.PropsValues;
31 import com.liferay.portal.util.WebKeys;
32
33 import java.util.Collections;
34 import java.util.HashSet;
35 import java.util.Locale;
36 import java.util.Set;
37
38 import javax.servlet.FilterChain;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
41
42
47 public class I18nFilter extends BasePortalFilter {
48
49 public static final String SKIP_FILTER =
50 I18nFilter.class.getName() + "SKIP_FILTER";
51
52 public static Set<String> getLanguageIds() {
53 return _languageIds;
54 }
55
56 public static void setLanguageIds(Set<String> languageIds) {
57 for (String languageId : languageIds) {
58 languageId = languageId.substring(1);
59
60 _languageIds.add(languageId);
61 }
62
63 _languageIds = Collections.unmodifiableSet(_languageIds);
64 }
65
66 protected String getRedirect(HttpServletRequest request) {
67 if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 0) {
68 return null;
69 }
70
71 String contextPath = PortalUtil.getPathContext();
72
73 String requestURI = request.getRequestURI();
74
75 if ((Validator.isNotNull(contextPath)) &&
76 (requestURI.indexOf(contextPath) != -1)) {
77
78 requestURI = requestURI.substring(contextPath.length());
79 }
80
81 requestURI = StringUtil.replace(
82 requestURI, StringPool.DOUBLE_SLASH, StringPool.SLASH);
83
84 String i18nLanguageId = requestURI.substring(1);
85
86 int pos = requestURI.indexOf(CharPool.SLASH, 1);
87
88 if (pos != -1) {
89 i18nLanguageId = i18nLanguageId.substring(0, pos - 1);
90 }
91
92 if (_languageIds.contains(i18nLanguageId)) {
93 return null;
94 }
95
96 String defaultLanguageId = LocaleUtil.toLanguageId(
97 LocaleUtil.getDefault());
98
99 String guestLanguageId = CookieKeys.getCookie(
100 request, CookieKeys.GUEST_LANGUAGE_ID);
101
102 if (Validator.isNull(guestLanguageId)) {
103 guestLanguageId = defaultLanguageId;
104 }
105
106 if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 1) {
107 if (!defaultLanguageId.equals(guestLanguageId)) {
108 i18nLanguageId = guestLanguageId;
109 }
110 else {
111 return null;
112 }
113 }
114 else if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 2) {
115 i18nLanguageId = guestLanguageId;
116 }
117
118 if (i18nLanguageId == null) {
119 return null;
120 }
121
122 String i18nPath = StringPool.SLASH + i18nLanguageId;
123
124 Locale locale = LocaleUtil.fromLanguageId(i18nLanguageId);
125
126 if (!LanguageUtil.isDuplicateLanguageCode(locale.getLanguage())) {
127 i18nPath = StringPool.SLASH + locale.getLanguage();
128 }
129 else {
130 Locale priorityLocale = LanguageUtil.getLocale(
131 locale.getLanguage());
132
133 if (locale.equals(priorityLocale)) {
134 i18nPath = StringPool.SLASH + locale.getLanguage();
135 }
136 }
137
138 String redirect = contextPath + i18nPath + requestURI;
139
140 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
141 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
142
143 if ((layoutSet != null) &&
144 (requestURI.startsWith(_PRIVATE_GROUP_SERVLET_MAPPING) ||
145 requestURI.startsWith(_PRIVATE_USER_SERVLET_MAPPING) ||
146 requestURI.startsWith(_PUBLIC_GROUP_SERVLET_MAPPING))) {
147
148 int x = requestURI.indexOf(StringPool.SLASH, 1);
149
150 if (x == -1) {
151
152
154 requestURI += StringPool.SLASH;
155
156 x = requestURI.indexOf(CharPool.SLASH, 1);
157 }
158
159 int y = requestURI.indexOf(CharPool.SLASH, x + 1);
160
161 if (y == -1) {
162
163
165 requestURI += StringPool.SLASH;
166
167 y = requestURI.indexOf(CharPool.SLASH, x + 1);
168 }
169
170 String groupFriendlyURL = requestURI.substring(x, y);
171
172 Group group = layoutSet.getGroup();
173
174 if (group.getFriendlyURL().equals(groupFriendlyURL)) {
175 redirect = contextPath + i18nPath + requestURI.substring(y);
176 }
177 }
178
179 String queryString = request.getQueryString();
180
181 if (Validator.isNotNull(queryString)) {
182 redirect += StringPool.QUESTION + request.getQueryString();
183 }
184
185 return redirect;
186 }
187
188 protected boolean isAlreadyFiltered(HttpServletRequest request) {
189 if (request.getAttribute(SKIP_FILTER) != null) {
190 return true;
191 }
192 else {
193 return false;
194 }
195 }
196
197 protected boolean isForwardedByI18nServlet(HttpServletRequest request) {
198 if ((request.getAttribute(WebKeys.I18N_LANGUAGE_ID) != null) ||
199 (request.getAttribute(WebKeys.I18N_PATH) != null)) {
200
201 return true;
202 }
203 else {
204 return false;
205 }
206 }
207
208 protected void processFilter(
209 HttpServletRequest request, HttpServletResponse response,
210 FilterChain filterChain)
211 throws Exception {
212
213 if (isAlreadyFiltered(request) || isForwardedByI18nServlet(request)) {
214 processFilter(I18nFilter.class, request, response, filterChain);
215
216 return;
217 }
218
219 request.setAttribute(SKIP_FILTER, Boolean.TRUE);
220
221 String redirect = getRedirect(request);
222
223 if (redirect == null) {
224 processFilter(I18nFilter.class, request, response, filterChain);
225
226 return;
227 }
228
229 if (_log.isDebugEnabled()) {
230 _log.debug("Redirect " + redirect);
231 }
232
233 response.sendRedirect(redirect);
234 }
235
236 private static Log _log = LogFactoryUtil.getLog(I18nFilter.class);
237
238 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
239 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
240
241 private static final String _PRIVATE_USER_SERVLET_MAPPING =
242 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
243
244 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
245 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
246
247 private static Set<String> _languageIds = new HashSet<String>();
248
249 }