1   /**
2    * Copyright (c) 2000-2008 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.portlet.FriendlyURLMapper;
27  import com.liferay.portal.kernel.portlet.LiferayPortletURL;
28  import com.liferay.portal.kernel.portlet.LiferayWindowState;
29  import com.liferay.portal.kernel.portlet.PortletModeFactory;
30  import com.liferay.portal.kernel.portlet.WindowStateFactory;
31  import com.liferay.portal.kernel.util.ArrayUtil;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.kernel.util.Http;
34  import com.liferay.portal.kernel.util.HttpUtil;
35  import com.liferay.portal.kernel.util.StringMaker;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.kernel.util.Validator;
38  import com.liferay.portal.model.Company;
39  import com.liferay.portal.model.Layout;
40  import com.liferay.portal.model.Portlet;
41  import com.liferay.portal.model.PortletApp;
42  import com.liferay.portal.model.PublicRenderParameter;
43  import com.liferay.portal.service.LayoutLocalServiceUtil;
44  import com.liferay.portal.service.PortletLocalServiceUtil;
45  import com.liferay.portal.theme.PortletDisplay;
46  import com.liferay.portal.theme.ThemeDisplay;
47  import com.liferay.portal.util.CookieKeys;
48  import com.liferay.portal.util.PortalUtil;
49  import com.liferay.portal.util.PropsValues;
50  import com.liferay.portal.util.QNameUtil;
51  import com.liferay.portal.util.WebKeys;
52  import com.liferay.util.Encryptor;
53  import com.liferay.util.EncryptorException;
54  import com.liferay.util.MapUtil;
55  
56  import com.sun.portal.portletcontainer.common.URLHelper;
57  
58  import java.io.IOException;
59  import java.io.Serializable;
60  import java.io.Writer;
61  
62  import java.security.Key;
63  
64  import java.util.Enumeration;
65  import java.util.Iterator;
66  import java.util.LinkedHashMap;
67  import java.util.LinkedHashSet;
68  import java.util.Map;
69  import java.util.Set;
70  
71  import javax.portlet.PortletMode;
72  import javax.portlet.PortletModeException;
73  import javax.portlet.PortletRequest;
74  import javax.portlet.PortletSecurityException;
75  import javax.portlet.PortletURL;
76  import javax.portlet.ResourceRequest;
77  import javax.portlet.ResourceURL;
78  import javax.portlet.WindowState;
79  import javax.portlet.WindowStateException;
80  
81  import javax.servlet.http.HttpServletRequest;
82  
83  import javax.xml.namespace.QName;
84  
85  import org.apache.commons.logging.Log;
86  import org.apache.commons.logging.LogFactory;
87  
88  /**
89   * <a href="PortletURLImpl.java.html"><b><i>View Source</i></b></a>
90   *
91   * @author Brian Wing Shun Chan
92   * @author Jorge Ferrer
93   *
94   */
95  public class PortletURLImpl
96      implements LiferayPortletURL, PortletURL, ResourceURL, Serializable {
97  
98      public PortletURLImpl(
99          PortletRequestImpl req, String portletId, long plid, String lifecycle) {
100 
101         this(req.getHttpServletRequest(), portletId, plid, lifecycle);
102 
103         _portletReq = req;
104     }
105 
106     public PortletURLImpl(
107         HttpServletRequest req, String portletId, long plid, String lifecycle) {
108 
109         _req = req;
110         _portletId = portletId;
111         _plid = plid;
112         _lifecycle = lifecycle;
113         _parametersIncludedInPath = new LinkedHashSet<String>();
114         _params = new LinkedHashMap<String, String[]>();
115         _secure = req.isSecure();
116 
117         Portlet portlet = getPortlet();
118 
119         if (portlet != null) {
120             PortletApp portletApp = portlet.getPortletApp();
121 
122             _escapeXml = MapUtil.getBoolean(
123                 portletApp.getContainerRuntimeOptions(),
124                 PortletConfigImpl.RUNTIME_OPTION_ESCAPE_XML, _ESCAPE_XML);
125         }
126     }
127 
128     public void addParameterIncludedInPath(String name) {
129         _parametersIncludedInPath.add(name);
130     }
131 
132     public void addProperty(String key, String value) {
133         if (key == null) {
134             throw new IllegalArgumentException();
135         }
136     }
137 
138     public String getCacheability() {
139         return _cacheability;
140     }
141 
142     public HttpServletRequest getHttpServletRequest() {
143         return _req;
144     }
145 
146     public String getNamespace() {
147         if (_namespace == null) {
148             _namespace = PortalUtil.getPortletNamespace(_portletId);
149         }
150 
151         return _namespace;
152     }
153 
154     public Layout getLayout() {
155         if (_layout == null) {
156             try {
157                 if (_plid > 0) {
158                     _layout = LayoutLocalServiceUtil.getLayout(_plid);
159                 }
160             }
161             catch (Exception e) {
162                 if (_log.isWarnEnabled()) {
163                     _log.warn("Layout cannot be found for " + _plid);
164                 }
165             }
166         }
167 
168         return _layout;
169     }
170 
171     public String getLayoutFriendlyURL() {
172         return _layoutFriendlyURL;
173     }
174 
175     public String getLifecycle() {
176         return _lifecycle;
177     }
178 
179     public String getParameter(String name) {
180         String[] values = _params.get(name);
181 
182         if ((values != null) && (values.length > 0)) {
183             return values[0];
184         }
185         else {
186             return null;
187         }
188     }
189 
190     public Map<String, String[]> getParameterMap() {
191         return _params;
192     }
193 
194     public Set<String> getParametersIncludedInPath() {
195         return _parametersIncludedInPath;
196     }
197 
198     public long getPlid() {
199         return _plid;
200     }
201 
202     public Portlet getPortlet() {
203         if (_portlet == null) {
204             try {
205                 _portlet = PortletLocalServiceUtil.getPortletById(
206                     PortalUtil.getCompanyId(_req), _portletId);
207             }
208             catch (SystemException se) {
209                 _log.error(se.getMessage());
210             }
211         }
212 
213         return _portlet;
214     }
215 
216     public String getPortletFriendlyURLPath() {
217         String portletFriendlyURLPath = null;
218 
219         Portlet portlet = getPortlet();
220 
221         if (portlet != null) {
222             FriendlyURLMapper mapper = portlet.getFriendlyURLMapperInstance();
223 
224             if (mapper != null) {
225                 portletFriendlyURLPath = mapper.buildPath(this);
226 
227                 if (_log.isDebugEnabled()) {
228                     _log.debug(
229                         "Portlet friendly URL path " + portletFriendlyURLPath);
230                 }
231             }
232         }
233 
234         return portletFriendlyURLPath;
235     }
236 
237     public String getPortletId() {
238         return _portletId;
239     }
240 
241     public PortletMode getPortletMode() {
242         return _portletMode;
243     }
244 
245     public PortletRequest getPortletRequest() {
246         return _portletReq;
247     }
248 
249     public String getResourceID() {
250         return _resourceID;
251     }
252 
253     public WindowState getWindowState() {
254         return _windowState;
255     }
256 
257     public boolean isAnchor() {
258         return _anchor;
259     }
260 
261     public boolean isCopyCurrentRenderParameters() {
262         return _copyCurrentRenderParameters;
263     }
264 
265     public boolean isEncrypt() {
266         return _encrypt;
267     }
268 
269     public boolean isEscapeXml() {
270         return _escapeXml;
271     }
272 
273     public boolean isParameterIncludedInPath(String name) {
274         if (_parametersIncludedInPath.contains(name)) {
275             return true;
276         }
277         else {
278             return false;
279         }
280     }
281 
282     public boolean isSecure() {
283         return _secure;
284     }
285 
286     public void removePublicRenderParameter(String name) {
287         if (name == null) {
288             throw new IllegalArgumentException();
289         }
290 
291         _params.remove(name);
292     }
293 
294     public void setAnchor(boolean anchor) {
295         _anchor = anchor;
296 
297         // Clear cache
298 
299         _toString = null;
300     }
301 
302     public void setCacheability(String cacheability) {
303         if (cacheability == null) {
304             throw new IllegalArgumentException("Cacheability is null");
305         }
306 
307         if (!cacheability.equals(FULL) && !cacheability.equals(PORTLET) &&
308             !cacheability.equals(PAGE)) {
309 
310             throw new IllegalArgumentException(
311                 "Cacheability " + cacheability + " is not " + FULL + ", " +
312                     PORTLET + ", or " + PAGE);
313         }
314 
315         if (_portletReq instanceof ResourceRequest) {
316             ResourceRequest resourceReq = (ResourceRequest)_portletReq;
317 
318             String parentCacheability = resourceReq.getCacheability();
319 
320             if (parentCacheability.equals(FULL)) {
321                 if (!cacheability.equals(FULL)) {
322                     throw new IllegalStateException(
323                         "Unable to set a weaker cacheability " + cacheability);
324                 }
325             }
326             else if (parentCacheability.equals(PORTLET)) {
327                 if (!cacheability.equals(FULL) &&
328                     !cacheability.equals(PORTLET)) {
329 
330                     throw new IllegalStateException(
331                         "Unable to set a weaker cacheability " + cacheability);
332                 }
333             }
334         }
335 
336         _cacheability = cacheability;
337 
338         // Clear cache
339 
340         _toString = null;
341     }
342 
343     public void setCopyCurrentRenderParameters(
344         boolean copyCurrentRenderParameters) {
345 
346         _copyCurrentRenderParameters = copyCurrentRenderParameters;
347     }
348 
349     public void setDoAsUserId(long doAsUserId) {
350         _doAsUserId = doAsUserId;
351 
352         // Clear cache
353 
354         _toString = null;
355     }
356 
357     public void setEncrypt(boolean encrypt) {
358         _encrypt = encrypt;
359 
360         // Clear cache
361 
362         _toString = null;
363     }
364 
365     public void setEscapeXml(boolean escapeXml) {
366         _escapeXml = escapeXml;
367 
368         // Clear cache
369 
370         _toString = null;
371     }
372 
373     public void setLifecycle(String lifecycle) {
374         _lifecycle = lifecycle;
375 
376         // Clear cache
377 
378         _toString = null;
379     }
380 
381     public void setParameter(String name, String value) {
382         setParameter(name, value, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
383     }
384 
385     public void setParameter(String name, String value, boolean append) {
386         if ((name == null) || (value == null)) {
387             throw new IllegalArgumentException();
388         }
389 
390         setParameter(name, new String[] {value}, append);
391     }
392 
393     public void setParameter(String name, String[] values) {
394         setParameter(name, values, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
395     }
396 
397     public void setParameter(String name, String[] values, boolean append) {
398         if ((name == null) || (values == null)) {
399             throw new IllegalArgumentException();
400         }
401 
402         for (int i = 0; i < values.length; i++) {
403             if (values[i] == null) {
404                 throw new IllegalArgumentException();
405             }
406         }
407 
408         if (append && _params.containsKey(name)) {
409             String[] oldValues = _params.get(name);
410 
411             String[] newValues = ArrayUtil.append(oldValues, values);
412 
413             _params.put(name, newValues);
414         }
415         else {
416             _params.put(name, values);
417         }
418 
419         // Clear cache
420 
421         _toString = null;
422     }
423 
424     public void setParameters(Map<String, String[]> params) {
425         if (params == null) {
426             throw new IllegalArgumentException();
427         }
428         else {
429             Map<String, String[]> newParams =
430                 new LinkedHashMap<String, String[]>();
431 
432             for (Map.Entry<String, String[]> entry : params.entrySet()) {
433                 try {
434                     String key = entry.getKey();
435                     String[] value = entry.getValue();
436 
437                     if (key == null) {
438                         throw new IllegalArgumentException();
439                     }
440                     else if (value == null) {
441                         throw new IllegalArgumentException();
442                     }
443 
444                     newParams.put(key, value);
445                 }
446                 catch (ClassCastException cce) {
447                     throw new IllegalArgumentException(cce);
448                 }
449             }
450 
451             _params = newParams;
452         }
453 
454         // Clear cache
455 
456         _toString = null;
457     }
458 
459     public void setPortletId(String portletId) {
460         _portletId = portletId;
461 
462         // Clear cache
463 
464         _toString = null;
465     }
466 
467     public void setPortletMode(String portletMode) throws PortletModeException {
468         setPortletMode(PortletModeFactory.getPortletMode(portletMode));
469     }
470 
471     public void setPortletMode(PortletMode portletMode)
472         throws PortletModeException {
473 
474         if (_portletReq != null) {
475             if (!getPortlet().hasPortletMode(
476                     _portletReq.getResponseContentType(), portletMode)) {
477 
478                 throw new PortletModeException(
479                     portletMode.toString(), portletMode);
480             }
481         }
482 
483         _portletMode = portletMode;
484 
485         // Clear cache
486 
487         _toString = null;
488     }
489 
490     public void setProperty(String key, String value) {
491         if (key == null) {
492             throw new IllegalArgumentException();
493         }
494     }
495 
496     public void setResourceID(String resourceID) {
497         _resourceID = resourceID;
498     }
499 
500     public void setSecure(boolean secure) throws PortletSecurityException {
501         _secure = secure;
502 
503         // Clear cache
504 
505         _toString = null;
506     }
507 
508     public void setWindowState(String windowState) throws WindowStateException {
509         setWindowState(WindowStateFactory.getWindowState(windowState));
510     }
511 
512     public void setWindowState(WindowState windowState)
513         throws WindowStateException {
514 
515         if (_portletReq != null) {
516             if (!_portletReq.isWindowStateAllowed(windowState)) {
517                 throw new WindowStateException(
518                     windowState.toString(), windowState);
519             }
520         }
521 
522         if (LiferayWindowState.isWindowStatePreserved(
523                 getWindowState(), windowState)) {
524 
525             _windowState = windowState;
526         }
527 
528         // Clear cache
529 
530         _toString = null;
531     }
532 
533     public String toString() {
534         if (_toString != null) {
535             return _toString;
536         }
537 
538         _toString = generateToString();
539 
540         return _toString;
541     }
542 
543     public void write(Writer writer) throws IOException {
544         write(writer, _escapeXml);
545     }
546 
547     public void write(Writer writer, boolean escapeXml) throws IOException {
548         String toString = toString();
549 
550         if (escapeXml && !_escapeXml) {
551             toString = URLHelper.escapeURL(toString);
552         }
553 
554         writer.write(toString());
555     }
556 
557     protected String generateToString() {
558         StringMaker sm = new StringMaker();
559 
560         ThemeDisplay themeDisplay =
561             (ThemeDisplay)_req.getAttribute(WebKeys.THEME_DISPLAY);
562 
563         PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
564 
565         Portlet portlet = getPortlet();
566 
567         String portalURL = PortalUtil.getPortalURL(_req, _secure);
568 
569         try {
570             if (_layoutFriendlyURL == null) {
571                 Layout layout = getLayout();
572 
573                 if (layout != null) {
574                     _layoutFriendlyURL = GetterUtil.getString(
575                         PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
576                 }
577             }
578         }
579         catch (Exception e) {
580             _log.error(e);
581         }
582 
583         Key key = null;
584 
585         try {
586             if (_encrypt) {
587                 Company company = PortalUtil.getCompany(_req);
588 
589                 key = company.getKeyObj();
590             }
591         }
592         catch (Exception e) {
593             _log.error(e);
594         }
595 
596         if (Validator.isNull(_layoutFriendlyURL)) {
597             sm.append(portalURL);
598             sm.append(themeDisplay.getPathMain());
599             sm.append("/portal/layout?");
600 
601             sm.append("p_l_id");
602             sm.append(StringPool.EQUAL);
603             sm.append(processValue(key, _plid));
604             sm.append(StringPool.AMPERSAND);
605         }
606         else {
607 
608             // A virtual host URL will contain the complete path. Do not append
609             // the portal URL if the virtual host URL starts with "http://" or
610             // "https://".
611 
612             if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
613                 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
614 
615                 sm.append(portalURL);
616             }
617 
618             sm.append(_layoutFriendlyURL);
619 
620             String friendlyURLPath = getPortletFriendlyURLPath();
621 
622             if (Validator.isNotNull(friendlyURLPath)) {
623                 sm.append(friendlyURLPath);
624 
625                 if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
626                     addParameterIncludedInPath("p_p_lifecycle");
627                 }
628 
629                 //if ((_windowState != null) &&
630                 //  _windowState.equals(WindowState.MAXIMIZED)) {
631 
632                     addParameterIncludedInPath("p_p_state");
633                 //}
634 
635                 //if ((_portletMode != null) &&
636                 //  _portletMode.equals(PortletMode.VIEW)) {
637 
638                     addParameterIncludedInPath("p_p_mode");
639                 //}
640 
641                 addParameterIncludedInPath("p_p_col_id");
642                 addParameterIncludedInPath("p_p_col_pos");
643                 addParameterIncludedInPath("p_p_col_count");
644             }
645 
646             sm.append(StringPool.QUESTION);
647         }
648 
649         if (!isParameterIncludedInPath("p_p_id")) {
650             sm.append("p_p_id");
651             sm.append(StringPool.EQUAL);
652             sm.append(processValue(key, _portletId));
653             sm.append(StringPool.AMPERSAND);
654         }
655 
656         if (!isParameterIncludedInPath("p_p_lifecycle")) {
657             sm.append("p_p_lifecycle");
658             sm.append(StringPool.EQUAL);
659 
660             if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
661                 sm.append(processValue(key, "1"));
662             }
663             else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
664                 sm.append(processValue(key, "0"));
665             }
666             else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
667                 sm.append(processValue(key, "2"));
668             }
669 
670             sm.append(StringPool.AMPERSAND);
671         }
672 
673         if (!isParameterIncludedInPath("p_p_state")) {
674             if (_windowState != null) {
675                 sm.append("p_p_state");
676                 sm.append(StringPool.EQUAL);
677                 sm.append(processValue(key, _windowState.toString()));
678                 sm.append(StringPool.AMPERSAND);
679             }
680         }
681 
682         if (!isParameterIncludedInPath("p_p_mode")) {
683             if (_portletMode != null) {
684                 sm.append("p_p_mode");
685                 sm.append(StringPool.EQUAL);
686                 sm.append(processValue(key, _portletMode.toString()));
687                 sm.append(StringPool.AMPERSAND);
688             }
689         }
690 
691         if (!isParameterIncludedInPath("p_p_resource_id")) {
692             if (_resourceID != null) {
693                 sm.append("p_p_resource_id");
694                 sm.append(StringPool.EQUAL);
695                 sm.append(processValue(key, _resourceID));
696                 sm.append(StringPool.AMPERSAND);
697             }
698         }
699 
700         if (!isParameterIncludedInPath("p_p_cacheability")) {
701             if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
702                 sm.append("p_p_cacheability");
703                 sm.append(StringPool.EQUAL);
704                 sm.append(processValue(key, _cacheability));
705                 sm.append(StringPool.AMPERSAND);
706             }
707         }
708 
709         if (!isParameterIncludedInPath("p_p_col_id")) {
710             if (Validator.isNotNull(portletDisplay.getColumnId())) {
711                 sm.append("p_p_col_id");
712                 sm.append(StringPool.EQUAL);
713                 sm.append(processValue(key, portletDisplay.getColumnId()));
714                 sm.append(StringPool.AMPERSAND);
715             }
716         }
717 
718         if (!isParameterIncludedInPath("p_p_col_pos")) {
719             if (portletDisplay.getColumnPos() > 0) {
720                 sm.append("p_p_col_pos");
721                 sm.append(StringPool.EQUAL);
722                 sm.append(processValue(key, portletDisplay.getColumnPos()));
723                 sm.append(StringPool.AMPERSAND);
724             }
725         }
726 
727         if (!isParameterIncludedInPath("p_p_col_count")) {
728             if (portletDisplay.getColumnCount() > 0) {
729                 sm.append("p_p_col_count");
730                 sm.append(StringPool.EQUAL);
731                 sm.append(processValue(key, portletDisplay.getColumnCount()));
732                 sm.append(StringPool.AMPERSAND);
733             }
734         }
735 
736         if (_doAsUserId > 0) {
737             try {
738                 Company company = PortalUtil.getCompany(_req);
739 
740                 sm.append("doAsUserId");
741                 sm.append(StringPool.EQUAL);
742                 sm.append(processValue(company.getKeyObj(), _doAsUserId));
743                 sm.append(StringPool.AMPERSAND);
744             }
745             catch (Exception e) {
746                 _log.error(e);
747             }
748         }
749         else {
750             String doAsUserId = themeDisplay.getDoAsUserId();
751 
752             if (Validator.isNotNull(doAsUserId)) {
753                 sm.append("doAsUserId");
754                 sm.append(StringPool.EQUAL);
755                 sm.append(processValue(key, doAsUserId));
756                 sm.append(StringPool.AMPERSAND);
757             }
758         }
759 
760         if (_copyCurrentRenderParameters) {
761             Enumeration<String> enu = _req.getParameterNames();
762 
763             while (enu.hasMoreElements()) {
764                 String name = enu.nextElement();
765 
766                 String[] oldValues = _req.getParameterValues(name);
767                 String[] newValues = _params.get(name);
768 
769                 if (newValues == null) {
770                     _params.put(name, oldValues);
771                 }
772                 else if (isBlankValue(newValues)) {
773                 }
774                 else {
775                     newValues = ArrayUtil.append(newValues, oldValues);
776 
777                     _params.put(name, newValues);
778                 }
779             }
780         }
781 
782         Iterator<Map.Entry<String, String[]>> itr =
783             _params.entrySet().iterator();
784 
785         while (itr.hasNext()) {
786             Map.Entry<String, String[]> entry = itr.next();
787 
788             String name = entry.getKey();
789             String[] values = entry.getValue();
790 
791             if (portlet != null) {
792                 PublicRenderParameter publicRenderParameter =
793                     portlet.getPublicRenderParameter(name);
794 
795                 if (publicRenderParameter != null) {
796                     QName qName = publicRenderParameter.getQName();
797 
798                     if (!_copyCurrentRenderParameters) {
799                         String[] oldValues = _req.getParameterValues(name);
800 
801                         if (oldValues != null) {
802                             if (values == null) {
803                                 values = oldValues;
804                             }
805                             else {
806                                 values = ArrayUtil.append(values, oldValues);
807                             }
808                         }
809                     }
810 
811                     name = QNameUtil.getPublicRenderParameterName(qName);
812                 }
813             }
814 
815             if (isBlankValue(values)) {
816                 continue;
817             }
818 
819             for (int i = 0; i < values.length; i++) {
820                 if (isParameterIncludedInPath(name)) {
821                     continue;
822                 }
823 
824                 if (!PortalUtil.isReservedParameter(name) &&
825                     !name.startsWith(
826                         QNameUtil.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
827 
828                     sm.append(getNamespace());
829                 }
830 
831                 sm.append(name);
832                 sm.append(StringPool.EQUAL);
833                 sm.append(processValue(key, values[i]));
834 
835                 if ((i + 1 < values.length) || itr.hasNext()) {
836                     sm.append(StringPool.AMPERSAND);
837                 }
838             }
839         }
840 
841         if (_encrypt) {
842             sm.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
843         }
844 
845         if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
846             if (_anchor && (_windowState != null) &&
847                 (!_windowState.equals(WindowState.MAXIMIZED)) &&
848                 (!_windowState.equals(LiferayWindowState.EXCLUSIVE)) &&
849                 (!_windowState.equals(LiferayWindowState.POP_UP))) {
850 
851                 if (sm.lastIndexOf(StringPool.AMPERSAND) != (sm.length() - 1)) {
852                     sm.append(StringPool.AMPERSAND);
853                 }
854 
855                 sm.append("#p_").append(_portletId);
856             }
857         }
858 
859         String result = sm.toString();
860 
861         if (result.endsWith(StringPool.QUESTION)) {
862             result = result.substring(0, result.length() - 1);
863         }
864 
865         if (!CookieKeys.hasSessionId(_req)) {
866             result = PortalUtil.getURLWithSessionId(
867                 result, _req.getSession().getId());
868         }
869 
870         if (_escapeXml) {
871             result = URLHelper.escapeURL(result);
872         }
873 
874         return result;
875     }
876 
877     protected boolean isBlankValue(String[] value) {
878         if ((value != null) && (value.length == 1) &&
879             (value[0].equals(StringPool.BLANK))) {
880 
881             return true;
882         }
883         else {
884             return false;
885         }
886     }
887 
888     protected String processValue(Key key, int value) {
889         return processValue(key, String.valueOf(value));
890     }
891 
892     protected String processValue(Key key, long value) {
893         return processValue(key, String.valueOf(value));
894     }
895 
896     protected String processValue(Key key, String value) {
897         if (key == null) {
898             return HttpUtil.encodeURL(value);
899         }
900         else {
901             try {
902                 return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
903             }
904             catch (EncryptorException ee) {
905                 return value;
906             }
907         }
908     }
909 
910     private static final boolean _ESCAPE_XML = true;
911 
912     private static Log _log = LogFactory.getLog(PortletURLImpl.class);
913 
914     private HttpServletRequest _req;
915     private PortletRequest _portletReq;
916     private String _portletId;
917     private Portlet _portlet;
918     private String _namespace;
919     private long _plid;
920     private Layout _layout;
921     private String _layoutFriendlyURL;
922     private String _lifecycle;
923     private boolean _anchor = true;
924     private String _cacheability = ResourceURL.PAGE;
925     private boolean _copyCurrentRenderParameters;
926     private long _doAsUserId;
927     private boolean _encrypt;
928     private boolean _escapeXml = _ESCAPE_XML;
929     private Set<String> _parametersIncludedInPath;
930     private Map<String, String[]> _params;
931     private PortletMode _portletMode;
932     private String _resourceID;
933     private boolean _secure;
934     private WindowState _windowState;
935     private String _toString;
936 
937 }