001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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(
061                            servletConfig.getInitParameter("user"));
062    
063                    if (_private) {
064                            if (_user) {
065                                    _friendlyURLPathPrefix =
066                                            PortalUtil.getPathFriendlyURLPrivateUser();
067                            }
068                            else {
069                                    _friendlyURLPathPrefix =
070                                            PortalUtil.getPathFriendlyURLPrivateGroup();
071                            }
072                    }
073                    else {
074                            _friendlyURLPathPrefix = PortalUtil.getPathFriendlyURLPublic();
075                    }
076            }
077    
078            @Override
079            public void service(
080                            HttpServletRequest request, HttpServletResponse response)
081                    throws IOException, ServletException {
082    
083                    // Do not set the entire full main path. See LEP-456.
084    
085                    //String mainPath = (String)ctx.getAttribute(WebKeys.MAIN_PATH);
086                    String mainPath = Portal.PATH_MAIN;
087    
088                    String redirect = mainPath;
089    
090                    String pathInfo = request.getPathInfo();
091    
092                    request.setAttribute(
093                            WebKeys.FRIENDLY_URL, _friendlyURLPathPrefix.concat(pathInfo));
094    
095                    try {
096                            redirect = getRedirect(
097                                    request, pathInfo, mainPath, request.getParameterMap());
098    
099                            if (request.getAttribute(WebKeys.LAST_PATH) == null) {
100                                    LastPath lastPath = new LastPath(
101                                            _friendlyURLPathPrefix, pathInfo,
102                                            request.getParameterMap());
103    
104                                    request.setAttribute(WebKeys.LAST_PATH, lastPath);
105                            }
106                    }
107                    catch (NoSuchLayoutException nsle) {
108                            _log.warn(nsle);
109    
110                            PortalUtil.sendError(
111                                    HttpServletResponse.SC_NOT_FOUND, nsle, request, response);
112    
113                            return;
114                    }
115                    catch (Exception e) {
116                            if (_log.isWarnEnabled()) {
117                                    _log.warn(e);
118                            }
119                    }
120    
121                    if (Validator.isNull(redirect)) {
122                            redirect = mainPath;
123                    }
124    
125                    if (_log.isDebugEnabled()) {
126                            _log.debug("Redirect " + redirect);
127                    }
128    
129                    if (redirect.charAt(0) == CharPool.SLASH) {
130                            ServletContext servletContext = getServletContext();
131    
132                            RequestDispatcher requestDispatcher =
133                                    servletContext.getRequestDispatcher(redirect);
134    
135                            if (requestDispatcher != null) {
136                                    requestDispatcher.forward(request, response);
137                            }
138                    }
139                    else {
140                            response.sendRedirect(redirect);
141                    }
142            }
143    
144            protected String getRedirect(
145                            HttpServletRequest request, String path, String mainPath,
146                            Map<String, String[]> params)
147                    throws Exception {
148    
149                    if (Validator.isNull(path) || (path.charAt(0) != CharPool.SLASH)) {
150                            return mainPath;
151                    }
152    
153                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH &&
154                            (request.getRemoteUser() != null)) {
155    
156                            return mainPath;
157                    }
158    
159                    // Group friendly URL
160    
161                    String friendlyURL = null;
162    
163                    int pos = path.indexOf(CharPool.SLASH, 1);
164    
165                    if (pos != -1) {
166                            friendlyURL = path.substring(0, pos);
167                    }
168                    else if (path.length() > 1) {
169                            friendlyURL = path;
170                    }
171    
172                    if (Validator.isNull(friendlyURL)) {
173                            return mainPath;
174                    }
175    
176                    long companyId = PortalInstances.getCompanyId(request);
177    
178                    Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
179                            companyId, friendlyURL);
180    
181                    if (group == null) {
182                            String screenName = friendlyURL.substring(1);
183    
184                            if (_user || !Validator.isNumber(screenName)) {
185                                    User user = UserLocalServiceUtil.fetchUserByScreenName(
186                                            companyId, screenName);
187    
188                                    if (user != null) {
189                                            group = user.getGroup();
190                                    }
191                                    else if (_log.isWarnEnabled()) {
192                                            _log.warn(
193                                                    "No user exists with friendly URL " + screenName);
194                                    }
195                            }
196                            else {
197                                    long groupId = GetterUtil.getLong(screenName);
198    
199                                    group = GroupLocalServiceUtil.fetchGroup(groupId);
200    
201                                    if (group == null) {
202                                            if (_log.isDebugEnabled()) {
203                                                    _log.debug(
204                                                            "No group exists with friendly URL " + groupId +
205                                                                    ". Try fetching by screen name instead.");
206                                            }
207    
208                                            User user = UserLocalServiceUtil.fetchUserByScreenName(
209                                                    companyId, screenName);
210    
211                                            if (user != null) {
212                                                    group = user.getGroup();
213                                            }
214                                            else if (_log.isWarnEnabled()) {
215                                                    _log.warn(
216                                                            "No user or group exists with friendly URL " +
217                                                                    groupId);
218                                            }
219                                    }
220                            }
221                    }
222    
223                    if (group == null) {
224                            return mainPath;
225                    }
226    
227                    // Layout friendly URL
228    
229                    friendlyURL = null;
230    
231                    if ((pos != -1) && ((pos + 1) != path.length())) {
232                            friendlyURL = path.substring(pos, path.length());
233                    }
234    
235                    Map<String, Object> requestContext = new HashMap<String, Object>();
236    
237                    requestContext.put("request", request);
238    
239                    return PortalUtil.getActualURL(
240                            group.getGroupId(), _private, mainPath, friendlyURL, params,
241                            requestContext);
242            }
243    
244            private static Log _log = LogFactoryUtil.getLog(FriendlyURLServlet.class);
245    
246            private String _friendlyURLPathPrefix;
247            private boolean _private;
248            private boolean _user;
249    
250    }