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