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