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