/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portlet; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Company; import com.liferay.portal.kernel.model.Layout; import com.liferay.portal.kernel.model.Portlet; import com.liferay.portal.kernel.model.PortletApp; import com.liferay.portal.kernel.model.PublicRenderParameter; import com.liferay.portal.kernel.portlet.FriendlyURLMapper; import com.liferay.portal.kernel.portlet.LiferayPortletConfig; import com.liferay.portal.kernel.portlet.LiferayPortletURL; import com.liferay.portal.kernel.portlet.LiferayWindowState; import com.liferay.portal.kernel.portlet.PortletModeFactory; import com.liferay.portal.kernel.portlet.PortletQName; import com.liferay.portal.kernel.portlet.PortletQNameUtil; import com.liferay.portal.kernel.portlet.WindowStateFactory; import com.liferay.portal.kernel.security.auth.AuthTokenUtil; import com.liferay.portal.kernel.service.LayoutLocalServiceUtil; import com.liferay.portal.kernel.service.PortletLocalServiceUtil; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.Base64; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.CookieKeys; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.HtmlUtil; import com.liferay.portal.kernel.util.Http; import com.liferay.portal.kernel.util.HttpUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.URLCodec; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.kernel.xml.QName; import com.liferay.portal.security.lang.DoPrivilegedUtil; import com.liferay.portal.util.PropsValues; import com.liferay.util.Encryptor; import com.liferay.util.EncryptorException; import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.Key; import java.security.PrivilegedAction; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; import javax.portlet.PortletMode; import javax.portlet.PortletModeException; import javax.portlet.PortletRequest; import javax.portlet.PortletURL; import javax.portlet.ResourceRequest; import javax.portlet.ResourceURL; import javax.portlet.WindowState; import javax.portlet.WindowStateException; import javax.servlet.http.HttpServletRequest; /** * @author Brian Wing Shun Chan * @author Jorge Ferrer * @author Connor McKay */ public class PortletURLImpl implements LiferayPortletURL, PortletURL, ResourceURL, Serializable { public PortletURLImpl( HttpServletRequest request, Portlet portlet, Layout layout, String lifecycle) { this(request, portlet, null, layout, lifecycle); } /** * @deprecated As of 7.0.0, replaced by {@link * #PortletURLImpl(HttpServletRequest, Portlet, Layout, String)} */ @Deprecated public PortletURLImpl( HttpServletRequest request, String portletId, Layout layout, String lifecycle) { this(request, portletId, null, layout, lifecycle); } /** * @deprecated As of 7.0.0, replaced by {@link * #PortletURLImpl(HttpServletRequest, String, Layout, String)} */ @Deprecated public PortletURLImpl( HttpServletRequest request, String portletId, long plid, String lifecycle) { this(request, portletId, null, plid, lifecycle); } public PortletURLImpl( PortletRequest portletRequest, Portlet portlet, Layout layout, String lifecycle) { this( PortalUtil.getHttpServletRequest(portletRequest), portlet, portletRequest, layout, lifecycle); } /** * @deprecated As of 7.0.0, replaced by {@link * #PortletURLImpl(PortletRequest, Portlet, Layout, String)} */ @Deprecated public PortletURLImpl( PortletRequest portletRequest, String portletId, Layout layout, String lifecycle) { this( PortalUtil.getHttpServletRequest(portletRequest), portletId, portletRequest, layout, lifecycle); } /** * @deprecated As of 7.0.0, replaced by {@link * #PortletURLImpl(PortletRequest, String, Layout, String)} */ @Deprecated public PortletURLImpl( PortletRequest portletRequest, String portletId, long plid, String lifecycle) { this( PortalUtil.getHttpServletRequest(portletRequest), portletId, portletRequest, plid, lifecycle); } @Override public void addParameterIncludedInPath(String name) { if (_parametersIncludedInPath.isEmpty()) { _parametersIncludedInPath = new LinkedHashSet<>(); } _parametersIncludedInPath.add(name); } @Override public void addProperty(String key, String value) { if (key == null) { throw new IllegalArgumentException(); } } @Override public String getCacheability() { return _cacheability; } public HttpServletRequest getHttpServletRequest() { return _request; } public Layout getLayout() { if (_layout == null) { try { Layout layout = (Layout)_request.getAttribute(WebKeys.LAYOUT); if ((layout != null) && (layout.getPlid() == _plid)) { _layout = layout; } else if (_plid > 0) { _layout = LayoutLocalServiceUtil.getLayout(_plid); } } catch (Exception e) { if (_log.isWarnEnabled()) { _log.warn("Layout cannot be found for " + _plid); } } } return _layout; } public String getLayoutFriendlyURL() { return _layoutFriendlyURL; } @Override public String getLifecycle() { return _lifecycle; } public String getNamespace() { if (_namespace == null) { _namespace = PortalUtil.getPortletNamespace( _portlet.getPortletId()); } return _namespace; } @Override public String getParameter(String name) { String[] values = _params.get(name); if (ArrayUtil.isNotEmpty(values)) { return values[0]; } else { return null; } } @Override public Map<String, String[]> getParameterMap() { return _params; } @Override public Set<String> getParametersIncludedInPath() { return _parametersIncludedInPath; } @Override public long getPlid() { return _plid; } public Portlet getPortlet() { return _portlet; } public String getPortletFriendlyURLPath() { String portletFriendlyURLPath = null; if (_portlet.isUndeployedPortlet()) { return portletFriendlyURLPath; } FriendlyURLMapper friendlyURLMapper = _portlet.getFriendlyURLMapperInstance(); if (friendlyURLMapper != null) { portletFriendlyURLPath = friendlyURLMapper.buildPath(this); if (_log.isDebugEnabled()) { _log.debug( "Portlet friendly URL path " + portletFriendlyURLPath); } } return portletFriendlyURLPath; } @Override public String getPortletId() { return _portlet.getPortletId(); } @Override public PortletMode getPortletMode() { if (_portletModeString == null) { return null; } return PortletModeFactory.getPortletMode(_portletModeString); } public PortletRequest getPortletRequest() { return _portletRequest; } @Override public Set<String> getRemovedParameterNames() { return _removedParameterNames; } /** * @deprecated As of 7.0.0, replaced by {@link #visitReservedParameters( * BiConsumer)} */ @Deprecated @Override public Map<String, String> getReservedParameterMap() { LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>(); visitReservedParameters(linkedHashMap::put); return Collections.unmodifiableMap(linkedHashMap); } @Override public String getResourceID() { return _resourceID; } @Override public WindowState getWindowState() { if (_windowStateString == null) { return null; } return WindowStateFactory.getWindowState(_windowStateString); } @Override public boolean isAnchor() { return _anchor; } @Override public boolean isCopyCurrentRenderParameters() { return _copyCurrentRenderParameters; } @Override public boolean isEncrypt() { return _encrypt; } @Override public boolean isEscapeXml() { return _escapeXml; } @Override public boolean isParameterIncludedInPath(String name) { if (_parametersIncludedInPath.contains(name)) { return true; } else { return false; } } @Override public boolean isSecure() { return _secure; } @Override public void removePublicRenderParameter(String name) { if (name == null) { throw new IllegalArgumentException(); } if (_portlet.isUndeployedPortlet()) { return; } PublicRenderParameter publicRenderParameter = _portlet.getPublicRenderParameter(name); if (publicRenderParameter == null) { if (_log.isWarnEnabled()) { _log.warn("Public parameter " + name + "does not exist"); } return; } QName qName = publicRenderParameter.getQName(); _removePublicRenderParameters.add( PortletQNameUtil.getRemovePublicRenderParameterName(qName)); } @Override public void setAnchor(boolean anchor) { _anchor = anchor; clearCache(); } @Override public void setCacheability(String cacheability) { if (cacheability == null) { throw new IllegalArgumentException("Cacheability is null"); } if (!cacheability.equals(FULL) && !cacheability.equals(PORTLET) && !cacheability.equals(PAGE)) { throw new IllegalArgumentException( "Cacheability " + cacheability + " is not " + FULL + ", " + PORTLET + ", or " + PAGE); } if (_portletRequest instanceof ResourceRequest) { ResourceRequest resourceRequest = (ResourceRequest)_portletRequest; String parentCacheability = resourceRequest.getCacheability(); if (parentCacheability.equals(FULL)) { if (!cacheability.equals(FULL)) { throw new IllegalStateException( "Unable to set a weaker cacheability " + cacheability); } } else if (parentCacheability.equals(PORTLET)) { if (!cacheability.equals(FULL) && !cacheability.equals(PORTLET)) { throw new IllegalStateException( "Unable to set a weaker cacheability " + cacheability); } } } _cacheability = cacheability; clearCache(); } @Override public void setCopyCurrentRenderParameters( boolean copyCurrentRenderParameters) { _copyCurrentRenderParameters = copyCurrentRenderParameters; } @Override public void setDoAsGroupId(long doAsGroupId) { _doAsGroupId = doAsGroupId; clearCache(); } @Override public void setDoAsUserId(long doAsUserId) { _doAsUserId = doAsUserId; clearCache(); } @Override public void setDoAsUserLanguageId(String doAsUserLanguageId) { _doAsUserLanguageId = doAsUserLanguageId; clearCache(); } @Override public void setEncrypt(boolean encrypt) { _encrypt = encrypt; clearCache(); } @Override public void setEscapeXml(boolean escapeXml) { _escapeXml = escapeXml; clearCache(); } @Override public void setLifecycle(String lifecycle) { _lifecycle = lifecycle; clearCache(); } @Override public void setParameter(String name, String value) { setParameter(name, value, PropsValues.PORTLET_URL_APPEND_PARAMETERS); } @Override public void setParameter(String name, String value, boolean append) { if (name == null) { throw new IllegalArgumentException(); } if ((value == null) || value.isEmpty()) { removeParameter(name); return; } setParameter(name, new String[] {value}, append); } @Override public void setParameter(String name, String[] values) { setParameter(name, values, PropsValues.PORTLET_URL_APPEND_PARAMETERS); } @Override public void setParameter(String name, String[] values, boolean append) { if ((name == null) || (values == null)) { throw new IllegalArgumentException(); } for (String value : values) { if (value == null) { throw new IllegalArgumentException(); } } if (!append) { _params.put(name, values); } else { String[] oldValues = _params.get(name); if (oldValues == null) { _params.put(name, values); } else { String[] newValues = ArrayUtil.append(oldValues, values); _params.put(name, newValues); } } clearCache(); } @Override public void setParameters(Map<String, String[]> params) { if (params == null) { throw new IllegalArgumentException(); } else { Map<String, String[]> newParams = new LinkedHashMap<>(); for (Map.Entry<String, String[]> entry : params.entrySet()) { try { String key = entry.getKey(); String[] value = entry.getValue(); if (key == null) { throw new IllegalArgumentException(); } else if (value == null) { throw new IllegalArgumentException(); } newParams.put(key, value); } catch (ClassCastException cce) { throw new IllegalArgumentException(cce); } } _params = newParams; } clearCache(); } @Override public void setPlid(long plid) { _plid = plid; clearCache(); } @Override public void setPortletId(String portletId) { _portlet = PortletLocalServiceUtil.getPortletById( PortalUtil.getCompanyId(_request), portletId); clearCache(); } @Override public void setPortletMode(PortletMode portletMode) throws PortletModeException { if (_portletRequest != null) { if (!_portlet.isUndeployedPortlet() && !_portlet.hasPortletMode( _portletRequest.getResponseContentType(), portletMode)) { throw new PortletModeException( portletMode.toString(), portletMode); } } _portletModeString = portletMode.toString(); clearCache(); } public void setPortletMode(String portletMode) throws PortletModeException { setPortletMode(PortletModeFactory.getPortletMode(portletMode)); } @Override public void setProperty(String key, String value) { if (key == null) { throw new IllegalArgumentException(); } } @Override public void setRefererGroupId(long refererGroupId) { _refererGroupId = refererGroupId; clearCache(); } @Override public void setRefererPlid(long refererPlid) { _refererPlid = refererPlid; clearCache(); } @Override public void setRemovedParameterNames(Set<String> removedParameterNames) { _removedParameterNames = removedParameterNames; clearCache(); } @Override public void setResourceID(String resourceID) { _resourceID = resourceID; } @Override public void setSecure(boolean secure) { _secure = secure; clearCache(); } public void setWindowState(String windowState) throws WindowStateException { setWindowState(WindowStateFactory.getWindowState(windowState)); } @Override public void setWindowState(WindowState windowState) throws WindowStateException { if (_portletRequest != null) { if (!_portletRequest.isWindowStateAllowed(windowState)) { throw new WindowStateException( windowState.toString(), windowState); } } if (LiferayWindowState.isWindowStatePreserved( getWindowState(), windowState)) { _windowStateString = windowState.toString(); } clearCache(); } public void setWindowStateRestoreCurrentView( boolean windowStateRestoreCurrentView) { _windowStateRestoreCurrentView = windowStateRestoreCurrentView; } @Override public String toString() { if (_toString != null) { return _toString; } _toString = DoPrivilegedUtil.wrap(new ToStringPrivilegedAction()); return _toString; } @Override public void visitReservedParameters(BiConsumer<String, String> biConsumer) { biConsumer.accept("p_p_id", _portlet.getPortletId()); if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) { biConsumer.accept("p_p_lifecycle", "1"); } else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) { biConsumer.accept("p_p_lifecycle", "0"); } else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) { biConsumer.accept("p_p_lifecycle", "2"); } if (_windowStateString != null) { biConsumer.accept("p_p_state", _windowStateString); } if (_windowStateRestoreCurrentView) { biConsumer.accept("p_p_state_rcv", "1"); } if (_portletModeString != null) { biConsumer.accept("p_p_mode", _portletModeString); } if (_resourceID != null) { biConsumer.accept("p_p_resource_id", _resourceID); } if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) { biConsumer.accept("p_p_cacheability", _cacheability); } } @Override public void write(Writer writer) throws IOException { write(writer, _escapeXml); } @Override public void write(Writer writer, boolean escapeXml) throws IOException { String toString = toString(); if (escapeXml && !_escapeXml) { toString = HtmlUtil.escape(toString); } writer.write(toString); } /** * @deprecated As of 7.0.0, replaced by {@link * #PortletURLImpl(PortletRequest, String, PortletRequest, Layout, String)} */ @Deprecated protected PortletURLImpl( HttpServletRequest request, String portletId, PortletRequest portletRequest, long plid, String lifecycle) { this(request, portletId, portletRequest, null, lifecycle); _plid = plid; } protected void addPortalAuthToken(StringBundler sb, Key key) { AuthTokenUtil.addCSRFToken(_request, this); } protected void addPortletAuthToken(StringBundler sb, Key key) { AuthTokenUtil.addPortletInvocationToken(_request, this); } protected void clearCache() { _toString = null; } protected String generateToString() { StringBundler sb = new StringBundler(64); ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute( WebKeys.THEME_DISPLAY); if (themeDisplay == null) { if (_log.isWarnEnabled()) { _log.warn( "Unable to generate string because theme display is null"); } return StringPool.BLANK; } try { if (_layoutFriendlyURL == null) { Layout layout = getLayout(); if (layout != null) { _layoutFriendlyURL = GetterUtil.getString( PortalUtil.getLayoutFriendlyURL(layout, themeDisplay)); if (_secure) { _layoutFriendlyURL = HttpUtil.protocolize( _layoutFriendlyURL, PropsValues.WEB_SERVER_HTTPS_PORT, true); } } } } catch (Exception e) { _log.error(e); } Key key = _getKey(); if (Validator.isNull(_layoutFriendlyURL)) { sb.append(PortalUtil.getPortalURL(_request, _secure)); sb.append(themeDisplay.getPathMain()); sb.append("/portal/layout?p_l_id="); sb.append(processValue(key, _plid)); sb.append(StringPool.AMPERSAND); } else { // A virtual host URL will contain the complete path. Do not // append the portal URL if the virtual host URL starts with // "http://" or "https://". if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) && !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) { sb.append(PortalUtil.getPortalURL(_request, _secure)); } sb.append(_layoutFriendlyURL); String friendlyURLPath = getPortletFriendlyURLPath(); if (Validator.isNotNull(friendlyURLPath)) { sb.append("/-"); sb.append(friendlyURLPath); } sb.append(StringPool.QUESTION); } addPortalAuthToken(sb, key); addPortletAuthToken(sb, key); visitReservedParameters( (name, value) -> { if (!isParameterIncludedInPath(name)) { sb.append(name); sb.append(StringPool.EQUAL); sb.append(processValue(key, value)); sb.append(StringPool.AMPERSAND); } }); if (_doAsUserId > 0) { try { Company company = PortalUtil.getCompany(_request); sb.append("doAsUserId="); sb.append(processValue(company.getKeyObj(), _doAsUserId)); sb.append(StringPool.AMPERSAND); } catch (Exception e) { _log.error(e); } } else { String doAsUserId = themeDisplay.getDoAsUserId(); if (Validator.isNotNull(doAsUserId)) { sb.append("doAsUserId="); sb.append(processValue(key, doAsUserId)); sb.append(StringPool.AMPERSAND); } } String doAsUserLanguageId = _doAsUserLanguageId; if (Validator.isNull(doAsUserLanguageId)) { doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId(); } if (Validator.isNotNull(doAsUserLanguageId)) { sb.append("doAsUserLanguageId="); sb.append(processValue(key, doAsUserLanguageId)); sb.append(StringPool.AMPERSAND); } long doAsGroupId = _doAsGroupId; if (doAsGroupId <= 0) { doAsGroupId = themeDisplay.getDoAsGroupId(); } if (doAsGroupId > 0) { sb.append("doAsGroupId="); sb.append(processValue(key, doAsGroupId)); sb.append(StringPool.AMPERSAND); } long refererGroupId = _refererGroupId; if (refererGroupId <= 0) { refererGroupId = themeDisplay.getRefererGroupId(); } if (refererGroupId > 0) { sb.append("refererGroupId="); sb.append(processValue(key, refererGroupId)); sb.append(StringPool.AMPERSAND); } long refererPlid = _refererPlid; if (refererPlid <= 0) { refererPlid = themeDisplay.getRefererPlid(); } if (refererPlid > 0) { sb.append("refererPlid="); sb.append(processValue(key, refererPlid)); sb.append(StringPool.AMPERSAND); } if (!_removePublicRenderParameters.isEmpty()) { String lastString = sb.stringAt(sb.index() - 1); if (lastString.charAt(lastString.length() - 1) != CharPool.AMPERSAND) { sb.append(StringPool.AMPERSAND); } String removeValue = processValue(key, "1"); for (String removedPublicParameter : _removePublicRenderParameters) { sb.append(URLCodec.encodeURL(removedPublicParameter)); sb.append(StringPool.EQUAL); sb.append(removeValue); sb.append(StringPool.AMPERSAND); } } Map<String, String[]> renderParams = _params; if (_copyCurrentRenderParameters) { renderParams = _mergeWithRenderParameters(renderParams); } int previousSbIndex = sb.index(); for (Map.Entry<String, String[]> entry : renderParams.entrySet()) { String name = entry.getKey(); String[] values = entry.getValue(); if (isParameterIncludedInPath(name)) { continue; } String publicRenderParameterName = getPublicRenderParameterName( name); if (Validator.isNotNull(publicRenderParameterName)) { name = publicRenderParameterName; } for (String value : values) { _appendNamespaceAndEncode(sb, name); sb.append(StringPool.EQUAL); sb.append(processValue(key, value)); sb.append(StringPool.AMPERSAND); } } if (sb.index() > previousSbIndex) { sb.setIndex(sb.index() - 1); } if (_encrypt) { sb.append(StringPool.AMPERSAND); sb.append(WebKeys.ENCRYPT); sb.append("=1"); } if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) { if (_anchor && (_windowStateString != null) && !_windowStateString.equals(WindowState.MAXIMIZED.toString()) && !_windowStateString.equals( LiferayWindowState.EXCLUSIVE.toString()) && !_windowStateString.equals( LiferayWindowState.POP_UP.toString())) { String lastString = sb.stringAt(sb.index() - 1); char lastChar = lastString.charAt(lastString.length() - 1); if ((lastChar != CharPool.AMPERSAND) && (lastChar != CharPool.QUESTION)) { sb.append(StringPool.AMPERSAND); } sb.append("#p_"); sb.append(URLCodec.encodeURL(_portlet.getPortletId())); } } String lastString = sb.stringAt(sb.index() - 1); char lastChar = lastString.charAt(lastString.length() - 1); if ((lastChar == CharPool.AMPERSAND) || (lastChar == CharPool.QUESTION)) { sb.setStringAt( lastString.substring(0, lastString.length() - 1), sb.index() - 1); } String result = sb.toString(); if (!CookieKeys.hasSessionId(_request)) { result = PortalUtil.getURLWithSessionId( result, _request.getSession().getId()); } if (_escapeXml) { result = HtmlUtil.escape(result); } if (result.length() > Http.URL_MAXIMUM_LENGTH) { result = HttpUtil.shortenURL(result, 2); } return result; } protected String generateWSRPToString() { StringBundler sb = new StringBundler("wsrp_rewrite?"); sb.append("wsrp-urlType"); sb.append(StringPool.EQUAL); if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) { sb.append(URLCodec.encodeURL("blockingAction")); } else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) { sb.append(URLCodec.encodeURL("render")); } else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) { sb.append(URLCodec.encodeURL("resource")); } sb.append(StringPool.AMPERSAND); if (_windowStateString != null) { sb.append("wsrp-windowState="); sb.append(URLCodec.encodeURL("wsrp:" + _windowStateString)); sb.append(StringPool.AMPERSAND); } if (_portletModeString != null) { sb.append("wsrp-mode="); sb.append(URLCodec.encodeURL("wsrp:" + _portletModeString)); sb.append(StringPool.AMPERSAND); } if (_resourceID != null) { sb.append("wsrp-resourceID="); sb.append(URLCodec.encodeURL(_resourceID)); sb.append(StringPool.AMPERSAND); } if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) { sb.append("wsrp-resourceCacheability="); sb.append(URLCodec.encodeURL(_cacheability)); sb.append(StringPool.AMPERSAND); } if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) { if (_anchor && (_windowStateString != null) && !_windowStateString.equals(WindowState.MAXIMIZED.toString()) && !_windowStateString.equals( LiferayWindowState.EXCLUSIVE.toString()) && !_windowStateString.equals( LiferayWindowState.POP_UP.toString())) { sb.append("wsrp-fragmentID=#p_"); sb.append(URLCodec.encodeURL(_portlet.getPortletId())); sb.append(StringPool.AMPERSAND); } } Map<String, String[]> renderParams = _params; if (_copyCurrentRenderParameters) { renderParams = _mergeWithRenderParameters(renderParams); } StringBundler parameterSB = new StringBundler(); int previousSbIndex = sb.index(); for (Map.Entry<String, String[]> entry : renderParams.entrySet()) { String name = entry.getKey(); String[] values = entry.getValue(); if (isParameterIncludedInPath(name)) { continue; } String publicRenderParameterName = getPublicRenderParameterName( name); if (Validator.isNotNull(publicRenderParameterName)) { name = publicRenderParameterName; } for (String value : values) { _appendNamespaceAndEncode(parameterSB, name); parameterSB.append(StringPool.EQUAL); parameterSB.append(URLCodec.encodeURL(value)); parameterSB.append(StringPool.AMPERSAND); } } if (sb.index() > previousSbIndex) { sb.setIndex(sb.index() - 1); } sb.append("wsrp-navigationalState"); sb.append(StringPool.EQUAL); byte[] parameterBytes = null; try { String parameterString = parameterSB.toString(); parameterBytes = parameterString.getBytes(StringPool.UTF8); } catch (UnsupportedEncodingException uee) { if (_log.isWarnEnabled()) { _log.warn(uee, uee); } } String navigationalState = Base64.toURLSafe( Base64.encode(parameterBytes)); sb.append(navigationalState); sb.append("/wsrp_rewrite"); return sb.toString(); } protected String getPublicRenderParameterName(String name) { String publicRenderParameterName = null; if (!_portlet.isUndeployedPortlet()) { PublicRenderParameter publicRenderParameter = _portlet.getPublicRenderParameter(name); if (publicRenderParameter != null) { QName qName = publicRenderParameter.getQName(); publicRenderParameterName = PortletQNameUtil.getPublicRenderParameterName(qName); } } return publicRenderParameterName; } protected boolean isBlankValue(String[] value) { if ((value != null) && (value.length == 1) && value[0].equals(StringPool.BLANK)) { return true; } else { return false; } } /** * @deprecated As of 7.0.0, with no direct replacement */ @Deprecated protected void mergeRenderParameters() { _params = _mergeWithRenderParameters(_params); } /** * @deprecated As of 7.0.0, with no direct replacement */ @Deprecated protected String prependNamespace(String name) { String namespace = getNamespace(); if (!name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) && !name.startsWith(namespace) && !PortalUtil.isReservedParameter(name)) { return namespace.concat(name); } return name; } protected String processValue(Key key, int value) { return processValue(key, String.valueOf(value)); } protected String processValue(Key key, long value) { return processValue(key, String.valueOf(value)); } protected String processValue(Key key, String value) { if (key == null) { return URLCodec.encodeURL(value); } try { return URLCodec.encodeURL(Encryptor.encrypt(key, value)); } catch (EncryptorException ee) { return value; } } protected void removeParameter(String name) { if (_params.containsKey(name)) { _params.remove(name); } } private PortletURLImpl( HttpServletRequest request, Portlet portlet, PortletRequest portletRequest, Layout layout, String lifecycle) { if (portlet == null) { throw new NullPointerException("Portlet is null"); } _request = request; _portlet = portlet; _portletRequest = portletRequest; _layout = layout; _lifecycle = lifecycle; _parametersIncludedInPath = Collections.emptySet(); _params = new LinkedHashMap<>(); _removePublicRenderParameters = new LinkedHashSet<>(); _secure = PortalUtil.isSecure(request); _wsrp = ParamUtil.getBoolean(request, "wsrp"); if (!portlet.isUndeployedPortlet()) { Set<String> autopropagatedParameters = portlet.getAutopropagatedParameters(); for (String autopropagatedParameter : autopropagatedParameters) { if (PortalUtil.isReservedParameter(autopropagatedParameter)) { continue; } String value = request.getParameter(autopropagatedParameter); if (value != null) { setParameter(autopropagatedParameter, value); } } PortletApp portletApp = portlet.getPortletApp(); _escapeXml = MapUtil.getBoolean( portletApp.getContainerRuntimeOptions(), LiferayPortletConfig.RUNTIME_OPTION_ESCAPE_XML, PropsValues.PORTLET_URL_ESCAPE_XML); } if (layout != null) { _plid = layout.getPlid(); } } private PortletURLImpl( HttpServletRequest request, String portletId, PortletRequest portletRequest, Layout layout, String lifecycle) { this( request, PortletLocalServiceUtil.getPortletById( PortalUtil.getCompanyId(request), portletId), portletRequest, layout, lifecycle); } private void _appendNamespaceAndEncode(StringBundler sb, String name) { String namespace = getNamespace(); if (!name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) && !name.startsWith(namespace) && !PortalUtil.isReservedParameter(name)) { if (_encodedNamespace == null) { _encodedNamespace = URLCodec.encodeURL(namespace); } sb.append(_encodedNamespace); } sb.append(URLCodec.encodeURL(name)); } private Key _getKey() { try { if (_encrypt) { Company company = PortalUtil.getCompany(_request); return company.getKeyObj(); } } catch (Exception e) { _log.error(e); } return null; } private Map<String, String[]> _mergeWithRenderParameters( Map<String, String[]> portletURLParams) { String namespace = getNamespace(); Map<String, String[]> renderParameters = RenderParametersPool.get( _request, _plid, _portlet.getPortletId()); if (renderParameters == null) { return portletURLParams; } Map<String, String[]> mergedRenderParams = new LinkedHashMap<>( portletURLParams); for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) { String name = entry.getKey(); if (name.contains(namespace)) { name = name.substring(namespace.length()); } if (!_lifecycle.equals(PortletRequest.RESOURCE_PHASE) && (_removedParameterNames != null) && _removedParameterNames.contains(name)) { continue; } String[] oldValues = entry.getValue(); String[] newValues = _params.get(name); if (newValues == null) { mergedRenderParams.put(name, oldValues); } else if (isBlankValue(newValues)) { mergedRenderParams.remove(name); } else { newValues = ArrayUtil.append(newValues, oldValues); mergedRenderParams.put(name, newValues); } } return mergedRenderParams; } private static final Log _log = LogFactoryUtil.getLog(PortletURLImpl.class); private boolean _anchor = true; private String _cacheability = ResourceURL.PAGE; private boolean _copyCurrentRenderParameters; private long _doAsGroupId; private long _doAsUserId; private String _doAsUserLanguageId; private String _encodedNamespace; private boolean _encrypt; private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML; private Layout _layout; private String _layoutFriendlyURL; private String _lifecycle; private String _namespace; private Set<String> _parametersIncludedInPath; private Map<String, String[]> _params; private long _plid; private Portlet _portlet; private String _portletModeString; private final PortletRequest _portletRequest; private long _refererGroupId; private long _refererPlid; private Set<String> _removedParameterNames; private final Set<String> _removePublicRenderParameters; private final HttpServletRequest _request; private String _resourceID; private boolean _secure; private String _toString; private boolean _windowStateRestoreCurrentView; private String _windowStateString; private final boolean _wsrp; private class ToStringPrivilegedAction implements PrivilegedAction<String> { @Override public String run() { if (_wsrp) { return generateWSRPToString(); } return generateToString(); } } }