001
014
015 package com.liferay.portal.servlet.filters.i18n;
016
017 import com.liferay.portal.kernel.language.LanguageUtil;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.util.CharPool;
021 import com.liferay.portal.kernel.util.CookieKeys;
022 import com.liferay.portal.kernel.util.LocaleUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.model.Group;
027 import com.liferay.portal.model.LayoutSet;
028 import com.liferay.portal.servlet.filters.BasePortalFilter;
029 import com.liferay.portal.util.PortalUtil;
030 import com.liferay.portal.util.PropsValues;
031 import com.liferay.portal.util.WebKeys;
032
033 import java.util.Collections;
034 import java.util.HashSet;
035 import java.util.Locale;
036 import java.util.Set;
037
038 import javax.servlet.FilterChain;
039 import javax.servlet.http.HttpServletRequest;
040 import javax.servlet.http.HttpServletResponse;
041
042
045 public class I18nFilter extends BasePortalFilter {
046
047 public static final String SKIP_FILTER =
048 I18nFilter.class.getName() + "SKIP_FILTER";
049
050 public static Set<String> getLanguageIds() {
051 return _languageIds;
052 }
053
054 public static void setLanguageIds(Set<String> languageIds) {
055 for (String languageId : languageIds) {
056 languageId = languageId.substring(1);
057
058 _languageIds.add(languageId);
059 }
060
061 _languageIds = Collections.unmodifiableSet(_languageIds);
062 }
063
064 @Override
065 public boolean isFilterEnabled(
066 HttpServletRequest request, HttpServletResponse response) {
067
068 if (!isAlreadyFiltered(request) && !isForwardedByI18nServlet(request)) {
069 return true;
070 }
071 else {
072 return false;
073 }
074 }
075
076 protected String getRedirect(HttpServletRequest request) throws Exception {
077 if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 0) {
078 return null;
079 }
080
081 String contextPath = PortalUtil.getPathContext();
082
083 String requestURI = request.getRequestURI();
084
085 if (Validator.isNotNull(contextPath) &&
086 requestURI.contains(contextPath)) {
087
088 requestURI = requestURI.substring(contextPath.length());
089 }
090
091 requestURI = StringUtil.replace(
092 requestURI, StringPool.DOUBLE_SLASH, StringPool.SLASH);
093
094 String i18nLanguageId = requestURI.substring(1);
095
096 int pos = requestURI.indexOf(CharPool.SLASH, 1);
097
098 if (pos != -1) {
099 i18nLanguageId = i18nLanguageId.substring(0, pos - 1);
100 }
101
102 if (_languageIds.contains(i18nLanguageId)) {
103 return null;
104 }
105
106 String defaultLanguageId = LocaleUtil.toLanguageId(
107 LocaleUtil.getDefault());
108
109 String guestLanguageId = CookieKeys.getCookie(
110 request, CookieKeys.GUEST_LANGUAGE_ID, false);
111
112 if (Validator.isNull(guestLanguageId)) {
113 guestLanguageId = defaultLanguageId;
114 }
115
116 if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 1) {
117 if (!defaultLanguageId.equals(guestLanguageId)) {
118 i18nLanguageId = guestLanguageId;
119 }
120 else {
121 return null;
122 }
123 }
124 else if (PropsValues.LOCALE_PREPEND_FRIENDLY_URL_STYLE == 2) {
125 i18nLanguageId = guestLanguageId;
126 }
127
128 if (i18nLanguageId == null) {
129 return null;
130 }
131
132 String i18nPathLanguageId = i18nLanguageId;
133
134 Locale locale = LocaleUtil.fromLanguageId(i18nLanguageId);
135
136 if (!LanguageUtil.isDuplicateLanguageCode(locale.getLanguage())) {
137 i18nPathLanguageId = locale.getLanguage();
138 }
139 else {
140 Locale priorityLocale = LanguageUtil.getLocale(
141 locale.getLanguage());
142
143 if (locale.equals(priorityLocale)) {
144 i18nPathLanguageId = locale.getLanguage();
145 }
146 }
147
148 Locale i18nPathLocale = LocaleUtil.fromLanguageId(i18nPathLanguageId);
149
150 if (!LanguageUtil.isAvailableLocale(i18nPathLocale) &&
151 !LanguageUtil.isDuplicateLanguageCode(i18nPathLanguageId)) {
152
153 return null;
154 }
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 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
165 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
166
167 if ((layoutSet != null) &&
168 (requestURI.startsWith(_PRIVATE_GROUP_SERVLET_MAPPING) ||
169 requestURI.startsWith(_PRIVATE_USER_SERVLET_MAPPING) ||
170 requestURI.startsWith(_PUBLIC_GROUP_SERVLET_MAPPING))) {
171
172 int x = requestURI.indexOf(StringPool.SLASH, 1);
173
174 if (x == -1) {
175
176
177
178 requestURI += StringPool.SLASH;
179
180 x = requestURI.indexOf(CharPool.SLASH, 1);
181 }
182
183 int y = requestURI.indexOf(CharPool.SLASH, x + 1);
184
185 if (y == -1) {
186
187
188
189 requestURI += StringPool.SLASH;
190
191 y = requestURI.indexOf(CharPool.SLASH, x + 1);
192 }
193
194 String groupFriendlyURL = requestURI.substring(x, y);
195
196 Group group = layoutSet.getGroup();
197
198 if (group.getFriendlyURL().equals(groupFriendlyURL)) {
199 redirect = contextPath + i18nPath + requestURI.substring(y);
200 }
201 }
202
203 String queryString = request.getQueryString();
204
205 if (Validator.isNotNull(queryString)) {
206 redirect += StringPool.QUESTION + request.getQueryString();
207 }
208
209 return redirect;
210 }
211
212 protected boolean isAlreadyFiltered(HttpServletRequest request) {
213 if (request.getAttribute(SKIP_FILTER) != null) {
214 return true;
215 }
216 else {
217 return false;
218 }
219 }
220
221 protected boolean isForwardedByI18nServlet(HttpServletRequest request) {
222 if ((request.getAttribute(WebKeys.I18N_LANGUAGE_ID) != null) ||
223 (request.getAttribute(WebKeys.I18N_PATH) != null)) {
224
225 return true;
226 }
227 else {
228 return false;
229 }
230 }
231
232 @Override
233 protected void processFilter(
234 HttpServletRequest request, HttpServletResponse response,
235 FilterChain filterChain)
236 throws Exception {
237
238 request.setAttribute(SKIP_FILTER, Boolean.TRUE);
239
240 String redirect = getRedirect(request);
241
242 if (redirect == null) {
243 processFilter(I18nFilter.class, request, response, filterChain);
244
245 return;
246 }
247
248 if (_log.isDebugEnabled()) {
249 _log.debug("Redirect " + redirect);
250 }
251
252 response.sendRedirect(redirect);
253 }
254
255 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
256 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
257
258 private static final String _PRIVATE_USER_SERVLET_MAPPING =
259 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
260
261 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
262 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
263
264 private static Log _log = LogFactoryUtil.getLog(I18nFilter.class);
265
266 private static Set<String> _languageIds = new HashSet<String>();
267
268 }