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