001
014
015 package com.liferay.portal.servlet;
016
017 import com.liferay.portal.kernel.exception.NoSuchGroupException;
018 import com.liferay.portal.kernel.exception.NoSuchLayoutException;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.model.Group;
023 import com.liferay.portal.kernel.model.Layout;
024 import com.liferay.portal.kernel.model.LayoutConstants;
025 import com.liferay.portal.kernel.model.LayoutFriendlyURL;
026 import com.liferay.portal.kernel.model.LayoutFriendlyURLComposite;
027 import com.liferay.portal.kernel.model.User;
028 import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
029 import com.liferay.portal.kernel.service.LayoutFriendlyURLLocalServiceUtil;
030 import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
031 import com.liferay.portal.kernel.service.ServiceContext;
032 import com.liferay.portal.kernel.service.ServiceContextFactory;
033 import com.liferay.portal.kernel.service.ServiceContextThreadLocal;
034 import com.liferay.portal.kernel.service.UserLocalServiceUtil;
035 import com.liferay.portal.kernel.servlet.PortalMessages;
036 import com.liferay.portal.kernel.servlet.SessionMessages;
037 import com.liferay.portal.kernel.struts.LastPath;
038 import com.liferay.portal.kernel.util.CharPool;
039 import com.liferay.portal.kernel.util.GetterUtil;
040 import com.liferay.portal.kernel.util.HttpUtil;
041 import com.liferay.portal.kernel.util.LocaleUtil;
042 import com.liferay.portal.kernel.util.ParamUtil;
043 import com.liferay.portal.kernel.util.Portal;
044 import com.liferay.portal.kernel.util.PortalUtil;
045 import com.liferay.portal.kernel.util.StringBundler;
046 import com.liferay.portal.kernel.util.StringUtil;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.kernel.util.WebKeys;
049 import com.liferay.portal.util.PortalInstances;
050
051 import java.io.IOException;
052
053 import java.util.HashMap;
054 import java.util.List;
055 import java.util.Locale;
056 import java.util.Map;
057
058 import javax.servlet.RequestDispatcher;
059 import javax.servlet.ServletConfig;
060 import javax.servlet.ServletContext;
061 import javax.servlet.ServletException;
062 import javax.servlet.http.HttpServlet;
063 import javax.servlet.http.HttpServletRequest;
064 import javax.servlet.http.HttpServletResponse;
065
066
071 public class FriendlyURLServlet extends HttpServlet {
072
073 @Override
074 public void init(ServletConfig servletConfig) throws ServletException {
075 super.init(servletConfig);
076
077 _private = GetterUtil.getBoolean(
078 servletConfig.getInitParameter("private"));
079 _user = GetterUtil.getBoolean(servletConfig.getInitParameter("user"));
080
081 if (_private) {
082 if (_user) {
083 _friendlyURLPathPrefix =
084 PortalUtil.getPathFriendlyURLPrivateUser();
085 }
086 else {
087 _friendlyURLPathPrefix =
088 PortalUtil.getPathFriendlyURLPrivateGroup();
089 }
090 }
091 else {
092 _friendlyURLPathPrefix = PortalUtil.getPathFriendlyURLPublic();
093 }
094 }
095
096 @Override
097 public void service(
098 HttpServletRequest request, HttpServletResponse response)
099 throws IOException, ServletException {
100
101
102
103
104 String mainPath = Portal.PATH_MAIN;
105
106 String redirect = mainPath;
107
108 String pathInfo = getPathInfo(request);
109
110 request.setAttribute(WebKeys.FRIENDLY_URL, getFriendlyURL(pathInfo));
111
112 Object[] redirectArray = null;
113
114 boolean forcePermanentRedirect = false;
115
116 try {
117 redirectArray = getRedirect(
118 request, pathInfo, mainPath, request.getParameterMap());
119
120 redirect = (String)redirectArray[0];
121 forcePermanentRedirect = (Boolean)redirectArray[1];
122
123 if (request.getAttribute(WebKeys.LAST_PATH) == null) {
124 LastPath lastPath = null;
125
126 String lifecycle = ParamUtil.getString(
127 request, "p_p_lifecycle");
128
129 if (lifecycle.equals("1")) {
130 lastPath = new LastPath(_friendlyURLPathPrefix, pathInfo);
131 }
132 else {
133 lastPath = new LastPath(
134 _friendlyURLPathPrefix, pathInfo,
135 HttpUtil.parameterMapToString(
136 request.getParameterMap()));
137 }
138
139 request.setAttribute(WebKeys.LAST_PATH, lastPath);
140 }
141 }
142 catch (Exception e) {
143 if (_log.isWarnEnabled()) {
144 _log.warn(e);
145 }
146
147 if ((e instanceof NoSuchGroupException) ||
148 (e instanceof NoSuchLayoutException)) {
149
150 PortalUtil.sendError(
151 HttpServletResponse.SC_NOT_FOUND, e, request, response);
152
153 return;
154 }
155 }
156
157 if (Validator.isNull(redirect)) {
158 redirect = mainPath;
159 }
160
161 if (_log.isDebugEnabled()) {
162 _log.debug("Redirect " + redirect);
163 }
164
165 if ((redirect.charAt(0) == CharPool.SLASH) && !forcePermanentRedirect) {
166 ServletContext servletContext = getServletContext();
167
168 RequestDispatcher requestDispatcher =
169 servletContext.getRequestDispatcher(redirect);
170
171 if (requestDispatcher != null) {
172 requestDispatcher.forward(request, response);
173 }
174 }
175 else {
176 if (forcePermanentRedirect) {
177 response.setHeader("Location", redirect);
178 response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
179 }
180 else {
181 response.sendRedirect(redirect);
182 }
183 }
184 }
185
186 protected String getFriendlyURL(String pathInfo) {
187 String friendlyURL = _friendlyURLPathPrefix;
188
189 if (Validator.isNotNull(pathInfo)) {
190 friendlyURL = friendlyURL.concat(pathInfo);
191 }
192
193 return friendlyURL;
194 }
195
196 protected String getPathInfo(HttpServletRequest request) {
197 String requestURI = request.getRequestURI();
198
199 int pos = requestURI.indexOf(Portal.JSESSIONID);
200
201 if (pos != -1) {
202 requestURI = requestURI.substring(0, pos);
203 }
204
205 String pathProxy = PortalUtil.getPathProxy();
206
207 pos = _friendlyURLPathPrefix.length() - pathProxy.length();
208
209 return requestURI.substring(pos);
210 }
211
212 protected Object[] getRedirect(
213 HttpServletRequest request, String path, String mainPath,
214 Map<String, String[]> params)
215 throws Exception {
216
217 if (Validator.isNull(path) || (path.charAt(0) != CharPool.SLASH)) {
218 return new Object[] {mainPath, false};
219 }
220
221
222
223 String friendlyURL = null;
224
225 int pos = path.indexOf(CharPool.SLASH, 1);
226
227 if (pos != -1) {
228 friendlyURL = path.substring(0, pos);
229 }
230 else if (path.length() > 1) {
231 friendlyURL = path;
232 }
233
234 if (Validator.isNull(friendlyURL)) {
235 return new Object[] {mainPath, Boolean.FALSE};
236 }
237
238 long companyId = PortalInstances.getCompanyId(request);
239
240 Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
241 companyId, friendlyURL);
242
243 if (group == null) {
244 String screenName = friendlyURL.substring(1);
245
246 if (_user || !Validator.isNumber(screenName)) {
247 User user = UserLocalServiceUtil.fetchUserByScreenName(
248 companyId, screenName);
249
250 if (user != null) {
251 group = user.getGroup();
252 }
253 else if (_log.isWarnEnabled()) {
254 _log.warn("No user exists with friendly URL " + screenName);
255 }
256 }
257 else {
258 long groupId = GetterUtil.getLong(screenName);
259
260 group = GroupLocalServiceUtil.fetchGroup(groupId);
261
262 if (group == null) {
263 if (_log.isDebugEnabled()) {
264 _log.debug(
265 "No group exists with friendly URL " + groupId +
266 ". Try fetching by screen name instead.");
267 }
268
269 User user = UserLocalServiceUtil.fetchUserByScreenName(
270 companyId, screenName);
271
272 if (user != null) {
273 group = user.getGroup();
274 }
275 else if (_log.isWarnEnabled()) {
276 _log.warn(
277 "No user or group exists with friendly URL " +
278 groupId);
279 }
280 }
281 }
282 }
283
284 if (group == null) {
285 StringBundler sb = new StringBundler(5);
286
287 sb.append("{companyId=");
288 sb.append(companyId);
289 sb.append(", friendlyURL=");
290 sb.append(friendlyURL);
291 sb.append("}");
292
293 throw new NoSuchGroupException(sb.toString());
294 }
295
296
297
298 friendlyURL = null;
299
300 if ((pos != -1) && ((pos + 1) != path.length())) {
301 friendlyURL = path.substring(pos);
302 }
303
304 if (Validator.isNull(friendlyURL)) {
305 request.setAttribute(
306 WebKeys.REDIRECT_TO_DEFAULT_LAYOUT, Boolean.TRUE);
307 }
308
309 Map<String, Object> requestContext = new HashMap<>();
310
311 requestContext.put("request", request);
312
313 ServiceContext serviceContext =
314 ServiceContextThreadLocal.getServiceContext();
315
316 if (serviceContext == null) {
317 serviceContext = ServiceContextFactory.getInstance(request);
318
319 ServiceContextThreadLocal.pushServiceContext(serviceContext);
320 }
321
322 try {
323 LayoutFriendlyURLComposite layoutFriendlyURLComposite =
324 PortalUtil.getLayoutFriendlyURLComposite(
325 group.getGroupId(), _private, friendlyURL, params,
326 requestContext);
327
328 Layout layout = layoutFriendlyURLComposite.getLayout();
329
330 request.setAttribute(WebKeys.LAYOUT, layout);
331
332 Locale locale = PortalUtil.getLocale(request);
333
334 String layoutFriendlyURLCompositeFriendlyURL =
335 layoutFriendlyURLComposite.getFriendlyURL();
336
337 if (Validator.isNull(layoutFriendlyURLCompositeFriendlyURL)) {
338 layoutFriendlyURLCompositeFriendlyURL = layout.getFriendlyURL(
339 locale);
340 }
341
342 pos = layoutFriendlyURLCompositeFriendlyURL.indexOf(
343 Portal.FRIENDLY_URL_SEPARATOR);
344
345 if (pos != 0) {
346 if (pos != -1) {
347 layoutFriendlyURLCompositeFriendlyURL =
348 layoutFriendlyURLCompositeFriendlyURL.substring(0, pos);
349 }
350
351 String i18nLanguageId = (String)request.getAttribute(
352 WebKeys.I18N_LANGUAGE_ID);
353
354 if ((Validator.isNotNull(i18nLanguageId) &&
355 !LanguageUtil.isAvailableLocale(
356 group.getGroupId(), i18nLanguageId)) ||
357 !StringUtil.equalsIgnoreCase(
358 layoutFriendlyURLCompositeFriendlyURL,
359 layout.getFriendlyURL(locale))) {
360
361 Locale originalLocale = setAlternativeLayoutFriendlyURL(
362 request, layout, layoutFriendlyURLCompositeFriendlyURL);
363
364 String redirect = PortalUtil.getLocalizedFriendlyURL(
365 request, layout, locale, originalLocale);
366
367 return new Object[] {redirect, Boolean.TRUE};
368 }
369 }
370 }
371 catch (NoSuchLayoutException nsle) {
372 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
373 group.getGroupId(), _private,
374 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
375
376 for (Layout layout : layouts) {
377 if (layout.matches(request, friendlyURL)) {
378 String redirect = PortalUtil.getLayoutActualURL(
379 layout, mainPath);
380
381 return new Object[] {redirect, Boolean.FALSE};
382 }
383 }
384
385 throw nsle;
386 }
387
388 String actualURL = PortalUtil.getActualURL(
389 group.getGroupId(), _private, mainPath, friendlyURL, params,
390 requestContext);
391
392 return new Object[] {actualURL, Boolean.FALSE};
393 }
394
395 protected Locale setAlternativeLayoutFriendlyURL(
396 HttpServletRequest request, Layout layout, String friendlyURL)
397 throws Exception {
398
399 List<LayoutFriendlyURL> layoutFriendlyURLs =
400 LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(
401 layout.getPlid(), friendlyURL, 0, 1);
402
403 if (layoutFriendlyURLs.isEmpty()) {
404 return null;
405 }
406
407 LayoutFriendlyURL layoutFriendlyURL = layoutFriendlyURLs.get(0);
408
409 Locale locale = LocaleUtil.fromLanguageId(
410 layoutFriendlyURL.getLanguageId());
411
412 String alternativeLayoutFriendlyURL =
413 PortalUtil.getLocalizedFriendlyURL(request, layout, locale, locale);
414
415 SessionMessages.add(
416 request, "alternativeLayoutFriendlyURL",
417 alternativeLayoutFriendlyURL);
418
419 PortalMessages.add(
420 request, PortalMessages.KEY_JSP_PATH,
421 "/html/common/themes/layout_friendly_url_redirect.jsp");
422
423 return locale;
424 }
425
426 private static final Log _log = LogFactoryUtil.getLog(
427 FriendlyURLServlet.class);
428
429 private String _friendlyURLPathPrefix;
430 private boolean _private;
431 private boolean _user;
432
433 }