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