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