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.WebKeys;
035    
036    import java.io.IOException;
037    
038    import java.util.HashMap;
039    import java.util.Map;
040    
041    import javax.servlet.RequestDispatcher;
042    import javax.servlet.ServletConfig;
043    import javax.servlet.ServletContext;
044    import javax.servlet.ServletException;
045    import javax.servlet.http.HttpServlet;
046    import javax.servlet.http.HttpServletRequest;
047    import javax.servlet.http.HttpServletResponse;
048    
049    /**
050     * @author Brian Wing Shun Chan
051     * @author Jorge Ferrer
052     * @author Shuyang Zhou
053     */
054    public class FriendlyURLServlet extends HttpServlet {
055    
056            @Override
057            public void init(ServletConfig servletConfig) throws ServletException {
058                    super.init(servletConfig);
059    
060                    _private = GetterUtil.getBoolean(
061                            servletConfig.getInitParameter("private"));
062                    _user = GetterUtil.getBoolean(servletConfig.getInitParameter("user"));
063    
064                    if (_private) {
065                            if (_user) {
066                                    _friendlyURLPathPrefix =
067                                            PortalUtil.getPathFriendlyURLPrivateUser();
068                            }
069                            else {
070                                    _friendlyURLPathPrefix =
071                                            PortalUtil.getPathFriendlyURLPrivateGroup();
072                            }
073                    }
074                    else {
075                            _friendlyURLPathPrefix = PortalUtil.getPathFriendlyURLPublic();
076                    }
077            }
078    
079            @Override
080            public void service(
081                            HttpServletRequest request, HttpServletResponse response)
082                    throws IOException, ServletException {
083    
084                    // Do not set the entire full main path. See LEP-456.
085    
086                    //String mainPath = (String)ctx.getAttribute(WebKeys.MAIN_PATH);
087                    String mainPath = Portal.PATH_MAIN;
088    
089                    String redirect = mainPath;
090    
091                    String pathInfo = request.getPathInfo();
092    
093                    request.setAttribute(
094                            WebKeys.FRIENDLY_URL, _friendlyURLPathPrefix.concat(pathInfo));
095    
096                    try {
097                            redirect = getRedirect(
098                                    request, pathInfo, mainPath, request.getParameterMap());
099    
100                            if (request.getAttribute(WebKeys.LAST_PATH) == null) {
101                                    LastPath lastPath = new LastPath(
102                                            _friendlyURLPathPrefix, pathInfo,
103                                            request.getParameterMap());
104    
105                                    request.setAttribute(WebKeys.LAST_PATH, lastPath);
106                            }
107                    }
108                    catch (NoSuchLayoutException nsle) {
109                            _log.warn(nsle);
110    
111                            PortalUtil.sendError(
112                                    HttpServletResponse.SC_NOT_FOUND, nsle, request, response);
113    
114                            return;
115                    }
116                    catch (Exception e) {
117                            if (_log.isWarnEnabled()) {
118                                    _log.warn(e);
119                            }
120                    }
121    
122                    if (Validator.isNull(redirect)) {
123                            redirect = mainPath;
124                    }
125    
126                    if (_log.isDebugEnabled()) {
127                            _log.debug("Redirect " + redirect);
128                    }
129    
130                    if (redirect.charAt(0) == CharPool.SLASH) {
131                            ServletContext servletContext = getServletContext();
132    
133                            RequestDispatcher requestDispatcher =
134                                    servletContext.getRequestDispatcher(redirect);
135    
136                            if (requestDispatcher != null) {
137                                    requestDispatcher.forward(request, response);
138                            }
139                    }
140                    else {
141                            response.sendRedirect(redirect);
142                    }
143            }
144    
145            protected String getRedirect(
146                            HttpServletRequest request, String path, String mainPath,
147                            Map<String, String[]> params)
148                    throws Exception {
149    
150                    if (Validator.isNull(path) || (path.charAt(0) != CharPool.SLASH)) {
151                            return mainPath;
152                    }
153    
154                    // Group friendly URL
155    
156                    String friendlyURL = null;
157    
158                    int pos = path.indexOf(CharPool.SLASH, 1);
159    
160                    if (pos != -1) {
161                            friendlyURL = path.substring(0, pos);
162                    }
163                    else if (path.length() > 1) {
164                            friendlyURL = path;
165                    }
166    
167                    if (Validator.isNull(friendlyURL)) {
168                            return mainPath;
169                    }
170    
171                    long companyId = PortalInstances.getCompanyId(request);
172    
173                    Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
174                            companyId, friendlyURL);
175    
176                    if (group == null) {
177                            String screenName = friendlyURL.substring(1);
178    
179                            if (_user || !Validator.isNumber(screenName)) {
180                                    User user = UserLocalServiceUtil.fetchUserByScreenName(
181                                            companyId, screenName);
182    
183                                    if (user != null) {
184                                            group = user.getGroup();
185                                    }
186                                    else if (_log.isWarnEnabled()) {
187                                            _log.warn("No user exists with friendly URL " + screenName);
188                                    }
189                            }
190                            else {
191                                    long groupId = GetterUtil.getLong(screenName);
192    
193                                    group = GroupLocalServiceUtil.fetchGroup(groupId);
194    
195                                    if (group == null) {
196                                            if (_log.isDebugEnabled()) {
197                                                    _log.debug(
198                                                            "No group exists with friendly URL " + groupId +
199                                                                    ". Try fetching by screen name instead.");
200                                            }
201    
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(
210                                                            "No user or group exists with friendly URL " +
211                                                                    groupId);
212                                            }
213                                    }
214                            }
215                    }
216    
217                    if (group == null) {
218                            return mainPath;
219                    }
220    
221                    // Layout friendly URL
222    
223                    friendlyURL = null;
224    
225                    if ((pos != -1) && ((pos + 1) != path.length())) {
226                            friendlyURL = path.substring(pos);
227                    }
228    
229                    if (Validator.isNull(friendlyURL)) {
230                            request.setAttribute(
231                                    WebKeys.REDIRECT_TO_DEFAULT_LAYOUT, Boolean.TRUE);
232                    }
233    
234                    Map<String, Object> requestContext = new HashMap<String, Object>();
235    
236                    requestContext.put("request", request);
237    
238                    ServiceContext serviceContext =
239                            ServiceContextThreadLocal.getServiceContext();
240    
241                    if (serviceContext == null) {
242                            serviceContext = ServiceContextFactory.getInstance(request);
243    
244                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
245                    }
246    
247                    return PortalUtil.getActualURL(
248                            group.getGroupId(), _private, mainPath, friendlyURL, params,
249                            requestContext);
250            }
251    
252            private static Log _log = LogFactoryUtil.getLog(FriendlyURLServlet.class);
253    
254            private String _friendlyURLPathPrefix;
255            private boolean _private;
256            private boolean _user;
257    
258    }