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