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