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