001    /**
002     * Copyright (c) 2000-present 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.portlet;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
021    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
022    import com.liferay.portal.kernel.portlet.LiferayPortletURL;
023    import com.liferay.portal.kernel.portlet.LiferayWindowState;
024    import com.liferay.portal.kernel.portlet.PortletModeFactory;
025    import com.liferay.portal.kernel.portlet.PortletProvider;
026    import com.liferay.portal.kernel.portlet.PortletProviderUtil;
027    import com.liferay.portal.kernel.portlet.WindowStateFactory;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.Base64;
030    import com.liferay.portal.kernel.util.CharPool;
031    import com.liferay.portal.kernel.util.CookieKeys;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.HtmlUtil;
034    import com.liferay.portal.kernel.util.Http;
035    import com.liferay.portal.kernel.util.HttpUtil;
036    import com.liferay.portal.kernel.util.MapUtil;
037    import com.liferay.portal.kernel.util.ParamUtil;
038    import com.liferay.portal.kernel.util.StringBundler;
039    import com.liferay.portal.kernel.util.StringPool;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.kernel.xml.QName;
042    import com.liferay.portal.model.Company;
043    import com.liferay.portal.model.Layout;
044    import com.liferay.portal.model.LayoutTypePortlet;
045    import com.liferay.portal.model.Portlet;
046    import com.liferay.portal.model.PortletApp;
047    import com.liferay.portal.model.PublicRenderParameter;
048    import com.liferay.portal.model.impl.VirtualLayout;
049    import com.liferay.portal.security.auth.AuthTokenUtil;
050    import com.liferay.portal.security.auth.AuthTokenWhitelistUtil;
051    import com.liferay.portal.security.lang.DoPrivilegedUtil;
052    import com.liferay.portal.service.LayoutLocalServiceUtil;
053    import com.liferay.portal.service.PortletLocalServiceUtil;
054    import com.liferay.portal.theme.PortletDisplay;
055    import com.liferay.portal.theme.ThemeDisplay;
056    import com.liferay.portal.util.PortalUtil;
057    import com.liferay.portal.util.PropsValues;
058    import com.liferay.portal.util.WebKeys;
059    import com.liferay.portlet.admin.util.PortalAdministrationApplicationType;
060    import com.liferay.portlet.social.util.FacebookUtil;
061    import com.liferay.util.Encryptor;
062    import com.liferay.util.EncryptorException;
063    
064    import java.io.IOException;
065    import java.io.Serializable;
066    import java.io.UnsupportedEncodingException;
067    import java.io.Writer;
068    
069    import java.security.Key;
070    import java.security.PrivilegedAction;
071    
072    import java.util.Collections;
073    import java.util.LinkedHashMap;
074    import java.util.LinkedHashSet;
075    import java.util.Map;
076    import java.util.Set;
077    
078    import javax.portlet.PortletMode;
079    import javax.portlet.PortletModeException;
080    import javax.portlet.PortletRequest;
081    import javax.portlet.PortletURL;
082    import javax.portlet.ResourceRequest;
083    import javax.portlet.ResourceURL;
084    import javax.portlet.WindowState;
085    import javax.portlet.WindowStateException;
086    
087    import javax.servlet.http.HttpServletRequest;
088    
089    /**
090     * @author Brian Wing Shun Chan
091     * @author Jorge Ferrer
092     * @author Connor McKay
093     */
094    public class PortletURLImpl
095            implements LiferayPortletURL, PortletURL, ResourceURL, Serializable {
096    
097            public PortletURLImpl(
098                    HttpServletRequest request, String portletId, long plid,
099                    String lifecycle) {
100    
101                    this(request, portletId, null, plid, lifecycle);
102            }
103    
104            public PortletURLImpl(
105                    PortletRequest portletRequest, String portletId, long plid,
106                    String lifecycle) {
107    
108                    this(
109                            PortalUtil.getHttpServletRequest(portletRequest), portletId,
110                            portletRequest, plid, lifecycle);
111            }
112    
113            @Override
114            public void addParameterIncludedInPath(String name) {
115                    _parametersIncludedInPath.add(name);
116            }
117    
118            @Override
119            public void addProperty(String key, String value) {
120                    if (key == null) {
121                            throw new IllegalArgumentException();
122                    }
123            }
124    
125            @Override
126            public String getCacheability() {
127                    return _cacheability;
128            }
129    
130            public HttpServletRequest getHttpServletRequest() {
131                    return _request;
132            }
133    
134            public Layout getLayout() {
135                    if (_layout == null) {
136                            try {
137                                    if (_plid > 0) {
138                                            _layout = LayoutLocalServiceUtil.getLayout(_plid);
139                                    }
140                            }
141                            catch (Exception e) {
142                                    if (_log.isWarnEnabled()) {
143                                            _log.warn("Layout cannot be found for " + _plid);
144                                    }
145                            }
146                    }
147    
148                    return _layout;
149            }
150    
151            public String getLayoutFriendlyURL() {
152                    return _layoutFriendlyURL;
153            }
154    
155            @Override
156            public String getLifecycle() {
157                    return _lifecycle;
158            }
159    
160            public String getNamespace() {
161                    if (_namespace == null) {
162                            _namespace = PortalUtil.getPortletNamespace(_portletId);
163                    }
164    
165                    return _namespace;
166            }
167    
168            @Override
169            public String getParameter(String name) {
170                    String[] values = _params.get(name);
171    
172                    if (ArrayUtil.isNotEmpty(values)) {
173                            return values[0];
174                    }
175                    else {
176                            return null;
177                    }
178            }
179    
180            @Override
181            public Map<String, String[]> getParameterMap() {
182                    return _params;
183            }
184    
185            @Override
186            public Set<String> getParametersIncludedInPath() {
187                    return _parametersIncludedInPath;
188            }
189    
190            public long getPlid() {
191                    return _plid;
192            }
193    
194            public Portlet getPortlet() {
195                    if (_portlet == null) {
196                            try {
197                                    _portlet = PortletLocalServiceUtil.getPortletById(
198                                            PortalUtil.getCompanyId(_request), _portletId);
199                            }
200                            catch (SystemException se) {
201                                    _log.error(se.getMessage());
202                            }
203                    }
204    
205                    return _portlet;
206            }
207    
208            public String getPortletFriendlyURLPath() {
209                    String portletFriendlyURLPath = null;
210    
211                    Portlet portlet = getPortlet();
212    
213                    if (portlet != null) {
214                            if (portlet.isUndeployedPortlet()) {
215                                    return portletFriendlyURLPath;
216                            }
217    
218                            FriendlyURLMapper friendlyURLMapper =
219                                    portlet.getFriendlyURLMapperInstance();
220    
221                            if (friendlyURLMapper != null) {
222                                    portletFriendlyURLPath = friendlyURLMapper.buildPath(this);
223    
224                                    if (_log.isDebugEnabled()) {
225                                            _log.debug(
226                                                    "Portlet friendly URL path " + portletFriendlyURLPath);
227                                    }
228                            }
229                    }
230    
231                    return portletFriendlyURLPath;
232            }
233    
234            @Override
235            public String getPortletId() {
236                    return _portletId;
237            }
238    
239            @Override
240            public PortletMode getPortletMode() {
241                    if (_portletModeString == null) {
242                            return null;
243                    }
244    
245                    return PortletModeFactory.getPortletMode(_portletModeString);
246            }
247    
248            public PortletRequest getPortletRequest() {
249                    return _portletRequest;
250            }
251    
252            @Override
253            public Set<String> getRemovedParameterNames() {
254                    return _removedParameterNames;
255            }
256    
257            @Override
258            public Map<String, String> getReservedParameterMap() {
259                    if (_reservedParameters != null) {
260                            return _reservedParameters;
261                    }
262    
263                    _reservedParameters = new LinkedHashMap<>();
264    
265                    _reservedParameters.put("p_p_id", _portletId);
266    
267                    if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
268                            _reservedParameters.put("p_p_lifecycle", "1");
269                    }
270                    else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
271                            _reservedParameters.put("p_p_lifecycle", "0");
272                    }
273                    else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
274                            _reservedParameters.put("p_p_lifecycle", "2");
275                    }
276    
277                    if (_windowStateString != null) {
278                            _reservedParameters.put("p_p_state", _windowStateString);
279                    }
280    
281                    if (_windowStateRestoreCurrentView) {
282                            _reservedParameters.put("p_p_state_rcv", "1");
283                    }
284    
285                    if (_portletModeString != null) {
286                            _reservedParameters.put("p_p_mode", _portletModeString);
287                    }
288    
289                    if (_resourceID != null) {
290                            _reservedParameters.put("p_p_resource_id", _resourceID);
291                    }
292    
293                    if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
294                            _reservedParameters.put("p_p_cacheability", _cacheability);
295                    }
296    
297                    ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
298                            WebKeys.THEME_DISPLAY);
299    
300                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
301    
302                    if (Validator.isNotNull(portletDisplay.getColumnId())) {
303                            _reservedParameters.put("p_p_col_id", portletDisplay.getColumnId());
304                    }
305    
306                    if (portletDisplay.getColumnPos() > 0) {
307                            _reservedParameters.put(
308                                    "p_p_col_pos", String.valueOf(portletDisplay.getColumnPos()));
309                    }
310    
311                    if (portletDisplay.getColumnCount() > 0) {
312                            _reservedParameters.put(
313                                    "p_p_col_count",
314                                    String.valueOf(portletDisplay.getColumnCount()));
315                    }
316    
317                    _reservedParameters = Collections.unmodifiableMap(_reservedParameters);
318    
319                    return _reservedParameters;
320            }
321    
322            @Override
323            public String getResourceID() {
324                    return _resourceID;
325            }
326    
327            @Override
328            public WindowState getWindowState() {
329                    if (_windowStateString == null) {
330                            return null;
331                    }
332    
333                    return WindowStateFactory.getWindowState(_windowStateString);
334            }
335    
336            @Override
337            public boolean isAnchor() {
338                    return _anchor;
339            }
340    
341            @Override
342            public boolean isCopyCurrentRenderParameters() {
343                    return _copyCurrentRenderParameters;
344            }
345    
346            @Override
347            public boolean isEncrypt() {
348                    return _encrypt;
349            }
350    
351            @Override
352            public boolean isEscapeXml() {
353                    return _escapeXml;
354            }
355    
356            @Override
357            public boolean isParameterIncludedInPath(String name) {
358                    if (_parametersIncludedInPath.contains(name)) {
359                            return true;
360                    }
361                    else {
362                            return false;
363                    }
364            }
365    
366            @Override
367            public boolean isSecure() {
368                    return _secure;
369            }
370    
371            @Override
372            public void removePublicRenderParameter(String name) {
373                    if (name == null) {
374                            throw new IllegalArgumentException();
375                    }
376    
377                    Portlet portlet = getPortlet();
378    
379                    if (portlet == null) {
380                            return;
381                    }
382    
383                    PublicRenderParameter publicRenderParameter =
384                            portlet.getPublicRenderParameter(name);
385    
386                    if (publicRenderParameter == null) {
387                            if (_log.isWarnEnabled()) {
388                                    _log.warn("Public parameter " + name + "does not exist");
389                            }
390    
391                            return;
392                    }
393    
394                    QName qName = publicRenderParameter.getQName();
395    
396                    _removePublicRenderParameters.put(
397                            PortletQNameUtil.getRemovePublicRenderParameterName(qName),
398                            new String[] {"1"});
399            }
400    
401            @Override
402            public void setAnchor(boolean anchor) {
403                    _anchor = anchor;
404    
405                    clearCache();
406            }
407    
408            @Override
409            public void setCacheability(String cacheability) {
410                    if (cacheability == null) {
411                            throw new IllegalArgumentException("Cacheability is null");
412                    }
413    
414                    if (!cacheability.equals(FULL) && !cacheability.equals(PORTLET) &&
415                            !cacheability.equals(PAGE)) {
416    
417                            throw new IllegalArgumentException(
418                                    "Cacheability " + cacheability + " is not " + FULL + ", " +
419                                            PORTLET + ", or " + PAGE);
420                    }
421    
422                    if (_portletRequest instanceof ResourceRequest) {
423                            ResourceRequest resourceRequest = (ResourceRequest)_portletRequest;
424    
425                            String parentCacheability = resourceRequest.getCacheability();
426    
427                            if (parentCacheability.equals(FULL)) {
428                                    if (!cacheability.equals(FULL)) {
429                                            throw new IllegalStateException(
430                                                    "Unable to set a weaker cacheability " + cacheability);
431                                    }
432                            }
433                            else if (parentCacheability.equals(PORTLET)) {
434                                    if (!cacheability.equals(FULL) &&
435                                            !cacheability.equals(PORTLET)) {
436    
437                                            throw new IllegalStateException(
438                                                    "Unable to set a weaker cacheability " + cacheability);
439                                    }
440                            }
441                    }
442    
443                    _cacheability = cacheability;
444    
445                    clearCache();
446            }
447    
448            @Override
449            public void setControlPanelCategory(String controlPanelCategory) {
450                    _controlPanelCategory = controlPanelCategory;
451    
452                    clearCache();
453            }
454    
455            @Override
456            public void setCopyCurrentRenderParameters(
457                    boolean copyCurrentRenderParameters) {
458    
459                    _copyCurrentRenderParameters = copyCurrentRenderParameters;
460            }
461    
462            @Override
463            public void setDoAsGroupId(long doAsGroupId) {
464                    _doAsGroupId = doAsGroupId;
465    
466                    clearCache();
467            }
468    
469            @Override
470            public void setDoAsUserId(long doAsUserId) {
471                    _doAsUserId = doAsUserId;
472    
473                    clearCache();
474            }
475    
476            @Override
477            public void setDoAsUserLanguageId(String doAsUserLanguageId) {
478                    _doAsUserLanguageId = doAsUserLanguageId;
479    
480                    clearCache();
481            }
482    
483            @Override
484            public void setEncrypt(boolean encrypt) {
485                    _encrypt = encrypt;
486    
487                    clearCache();
488            }
489    
490            @Override
491            public void setEscapeXml(boolean escapeXml) {
492                    _escapeXml = escapeXml;
493    
494                    clearCache();
495            }
496    
497            @Override
498            public void setLifecycle(String lifecycle) {
499                    _lifecycle = lifecycle;
500    
501                    clearCache();
502            }
503    
504            @Override
505            public void setParameter(String name, String value) {
506                    setParameter(name, value, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
507            }
508    
509            @Override
510            public void setParameter(String name, String value, boolean append) {
511                    if ((name == null) || (value == null)) {
512                            throw new IllegalArgumentException();
513                    }
514    
515                    setParameter(name, new String[] {value}, append);
516            }
517    
518            @Override
519            public void setParameter(String name, String[] values) {
520                    setParameter(name, values, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
521            }
522    
523            @Override
524            public void setParameter(String name, String[] values, boolean append) {
525                    if ((name == null) || (values == null)) {
526                            throw new IllegalArgumentException();
527                    }
528    
529                    for (String value : values) {
530                            if (value == null) {
531                                    throw new IllegalArgumentException();
532                            }
533                    }
534    
535                    if (!append) {
536                            _params.put(name, values);
537                    }
538                    else {
539                            String[] oldValues = _params.get(name);
540    
541                            if (oldValues == null) {
542                                    _params.put(name, values);
543                            }
544                            else {
545                                    String[] newValues = ArrayUtil.append(oldValues, values);
546    
547                                    _params.put(name, newValues);
548                            }
549                    }
550    
551                    clearCache();
552            }
553    
554            @Override
555            public void setParameters(Map<String, String[]> params) {
556                    if (params == null) {
557                            throw new IllegalArgumentException();
558                    }
559                    else {
560                            Map<String, String[]> newParams = new LinkedHashMap<>();
561    
562                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
563                                    try {
564                                            String key = entry.getKey();
565                                            String[] value = entry.getValue();
566    
567                                            if (key == null) {
568                                                    throw new IllegalArgumentException();
569                                            }
570                                            else if (value == null) {
571                                                    throw new IllegalArgumentException();
572                                            }
573    
574                                            newParams.put(key, value);
575                                    }
576                                    catch (ClassCastException cce) {
577                                            throw new IllegalArgumentException(cce);
578                                    }
579                            }
580    
581                            _params = newParams;
582                    }
583    
584                    clearCache();
585            }
586    
587            @Override
588            public void setPlid(long plid) {
589                    _plid = plid;
590    
591                    clearCache();
592            }
593    
594            @Override
595            public void setPortletId(String portletId) {
596                    _portletId = portletId;
597    
598                    clearCache();
599            }
600    
601            @Override
602            public void setPortletMode(PortletMode portletMode)
603                    throws PortletModeException {
604    
605                    if (_portletRequest != null) {
606                            Portlet portlet = getPortlet();
607    
608                            if ((portlet != null) &&
609                                    !portlet.hasPortletMode(
610                                            _portletRequest.getResponseContentType(), portletMode)) {
611    
612                                    throw new PortletModeException(
613                                            portletMode.toString(), portletMode);
614                            }
615                    }
616    
617                    _portletModeString = portletMode.toString();
618    
619                    clearCache();
620            }
621    
622            public void setPortletMode(String portletMode) throws PortletModeException {
623                    setPortletMode(PortletModeFactory.getPortletMode(portletMode));
624            }
625    
626            @Override
627            public void setProperty(String key, String value) {
628                    if (key == null) {
629                            throw new IllegalArgumentException();
630                    }
631            }
632    
633            public void setRefererGroupId(long refererGroupId) {
634                    _refererGroupId = refererGroupId;
635    
636                    clearCache();
637            }
638    
639            @Override
640            public void setRefererPlid(long refererPlid) {
641                    _refererPlid = refererPlid;
642    
643                    clearCache();
644            }
645    
646            @Override
647            public void setRemovedParameterNames(Set<String> removedParameterNames) {
648                    _removedParameterNames = removedParameterNames;
649    
650                    clearCache();
651            }
652    
653            @Override
654            public void setResourceID(String resourceID) {
655                    _resourceID = resourceID;
656            }
657    
658            @Override
659            public void setSecure(boolean secure) {
660                    _secure = secure;
661    
662                    clearCache();
663            }
664    
665            public void setWindowState(String windowState) throws WindowStateException {
666                    setWindowState(WindowStateFactory.getWindowState(windowState));
667            }
668    
669            @Override
670            public void setWindowState(WindowState windowState)
671                    throws WindowStateException {
672    
673                    if (_portletRequest != null) {
674                            if (!_portletRequest.isWindowStateAllowed(windowState)) {
675                                    throw new WindowStateException(
676                                            windowState.toString(), windowState);
677                            }
678                    }
679    
680                    if (LiferayWindowState.isWindowStatePreserved(
681                                    getWindowState(), windowState)) {
682    
683                            _windowStateString = windowState.toString();
684                    }
685    
686                    clearCache();
687            }
688    
689            public void setWindowStateRestoreCurrentView(
690                    boolean windowStateRestoreCurrentView) {
691    
692                    _windowStateRestoreCurrentView = windowStateRestoreCurrentView;
693            }
694    
695            @Override
696            public String toString() {
697                    if (_toString != null) {
698                            return _toString;
699                    }
700    
701                    _toString = DoPrivilegedUtil.wrap(new ToStringPrivilegedAction());
702    
703                    return _toString;
704            }
705    
706            @Override
707            public void write(Writer writer) throws IOException {
708                    write(writer, _escapeXml);
709            }
710    
711            @Override
712            public void write(Writer writer, boolean escapeXml) throws IOException {
713                    String toString = toString();
714    
715                    if (escapeXml && !_escapeXml) {
716                            toString = HtmlUtil.escape(toString);
717                    }
718    
719                    writer.write(toString);
720            }
721    
722            protected PortletURLImpl(
723                    HttpServletRequest request, String portletId,
724                    PortletRequest portletRequest, long plid, String lifecycle) {
725    
726                    _request = request;
727                    _portletId = portletId;
728                    _portletRequest = portletRequest;
729                    _plid = plid;
730                    _lifecycle = lifecycle;
731                    _parametersIncludedInPath = new LinkedHashSet<>();
732                    _params = new LinkedHashMap<>();
733                    _removePublicRenderParameters = new LinkedHashMap<>();
734                    _secure = PortalUtil.isSecure(request);
735                    _wsrp = ParamUtil.getBoolean(request, "wsrp");
736    
737                    Portlet portlet = getPortlet();
738    
739                    if (portlet != null) {
740                            Set<String> autopropagatedParameters =
741                                    portlet.getAutopropagatedParameters();
742    
743                            for (String autopropagatedParameter : autopropagatedParameters) {
744                                    if (PortalUtil.isReservedParameter(autopropagatedParameter)) {
745                                            continue;
746                                    }
747    
748                                    String value = request.getParameter(autopropagatedParameter);
749    
750                                    if (value != null) {
751                                            setParameter(autopropagatedParameter, value);
752                                    }
753                            }
754    
755                            PortletApp portletApp = portlet.getPortletApp();
756    
757                            _escapeXml = MapUtil.getBoolean(
758                                    portletApp.getContainerRuntimeOptions(),
759                                    LiferayPortletConfig.RUNTIME_OPTION_ESCAPE_XML,
760                                    PropsValues.PORTLET_URL_ESCAPE_XML);
761                    }
762    
763                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
764    
765                    if ((layout != null) && (layout.getPlid() == _plid) &&
766                            (layout instanceof VirtualLayout)) {
767    
768                            _layout = layout;
769                    }
770            }
771    
772            protected void addPortalAuthToken(StringBundler sb, Key key) {
773                    if (!PropsValues.AUTH_TOKEN_CHECK_ENABLED ||
774                            !_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
775    
776                            return;
777                    }
778    
779                    Portlet portlet = getPortlet();
780    
781                    if (portlet == null) {
782                            return;
783                    }
784    
785                    String strutsAction = getParameter("struts_action");
786    
787                    if (AuthTokenWhitelistUtil.isPortletCSRFWhitelisted(
788                                    portlet.getCompanyId(), _portletId, strutsAction)) {
789    
790                            return;
791                    }
792    
793                    sb.append("p_auth");
794                    sb.append(StringPool.EQUAL);
795                    sb.append(processValue(key, AuthTokenUtil.getToken(_request)));
796                    sb.append(StringPool.AMPERSAND);
797            }
798    
799            protected void addPortletAuthToken(StringBundler sb, Key key) {
800                    if (!PropsValues.PORTLET_ADD_DEFAULT_RESOURCE_CHECK_ENABLED) {
801                            return;
802                    }
803    
804                    Portlet portlet = getPortlet();
805    
806                    if (portlet == null) {
807                            return;
808                    }
809    
810                    if (!portlet.isAddDefaultResource()) {
811                            return;
812                    }
813    
814                    String strutsAction = getParameter("struts_action");
815    
816                    if (AuthTokenWhitelistUtil.isPortletInvocationWhitelisted(
817                                    portlet.getCompanyId(), _portletId, strutsAction)) {
818    
819                            return;
820                    }
821    
822                    try {
823                            LayoutTypePortlet targetLayoutTypePortlet =
824                                    (LayoutTypePortlet)getLayout().getLayoutType();
825    
826                            if (targetLayoutTypePortlet.hasPortletId(_portletId)) {
827                                    return;
828                            }
829                    }
830                    catch (Exception e) {
831                            if (_log.isDebugEnabled()) {
832                                    _log.debug(e.getMessage(), e);
833                            }
834                    }
835    
836                    String controlPanelMenuPortletId = PortletProviderUtil.getPortletId(
837                            PortalAdministrationApplicationType.SiteAdmin.CLASS_NAME,
838                            PortletProvider.Action.VIEW);
839    
840                    if (_portletId.equals(controlPanelMenuPortletId)) {
841                            return;
842                    }
843    
844                    sb.append("p_p_auth");
845                    sb.append(StringPool.EQUAL);
846                    sb.append(
847                            processValue(
848                                    key, AuthTokenUtil.getToken(_request, _plid, _portletId)));
849                    sb.append(StringPool.AMPERSAND);
850            }
851    
852            protected void clearCache() {
853                    _reservedParameters = null;
854                    _toString = null;
855            }
856    
857            protected String generateToString() {
858                    StringBundler sb = new StringBundler(64);
859    
860                    ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
861                            WebKeys.THEME_DISPLAY);
862    
863                    if (themeDisplay == null) {
864                            if (_log.isWarnEnabled()) {
865                                    _log.warn(
866                                            "Unable to generate string because theme display is null");
867                            }
868    
869                            return StringPool.BLANK;
870                    }
871    
872                    String portalURL = null;
873    
874                    if (themeDisplay.isFacebook()) {
875                            portalURL =
876                                    FacebookUtil.FACEBOOK_APPS_URL +
877                                            themeDisplay.getFacebookCanvasPageURL();
878                    }
879                    else {
880                            portalURL = PortalUtil.getPortalURL(_request, _secure);
881                    }
882    
883                    try {
884                            if (_layoutFriendlyURL == null) {
885                                    Layout layout = getLayout();
886    
887                                    if (layout != null) {
888                                            _layoutFriendlyURL = GetterUtil.getString(
889                                                    PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
890    
891                                            if (_secure) {
892                                                    _layoutFriendlyURL = HttpUtil.protocolize(
893                                                            _layoutFriendlyURL,
894                                                            PropsValues.WEB_SERVER_HTTPS_PORT, true);
895                                            }
896                                    }
897                            }
898                    }
899                    catch (Exception e) {
900                            _log.error(e);
901                    }
902    
903                    Key key = null;
904    
905                    try {
906                            if (_encrypt) {
907                                    Company company = PortalUtil.getCompany(_request);
908    
909                                    key = company.getKeyObj();
910                            }
911                    }
912                    catch (Exception e) {
913                            _log.error(e);
914                    }
915    
916                    if (Validator.isNull(_layoutFriendlyURL)) {
917                            sb.append(portalURL);
918                            sb.append(themeDisplay.getPathMain());
919                            sb.append("/portal/layout?");
920    
921                            addPortalAuthToken(sb, key);
922    
923                            sb.append("p_l_id");
924                            sb.append(StringPool.EQUAL);
925                            sb.append(processValue(key, _plid));
926                            sb.append(StringPool.AMPERSAND);
927                    }
928                    else {
929                            if (themeDisplay.isFacebook()) {
930                                    sb.append(portalURL);
931                            }
932                            else {
933    
934                                    // A virtual host URL will contain the complete path. Do not
935                                    // append the portal URL if the virtual host URL starts with
936                                    // "http://" or "https://".
937    
938                                    if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
939                                            !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
940    
941                                            sb.append(portalURL);
942                                    }
943    
944                                    sb.append(_layoutFriendlyURL);
945                            }
946    
947                            String friendlyURLPath = getPortletFriendlyURLPath();
948    
949                            if (Validator.isNotNull(friendlyURLPath)) {
950                                    if (themeDisplay.isFacebook()) {
951                                            int pos = friendlyURLPath.indexOf(CharPool.SLASH, 1);
952    
953                                            if (pos != -1) {
954                                                    sb.append(friendlyURLPath.substring(pos));
955                                            }
956                                            else {
957                                                    sb.append(friendlyURLPath);
958                                            }
959                                    }
960                                    else {
961                                            sb.append("/-");
962                                            sb.append(friendlyURLPath);
963                                    }
964                            }
965    
966                            sb.append(StringPool.QUESTION);
967    
968                            addPortalAuthToken(sb, key);
969                    }
970    
971                    addPortletAuthToken(sb, key);
972    
973                    for (Map.Entry<String, String> entry :
974                                    getReservedParameterMap().entrySet()) {
975    
976                            String name = entry.getKey();
977    
978                            if (!isParameterIncludedInPath(name)) {
979                                    sb.append(HttpUtil.encodeURL(name));
980                                    sb.append(StringPool.EQUAL);
981                                    sb.append(processValue(key, entry.getValue()));
982                                    sb.append(StringPool.AMPERSAND);
983                            }
984                    }
985    
986                    if (_doAsUserId > 0) {
987                            try {
988                                    Company company = PortalUtil.getCompany(_request);
989    
990                                    sb.append("doAsUserId");
991                                    sb.append(StringPool.EQUAL);
992                                    sb.append(processValue(company.getKeyObj(), _doAsUserId));
993                                    sb.append(StringPool.AMPERSAND);
994                            }
995                            catch (Exception e) {
996                                    _log.error(e);
997                            }
998                    }
999                    else {
1000                            String doAsUserId = themeDisplay.getDoAsUserId();
1001    
1002                            if (Validator.isNotNull(doAsUserId)) {
1003                                    sb.append("doAsUserId");
1004                                    sb.append(StringPool.EQUAL);
1005                                    sb.append(processValue(key, doAsUserId));
1006                                    sb.append(StringPool.AMPERSAND);
1007                            }
1008                    }
1009    
1010                    String doAsUserLanguageId = _doAsUserLanguageId;
1011    
1012                    if (Validator.isNull(doAsUserLanguageId)) {
1013                            doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
1014                    }
1015    
1016                    if (Validator.isNotNull(doAsUserLanguageId)) {
1017                            sb.append("doAsUserLanguageId");
1018                            sb.append(StringPool.EQUAL);
1019                            sb.append(processValue(key, doAsUserLanguageId));
1020                            sb.append(StringPool.AMPERSAND);
1021                    }
1022    
1023                    long doAsGroupId = _doAsGroupId;
1024    
1025                    if (doAsGroupId <= 0) {
1026                            doAsGroupId = themeDisplay.getDoAsGroupId();
1027                    }
1028    
1029                    if (doAsGroupId > 0) {
1030                            sb.append("doAsGroupId");
1031                            sb.append(StringPool.EQUAL);
1032                            sb.append(processValue(key, doAsGroupId));
1033                            sb.append(StringPool.AMPERSAND);
1034                    }
1035    
1036                    long refererGroupId = _refererGroupId;
1037    
1038                    if (refererGroupId <= 0) {
1039                            refererGroupId = themeDisplay.getRefererGroupId();
1040                    }
1041    
1042                    if (refererGroupId > 0) {
1043                            sb.append("refererGroupId");
1044                            sb.append(StringPool.EQUAL);
1045                            sb.append(processValue(key, refererGroupId));
1046                            sb.append(StringPool.AMPERSAND);
1047                    }
1048    
1049                    long refererPlid = _refererPlid;
1050    
1051                    if (refererPlid <= 0) {
1052                            refererPlid = themeDisplay.getRefererPlid();
1053                    }
1054    
1055                    if (refererPlid > 0) {
1056                            sb.append("refererPlid");
1057                            sb.append(StringPool.EQUAL);
1058                            sb.append(processValue(key, refererPlid));
1059                            sb.append(StringPool.AMPERSAND);
1060                    }
1061    
1062                    String controlPanelCategory = _controlPanelCategory;
1063    
1064                    if (Validator.isNull(controlPanelCategory)) {
1065                            HttpServletRequest request = PortalUtil.getOriginalServletRequest(
1066                                    _request);
1067    
1068                            controlPanelCategory = ParamUtil.getString(
1069                                    request, "controlPanelCategory");
1070                    }
1071    
1072                    if (Validator.isNotNull(controlPanelCategory)) {
1073                            sb.append("controlPanelCategory");
1074                            sb.append(StringPool.EQUAL);
1075                            sb.append(processValue(key, controlPanelCategory));
1076                            sb.append(StringPool.AMPERSAND);
1077                    }
1078    
1079                    for (Map.Entry<String, String[]> entry :
1080                                    _removePublicRenderParameters.entrySet()) {
1081    
1082                            String lastString = sb.stringAt(sb.index() - 1);
1083    
1084                            if (lastString.charAt(lastString.length() - 1) !=
1085                                            CharPool.AMPERSAND) {
1086    
1087                                    sb.append(StringPool.AMPERSAND);
1088                            }
1089    
1090                            sb.append(HttpUtil.encodeURL(entry.getKey()));
1091                            sb.append(StringPool.EQUAL);
1092                            sb.append(processValue(key, entry.getValue()[0]));
1093                            sb.append(StringPool.AMPERSAND);
1094                    }
1095    
1096                    if (_copyCurrentRenderParameters) {
1097                            mergeRenderParameters();
1098                    }
1099    
1100                    int previousSbIndex = sb.index();
1101    
1102                    for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1103                            String name = entry.getKey();
1104                            String[] values = entry.getValue();
1105    
1106                            if (isParameterIncludedInPath(name)) {
1107                                    continue;
1108                            }
1109    
1110                            String publicRenderParameterName = getPublicRenderParameterName(
1111                                    name);
1112    
1113                            if (Validator.isNotNull(publicRenderParameterName)) {
1114                                    name = publicRenderParameterName;
1115                            }
1116    
1117                            name = HttpUtil.encodeURL(prependNamespace(name));
1118    
1119                            for (String value : values) {
1120                                    sb.append(name);
1121                                    sb.append(StringPool.EQUAL);
1122                                    sb.append(processValue(key, value));
1123                                    sb.append(StringPool.AMPERSAND);
1124                            }
1125                    }
1126    
1127                    if (sb.index() > previousSbIndex) {
1128                            sb.setIndex(sb.index() - 1);
1129                    }
1130    
1131                    if (_encrypt) {
1132                            sb.append(StringPool.AMPERSAND);
1133                            sb.append(WebKeys.ENCRYPT);
1134                            sb.append("=1");
1135                    }
1136    
1137                    if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1138                            if (_anchor && (_windowStateString != null) &&
1139                                    !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1140                                    !_windowStateString.equals(
1141                                            LiferayWindowState.EXCLUSIVE.toString()) &&
1142                                    !_windowStateString.equals(
1143                                            LiferayWindowState.POP_UP.toString())) {
1144    
1145                                    String lastString = sb.stringAt(sb.index() - 1);
1146    
1147                                    if (lastString.charAt(lastString.length() - 1) !=
1148                                                    CharPool.AMPERSAND) {
1149    
1150                                            sb.append(StringPool.AMPERSAND);
1151                                    }
1152    
1153                                    sb.append("#p_");
1154                                    sb.append(HttpUtil.encodeURL(_portletId));
1155                            }
1156                    }
1157    
1158                    String result = sb.toString();
1159    
1160                    if (result.endsWith(StringPool.AMPERSAND) ||
1161                            result.endsWith(StringPool.QUESTION)) {
1162    
1163                            result = result.substring(0, result.length() - 1);
1164                    }
1165    
1166                    if (themeDisplay.isFacebook()) {
1167    
1168                            // Facebook requires the path portion of the URL to end with a slash
1169    
1170                            int pos = result.indexOf(CharPool.QUESTION);
1171    
1172                            if (pos == -1) {
1173                                    if (!result.endsWith(StringPool.SLASH)) {
1174                                            result += StringPool.SLASH;
1175                                    }
1176                            }
1177                            else {
1178                                    String path = result.substring(0, pos);
1179    
1180                                    if (!result.endsWith(StringPool.SLASH)) {
1181                                            result = path + StringPool.SLASH + result.substring(pos);
1182                                    }
1183                            }
1184                    }
1185                    else if (!CookieKeys.hasSessionId(_request)) {
1186                            result = PortalUtil.getURLWithSessionId(
1187                                    result, _request.getSession().getId());
1188                    }
1189    
1190                    if (_escapeXml) {
1191                            result = HtmlUtil.escape(result);
1192                    }
1193    
1194                    if (result.length() > Http.URL_MAXIMUM_LENGTH) {
1195                            result = HttpUtil.shortenURL(result, 2);
1196                    }
1197    
1198                    return result;
1199            }
1200    
1201            protected String generateWSRPToString() {
1202                    StringBundler sb = new StringBundler("wsrp_rewrite?");
1203    
1204                    sb.append("wsrp-urlType");
1205                    sb.append(StringPool.EQUAL);
1206    
1207                    if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
1208                            sb.append(HttpUtil.encodeURL("blockingAction"));
1209                    }
1210                    else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
1211                            sb.append(HttpUtil.encodeURL("render"));
1212                    }
1213                    else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1214                            sb.append(HttpUtil.encodeURL("resource"));
1215                    }
1216    
1217                    sb.append(StringPool.AMPERSAND);
1218    
1219                    if (_windowStateString != null) {
1220                            sb.append("wsrp-windowState");
1221                            sb.append(StringPool.EQUAL);
1222                            sb.append(HttpUtil.encodeURL("wsrp:" + _windowStateString));
1223                            sb.append(StringPool.AMPERSAND);
1224                    }
1225    
1226                    if (_portletModeString != null) {
1227                            sb.append("wsrp-mode");
1228                            sb.append(StringPool.EQUAL);
1229                            sb.append(HttpUtil.encodeURL("wsrp:" + _portletModeString));
1230                            sb.append(StringPool.AMPERSAND);
1231                    }
1232    
1233                    if (_resourceID != null) {
1234                            sb.append("wsrp-resourceID");
1235                            sb.append(StringPool.EQUAL);
1236                            sb.append(HttpUtil.encodeURL(_resourceID));
1237                            sb.append(StringPool.AMPERSAND);
1238                    }
1239    
1240                    if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1241                            sb.append("wsrp-resourceCacheability");
1242                            sb.append(StringPool.EQUAL);
1243                            sb.append(HttpUtil.encodeURL(_cacheability));
1244                            sb.append(StringPool.AMPERSAND);
1245                    }
1246    
1247                    if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1248                            if (_anchor && (_windowStateString != null) &&
1249                                    !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1250                                    !_windowStateString.equals(
1251                                            LiferayWindowState.EXCLUSIVE.toString()) &&
1252                                    !_windowStateString.equals(
1253                                            LiferayWindowState.POP_UP.toString())) {
1254    
1255                                    sb.append("wsrp-fragmentID");
1256                                    sb.append(StringPool.EQUAL);
1257                                    sb.append("#p_");
1258                                    sb.append(HttpUtil.encodeURL(_portletId));
1259                                    sb.append(StringPool.AMPERSAND);
1260                            }
1261                    }
1262    
1263                    if (_copyCurrentRenderParameters) {
1264                            mergeRenderParameters();
1265                    }
1266    
1267                    StringBundler parameterSb = new StringBundler();
1268    
1269                    int previousSbIndex = sb.index();
1270    
1271                    for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1272                            String name = entry.getKey();
1273                            String[] values = entry.getValue();
1274    
1275                            if (isParameterIncludedInPath(name)) {
1276                                    continue;
1277                            }
1278    
1279                            String publicRenderParameterName = getPublicRenderParameterName(
1280                                    name);
1281    
1282                            if (Validator.isNotNull(publicRenderParameterName)) {
1283                                    name = publicRenderParameterName;
1284                            }
1285    
1286                            name = HttpUtil.encodeURL(prependNamespace(name));
1287    
1288                            for (String value : values) {
1289                                    parameterSb.append(name);
1290                                    parameterSb.append(StringPool.EQUAL);
1291                                    parameterSb.append(HttpUtil.encodeURL(value));
1292                                    parameterSb.append(StringPool.AMPERSAND);
1293                            }
1294                    }
1295    
1296                    if (sb.index() > previousSbIndex) {
1297                            sb.setIndex(sb.index() - 1);
1298                    }
1299    
1300                    sb.append("wsrp-navigationalState");
1301                    sb.append(StringPool.EQUAL);
1302    
1303                    byte[] parameterBytes = null;
1304    
1305                    try {
1306                            String parameterString = parameterSb.toString();
1307    
1308                            parameterBytes = parameterString.getBytes(StringPool.UTF8);
1309                    }
1310                    catch (UnsupportedEncodingException uee) {
1311                            if (_log.isWarnEnabled()) {
1312                                    _log.warn(uee, uee);
1313                            }
1314                    }
1315    
1316                    String navigationalState = Base64.toURLSafe(
1317                            Base64.encode(parameterBytes));
1318    
1319                    sb.append(navigationalState);
1320    
1321                    sb.append("/wsrp_rewrite");
1322    
1323                    return sb.toString();
1324            }
1325    
1326            protected String getPublicRenderParameterName(String name) {
1327                    Portlet portlet = getPortlet();
1328    
1329                    String publicRenderParameterName = null;
1330    
1331                    if (portlet != null) {
1332                            PublicRenderParameter publicRenderParameter =
1333                                    portlet.getPublicRenderParameter(name);
1334    
1335                            if (publicRenderParameter != null) {
1336                                    QName qName = publicRenderParameter.getQName();
1337    
1338                                    publicRenderParameterName =
1339                                            PortletQNameUtil.getPublicRenderParameterName(qName);
1340                            }
1341                    }
1342    
1343                    return publicRenderParameterName;
1344            }
1345    
1346            protected boolean isBlankValue(String[] value) {
1347                    if ((value != null) && (value.length == 1) &&
1348                            value[0].equals(StringPool.BLANK)) {
1349    
1350                            return true;
1351                    }
1352                    else {
1353                            return false;
1354                    }
1355            }
1356    
1357            protected void mergeRenderParameters() {
1358                    String namespace = getNamespace();
1359    
1360                    Layout layout = getLayout();
1361    
1362                    Map<String, String[]> renderParameters = RenderParametersPool.get(
1363                            _request, layout.getPlid(), getPortlet().getPortletId());
1364    
1365                    for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1366                            String name = entry.getKey();
1367    
1368                            if (name.contains(namespace)) {
1369                                    name = name.substring(namespace.length());
1370                            }
1371    
1372                            if (!_lifecycle.equals(PortletRequest.RESOURCE_PHASE) &&
1373                                    (_removedParameterNames != null) &&
1374                                    _removedParameterNames.contains(name)) {
1375    
1376                                    continue;
1377                            }
1378    
1379                            String[] oldValues = entry.getValue();
1380                            String[] newValues = _params.get(name);
1381    
1382                            if (newValues == null) {
1383                                    _params.put(name, oldValues);
1384                            }
1385                            else if (isBlankValue(newValues)) {
1386                                    _params.remove(name);
1387                            }
1388                            else {
1389                                    newValues = ArrayUtil.append(newValues, oldValues);
1390    
1391                                    _params.put(name, newValues);
1392                            }
1393                    }
1394            }
1395    
1396            protected String prependNamespace(String name) {
1397                    String namespace = getNamespace();
1398    
1399                    if (!PortalUtil.isReservedParameter(name) &&
1400                            !name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) &&
1401                            !name.startsWith(namespace)) {
1402    
1403                            return namespace.concat(name);
1404                    }
1405                    else {
1406                            return name;
1407                    }
1408            }
1409    
1410            protected String processValue(Key key, int value) {
1411                    return processValue(key, String.valueOf(value));
1412            }
1413    
1414            protected String processValue(Key key, long value) {
1415                    return processValue(key, String.valueOf(value));
1416            }
1417    
1418            protected String processValue(Key key, String value) {
1419                    if (key == null) {
1420                            return HttpUtil.encodeURL(value);
1421                    }
1422    
1423                    try {
1424                            return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1425                    }
1426                    catch (EncryptorException ee) {
1427                            return value;
1428                    }
1429            }
1430    
1431            private static final Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1432    
1433            private boolean _anchor = true;
1434            private String _cacheability = ResourceURL.PAGE;
1435            private String _controlPanelCategory;
1436            private boolean _copyCurrentRenderParameters;
1437            private long _doAsGroupId;
1438            private long _doAsUserId;
1439            private String _doAsUserLanguageId;
1440            private boolean _encrypt;
1441            private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1442            private Layout _layout;
1443            private String _layoutFriendlyURL;
1444            private String _lifecycle;
1445            private String _namespace;
1446            private final Set<String> _parametersIncludedInPath;
1447            private Map<String, String[]> _params;
1448            private long _plid;
1449            private Portlet _portlet;
1450            private String _portletId;
1451            private String _portletModeString;
1452            private final PortletRequest _portletRequest;
1453            private long _refererGroupId;
1454            private long _refererPlid;
1455            private Set<String> _removedParameterNames;
1456            private final Map<String, String[]> _removePublicRenderParameters;
1457            private final HttpServletRequest _request;
1458            private Map<String, String> _reservedParameters;
1459            private String _resourceID;
1460            private boolean _secure;
1461            private String _toString;
1462            private boolean _windowStateRestoreCurrentView;
1463            private String _windowStateString;
1464            private final boolean _wsrp;
1465    
1466            private class ToStringPrivilegedAction implements PrivilegedAction<String> {
1467    
1468                    @Override
1469                    public String run() {
1470                            if (_wsrp) {
1471                                    return generateWSRPToString();
1472                            }
1473    
1474                            return generateToString();
1475                    }
1476    
1477            }
1478    
1479    }