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