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.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 && _params.containsKey(name)) {
493                            String[] oldValues = _params.get(name);
494    
495                            String[] newValues = ArrayUtil.append(oldValues, values);
496    
497                            _params.put(name, newValues);
498                    }
499                    else {
500                            _params.put(name, values);
501                    }
502    
503                    clearCache();
504            }
505    
506            public void setParameters(Map<String, String[]> params) {
507                    if (params == null) {
508                            throw new IllegalArgumentException();
509                    }
510                    else {
511                            Map<String, String[]> newParams =
512                                    new LinkedHashMap<String, String[]>();
513    
514                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
515                                    try {
516                                            String key = entry.getKey();
517                                            String[] value = entry.getValue();
518    
519                                            if (key == null) {
520                                                    throw new IllegalArgumentException();
521                                            }
522                                            else if (value == null) {
523                                                    throw new IllegalArgumentException();
524                                            }
525    
526                                            newParams.put(key, value);
527                                    }
528                                    catch (ClassCastException cce) {
529                                            throw new IllegalArgumentException(cce);
530                                    }
531                            }
532    
533                            _params = newParams;
534                    }
535    
536                    clearCache();
537            }
538    
539            public void setPlid(long plid) {
540                    _plid = plid;
541    
542                    clearCache();
543            }
544    
545            public void setPortletId(String portletId) {
546                    _portletId = portletId;
547    
548                    clearCache();
549            }
550    
551            public void setPortletMode(PortletMode portletMode)
552                    throws PortletModeException {
553    
554                    if (_portletRequest != null) {
555                            if (!getPortlet().hasPortletMode(
556                                            _portletRequest.getResponseContentType(), portletMode)) {
557    
558                                    throw new PortletModeException(
559                                            portletMode.toString(), portletMode);
560                            }
561                    }
562    
563                    _portletMode = portletMode;
564    
565                    clearCache();
566            }
567    
568            public void setPortletMode(String portletMode) throws PortletModeException {
569                    setPortletMode(PortletModeFactory.getPortletMode(portletMode));
570            }
571    
572            public void setProperty(String key, String value) {
573                    if (key == null) {
574                            throw new IllegalArgumentException();
575                    }
576            }
577    
578            public void setRefererPlid(long refererPlid) {
579                    _refererPlid = refererPlid;
580    
581                    clearCache();
582            }
583    
584            public void setResourceID(String resourceID) {
585                    _resourceID = resourceID;
586            }
587    
588            public void setSecure(boolean secure) {
589                    _secure = secure;
590    
591                    clearCache();
592            }
593    
594            public void setWindowState(String windowState) throws WindowStateException {
595                    setWindowState(WindowStateFactory.getWindowState(windowState));
596            }
597    
598            public void setWindowState(WindowState windowState)
599                    throws WindowStateException {
600    
601                    if (_portletRequest != null) {
602                            if (!_portletRequest.isWindowStateAllowed(windowState)) {
603                                    throw new WindowStateException(
604                                            windowState.toString(), windowState);
605                            }
606                    }
607    
608                    if (LiferayWindowState.isWindowStatePreserved(
609                                    getWindowState(), windowState)) {
610    
611                            _windowState = windowState;
612                    }
613    
614                    clearCache();
615            }
616    
617            public String toString() {
618                    if (_toString != null) {
619                            return _toString;
620                    }
621    
622                    if (_wsrp) {
623                            _toString = generateWSRPToString();
624                    }
625                    else {
626                            _toString = generateToString();
627                    }
628    
629                    return _toString;
630            }
631    
632            public void write(Writer writer) throws IOException {
633                    write(writer, _escapeXml);
634            }
635    
636            public void write(Writer writer, boolean escapeXml) throws IOException {
637                    String toString = toString();
638    
639                    if (escapeXml && !_escapeXml) {
640                            toString = HtmlUtil.escape(toString);
641                    }
642    
643                    writer.write(toString);
644            }
645    
646            protected void addPortalAuthToken(StringBundler sb, Key key) {
647                    if (!PropsValues.AUTH_TOKEN_CHECK_ENABLED ||
648                            !_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
649    
650                            return;
651                    }
652    
653                    sb.append("p_auth");
654                    sb.append(StringPool.EQUAL);
655                    sb.append(processValue(key, AuthTokenUtil.getToken(_request)));
656                    sb.append(StringPool.AMPERSAND);
657            }
658    
659            protected void addPortletAuthToken(StringBundler sb, Key key) {
660                    if (!PropsValues.PORTLET_ADD_DEFAULT_RESOURCE_CHECK_ENABLED) {
661                            return;
662                    }
663    
664                    HttpServletRequest request = PortalUtil.getOriginalServletRequest(
665                            _request);
666    
667                    String ppauth = ParamUtil.getString(request, "p_p_auth");
668    
669                    String actualPortletAuthenticationToken = AuthTokenUtil.getToken(
670                            _request, _plid, _portletId);
671    
672                    if (Validator.isNotNull(ppauth) &&
673                            ppauth.equals(actualPortletAuthenticationToken)) {
674    
675                            sb.append("p_p_auth");
676                            sb.append(StringPool.EQUAL);
677                            sb.append(processValue(key, ppauth));
678                            sb.append(StringPool.AMPERSAND);
679    
680                            return;
681                    }
682    
683                    Portlet portlet = (Portlet)_request.getAttribute(
684                            WebKeys.RENDER_PORTLET);
685    
686                    if (portlet == null) {
687                            return;
688                    }
689    
690                    if (portlet.getPortletId().equals(_portletId) ||
691                            !_portlet.isAddDefaultResource() ||
692                            portlet.getPortletId().equals(PortletKeys.CONTROL_PANEL_MENU)) {
693    
694                            return;
695                    }
696    
697                    sb.append("p_p_auth");
698                    sb.append(StringPool.EQUAL);
699                    sb.append(processValue(key, actualPortletAuthenticationToken));
700                    sb.append(StringPool.AMPERSAND);
701            }
702    
703            protected void clearCache() {
704                    _reservedParameters = null;
705                    _toString = null;
706            }
707    
708            protected String generateToString() {
709                    StringBundler sb = new StringBundler(32);
710    
711                    ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
712                            WebKeys.THEME_DISPLAY);
713    
714                    Portlet portlet = getPortlet();
715    
716                    String portalURL = null;
717    
718                    if (themeDisplay.isFacebook()) {
719                            portalURL =
720                                    FacebookUtil.FACEBOOK_APPS_URL +
721                                            themeDisplay.getFacebookCanvasPageURL();
722                    }
723                    else {
724                            portalURL = PortalUtil.getPortalURL(_request, _secure);
725                    }
726    
727                    try {
728                            if (_layoutFriendlyURL == null) {
729                                    Layout layout = getLayout();
730    
731                                    if (layout != null) {
732                                            _layoutFriendlyURL = GetterUtil.getString(
733                                                    PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
734                                    }
735                            }
736                    }
737                    catch (Exception e) {
738                            _log.error(e);
739                    }
740    
741                    Key key = null;
742    
743                    try {
744                            if (_encrypt) {
745                                    Company company = PortalUtil.getCompany(_request);
746    
747                                    key = company.getKeyObj();
748                            }
749                    }
750                    catch (Exception e) {
751                            _log.error(e);
752                    }
753    
754                    if (Validator.isNull(_layoutFriendlyURL)) {
755                            sb.append(portalURL);
756                            sb.append(themeDisplay.getPathMain());
757                            sb.append("/portal/layout?");
758    
759                            addPortalAuthToken(sb, key);
760    
761                            sb.append("p_l_id");
762                            sb.append(StringPool.EQUAL);
763                            sb.append(processValue(key, _plid));
764                            sb.append(StringPool.AMPERSAND);
765                    }
766                    else {
767                            if (themeDisplay.isFacebook()) {
768                                    sb.append(portalURL);
769                            }
770                            else {
771    
772                                    // A virtual host URL will contain the complete path. Do not
773                                    // append the portal URL if the virtual host URL starts with
774                                    // "http://" or "https://".
775    
776                                    if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
777                                            !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
778    
779                                            sb.append(portalURL);
780                                    }
781    
782                                    sb.append(_layoutFriendlyURL);
783                            }
784    
785                            String friendlyURLPath = getPortletFriendlyURLPath();
786    
787                            if (Validator.isNotNull(friendlyURLPath)) {
788                                    if (themeDisplay.isFacebook()) {
789                                            int pos = friendlyURLPath.indexOf(StringPool.SLASH, 1);
790    
791                                            if (pos != -1) {
792                                                    sb.append(friendlyURLPath.substring(pos));
793                                            }
794                                            else {
795                                                    sb.append(friendlyURLPath);
796                                            }
797                                    }
798                                    else {
799                                            sb.append("/-");
800                                            sb.append(friendlyURLPath);
801                                    }
802                            }
803    
804                            sb.append(StringPool.QUESTION);
805    
806                            addPortalAuthToken(sb, key);
807                    }
808    
809                    addPortletAuthToken(sb, key);
810    
811                    for (Map.Entry<String, String> entry :
812                                    getReservedParameterMap().entrySet()) {
813    
814                            String name = entry.getKey();
815    
816                            if (!isParameterIncludedInPath(name)) {
817                                    sb.append(name);
818                                    sb.append(StringPool.EQUAL);
819                                    sb.append(processValue(key, entry.getValue()));
820                                    sb.append(StringPool.AMPERSAND);
821                            }
822                    }
823    
824                    if (_doAsUserId > 0) {
825                            try {
826                                    Company company = PortalUtil.getCompany(_request);
827    
828                                    sb.append("doAsUserId");
829                                    sb.append(StringPool.EQUAL);
830                                    sb.append(processValue(company.getKeyObj(), _doAsUserId));
831                                    sb.append(StringPool.AMPERSAND);
832                            }
833                            catch (Exception e) {
834                                    _log.error(e);
835                            }
836                    }
837                    else {
838                            String doAsUserId = themeDisplay.getDoAsUserId();
839    
840                            if (Validator.isNotNull(doAsUserId)) {
841                                    sb.append("doAsUserId");
842                                    sb.append(StringPool.EQUAL);
843                                    sb.append(processValue(key, doAsUserId));
844                                    sb.append(StringPool.AMPERSAND);
845                            }
846                    }
847    
848                    String doAsUserLanguageId = _doAsUserLanguageId;
849    
850                    if (Validator.isNull(doAsUserLanguageId)) {
851                            doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
852                    }
853    
854                    if (Validator.isNotNull(doAsUserLanguageId)) {
855                            sb.append("doAsUserLanguageId");
856                            sb.append(StringPool.EQUAL);
857                            sb.append(processValue(key, doAsUserLanguageId));
858                            sb.append(StringPool.AMPERSAND);
859                    }
860    
861                    long doAsGroupId = _doAsGroupId;
862    
863                    if (doAsGroupId <= 0) {
864                            doAsGroupId = themeDisplay.getDoAsGroupId();
865                    }
866    
867                    if (doAsGroupId > 0) {
868                            sb.append("doAsGroupId");
869                            sb.append(StringPool.EQUAL);
870                            sb.append(processValue(key, doAsGroupId));
871                            sb.append(StringPool.AMPERSAND);
872                    }
873    
874                    long refererPlid = _refererPlid;
875    
876                    if (refererPlid <= 0) {
877                            refererPlid = themeDisplay.getRefererPlid();
878                    }
879    
880                    if (refererPlid > 0) {
881                            sb.append("refererPlid");
882                            sb.append(StringPool.EQUAL);
883                            sb.append(processValue(key, refererPlid));
884                            sb.append(StringPool.AMPERSAND);
885                    }
886    
887                    Iterator<Map.Entry<String, String[]>> itr =
888                            _removePublicRenderParameters.entrySet().iterator();
889    
890                    while (itr.hasNext()) {
891                            String lastString = sb.stringAt(sb.index() - 1);
892    
893                            if (lastString.charAt(lastString.length() - 1) !=
894                                            CharPool.AMPERSAND) {
895    
896                                    sb.append(StringPool.AMPERSAND);
897                            }
898    
899                            Map.Entry<String, String[]> entry = itr.next();
900    
901                            sb.append(entry.getKey());
902                            sb.append(StringPool.EQUAL);
903                            sb.append(processValue(key, entry.getValue()[0]));
904                            sb.append(StringPool.AMPERSAND);
905                    }
906    
907                    if (_copyCurrentRenderParameters) {
908                            Enumeration<String> enu = _request.getParameterNames();
909    
910                            while (enu.hasMoreElements()) {
911                                    String name = enu.nextElement();
912    
913                                    String[] oldValues = _request.getParameterValues(name);
914                                    String[] newValues = _params.get(name);
915    
916                                    if (newValues == null) {
917                                            _params.put(name, oldValues);
918                                    }
919                                    else if (isBlankValue(newValues)) {
920                                            _params.remove(name);
921                                    }
922                                    else {
923                                            newValues = ArrayUtil.append(newValues, oldValues);
924    
925                                            _params.put(name, newValues);
926                                    }
927                            }
928                    }
929    
930                    itr = _params.entrySet().iterator();
931    
932                    while (itr.hasNext()) {
933                            Map.Entry<String, String[]> entry = itr.next();
934    
935                            String name = entry.getKey();
936                            String[] values = entry.getValue();
937    
938                            String identifier = null;
939    
940                            if (portlet != null) {
941                                    PublicRenderParameter publicRenderParameter =
942                                            portlet.getPublicRenderParameter(name);
943    
944                                    if (publicRenderParameter != null) {
945                                            QName qName = publicRenderParameter.getQName();
946    
947                                            if (_copyCurrentPublicRenderParameters) {
948                                                    String[] oldValues = _request.getParameterValues(name);
949    
950                                                    if (oldValues != null) {
951                                                            if (values == null) {
952                                                                    values = oldValues;
953                                                            }
954                                                            else {
955                                                                    values = ArrayUtil.append(values, oldValues);
956                                                            }
957                                                    }
958                                            }
959    
960                                            identifier = name;
961    
962                                            name = PortletQNameUtil.getPublicRenderParameterName(qName);
963    
964                                            PortletQNameUtil.setPublicRenderParameterIdentifier(
965                                                    name, identifier);
966                                    }
967                            }
968    
969                            // LEP-7495
970    
971                            //if (isBlankValue(values)) {
972                            //        continue;
973                            //}
974    
975                            for (int i = 0; i < values.length; i++) {
976                                    String parameterName = name;
977    
978                                    if (identifier != null) {
979                                            parameterName = identifier;
980                                    }
981    
982                                    if (isParameterIncludedInPath(parameterName)) {
983                                            continue;
984                                    }
985    
986                                    if (!PortalUtil.isReservedParameter(name) &&
987                                            !name.startsWith(
988                                                    PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
989    
990                                            sb.append(getNamespace());
991                                    }
992    
993                                    sb.append(name);
994                                    sb.append(StringPool.EQUAL);
995                                    sb.append(processValue(key, values[i]));
996    
997                                    if ((i + 1 < values.length) || itr.hasNext()) {
998                                            sb.append(StringPool.AMPERSAND);
999                                    }
1000                            }
1001                    }
1002    
1003                    if (_encrypt) {
1004                            sb.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
1005                    }
1006    
1007                    if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1008                            if (_anchor && (_windowState != null) &&
1009                                    (!_windowState.equals(WindowState.MAXIMIZED)) &&
1010                                    (!_windowState.equals(LiferayWindowState.EXCLUSIVE)) &&
1011                                    (!_windowState.equals(LiferayWindowState.POP_UP))) {
1012    
1013                                    String lastString = sb.stringAt(sb.index() - 1);
1014    
1015                                    if (lastString.charAt(lastString.length() - 1) !=
1016                                                    CharPool.AMPERSAND) {
1017    
1018                                            sb.append(StringPool.AMPERSAND);
1019                                    }
1020    
1021                                    sb.append("#p_");
1022                                    sb.append(_portletId);
1023                            }
1024                    }
1025    
1026                    String result = sb.toString();
1027    
1028                    if (result.endsWith(StringPool.AMPERSAND) ||
1029                            result.endsWith(StringPool.QUESTION)) {
1030    
1031                            result = result.substring(0, result.length() - 1);
1032                    }
1033    
1034                    if (themeDisplay.isFacebook()) {
1035    
1036                            // Facebook requires the path portion of the URL to end with a slash
1037    
1038                            int pos = result.indexOf(StringPool.QUESTION);
1039    
1040                            if (pos == -1) {
1041                                    if (!result.endsWith(StringPool.SLASH)) {
1042                                            result += StringPool.SLASH;
1043                                    }
1044                            }
1045                            else {
1046                                    String path = result.substring(0, pos);
1047    
1048                                    if (!result.endsWith(StringPool.SLASH)) {
1049                                            result = path + StringPool.SLASH + result.substring(pos);
1050                                    }
1051                            }
1052                    }
1053                    else if (!CookieKeys.hasSessionId(_request)) {
1054                            result = PortalUtil.getURLWithSessionId(
1055                                    result, _request.getSession().getId());
1056                    }
1057    
1058                    if (_escapeXml) {
1059                            result = HtmlUtil.escape(result);
1060                    }
1061    
1062                    return result;
1063            }
1064    
1065            protected String generateWSRPToString() {
1066                    StringBundler sb = new StringBundler("wsrp_rewrite?");
1067    
1068                    Portlet portlet = getPortlet();
1069    
1070                    Key key = null;
1071    
1072                    try {
1073                            if (_encrypt) {
1074                                    Company company = PortalUtil.getCompany(_request);
1075    
1076                                    key = company.getKeyObj();
1077                            }
1078                    }
1079                    catch (Exception e) {
1080                            _log.error(e);
1081                    }
1082    
1083                    sb.append("wsrp-urlType");
1084                    sb.append(StringPool.EQUAL);
1085    
1086                    if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
1087                            sb.append(processValue(key, "blockingAction"));
1088                    }
1089                    else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
1090                            sb.append(processValue(key, "render"));
1091                    }
1092                    else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1093                            sb.append(processValue(key, "resource"));
1094                    }
1095    
1096                    sb.append(StringPool.AMPERSAND);
1097    
1098                    if (_windowState != null) {
1099                            sb.append("wsrp-windowState");
1100                            sb.append(StringPool.EQUAL);
1101                            sb.append(processValue(key, "wsrp:" + _windowState.toString()));
1102                            sb.append(StringPool.AMPERSAND);
1103                    }
1104    
1105                    if (_portletMode != null) {
1106                            sb.append("wsrp-mode");
1107                            sb.append(StringPool.EQUAL);
1108                            sb.append(processValue(key, "wsrp:" + _portletMode.toString()));
1109                            sb.append(StringPool.AMPERSAND);
1110                    }
1111    
1112                    if (_resourceID != null) {
1113                            sb.append("wsrp-resourceID");
1114                            sb.append(StringPool.EQUAL);
1115                            sb.append(processValue(key, _resourceID));
1116                            sb.append(StringPool.AMPERSAND);
1117                    }
1118    
1119                    if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1120                            sb.append("wsrp-resourceCacheability");
1121                            sb.append(StringPool.EQUAL);
1122                            sb.append(processValue(key, _cacheability));
1123                            sb.append(StringPool.AMPERSAND);
1124                    }
1125    
1126                    if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1127                            if (_anchor && (_windowState != null) &&
1128                                    (!_windowState.equals(WindowState.MAXIMIZED)) &&
1129                                    (!_windowState.equals(LiferayWindowState.EXCLUSIVE)) &&
1130                                    (!_windowState.equals(LiferayWindowState.POP_UP))) {
1131    
1132                                    sb.append("wsrp-fragmentID");
1133                                    sb.append(StringPool.EQUAL);
1134                                    sb.append("#p_");
1135                                    sb.append(_portletId);
1136                                    sb.append(StringPool.AMPERSAND);
1137                            }
1138                    }
1139    
1140                    if (_copyCurrentRenderParameters) {
1141                            Enumeration<String> enu = _request.getParameterNames();
1142    
1143                            while (enu.hasMoreElements()) {
1144                                    String name = enu.nextElement();
1145    
1146                                    String[] oldValues = _request.getParameterValues(name);
1147                                    String[] newValues = _params.get(name);
1148    
1149                                    if (newValues == null) {
1150                                            _params.put(name, oldValues);
1151                                    }
1152                                    else if (isBlankValue(newValues)) {
1153                                            _params.remove(name);
1154                                    }
1155                                    else {
1156                                            newValues = ArrayUtil.append(newValues, oldValues);
1157    
1158                                            _params.put(name, newValues);
1159                                    }
1160                            }
1161                    }
1162    
1163                    StringBundler parameterSb = new StringBundler();
1164    
1165                    Iterator<Map.Entry<String, String[]>> itr =
1166                            _params.entrySet().iterator();
1167    
1168                    while (itr.hasNext()) {
1169                            Map.Entry<String, String[]> entry = itr.next();
1170    
1171                            String name = entry.getKey();
1172                            String[] values = entry.getValue();
1173    
1174                            String identifier = null;
1175    
1176                            if (portlet != null) {
1177                                    PublicRenderParameter publicRenderParameter =
1178                                            portlet.getPublicRenderParameter(name);
1179    
1180                                    if (publicRenderParameter != null) {
1181                                            QName qName = publicRenderParameter.getQName();
1182    
1183                                            if (_copyCurrentPublicRenderParameters) {
1184                                                    String[] oldValues = _request.getParameterValues(name);
1185    
1186                                                    if (oldValues != null) {
1187                                                            if (values == null) {
1188                                                                    values = oldValues;
1189                                                            }
1190                                                            else {
1191                                                                    values = ArrayUtil.append(values, oldValues);
1192                                                            }
1193                                                    }
1194                                            }
1195    
1196                                            identifier = name;
1197    
1198                                            name = PortletQNameUtil.getPublicRenderParameterName(qName);
1199    
1200                                            PortletQNameUtil.setPublicRenderParameterIdentifier(
1201                                                    name, identifier);
1202                                    }
1203                            }
1204    
1205                            for (int i = 0; i < values.length; i++) {
1206                                    String parameterName = name;
1207    
1208                                    if (identifier != null) {
1209                                            parameterName = identifier;
1210                                    }
1211    
1212                                    if (isParameterIncludedInPath(parameterName)) {
1213                                            continue;
1214                                    }
1215    
1216                                    if (!PortalUtil.isReservedParameter(name) &&
1217                                            !name.startsWith(
1218                                                    PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
1219    
1220                                            parameterSb.append(getNamespace());
1221                                    }
1222    
1223                                    parameterSb.append(name);
1224                                    parameterSb.append(StringPool.EQUAL);
1225                                    parameterSb.append(processValue(key, values[i]));
1226    
1227                                    if ((i + 1 < values.length) || itr.hasNext()) {
1228                                            parameterSb.append(StringPool.AMPERSAND);
1229                                    }
1230                            }
1231                    }
1232    
1233                    if (_encrypt) {
1234                            parameterSb.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
1235                    }
1236    
1237                    sb.append("wsrp-navigationalState");
1238                    sb.append(StringPool.EQUAL);
1239                    sb.append(HttpUtil.encodeURL(parameterSb.toString()));
1240    
1241                    sb.append("/wsrp_rewrite");
1242    
1243                    return sb.toString();
1244            }
1245    
1246            protected boolean isBlankValue(String[] value) {
1247                    if ((value != null) && (value.length == 1) &&
1248                            (value[0].equals(StringPool.BLANK))) {
1249    
1250                            return true;
1251                    }
1252                    else {
1253                            return false;
1254                    }
1255            }
1256    
1257            protected String processValue(Key key, int value) {
1258                    return processValue(key, String.valueOf(value));
1259            }
1260    
1261            protected String processValue(Key key, long value) {
1262                    return processValue(key, String.valueOf(value));
1263            }
1264    
1265            protected String processValue(Key key, String value) {
1266                    if (key == null) {
1267                            return HttpUtil.encodeURL(value);
1268                    }
1269                    else {
1270                            try {
1271                                    return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1272                            }
1273                            catch (EncryptorException ee) {
1274                                    return value;
1275                            }
1276                    }
1277            }
1278    
1279            private static Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1280    
1281            private boolean _anchor = true;
1282            private String _cacheability = ResourceURL.PAGE;
1283            private boolean _copyCurrentPublicRenderParameters;
1284            private boolean _copyCurrentRenderParameters;
1285            private long _doAsGroupId;
1286            private long _doAsUserId;
1287            private String _doAsUserLanguageId;
1288            private boolean _encrypt;
1289            private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1290            private Layout _layout;
1291            private String _layoutFriendlyURL;
1292            private String _lifecycle;
1293            private String _namespace;
1294            private Set<String> _parametersIncludedInPath;
1295            private Map<String, String[]> _params;
1296            private long _plid;
1297            private Portlet _portlet;
1298            private String _portletId;
1299            private PortletMode _portletMode;
1300            private PortletRequest _portletRequest;
1301            private long _refererPlid;
1302            private Map<String, String[]> _removePublicRenderParameters;
1303            private HttpServletRequest _request;
1304            private Map<String, String> _reservedParameters;
1305            private String _resourceID;
1306            private boolean _secure;
1307            private String _toString;
1308            private WindowState _windowState;
1309            private boolean _wsrp;
1310    
1311    }