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