com.liferay.friendly.url.internal.servlet.FriendlyURLServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.friendly.url.service
Show all versions of com.liferay.friendly.url.service
Liferay Friendly URL Service
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.friendly.url.internal.servlet;
import com.liferay.friendly.url.configuration.FriendlyURLRedirectionConfiguration;
import com.liferay.friendly.url.configuration.FriendlyURLRedirectionConfigurationProvider;
import com.liferay.petra.lang.HashUtil;
import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.encryptor.Encryptor;
import com.liferay.portal.kernel.encryptor.EncryptorException;
import com.liferay.portal.kernel.exception.LayoutPermissionException;
import com.liferay.portal.kernel.exception.NoSuchGroupException;
import com.liferay.portal.kernel.exception.NoSuchLayoutException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.login.AuthLoginGroupSettingsUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.GroupConstants;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.LayoutConstants;
import com.liferay.portal.kernel.model.LayoutFriendlyURL;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.model.VirtualLayoutConstants;
import com.liferay.portal.kernel.module.service.Snapshot;
import com.liferay.portal.kernel.portlet.LayoutFriendlyURLSeparatorComposite;
import com.liferay.portal.kernel.portlet.LiferayWindowState;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.LayoutFriendlyURLLocalService;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.service.LayoutService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.ServiceContextFactory;
import com.liferay.portal.kernel.service.ServiceContextThreadLocal;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.service.permission.LayoutPermissionUtil;
import com.liferay.portal.kernel.servlet.HttpHeaders;
import com.liferay.portal.kernel.servlet.InactiveRequestHandler;
import com.liferay.portal.kernel.servlet.PortalMessages;
import com.liferay.portal.kernel.servlet.ServletContextPool;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.struts.LastPath;
import com.liferay.portal.kernel.util.FriendlyURLNormalizer;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HashMapBuilder;
import com.liferay.portal.kernel.util.HttpComponentsUtil;
import com.liferay.portal.kernel.util.JavaConstants;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.util.PortalInstances;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.AsyncPortletServletRequest;
import com.liferay.portlet.documentlibrary.constants.DLFriendlyURLConstants;
import com.liferay.redirect.provider.RedirectProvider;
import com.liferay.redirect.tracker.RedirectNotFoundTracker;
import com.liferay.site.model.SiteFriendlyURL;
import com.liferay.site.service.SiteFriendlyURLLocalService;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.osgi.service.component.annotations.Reference;
/**
* @author Brian Wing Shun Chan
* @author Jorge Ferrer
* @author Shuyang Zhou
* @author Marco Leo
*/
public class FriendlyURLServlet extends HttpServlet {
public Redirect getRedirect(
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, String path)
throws PortalException {
if (path.length() <= 1) {
return new Redirect();
}
String groupFriendlyURL = path;
int pos = path.indexOf(CharPool.SLASH, 1);
if (pos != -1) {
String friendlyURL = path.substring(pos);
if (friendlyURL.startsWith(
DLFriendlyURLConstants.PATH_PREFIX_DOCUMENT)) {
String fileEntryFriendlyURL = friendlyURL.substring(
DLFriendlyURLConstants.PATH_PREFIX_DOCUMENT.length() - 1);
groupFriendlyURL = fileEntryFriendlyURL.substring(
0, fileEntryFriendlyURL.indexOf(CharPool.SLASH, 1));
}
else {
groupFriendlyURL = path.substring(0, pos);
}
}
long companyId = PortalInstances.getCompanyId(httpServletRequest);
Group group = _getGroup(path, groupFriendlyURL, companyId);
Locale locale = portal.getLocale(httpServletRequest, null, false);
SiteFriendlyURL alternativeSiteFriendlyURL =
_getAlternativeSiteFriendlyURL(
groupFriendlyURL, companyId, group, locale);
String layoutFriendlyURL = null;
Redirect redirectProviderRedirect = null;
if ((pos != -1) && ((pos + 1) != path.length())) {
layoutFriendlyURL = path.substring(pos);
if (StringUtil.endsWith(layoutFriendlyURL, CharPool.SLASH)) {
layoutFriendlyURL = layoutFriendlyURL.substring(
0, layoutFriendlyURL.length() - 1);
}
redirectProviderRedirect = _getRedirectProviderRedirect(
group.getGroupId(), httpServletRequest, layoutFriendlyURL);
if ((redirectProviderRedirect != null) &&
!_isSkipRedirect(httpServletRequest)) {
return redirectProviderRedirect;
}
}
else {
httpServletRequest.setAttribute(
WebKeys.REDIRECT_TO_DEFAULT_LAYOUT, Boolean.TRUE);
}
Map requestContext = HashMapBuilder.put(
"request", httpServletRequest
).build();
ServiceContextThreadLocal.pushServiceContext(
_getServiceContext(group, httpServletRequest));
Layout defaultLayout = null;
Map params = httpServletRequest.getParameterMap();
try {
LayoutFriendlyURLSeparatorComposite
layoutFriendlyURLSeparatorComposite =
portal.getLayoutFriendlyURLSeparatorComposite(
group.getGroupId(), _private, layoutFriendlyURL, params,
requestContext);
if (layoutFriendlyURLSeparatorComposite.isRedirect()) {
pos = path.indexOf(
layoutFriendlyURLSeparatorComposite.getURLSeparator());
if (pos != 1) {
String requestURL = portal.getCurrentCompleteURL(
httpServletRequest);
int friendlyURLPos = requestURL.indexOf(layoutFriendlyURL);
String friendlyURL =
layoutFriendlyURLSeparatorComposite.getFriendlyURL();
String redirectURL = null;
if (friendlyURLPos > 0) {
redirectURL =
requestURL.substring(0, friendlyURLPos) +
friendlyURL;
}
else {
redirectURL = StringBundler.concat(
portal.getPathContext(),
PropsValues.
LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING,
path.substring(0, pos), friendlyURL);
}
String queryString = HttpComponentsUtil.getQueryString(
portal.getOriginalServletRequest(httpServletRequest));
if (Validator.isNotNull(queryString)) {
redirectURL += StringPool.QUESTION + queryString;
}
return new Redirect(
redirectURL, true,
_isPermanentRedirect(group.getCompanyId()));
}
}
Layout layout = layoutFriendlyURLSeparatorComposite.getLayout();
if (layout != null) {
User user = _getUser(httpServletRequest);
PermissionChecker permissionChecker =
PermissionThreadLocal.getPermissionChecker(
user, !user.isGuestUser());
if (!LayoutPermissionUtil.contains(
permissionChecker, layout, ActionKeys.VIEW)) {
if (AuthLoginGroupSettingsUtil.isPromptEnabled(
group.getGroupId())) {
String redirect = portal.getLayoutActualURL(
layout, Portal.PATH_MAIN);
return new Redirect(redirect);
}
throw new LayoutPermissionException();
}
if (user.isGuestUser() && layout.isSystem() &&
Objects.equals(
layout.getFriendlyURL(),
PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL)) {
throw new NoSuchLayoutException();
}
if ((redirectProviderRedirect != null) &&
!LayoutPermissionUtil.containsLayoutUpdatePermission(
permissionChecker, layout)) {
return redirectProviderRedirect;
}
}
defaultLayout = layout;
httpServletRequest.setAttribute(WebKeys.LAYOUT, layout);
if (Objects.equals(
httpServletRequest.getRequestURI(),
PropsValues.LAYOUT_FRIENDLY_URL_PAGE_NOT_FOUND)) {
httpServletRequest.removeAttribute(
NoSuchLayoutException.class.getName());
}
String layoutFriendlyURLSeparatorCompositeFriendlyURL =
layoutFriendlyURLSeparatorComposite.getFriendlyURL();
if (Validator.isNull(
layoutFriendlyURLSeparatorCompositeFriendlyURL)) {
layoutFriendlyURLSeparatorCompositeFriendlyURL =
layout.getFriendlyURL(locale);
}
pos = layoutFriendlyURLSeparatorCompositeFriendlyURL.indexOf(
layoutFriendlyURLSeparatorComposite.getURLSeparator());
if (pos != 0) {
if (pos != -1) {
layoutFriendlyURLSeparatorCompositeFriendlyURL =
layoutFriendlyURLSeparatorCompositeFriendlyURL.
substring(0, pos);
}
String i18nLanguageId = (String)httpServletRequest.getAttribute(
WebKeys.I18N_LANGUAGE_ID);
boolean localeUnavailable = false;
if (Validator.isNotNull(i18nLanguageId) &&
!LanguageUtil.isAvailableLocale(
group.getGroupId(), i18nLanguageId) &&
(!portal.isGroupControlPanelPath(path) ||
!LanguageUtil.isAvailableLocale(i18nLanguageId))) {
localeUnavailable = true;
}
if (localeUnavailable || (alternativeSiteFriendlyURL != null) ||
!_equalsLayoutFriendlyURL(
layoutFriendlyURLSeparatorCompositeFriendlyURL, layout,
locale)) {
Locale originalLocale = _setAlternativeLayoutFriendlyURL(
companyId, httpServletRequest, layout,
layoutFriendlyURLSeparatorCompositeFriendlyURL,
alternativeSiteFriendlyURL);
if (localeUnavailable &&
PropsValues.LOCALE_USE_DEFAULT_IF_NOT_AVAILABLE) {
locale = LocaleUtil.fromLanguageId(
group.getDefaultLanguageId());
}
String redirect = _getLocalizedFriendlyURL(
httpServletRequest, layout, locale, originalLocale);
HttpServletRequest originalHttpServletRequest =
portal.getOriginalServletRequest(httpServletRequest);
if (redirect.equals(
originalHttpServletRequest.getRequestURI())) {
throw new NoSuchLayoutException();
}
boolean forcePermanentRedirect = true;
if (Validator.isNull(i18nLanguageId)) {
forcePermanentRedirect = _isPermanentRedirect(
group.getCompanyId());
}
return new Redirect(redirect, true, forcePermanentRedirect);
}
}
}
catch (LayoutPermissionException | NoSuchLayoutException exception) {
Layout redirectLayout = null;
if (!(exception instanceof LayoutPermissionException)) {
if (layoutFriendlyURL == null) {
redirectLayout = defaultLayout;
}
else {
redirectLayout = _getLayoutFriendlyURLLayout(
group, layoutFriendlyURL, httpServletRequest);
}
}
if (redirectLayout != null) {
String redirect = portal.getLayoutActualURL(
redirectLayout, Portal.PATH_MAIN);
return new Redirect(redirect);
}
RedirectNotFoundTracker currentRedirectNotFoundTracker =
_redirectNotFoundTrackerSnapshot.get();
if (currentRedirectNotFoundTracker != null) {
currentRedirectNotFoundTracker.trackURL(
group, _normalizeFriendlyURL(layoutFriendlyURL));
}
if (Validator.isNotNull(
PropsValues.LAYOUT_FRIENDLY_URL_PAGE_NOT_FOUND)) {
if (exception instanceof NoSuchLayoutException) {
throw exception;
}
throw new NoSuchLayoutException(exception);
}
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
httpServletRequest.setAttribute(
NoSuchLayoutException.class.getName(), Boolean.TRUE);
layoutFriendlyURL = null;
}
finally {
ServiceContextThreadLocal.popServiceContext();
}
String actualURL = portal.getActualURL(
group.getGroupId(), _private, Portal.PATH_MAIN, layoutFriendlyURL,
params, requestContext);
String portalURL = portal.getPortalURL(httpServletRequest);
if (actualURL.startsWith(portalURL)) {
actualURL = StringUtil.removeSubstring(actualURL, portalURL);
}
long userId = portal.getUserId(httpServletRequest);
boolean impersonated = _isImpersonated(httpServletRequest, userId);
if ((userId > 0) && impersonated) {
try {
Company company = portal.getCompany(httpServletRequest);
String encDoAsUserId = encryptor.encrypt(
company.getKeyObj(), String.valueOf(userId));
actualURL = HttpComponentsUtil.setParameter(
actualURL, "doAsUserId", encDoAsUserId);
params = new HashMap<>(params);
params.remove("doAsUserId");
}
catch (EncryptorException encryptorException) {
if (_log.isDebugEnabled()) {
_log.debug(encryptorException);
}
return new Redirect(actualURL, false, false);
}
}
Layout layout = (Layout)httpServletRequest.getAttribute(WebKeys.LAYOUT);
if ((layout != null) &&
Objects.equals(layout.getType(), LayoutConstants.TYPE_URL)) {
actualURL = actualURL.concat(
HttpComponentsUtil.parameterMapToString(
params, !actualURL.contains(StringPool.QUESTION)));
}
return new Redirect(
actualURL, false,
!impersonated && _isPermanentRedirect(group.getCompanyId()));
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
ServletContext servletContext = servletConfig.getServletContext();
if (servletContext != ServletContextPool.get(
portal.getServletContextName())) {
return;
}
super.init(servletConfig);
_private = GetterUtil.getBoolean(
servletConfig.getInitParameter("servlet.init.private"));
String proxyPath = portal.getPathProxy();
_user = GetterUtil.getBoolean(
servletConfig.getInitParameter("servlet.init.user"));
if (_private) {
if (_user) {
_friendlyURLPathPrefix = portal.getPathFriendlyURLPrivateUser();
}
else {
_friendlyURLPathPrefix =
portal.getPathFriendlyURLPrivateGroup();
}
}
else {
_friendlyURLPathPrefix = portal.getPathFriendlyURLPublic();
}
_pathInfoOffset = _friendlyURLPathPrefix.length() - proxyPath.length();
}
@Override
public void service(
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throws IOException, ServletException {
// Do not set the entire full main path. See LEP-456.
String pathInfo = _getPathInfo(httpServletRequest);
Redirect redirect = null;
try {
redirect = getRedirect(
httpServletRequest, httpServletResponse, pathInfo);
if (httpServletRequest.getAttribute(WebKeys.LAST_PATH) == null) {
httpServletRequest.setAttribute(
WebKeys.LAST_PATH,
_getLastPath(httpServletRequest, pathInfo));
}
}
catch (PortalException portalException) {
if (_log.isWarnEnabled()) {
_log.warn(portalException);
}
if (portalException instanceof NoSuchGroupException ||
portalException instanceof NoSuchLayoutException) {
portal.sendError(
HttpServletResponse.SC_NOT_FOUND, portalException,
httpServletRequest, httpServletResponse);
return;
}
}
if (redirect == null) {
redirect = new Redirect();
}
if (redirect.isValidForward()) {
ServletContext servletContext = getServletContext();
RequestDispatcher requestDispatcher =
servletContext.getRequestDispatcher(redirect.getPath());
if (httpServletRequest.isAsyncSupported()) {
AsyncPortletServletRequest asyncPortletServletRequest =
AsyncPortletServletRequest.getAsyncPortletServletRequest(
httpServletRequest);
if (asyncPortletServletRequest != null) {
asyncPortletServletRequest.update(
servletContext.getContextPath(), redirect.getPath());
}
}
if (requestDispatcher != null) {
if (_log.isDebugEnabled()) {
_log.debug(
StringBundler.concat(
"Forward from ", httpServletRequest.getRequestURI(),
" to ", redirect.getPath()));
}
requestDispatcher.forward(
httpServletRequest, httpServletResponse);
}
}
else {
if (redirect.isPermanent()) {
if (_log.isDebugEnabled()) {
_log.debug(
StringBundler.concat(
"Location moved permanently from ",
httpServletRequest.getRequestURI(), " to ",
redirect.getPath()));
}
httpServletResponse.setHeader("Location", redirect.getPath());
httpServletResponse.setStatus(
HttpServletResponse.SC_MOVED_PERMANENTLY);
}
else {
if (_log.isDebugEnabled()) {
_log.debug(
StringBundler.concat(
"Redirect from ",
httpServletRequest.getRequestURI(), " to ",
redirect.getPath()));
}
httpServletResponse.sendRedirect(redirect.getPath());
}
}
}
public static class Redirect {
public Redirect() {
this(Portal.PATH_MAIN);
}
public Redirect(String path) {
this(path, false, false);
}
public Redirect(String path, boolean force, boolean permanent) {
_path = path;
_force = force;
_permanent = permanent;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Redirect)) {
return false;
}
Redirect redirect = (Redirect)object;
if (Objects.equals(getPath(), redirect.getPath()) &&
(isForce() == redirect.isForce()) &&
(isPermanent() == redirect.isPermanent())) {
return true;
}
return false;
}
public String getPath() {
if (Validator.isNull(_path)) {
return Portal.PATH_MAIN;
}
return _path;
}
@Override
public int hashCode() {
int hash = HashUtil.hash(0, _path);
hash = HashUtil.hash(hash, _force);
hash = HashUtil.hash(hash, _permanent);
return hash;
}
public boolean isForce() {
return _force;
}
public boolean isPermanent() {
return _permanent;
}
public boolean isValidForward() {
if (isForce()) {
return false;
}
String path = getPath();
if (path.equals(Portal.PATH_MAIN) || path.startsWith("/c/")) {
return true;
}
return false;
}
private final boolean _force;
private final String _path;
private final boolean _permanent;
}
@Reference
protected Encryptor encryptor;
@Reference
protected FriendlyURLNormalizer friendlyURLNormalizer;
@Reference
protected FriendlyURLRedirectionConfigurationProvider
friendlyURLRedirectionConfigurationProvider;
@Reference
protected GroupLocalService groupLocalService;
@Reference
protected InactiveRequestHandler inactiveRequestHandler;
@Reference
protected LayoutFriendlyURLLocalService layoutFriendlyURLLocalService;
@Reference
protected LayoutLocalService layoutLocalService;
@Reference
protected LayoutService layoutService;
@Reference
protected Portal portal;
@Reference
protected SiteFriendlyURLLocalService siteFriendlyURLLocalService;
@Reference
protected UserLocalService userLocalService;
private boolean _equalsLayoutFriendlyURL(
String layoutFriendlyURLSeparatorCompositeFriendlyURL, Layout layout,
Locale locale) {
String layoutFriendlyURL = layout.getFriendlyURL(locale);
if (StringUtil.equalsIgnoreCase(
layoutFriendlyURLSeparatorCompositeFriendlyURL,
layoutFriendlyURL) ||
StringUtil.equalsIgnoreCase(
friendlyURLNormalizer.normalizeWithEncoding(
layoutFriendlyURLSeparatorCompositeFriendlyURL),
layoutFriendlyURL)) {
return true;
}
return false;
}
private SiteFriendlyURL _getAlternativeSiteFriendlyURL(
String friendlyURL, long companyId, Group group, Locale locale) {
SiteFriendlyURL alternativeSiteFriendlyURL = null;
SiteFriendlyURL siteFriendlyURL =
siteFriendlyURLLocalService.fetchSiteFriendlyURL(
companyId, group.getGroupId(), LocaleUtil.toLanguageId(locale));
if (siteFriendlyURL == null) {
siteFriendlyURL =
siteFriendlyURLLocalService.fetchSiteFriendlyURLByFriendlyURL(
companyId, friendlyURL);
}
if ((siteFriendlyURL != null) &&
!StringUtil.equalsIgnoreCase(
siteFriendlyURL.getFriendlyURL(), friendlyURL)) {
alternativeSiteFriendlyURL =
siteFriendlyURLLocalService.fetchSiteFriendlyURLByFriendlyURL(
siteFriendlyURL.getCompanyId(), friendlyURL);
}
return alternativeSiteFriendlyURL;
}
private String _getFriendlyURLRedirectionType(long companyId) {
FriendlyURLRedirectionConfiguration
friendlyURLRedirectionConfiguration =
friendlyURLRedirectionConfigurationProvider.
getCompanyFriendlyURLRedirectionConfiguration(companyId);
return friendlyURLRedirectionConfiguration.redirectionType();
}
private Group _getGroup(String path, String friendlyURL, long companyId)
throws NoSuchGroupException {
Group group = groupLocalService.fetchFriendlyURLGroup(
companyId, friendlyURL);
if (group == null) {
String screenName = friendlyURL.substring(1);
User user = userLocalService.fetchUserByScreenName(
companyId, screenName);
if (user != null) {
group = user.getGroup();
}
else if (_log.isWarnEnabled()) {
_log.warn("No user exists with friendly URL " + screenName);
}
}
if ((group == null) ||
(!group.isActive() &&
!inactiveRequestHandler.isShowInactiveRequestMessage() &&
!path.startsWith(GroupConstants.CONTROL_PANEL_FRIENDLY_URL) &&
!path.startsWith(
friendlyURL +
VirtualLayoutConstants.CANONICAL_URL_SEPARATOR))) {
throw new NoSuchGroupException(
StringBundler.concat(
"{companyId=", companyId, ", friendlyURL=", friendlyURL,
"}"));
}
return group;
}
private LastPath _getLastPath(
HttpServletRequest httpServletRequest, String pathInfo) {
String lifecycle = ParamUtil.getString(
httpServletRequest, "p_p_lifecycle");
if (lifecycle.equals("1")) {
return new LastPath(_friendlyURLPathPrefix, pathInfo);
}
return new LastPath(
_friendlyURLPathPrefix, pathInfo,
HttpComponentsUtil.parameterMapToString(
httpServletRequest.getParameterMap()));
}
private Layout _getLayoutFriendlyURLLayout(
Group group, String friendlyURL,
HttpServletRequest httpServletRequest) {
LayoutFriendlyURL layoutFriendlyURL =
layoutFriendlyURLLocalService.fetchFirstLayoutFriendlyURL(
group.getGroupId(), _private, friendlyURL);
if (layoutFriendlyURL == null) {
if (group.isUser()) {
List layouts = layoutLocalService.getLayouts(
group.getGroupId(), _private,
LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
for (Layout layout : layouts) {
if (layout.matches(httpServletRequest, friendlyURL)) {
return layout;
}
}
}
return null;
}
Layout layout = layoutLocalService.fetchLayout(
layoutFriendlyURL.getPlid());
if ((layout != null) && !layout.isSystem()) {
return layout;
}
return null;
}
private String _getLocalizedFriendlyURL(
HttpServletRequest httpServletRequest, Layout layout, Locale locale,
Locale originalLocale) {
String requestURI = _getRequestURI(httpServletRequest);
int[] groupFriendlyURLIndex = portal.getGroupFriendlyURLIndex(
requestURI);
if (groupFriendlyURLIndex != null) {
String originalRequestURI = _getRequestURI(
portal.getOriginalServletRequest(httpServletRequest));
if (httpServletRequest.getAttribute(WebKeys.I18N_PATH) != null) {
int pos = originalRequestURI.indexOf(StringPool.SLASH, 1);
if (pos != -1) {
originalRequestURI = originalRequestURI.substring(pos);
}
}
if (portal.getGroupFriendlyURLIndex(originalRequestURI) == null) {
requestURI = requestURI.substring(groupFriendlyURLIndex[1]);
}
}
String layoutFriendlyURL = null;
if (originalLocale == null) {
String path = httpServletRequest.getPathInfo();
int x = path.indexOf(CharPool.SLASH, 1);
if ((x != -1) && ((x + 1) != path.length())) {
layoutFriendlyURL = path.substring(x);
}
int y = layoutFriendlyURL.indexOf(
VirtualLayoutConstants.CANONICAL_URL_SEPARATOR);
if (y != -1) {
y = layoutFriendlyURL.indexOf(CharPool.SLASH, 3);
if ((y != -1) && ((y + 1) != layoutFriendlyURL.length())) {
layoutFriendlyURL = layoutFriendlyURL.substring(y);
}
}
y = layoutFriendlyURL.indexOf(Portal.FRIENDLY_URL_SEPARATOR);
if (y != -1) {
layoutFriendlyURL = layoutFriendlyURL.substring(0, y);
}
}
else {
layoutFriendlyURL = layout.getFriendlyURL(originalLocale);
}
if (requestURI.contains(layoutFriendlyURL)) {
requestURI = StringUtil.replaceFirst(
requestURI, layoutFriendlyURL, layout.getFriendlyURL(locale));
}
boolean appendI18nPath = true;
int localePrependFriendlyURLStyle = PrefsPropsUtil.getInteger(
portal.getCompanyId(httpServletRequest),
PropsKeys.LOCALE_PREPEND_FRIENDLY_URL_STYLE);
if ((localePrependFriendlyURLStyle == 0) ||
((localePrependFriendlyURLStyle == 1) &&
locale.equals(LocaleUtil.getDefault()))) {
appendI18nPath = false;
}
String localizedFriendlyURL = portal.getPathContext();
if (appendI18nPath) {
String i18nPathLanguageId = portal.getI18nPathLanguageId(
locale, LocaleUtil.toLanguageId(locale));
String i18nPath = StringPool.SLASH + i18nPathLanguageId;
localizedFriendlyURL += i18nPath;
}
localizedFriendlyURL += requestURI;
String queryString = httpServletRequest.getQueryString();
if (Validator.isNull(queryString)) {
queryString = (String)httpServletRequest.getAttribute(
JavaConstants.JAVAX_SERVLET_FORWARD_QUERY_STRING);
}
if (Validator.isNotNull(queryString)) {
localizedFriendlyURL += StringPool.QUESTION + queryString;
}
return localizedFriendlyURL;
}
private String _getPathInfo(HttpServletRequest httpServletRequest) {
String requestURI = httpServletRequest.getRequestURI();
int pos = requestURI.indexOf(Portal.JSESSIONID);
if (pos == -1) {
return requestURI.substring(_pathInfoOffset);
}
return requestURI.substring(_pathInfoOffset, pos);
}
private Redirect _getRedirectProviderRedirect(
long groupId, HttpServletRequest httpServletRequest,
String layoutFriendlyURL) {
RedirectProvider redirectProvider = _redirectProviderSnapshot.get();
if ((redirectProvider == null) ||
LiferayWindowState.isExclusive(httpServletRequest) ||
LiferayWindowState.isPopUp(httpServletRequest)) {
return null;
}
HttpServletRequest originalHttpServletRequest =
portal.getOriginalServletRequest(httpServletRequest);
RedirectProvider.Redirect redirect = redirectProvider.getRedirect(
groupId, _normalizeFriendlyURL(layoutFriendlyURL),
_normalizeFriendlyURL(originalHttpServletRequest.getRequestURI()),
httpServletRequest.getHeader(HttpHeaders.USER_AGENT));
if (redirect == null) {
return null;
}
return new Redirect(
redirect.getDestinationURL(), true, redirect.isPermanent());
}
private String _getRequestURI(HttpServletRequest httpServletRequest) {
String contextPath = portal.getPathContext();
String requestURI = httpServletRequest.getRequestURI();
if (Validator.isNotNull(contextPath) &&
requestURI.startsWith(contextPath)) {
requestURI = requestURI.substring(contextPath.length());
}
return StringUtil.replace(
requestURI, StringPool.DOUBLE_SLASH, StringPool.SLASH);
}
private ServiceContext _getServiceContext(
Group group, HttpServletRequest httpServletRequest)
throws PortalException {
ServiceContext serviceContext =
ServiceContextThreadLocal.getServiceContext();
if (serviceContext == null) {
serviceContext = ServiceContextFactory.getInstance(
httpServletRequest);
ServiceContextThreadLocal.pushServiceContext(serviceContext);
}
serviceContext = (ServiceContext)serviceContext.clone();
serviceContext.setCompanyId(group.getCompanyId());
serviceContext.setScopeGroupId(group.getGroupId());
return serviceContext;
}
private User _getUser(HttpServletRequest httpServletRequest)
throws PortalException {
User user = portal.getUser(httpServletRequest);
if (user == null) {
user = userLocalService.getGuestUser(
portal.getCompanyId(httpServletRequest));
}
return user;
}
private boolean _isImpersonated(
HttpServletRequest httpServletRequest, long userId) {
HttpSession httpSession = httpServletRequest.getSession();
Long realUserId = (Long)httpSession.getAttribute(WebKeys.USER_ID);
if ((realUserId == null) || (userId == realUserId)) {
return false;
}
return true;
}
private boolean _isPermanentRedirect(long companyId) {
if (Objects.equals(
_getFriendlyURLRedirectionType(companyId), "permanent")) {
return true;
}
return false;
}
private boolean _isShowAlternativeLayoutFriendlyURLMessage(long companyId) {
FriendlyURLRedirectionConfiguration
friendlyURLRedirectionConfiguration =
friendlyURLRedirectionConfigurationProvider.
getCompanyFriendlyURLRedirectionConfiguration(companyId);
return friendlyURLRedirectionConfiguration.
showAlternativeLayoutFriendlyURLMessage();
}
private boolean _isSkipRedirect(HttpServletRequest httpServletRequest) {
String refererURL = httpServletRequest.getHeader(HttpHeaders.REFERER);
if (Validator.isNotNull(refererURL)) {
int index = refererURL.indexOf(CharPool.QUESTION);
if (index != -1) {
refererURL = refererURL.substring(0, index);
}
}
if (Validator.isNotNull(refererURL)) {
return refererURL.contains(
VirtualLayoutConstants.CANONICAL_URL_SEPARATOR +
GroupConstants.CONTROL_PANEL_FRIENDLY_URL);
}
return false;
}
private String _normalizeFriendlyURL(String friendlyURL) {
if (Validator.isNull(friendlyURL)) {
return friendlyURL;
}
String normalizedFriendlyURL =
friendlyURLNormalizer.normalizeWithEncoding(
HttpComponentsUtil.decodeURL(friendlyURL));
if (normalizedFriendlyURL.startsWith(StringPool.SLASH)) {
return normalizedFriendlyURL.substring(1);
}
return normalizedFriendlyURL;
}
private Locale _setAlternativeLayoutFriendlyURL(
long companyId, HttpServletRequest httpServletRequest, Layout layout,
String friendlyURL, SiteFriendlyURL siteFriendlyURL) {
List layoutFriendlyURLs =
layoutFriendlyURLLocalService.getLayoutFriendlyURLs(
layout.getPlid(), friendlyURL, 0, 1);
if (layoutFriendlyURLs.isEmpty()) {
return null;
}
LayoutFriendlyURL layoutFriendlyURL = layoutFriendlyURLs.get(0);
Locale locale = LocaleUtil.fromLanguageId(
layoutFriendlyURL.getLanguageId());
if (!LanguageUtil.isAvailableLocale(layout.getGroupId(), locale)) {
return LocaleUtil.fromLanguageId(
(String)httpServletRequest.getAttribute(
WebKeys.I18N_LANGUAGE_ID));
}
Locale groupLocale = locale;
if (siteFriendlyURL != null) {
groupLocale = LocaleUtil.fromLanguageId(
siteFriendlyURL.getLanguageId());
}
String alternativeLayoutFriendlyURL = _getLocalizedFriendlyURL(
httpServletRequest, layout, groupLocale, locale);
if (_isShowAlternativeLayoutFriendlyURLMessage(companyId)) {
SessionMessages.add(
httpServletRequest, "alternativeLayoutFriendlyURL",
alternativeLayoutFriendlyURL);
PortalMessages.add(
httpServletRequest, PortalMessages.KEY_JSP_PATH,
"/html/common/themes/layout_friendly_url_redirect.jsp");
}
return groupLocale;
}
private static final Log _log = LogFactoryUtil.getLog(
FriendlyURLServlet.class);
private static final Snapshot
_redirectNotFoundTrackerSnapshot = new Snapshot<>(
FriendlyURLServlet.class, RedirectNotFoundTracker.class, null,
true);
private static final Snapshot _redirectProviderSnapshot =
new Snapshot<>(
FriendlyURLServlet.class, RedirectProvider.class, null, true);
private String _friendlyURLPathPrefix;
private int _pathInfoOffset;
private boolean _private;
private boolean _user;
}