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