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