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