001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.struts.LastPath;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.model.Group;
025    import com.liferay.portal.model.User;
026    import com.liferay.portal.service.GroupLocalServiceUtil;
027    import com.liferay.portal.service.ServiceContext;
028    import com.liferay.portal.service.ServiceContextFactory;
029    import com.liferay.portal.service.ServiceContextThreadLocal;
030    import com.liferay.portal.service.UserLocalServiceUtil;
031    import com.liferay.portal.util.Portal;
032    import com.liferay.portal.util.PortalInstances;
033    import com.liferay.portal.util.PortalUtil;
034    import com.liferay.portal.util.PropsValues;
035    import com.liferay.portal.util.WebKeys;
036    
037    import java.io.IOException;
038    
039    import java.util.HashMap;
040    import java.util.Map;
041    
042    import javax.servlet.RequestDispatcher;
043    import javax.servlet.ServletConfig;
044    import javax.servlet.ServletContext;
045    import javax.servlet.ServletException;
046    import javax.servlet.http.HttpServlet;
047    import javax.servlet.http.HttpServletRequest;
048    import javax.servlet.http.HttpServletResponse;
049    
050    /**
051     * @author Brian Wing Shun Chan
052     * @author Jorge Ferrer
053     * @author Shuyang Zhou
054     */
055    public class FriendlyURLServlet extends HttpServlet {
056    
057            @Override
058            public void init(ServletConfig servletConfig) throws ServletException {
059                    super.init(servletConfig);
060    
061                    _private = GetterUtil.getBoolean(
062                            servletConfig.getInitParameter("private"));
063                    _user = GetterUtil.getBoolean(servletConfig.getInitParameter("user"));
064    
065                    if (_private) {
066                            if (_user) {
067                                    _friendlyURLPathPrefix =
068                                            PortalUtil.getPathFriendlyURLPrivateUser();
069                            }
070                            else {
071                                    _friendlyURLPathPrefix =
072                                            PortalUtil.getPathFriendlyURLPrivateGroup();
073                            }
074                    }
075                    else {
076                            _friendlyURLPathPrefix = PortalUtil.getPathFriendlyURLPublic();
077                    }
078            }
079    
080            @Override
081            public void service(
082                            HttpServletRequest request, HttpServletResponse response)
083                    throws IOException, ServletException {
084    
085                    // Do not set the entire full main path. See LEP-456.
086    
087                    //String mainPath = (String)ctx.getAttribute(WebKeys.MAIN_PATH);
088                    String mainPath = Portal.PATH_MAIN;
089    
090                    String redirect = mainPath;
091    
092                    String pathInfo = request.getPathInfo();
093    
094                    request.setAttribute(
095                            WebKeys.FRIENDLY_URL, _friendlyURLPathPrefix.concat(pathInfo));
096    
097                    try {
098                            redirect = getRedirect(
099                                    request, pathInfo, mainPath, request.getParameterMap());
100    
101                            if (request.getAttribute(WebKeys.LAST_PATH) == null) {
102                                    LastPath lastPath = new LastPath(
103                                            _friendlyURLPathPrefix, pathInfo,
104                                            request.getParameterMap());
105    
106                                    request.setAttribute(WebKeys.LAST_PATH, lastPath);
107                            }
108                    }
109                    catch (NoSuchLayoutException nsle) {
110                            _log.warn(nsle);
111    
112                            PortalUtil.sendError(
113                                    HttpServletResponse.SC_NOT_FOUND, nsle, request, response);
114    
115                            return;
116                    }
117                    catch (Exception e) {
118                            if (_log.isWarnEnabled()) {
119                                    _log.warn(e);
120                            }
121                    }
122    
123                    if (Validator.isNull(redirect)) {
124                            redirect = mainPath;
125                    }
126    
127                    if (_log.isDebugEnabled()) {
128                            _log.debug("Redirect " + redirect);
129                    }
130    
131                    if (redirect.charAt(0) == CharPool.SLASH) {
132                            ServletContext servletContext = getServletContext();
133    
134                            RequestDispatcher requestDispatcher =
135                                    servletContext.getRequestDispatcher(redirect);
136    
137                            if (requestDispatcher != null) {
138                                    requestDispatcher.forward(request, response);
139                            }
140                    }
141                    else {
142                            response.sendRedirect(redirect);
143                    }
144            }
145    
146            protected String getRedirect(
147                            HttpServletRequest request, String path, String mainPath,
148                            Map<String, String[]> params)
149                    throws Exception {
150    
151                    if (Validator.isNull(path) || (path.charAt(0) != CharPool.SLASH)) {
152                            return mainPath;
153                    }
154    
155                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH &&
156                            (request.getRemoteUser() != null)) {
157    
158                            return mainPath;
159                    }
160    
161                    // Group friendly URL
162    
163                    String friendlyURL = null;
164    
165                    int pos = path.indexOf(CharPool.SLASH, 1);
166    
167                    if (pos != -1) {
168                            friendlyURL = path.substring(0, pos);
169                    }
170                    else if (path.length() > 1) {
171                            friendlyURL = path;
172                    }
173    
174                    if (Validator.isNull(friendlyURL)) {
175                            return mainPath;
176                    }
177    
178                    long companyId = PortalInstances.getCompanyId(request);
179    
180                    Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
181                            companyId, friendlyURL);
182    
183                    if (group == null) {
184                            String screenName = friendlyURL.substring(1);
185    
186                            if (_user || !Validator.isNumber(screenName)) {
187                                    User user = UserLocalServiceUtil.fetchUserByScreenName(
188                                            companyId, screenName);
189    
190                                    if (user != null) {
191                                            group = user.getGroup();
192                                    }
193                                    else if (_log.isWarnEnabled()) {
194                                            _log.warn("No user exists with friendly URL " + screenName);
195                                    }
196                            }
197                            else {
198                                    long groupId = GetterUtil.getLong(screenName);
199    
200                                    group = GroupLocalServiceUtil.fetchGroup(groupId);
201    
202                                    if (group == null) {
203                                            if (_log.isDebugEnabled()) {
204                                                    _log.debug(
205                                                            "No group exists with friendly URL " + groupId +
206                                                                    ". Try fetching by screen name instead.");
207                                            }
208    
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(
217                                                            "No user or group exists with friendly URL " +
218                                                                    groupId);
219                                            }
220                                    }
221                            }
222                    }
223    
224                    if (group == null) {
225                            return mainPath;
226                    }
227    
228                    // Layout friendly URL
229    
230                    friendlyURL = null;
231    
232                    if ((pos != -1) && ((pos + 1) != path.length())) {
233                            friendlyURL = path.substring(pos);
234                    }
235    
236                    if (Validator.isNull(friendlyURL)) {
237                            request.setAttribute(
238                                    WebKeys.REDIRECT_TO_DEFAULT_LAYOUT, Boolean.TRUE);
239                    }
240    
241                    Map<String, Object> requestContext = new HashMap<String, Object>();
242    
243                    requestContext.put("request", request);
244    
245                    ServiceContext serviceContext =
246                            ServiceContextThreadLocal.getServiceContext();
247    
248                    if (serviceContext == null) {
249                            serviceContext = ServiceContextFactory.getInstance(request);
250    
251                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
252                    }
253    
254                    return PortalUtil.getActualURL(
255                            group.getGroupId(), _private, mainPath, friendlyURL, params,
256                            requestContext);
257            }
258    
259            private static Log _log = LogFactoryUtil.getLog(FriendlyURLServlet.class);
260    
261            private String _friendlyURLPathPrefix;
262            private boolean _private;
263            private boolean _user;
264    
265    }