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