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