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.LocaleUtil;
022 import com.liferay.portal.kernel.util.StringPool;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.kernel.util.Validator;
025 import com.liferay.portal.model.Group;
026 import com.liferay.portal.model.LayoutSet;
027 import com.liferay.portal.servlet.filters.BasePortalFilter;
028 import com.liferay.portal.util.CookieKeys;
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.indexOf(contextPath) != -1)) {
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 return null;
152 }
153
154 String i18nPath = StringPool.SLASH.concat(i18nPathLanguageId);
155
156 if (requestURI.contains(i18nPath.concat(StringPool.SLASH))) {
157 return null;
158 }
159
160 String redirect = contextPath + i18nPath + requestURI;
161
162 LayoutSet layoutSet = (LayoutSet)request.getAttribute(
163 WebKeys.VIRTUAL_HOST_LAYOUT_SET);
164
165 if ((layoutSet != null) &&
166 (requestURI.startsWith(_PRIVATE_GROUP_SERVLET_MAPPING) ||
167 requestURI.startsWith(_PRIVATE_USER_SERVLET_MAPPING) ||
168 requestURI.startsWith(_PUBLIC_GROUP_SERVLET_MAPPING))) {
169
170 int x = requestURI.indexOf(StringPool.SLASH, 1);
171
172 if (x == -1) {
173
174
175
176 requestURI += StringPool.SLASH;
177
178 x = requestURI.indexOf(CharPool.SLASH, 1);
179 }
180
181 int y = requestURI.indexOf(CharPool.SLASH, x + 1);
182
183 if (y == -1) {
184
185
186
187 requestURI += StringPool.SLASH;
188
189 y = requestURI.indexOf(CharPool.SLASH, x + 1);
190 }
191
192 String groupFriendlyURL = requestURI.substring(x, y);
193
194 Group group = layoutSet.getGroup();
195
196 if (group.getFriendlyURL().equals(groupFriendlyURL)) {
197 redirect = contextPath + i18nPath + requestURI.substring(y);
198 }
199 }
200
201 String queryString = request.getQueryString();
202
203 if (Validator.isNotNull(queryString)) {
204 redirect += StringPool.QUESTION + request.getQueryString();
205 }
206
207 return redirect;
208 }
209
210 protected boolean isAlreadyFiltered(HttpServletRequest request) {
211 if (request.getAttribute(SKIP_FILTER) != null) {
212 return true;
213 }
214 else {
215 return false;
216 }
217 }
218
219 protected boolean isForwardedByI18nServlet(HttpServletRequest request) {
220 if ((request.getAttribute(WebKeys.I18N_LANGUAGE_ID) != null) ||
221 (request.getAttribute(WebKeys.I18N_PATH) != null)) {
222
223 return true;
224 }
225 else {
226 return false;
227 }
228 }
229
230 @Override
231 protected void processFilter(
232 HttpServletRequest request, HttpServletResponse response,
233 FilterChain filterChain)
234 throws Exception {
235
236 request.setAttribute(SKIP_FILTER, Boolean.TRUE);
237
238 String redirect = getRedirect(request);
239
240 if (redirect == null) {
241 processFilter(I18nFilter.class, request, response, filterChain);
242
243 return;
244 }
245
246 if (_log.isDebugEnabled()) {
247 _log.debug("Redirect " + redirect);
248 }
249
250 response.sendRedirect(redirect);
251 }
252
253 private static final String _PRIVATE_GROUP_SERVLET_MAPPING =
254 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
255
256 private static final String _PRIVATE_USER_SERVLET_MAPPING =
257 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
258
259 private static final String _PUBLIC_GROUP_SERVLET_MAPPING =
260 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
261
262 private static Log _log = LogFactoryUtil.getLog(I18nFilter.class);
263
264 private static Set<String> _languageIds = new HashSet<String>();
265
266 }