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