1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions 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.Http;
36  import com.liferay.portal.kernel.util.HttpUtil;
37  import com.liferay.portal.kernel.util.MapUtil;
38  import com.liferay.portal.kernel.util.StringPool;
39  import com.liferay.portal.kernel.util.Validator;
40  import com.liferay.portal.kernel.xml.QName;
41  import com.liferay.portal.model.Company;
42  import com.liferay.portal.model.Layout;
43  import com.liferay.portal.model.Portlet;
44  import com.liferay.portal.model.PortletApp;
45  import com.liferay.portal.model.PublicRenderParameter;
46  import com.liferay.portal.service.LayoutLocalServiceUtil;
47  import com.liferay.portal.service.PortletLocalServiceUtil;
48  import com.liferay.portal.theme.PortletDisplay;
49  import com.liferay.portal.theme.ThemeDisplay;
50  import com.liferay.portal.util.CookieKeys;
51  import com.liferay.portal.util.PortalUtil;
52  import com.liferay.portal.util.PropsValues;
53  import com.liferay.portal.util.WebKeys;
54  import com.liferay.portlet.social.util.FacebookUtil;
55  import com.liferay.util.Encryptor;
56  import com.liferay.util.EncryptorException;
57  
58  import com.sun.portal.container.ChannelURLType;
59  import com.sun.portal.portletcontainer.common.URLHelper;
60  
61  import java.io.IOException;
62  import java.io.Serializable;
63  import java.io.Writer;
64  
65  import java.security.Key;
66  
67  import java.util.Enumeration;
68  import java.util.Iterator;
69  import java.util.LinkedHashMap;
70  import java.util.LinkedHashSet;
71  import java.util.Map;
72  import java.util.Set;
73  
74  import javax.portlet.PortletMode;
75  import javax.portlet.PortletModeException;
76  import javax.portlet.PortletRequest;
77  import javax.portlet.PortletURL;
78  import javax.portlet.ResourceRequest;
79  import javax.portlet.ResourceURL;
80  import javax.portlet.WindowState;
81  import javax.portlet.WindowStateException;
82  
83  import javax.servlet.http.HttpServletRequest;
84  
85  /**
86   * <a href="PortletURLImpl.java.html"><b><i>View Source</i></b></a>
87   *
88   * @author Brian Wing Shun Chan
89   * @author Jorge Ferrer
90   *
91   */
92  public class PortletURLImpl
93      implements LiferayPortletURL, PortletURL, ResourceURL, Serializable {
94  
95      public PortletURLImpl(
96          PortletRequestImpl portletRequestImpl, String portletId, long plid,
97          String lifecycle) {
98  
99          this(
100             portletRequestImpl.getHttpServletRequest(), portletId, plid,
101             lifecycle);
102 
103         _portletRequest = portletRequestImpl;
104     }
105 
106     public PortletURLImpl(
107         HttpServletRequest request, String portletId, long plid,
108         String lifecycle) {
109 
110         _request = request;
111         _portletId = portletId;
112         _plid = plid;
113         _lifecycle = lifecycle;
114         _parametersIncludedInPath = new LinkedHashSet<String>();
115         _params = new LinkedHashMap<String, String[]>();
116         _secure = request.isSecure();
117 
118         Portlet portlet = getPortlet();
119 
120         if (portlet != null) {
121             PortletApp portletApp = portlet.getPortletApp();
122 
123             _escapeXml = MapUtil.getBoolean(
124                 portletApp.getContainerRuntimeOptions(),
125                 PortletConfigImpl.RUNTIME_OPTION_ESCAPE_XML,
126                 PropsValues.PORTLET_URL_ESCAPE_XML);
127         }
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 String getNamespace() {
149         if (_namespace == null) {
150             _namespace = PortalUtil.getPortletNamespace(_portletId);
151         }
152 
153         return _namespace;
154     }
155 
156     public Layout getLayout() {
157         if (_layout == null) {
158             try {
159                 if (_plid > 0) {
160                     _layout = LayoutLocalServiceUtil.getLayout(_plid);
161                 }
162             }
163             catch (Exception e) {
164                 if (_log.isWarnEnabled()) {
165                     _log.warn("Layout cannot be found for " + _plid);
166                 }
167             }
168         }
169 
170         return _layout;
171     }
172 
173     public String getLayoutFriendlyURL() {
174         return _layoutFriendlyURL;
175     }
176 
177     public String getLifecycle() {
178         return _lifecycle;
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 setDoAsUserId(long doAsUserId) {
362         _doAsUserId = doAsUserId;
363 
364         // Clear cache
365 
366         _toString = null;
367     }
368 
369     public void setDoAsUserLanguageId(String doAsUserLanguageId) {
370         _doAsUserLanguageId = doAsUserLanguageId;
371 
372         // Clear cache
373 
374         _toString = null;
375     }
376 
377     public void setDoAsGroupId(long doAsGroupId) {
378         _doAsGroupId = doAsGroupId;
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(String portletMode) throws PortletModeException {
504         setPortletMode(PortletModeFactory.getPortletMode(portletMode));
505     }
506 
507     public void setPortletMode(PortletMode portletMode)
508         throws PortletModeException {
509 
510         if (_portletRequest != null) {
511             if (!getPortlet().hasPortletMode(
512                     _portletRequest.getResponseContentType(), portletMode)) {
513 
514                 throw new PortletModeException(
515                     portletMode.toString(), portletMode);
516             }
517         }
518 
519         _portletMode = portletMode;
520 
521         // Clear cache
522 
523         _toString = null;
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 void setURLType(ChannelURLType urlType) {
578         _urlType = urlType;
579 
580         // Clear cache
581 
582         _toString = null;
583     }
584 
585     public String toString() {
586         if (_toString != null) {
587             return _toString;
588         }
589 
590         _toString = generateToString();
591 
592         return _toString;
593     }
594 
595     public void write(Writer writer) throws IOException {
596         write(writer, _escapeXml);
597     }
598 
599     public void write(Writer writer, boolean escapeXml) throws IOException {
600         String toString = toString();
601 
602         if (escapeXml && !_escapeXml) {
603             toString = URLHelper.escapeURL(toString);
604         }
605 
606         writer.write(toString());
607     }
608 
609     protected String generateToString() {
610         StringBuilder sb = new StringBuilder();
611 
612         ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
613             WebKeys.THEME_DISPLAY);
614 
615         PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
616 
617         Portlet portlet = getPortlet();
618 
619         String portalURL = null;
620 
621         if (themeDisplay.isFacebook()) {
622             portalURL =
623                 FacebookUtil.FACEBOOK_APPS_URL +
624                     themeDisplay.getFacebookCanvasPageURL();
625         }
626         else {
627             portalURL = PortalUtil.getPortalURL(_request, _secure);
628         }
629 
630         try {
631             if (_layoutFriendlyURL == null) {
632                 Layout layout = getLayout();
633 
634                 if (layout != null) {
635                     _layoutFriendlyURL = GetterUtil.getString(
636                         PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
637                 }
638             }
639         }
640         catch (Exception e) {
641             _log.error(e);
642         }
643 
644         Key key = null;
645 
646         try {
647             if (_encrypt) {
648                 Company company = PortalUtil.getCompany(_request);
649 
650                 key = company.getKeyObj();
651             }
652         }
653         catch (Exception e) {
654             _log.error(e);
655         }
656 
657         if (Validator.isNull(_layoutFriendlyURL)) {
658             sb.append(portalURL);
659             sb.append(themeDisplay.getPathMain());
660             sb.append("/portal/layout?");
661 
662             sb.append("p_l_id");
663             sb.append(StringPool.EQUAL);
664             sb.append(processValue(key, _plid));
665             sb.append(StringPool.AMPERSAND);
666         }
667         else {
668 
669             // A virtual host URL will contain the complete path. Do not append
670             // the portal URL if the virtual host URL starts with "http://" or
671             // "https://".
672 
673             if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
674                 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
675 
676                 sb.append(portalURL);
677             }
678 
679             if (!themeDisplay.isFacebook()) {
680                 sb.append(_layoutFriendlyURL);
681             }
682 
683             String friendlyURLPath = getPortletFriendlyURLPath();
684 
685             if (Validator.isNotNull(friendlyURLPath)) {
686                 if (themeDisplay.isFacebook()) {
687                     int pos = friendlyURLPath.indexOf(StringPool.SLASH, 1);
688 
689                     if (pos != -1) {
690                         sb.append(friendlyURLPath.substring(pos));
691                     }
692                     else {
693                         sb.append(friendlyURLPath);
694                     }
695                 }
696                 else {
697                     sb.append("/-");
698                     sb.append(friendlyURLPath);
699                 }
700 
701                 if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
702                     addParameterIncludedInPath("p_p_lifecycle");
703                 }
704 
705                 //if ((_windowState != null) &&
706                 //  _windowState.equals(WindowState.MAXIMIZED)) {
707 
708                     addParameterIncludedInPath("p_p_state");
709                 //}
710 
711                 //if ((_portletMode != null) &&
712                 //  _portletMode.equals(PortletMode.VIEW)) {
713 
714                     addParameterIncludedInPath("p_p_mode");
715                 //}
716 
717                 addParameterIncludedInPath("p_p_col_id");
718                 addParameterIncludedInPath("p_p_col_pos");
719                 addParameterIncludedInPath("p_p_col_count");
720             }
721 
722             sb.append(StringPool.QUESTION);
723         }
724 
725         if (!isParameterIncludedInPath("p_p_id")) {
726             sb.append("p_p_id");
727             sb.append(StringPool.EQUAL);
728             sb.append(processValue(key, _portletId));
729             sb.append(StringPool.AMPERSAND);
730         }
731 
732         if (!isParameterIncludedInPath("p_p_lifecycle")) {
733             sb.append("p_p_lifecycle");
734             sb.append(StringPool.EQUAL);
735 
736             if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
737                 sb.append(processValue(key, "1"));
738             }
739             else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
740                 sb.append(processValue(key, "0"));
741             }
742             else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
743                 sb.append(processValue(key, "2"));
744             }
745 
746             sb.append(StringPool.AMPERSAND);
747         }
748 
749         if (PropsValues.PORTLET_CONTAINER_IMPL_SUN &&
750             !isParameterIncludedInPath("p_p_url_type")) {
751 
752             sb.append("p_p_url_type");
753             sb.append(StringPool.EQUAL);
754 
755             if (ChannelURLType.ACTION.equals(_urlType)) {
756                 sb.append(processValue(key, "1"));
757             }
758             else if (ChannelURLType.RENDER.equals(_urlType)) {
759                 sb.append(processValue(key, "0"));
760             }
761             else if (ChannelURLType.RESOURCE.equals(_urlType)) {
762                 sb.append(processValue(key, "2"));
763             }
764             else {
765                 sb.append(processValue(key, "0"));
766             }
767 
768             sb.append(StringPool.AMPERSAND);
769         }
770 
771         if (!isParameterIncludedInPath("p_p_state")) {
772             if (_windowState != null) {
773                 sb.append("p_p_state");
774                 sb.append(StringPool.EQUAL);
775                 sb.append(processValue(key, _windowState.toString()));
776                 sb.append(StringPool.AMPERSAND);
777             }
778         }
779 
780         if (!isParameterIncludedInPath("p_p_mode")) {
781             if (_portletMode != null) {
782                 sb.append("p_p_mode");
783                 sb.append(StringPool.EQUAL);
784                 sb.append(processValue(key, _portletMode.toString()));
785                 sb.append(StringPool.AMPERSAND);
786             }
787         }
788 
789         if (!isParameterIncludedInPath("p_p_resource_id")) {
790             if (_resourceID != null) {
791                 sb.append("p_p_resource_id");
792                 sb.append(StringPool.EQUAL);
793                 sb.append(processValue(key, _resourceID));
794                 sb.append(StringPool.AMPERSAND);
795             }
796         }
797 
798         if (!isParameterIncludedInPath("p_p_cacheability")) {
799             if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
800                 sb.append("p_p_cacheability");
801                 sb.append(StringPool.EQUAL);
802                 sb.append(processValue(key, _cacheability));
803                 sb.append(StringPool.AMPERSAND);
804             }
805         }
806 
807         if (!isParameterIncludedInPath("p_p_col_id")) {
808             if (Validator.isNotNull(portletDisplay.getColumnId())) {
809                 sb.append("p_p_col_id");
810                 sb.append(StringPool.EQUAL);
811                 sb.append(processValue(key, portletDisplay.getColumnId()));
812                 sb.append(StringPool.AMPERSAND);
813             }
814         }
815 
816         if (!isParameterIncludedInPath("p_p_col_pos")) {
817             if (portletDisplay.getColumnPos() > 0) {
818                 sb.append("p_p_col_pos");
819                 sb.append(StringPool.EQUAL);
820                 sb.append(processValue(key, portletDisplay.getColumnPos()));
821                 sb.append(StringPool.AMPERSAND);
822             }
823         }
824 
825         if (!isParameterIncludedInPath("p_p_col_count")) {
826             if (portletDisplay.getColumnCount() > 0) {
827                 sb.append("p_p_col_count");
828                 sb.append(StringPool.EQUAL);
829                 sb.append(processValue(key, portletDisplay.getColumnCount()));
830                 sb.append(StringPool.AMPERSAND);
831             }
832         }
833 
834         if (_doAsUserId > 0) {
835             try {
836                 Company company = PortalUtil.getCompany(_request);
837 
838                 sb.append("doAsUserId");
839                 sb.append(StringPool.EQUAL);
840                 sb.append(processValue(company.getKeyObj(), _doAsUserId));
841                 sb.append(StringPool.AMPERSAND);
842             }
843             catch (Exception e) {
844                 _log.error(e);
845             }
846         }
847         else {
848             String doAsUserId = themeDisplay.getDoAsUserId();
849 
850             if (Validator.isNotNull(doAsUserId)) {
851                 sb.append("doAsUserId");
852                 sb.append(StringPool.EQUAL);
853                 sb.append(processValue(key, doAsUserId));
854                 sb.append(StringPool.AMPERSAND);
855             }
856         }
857 
858         String doAsUserLanguageId = _doAsUserLanguageId;
859 
860         if (Validator.isNull(doAsUserLanguageId)) {
861             doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
862         }
863 
864         if (Validator.isNotNull(doAsUserLanguageId)) {
865             sb.append("doAsUserLanguageId");
866             sb.append(StringPool.EQUAL);
867             sb.append(processValue(key, doAsUserLanguageId));
868             sb.append(StringPool.AMPERSAND);
869         }
870 
871         long doAsGroupId = _doAsGroupId;
872 
873         if (doAsGroupId <= 0) {
874             doAsGroupId = themeDisplay.getDoAsGroupId();
875         }
876 
877         if (doAsGroupId > 0) {
878             sb.append("doAsGroupId");
879             sb.append(StringPool.EQUAL);
880             sb.append(processValue(key, doAsGroupId));
881             sb.append(StringPool.AMPERSAND);
882         }
883 
884         long refererPlid = _refererPlid;
885 
886         if (refererPlid <= 0) {
887             refererPlid = themeDisplay.getRefererPlid();
888         }
889 
890         if (refererPlid > 0) {
891             sb.append("refererPlid");
892             sb.append(StringPool.EQUAL);
893             sb.append(processValue(key, refererPlid));
894             sb.append(StringPool.AMPERSAND);
895         }
896 
897         if (_copyCurrentRenderParameters) {
898             Enumeration<String> enu = _request.getParameterNames();
899 
900             while (enu.hasMoreElements()) {
901                 String name = enu.nextElement();
902 
903                 String[] oldValues = _request.getParameterValues(name);
904                 String[] newValues = _params.get(name);
905 
906                 if (newValues == null) {
907                     _params.put(name, oldValues);
908                 }
909                 else if (isBlankValue(newValues)) {
910                     _params.remove(name);
911                 }
912                 else {
913                     newValues = ArrayUtil.append(newValues, oldValues);
914 
915                     _params.put(name, newValues);
916                 }
917             }
918         }
919 
920         Iterator<Map.Entry<String, String[]>> itr =
921             _params.entrySet().iterator();
922 
923         while (itr.hasNext()) {
924             Map.Entry<String, String[]> entry = itr.next();
925 
926             String name = entry.getKey();
927             String[] values = entry.getValue();
928 
929             String identifier = null;
930 
931             if (portlet != null) {
932                 PublicRenderParameter publicRenderParameter =
933                     portlet.getPublicRenderParameter(name);
934 
935                 if (publicRenderParameter != null) {
936                     QName qName = publicRenderParameter.getQName();
937 
938                     if (_copyCurrentPublicRenderParameters) {
939                         String[] oldValues = _request.getParameterValues(name);
940 
941                         if (oldValues != null) {
942                             if (values == null) {
943                                 values = oldValues;
944                             }
945                             else {
946                                 values = ArrayUtil.append(values, oldValues);
947                             }
948                         }
949                     }
950 
951                     identifier = name;
952 
953                     name = PortletQNameUtil.getPublicRenderParameterName(qName);
954 
955                     PortletQNameUtil.setPublicRenderParameterIdentifier(
956                         name, identifier);
957                 }
958             }
959 
960             // LEP-7495
961 
962             //if (isBlankValue(values)) {
963             //  continue;
964             //}
965 
966             for (int i = 0; i < values.length; i++) {
967                 String parameterName = name;
968 
969                 if (identifier != null) {
970                     parameterName = identifier;
971                 }
972 
973                 if (isParameterIncludedInPath(parameterName)) {
974                     continue;
975                 }
976 
977                 if (!PortalUtil.isReservedParameter(name) &&
978                     !name.startsWith(
979                         PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
980 
981                     sb.append(getNamespace());
982                 }
983 
984                 sb.append(name);
985                 sb.append(StringPool.EQUAL);
986                 sb.append(processValue(key, values[i]));
987 
988                 if ((i + 1 < values.length) || itr.hasNext()) {
989                     sb.append(StringPool.AMPERSAND);
990                 }
991             }
992         }
993 
994         if (_encrypt) {
995             sb.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
996         }
997 
998         if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
999             if (_anchor && (_windowState != null) &&
1000                (!_windowState.equals(WindowState.MAXIMIZED)) &&
1001                (!_windowState.equals(LiferayWindowState.EXCLUSIVE)) &&
1002                (!_windowState.equals(LiferayWindowState.POP_UP))) {
1003
1004                if (sb.lastIndexOf(StringPool.AMPERSAND) != (sb.length() - 1)) {
1005                    sb.append(StringPool.AMPERSAND);
1006                }
1007
1008                sb.append("#p_").append(_portletId);
1009            }
1010        }
1011
1012        String result = sb.toString();
1013
1014        if (result.endsWith(StringPool.AMPERSAND) ||
1015            result.endsWith(StringPool.QUESTION)) {
1016
1017            result = result.substring(0, result.length() - 1);
1018        }
1019
1020        if (themeDisplay.isFacebook()) {
1021
1022            // Facebook requires the path portion of the URL to end with a slash
1023
1024            int pos = result.indexOf(StringPool.QUESTION);
1025
1026            if (pos == -1) {
1027                if (!result.endsWith(StringPool.SLASH)) {
1028                    result += StringPool.SLASH;
1029                }
1030            }
1031            else {
1032                String path = result.substring(0, pos);
1033
1034                if (!result.endsWith(StringPool.SLASH)) {
1035                    result = path + StringPool.SLASH + result.substring(pos);
1036                }
1037            }
1038        }
1039
1040        if (!CookieKeys.hasSessionId(_request)) {
1041            result = PortalUtil.getURLWithSessionId(
1042                result, _request.getSession().getId());
1043        }
1044
1045        if (_escapeXml) {
1046            result = URLHelper.escapeURL(result);
1047        }
1048
1049        return result;
1050    }
1051
1052    protected boolean isBlankValue(String[] value) {
1053        if ((value != null) && (value.length == 1) &&
1054            (value[0].equals(StringPool.BLANK))) {
1055
1056            return true;
1057        }
1058        else {
1059            return false;
1060        }
1061    }
1062
1063    protected String processValue(Key key, int value) {
1064        return processValue(key, String.valueOf(value));
1065    }
1066
1067    protected String processValue(Key key, long value) {
1068        return processValue(key, String.valueOf(value));
1069    }
1070
1071    protected String processValue(Key key, String value) {
1072        if (key == null) {
1073            return HttpUtil.encodeURL(value);
1074        }
1075        else {
1076            try {
1077                return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1078            }
1079            catch (EncryptorException ee) {
1080                return value;
1081            }
1082        }
1083    }
1084
1085    private static Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1086
1087    private HttpServletRequest _request;
1088    private PortletRequest _portletRequest;
1089    private String _portletId;
1090    private Portlet _portlet;
1091    private String _namespace;
1092    private long _plid;
1093    private Layout _layout;
1094    private String _layoutFriendlyURL;
1095    private String _lifecycle;
1096    private boolean _anchor = true;
1097    private String _cacheability = ResourceURL.PAGE;
1098    private boolean _copyCurrentPublicRenderParameters;
1099    private boolean _copyCurrentRenderParameters;
1100    private long _doAsUserId;
1101    private String _doAsUserLanguageId;
1102    private long _doAsGroupId;
1103    private long _refererPlid;
1104    private boolean _encrypt;
1105    private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1106    private Set<String> _parametersIncludedInPath;
1107    private Map<String, String[]> _params;
1108    private PortletMode _portletMode;
1109    private String _resourceID;
1110    private boolean _secure;
1111    private WindowState _windowState;
1112    private ChannelURLType _urlType;
1113    private String _toString;
1114
1115}