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 request.setAttribute(
103 WebKeys.FRIENDLY_URL, _friendlyURLPathPrefix.concat(pathInfo));
104
105 Object[] redirectArray = null;
106
107 boolean forcePermanentRedirect = false;
108
109 try {
110 redirectArray = getRedirect(
111 request, pathInfo, mainPath, request.getParameterMap());
112
113 redirect = (String)redirectArray[0];
114 forcePermanentRedirect = (Boolean)redirectArray[1];
115
116 if (request.getAttribute(WebKeys.LAST_PATH) == null) {
117 LastPath lastPath = new LastPath(
118 _friendlyURLPathPrefix, pathInfo,
119 request.getParameterMap());
120
121 request.setAttribute(WebKeys.LAST_PATH, lastPath);
122 }
123 }
124 catch (NoSuchLayoutException nsle) {
125 _log.warn(nsle);
126
127 PortalUtil.sendError(
128 HttpServletResponse.SC_NOT_FOUND, nsle, request, response);
129
130 return;
131 }
132 catch (Exception e) {
133 if (_log.isWarnEnabled()) {
134 _log.warn(e);
135 }
136 }
137
138 if (Validator.isNull(redirect)) {
139 redirect = mainPath;
140 }
141
142 if (_log.isDebugEnabled()) {
143 _log.debug("Redirect " + redirect);
144 }
145
146 if ((redirect.charAt(0) == CharPool.SLASH) && !forcePermanentRedirect) {
147 ServletContext servletContext = getServletContext();
148
149 RequestDispatcher requestDispatcher =
150 servletContext.getRequestDispatcher(redirect);
151
152 if (requestDispatcher != null) {
153 requestDispatcher.forward(request, response);
154 }
155 }
156 else {
157 if (forcePermanentRedirect) {
158 response.setHeader("Location", redirect);
159 response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
160 }
161 else {
162 response.sendRedirect(redirect);
163 }
164 }
165 }
166
167 protected Object[] getRedirect(
168 HttpServletRequest request, String path, String mainPath,
169 Map<String, String[]> params)
170 throws Exception {
171
172 if (Validator.isNull(path) || (path.charAt(0) != CharPool.SLASH)) {
173 return new Object[] {mainPath, false};
174 }
175
176
177
178 String friendlyURL = null;
179
180 int pos = path.indexOf(CharPool.SLASH, 1);
181
182 if (pos != -1) {
183 friendlyURL = path.substring(0, pos);
184 }
185 else if (path.length() > 1) {
186 friendlyURL = path;
187 }
188
189 if (Validator.isNull(friendlyURL)) {
190 return new Object[] {mainPath, Boolean.FALSE};
191 }
192
193 long companyId = PortalInstances.getCompanyId(request);
194
195 Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
196 companyId, friendlyURL);
197
198 if (group == null) {
199 String screenName = friendlyURL.substring(1);
200
201 if (_user || !Validator.isNumber(screenName)) {
202 User user = UserLocalServiceUtil.fetchUserByScreenName(
203 companyId, screenName);
204
205 if (user != null) {
206 group = user.getGroup();
207 }
208 else if (_log.isWarnEnabled()) {
209 _log.warn("No user exists with friendly URL " + screenName);
210 }
211 }
212 else {
213 long groupId = GetterUtil.getLong(screenName);
214
215 group = GroupLocalServiceUtil.fetchGroup(groupId);
216
217 if (group == null) {
218 if (_log.isDebugEnabled()) {
219 _log.debug(
220 "No group exists with friendly URL " + groupId +
221 ". Try fetching by screen name instead.");
222 }
223
224 User user = UserLocalServiceUtil.fetchUserByScreenName(
225 companyId, screenName);
226
227 if (user != null) {
228 group = user.getGroup();
229 }
230 else if (_log.isWarnEnabled()) {
231 _log.warn(
232 "No user or group exists with friendly URL " +
233 groupId);
234 }
235 }
236 }
237 }
238
239 if (group == null) {
240 return new Object[] {mainPath, Boolean.FALSE};
241 }
242
243
244
245 friendlyURL = null;
246
247 if ((pos != -1) && ((pos + 1) != path.length())) {
248 friendlyURL = path.substring(pos);
249 }
250
251 if (Validator.isNull(friendlyURL)) {
252 request.setAttribute(
253 WebKeys.REDIRECT_TO_DEFAULT_LAYOUT, Boolean.TRUE);
254 }
255
256 Map<String, Object> requestContext = new HashMap<String, Object>();
257
258 requestContext.put("request", request);
259
260 ServiceContext serviceContext =
261 ServiceContextThreadLocal.getServiceContext();
262
263 if (serviceContext == null) {
264 serviceContext = ServiceContextFactory.getInstance(request);
265
266 ServiceContextThreadLocal.pushServiceContext(serviceContext);
267 }
268
269 String actualURL = PortalUtil.getActualURL(
270 group.getGroupId(), _private, mainPath, friendlyURL, params,
271 requestContext);
272
273 if (Validator.isNotNull(friendlyURL)) {
274 Locale locale = PortalUtil.getLocale(request);
275
276 LayoutFriendlyURLComposite layoutFriendlyURLComposite =
277 PortalUtil.getLayoutFriendlyURLComposite(
278 group.getGroupId(), _private, friendlyURL, params,
279 requestContext);
280
281 Layout layout = layoutFriendlyURLComposite.getLayout();
282
283 friendlyURL = layoutFriendlyURLComposite.getFriendlyURL();
284
285 pos = friendlyURL.indexOf(Portal.FRIENDLY_URL_SEPARATOR);
286
287 if (pos != 0) {
288 if (pos != -1) {
289 friendlyURL = friendlyURL.substring(0, pos);
290 }
291
292 if (!friendlyURL.equals(layout.getFriendlyURL(locale))) {
293 setAlternativeLayoutFriendlyURL(
294 request, layout, friendlyURL);
295
296 String redirect = PortalUtil.getLocalizedFriendlyURL(
297 request, layout, locale);
298
299 return new Object[] {redirect, Boolean.TRUE};
300 }
301 }
302 }
303
304 return new Object[] {actualURL, Boolean.FALSE};
305 }
306
307 protected void setAlternativeLayoutFriendlyURL(
308 HttpServletRequest request, Layout layout, String friendlyURL)
309 throws Exception {
310
311 List<LayoutFriendlyURL> layoutFriendlyURLs =
312 LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(
313 layout.getPlid(), friendlyURL, 0, 1);
314
315 if (layoutFriendlyURLs.isEmpty()) {
316 return;
317 }
318
319 LayoutFriendlyURL layoutFriendlyURL = layoutFriendlyURLs.get(0);
320
321 Locale locale = LocaleUtil.fromLanguageId(
322 layoutFriendlyURL.getLanguageId());
323
324 String alternativeLayoutFriendlyURL =
325 PortalUtil.getLocalizedFriendlyURL(request, layout, locale);
326
327 SessionMessages.add(
328 request, "alternativeLayoutFriendlyURL",
329 alternativeLayoutFriendlyURL);
330
331 PortalMessages.add(
332 request, PortalMessages.KEY_JSP_PATH,
333 "/html/common/themes/layout_friendly_url_redirect.jsp");
334 }
335
336 private static Log _log = LogFactoryUtil.getLog(FriendlyURLServlet.class);
337
338 private String _friendlyURLPathPrefix;
339 private boolean _private;
340 private boolean _user;
341
342 }