001
014
015 package com.liferay.portlet;
016
017 import com.liferay.portal.kernel.exception.SystemException;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
021 import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
022 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
023 import com.liferay.portal.kernel.portlet.LiferayWindowState;
024 import com.liferay.portal.kernel.portlet.PortletModeFactory;
025 import com.liferay.portal.kernel.portlet.WindowStateFactory;
026 import com.liferay.portal.kernel.util.ArrayUtil;
027 import com.liferay.portal.kernel.util.Base64;
028 import com.liferay.portal.kernel.util.CharPool;
029 import com.liferay.portal.kernel.util.CookieKeys;
030 import com.liferay.portal.kernel.util.GetterUtil;
031 import com.liferay.portal.kernel.util.HtmlUtil;
032 import com.liferay.portal.kernel.util.Http;
033 import com.liferay.portal.kernel.util.HttpUtil;
034 import com.liferay.portal.kernel.util.MapUtil;
035 import com.liferay.portal.kernel.util.ParamUtil;
036 import com.liferay.portal.kernel.util.StringBundler;
037 import com.liferay.portal.kernel.util.StringPool;
038 import com.liferay.portal.kernel.util.Validator;
039 import com.liferay.portal.kernel.util.WebKeys;
040 import com.liferay.portal.kernel.xml.QName;
041 import com.liferay.portal.model.Company;
042 import com.liferay.portal.model.Layout;
043 import com.liferay.portal.model.Portlet;
044 import com.liferay.portal.model.PortletApp;
045 import com.liferay.portal.model.PublicRenderParameter;
046 import com.liferay.portal.model.impl.VirtualLayout;
047 import com.liferay.portal.security.auth.AuthTokenUtil;
048 import com.liferay.portal.security.lang.DoPrivilegedUtil;
049 import com.liferay.portal.service.LayoutLocalServiceUtil;
050 import com.liferay.portal.service.PortletLocalServiceUtil;
051 import com.liferay.portal.theme.PortletDisplay;
052 import com.liferay.portal.theme.ThemeDisplay;
053 import com.liferay.portal.util.PortalUtil;
054 import com.liferay.portal.util.PropsValues;
055 import com.liferay.portlet.social.util.FacebookUtil;
056 import com.liferay.util.Encryptor;
057 import com.liferay.util.EncryptorException;
058
059 import java.io.IOException;
060 import java.io.Serializable;
061 import java.io.UnsupportedEncodingException;
062 import java.io.Writer;
063
064 import java.security.Key;
065 import java.security.PrivilegedAction;
066
067 import java.util.Collections;
068 import java.util.LinkedHashMap;
069 import java.util.LinkedHashSet;
070 import java.util.Map;
071 import java.util.Set;
072
073 import javax.portlet.PortletMode;
074 import javax.portlet.PortletModeException;
075 import javax.portlet.PortletRequest;
076 import javax.portlet.PortletURL;
077 import javax.portlet.ResourceRequest;
078 import javax.portlet.ResourceURL;
079 import javax.portlet.WindowState;
080 import javax.portlet.WindowStateException;
081
082 import javax.servlet.http.HttpServletRequest;
083
084
089 public class PortletURLImpl
090 implements LiferayPortletURL, PortletURL, ResourceURL, Serializable {
091
092 public PortletURLImpl(
093 HttpServletRequest request, String portletId, Layout layout,
094 String lifecycle) {
095
096 this(request, portletId, null, layout.getPlid(), lifecycle);
097
098 _layout = layout;
099 }
100
101 public PortletURLImpl(
102 HttpServletRequest request, String portletId, long plid,
103 String lifecycle) {
104
105 this(request, portletId, null, plid, lifecycle);
106 }
107
108 public PortletURLImpl(
109 PortletRequest portletRequest, String portletId, Layout layout,
110 String lifecycle) {
111
112 this(
113 PortalUtil.getHttpServletRequest(portletRequest), portletId,
114 portletRequest, layout.getPlid(), lifecycle);
115
116 _layout = layout;
117 }
118
119 public PortletURLImpl(
120 PortletRequest portletRequest, String portletId, long plid,
121 String lifecycle) {
122
123 this(
124 PortalUtil.getHttpServletRequest(portletRequest), portletId,
125 portletRequest, plid, lifecycle);
126 }
127
128 @Override
129 public void addParameterIncludedInPath(String name) {
130 _parametersIncludedInPath.add(name);
131 }
132
133 @Override
134 public void addProperty(String key, String value) {
135 if (key == null) {
136 throw new IllegalArgumentException();
137 }
138 }
139
140 @Override
141 public String getCacheability() {
142 return _cacheability;
143 }
144
145 public HttpServletRequest getHttpServletRequest() {
146 return _request;
147 }
148
149 public Layout getLayout() {
150 if (_layout == null) {
151 try {
152 if (_plid > 0) {
153 _layout = LayoutLocalServiceUtil.getLayout(_plid);
154 }
155 }
156 catch (Exception e) {
157 if (_log.isWarnEnabled()) {
158 _log.warn("Layout cannot be found for " + _plid);
159 }
160 }
161 }
162
163 return _layout;
164 }
165
166 public String getLayoutFriendlyURL() {
167 return _layoutFriendlyURL;
168 }
169
170 @Override
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 @Override
184 public String getParameter(String name) {
185 String[] values = _params.get(name);
186
187 if (ArrayUtil.isNotEmpty(values)) {
188 return values[0];
189 }
190 else {
191 return null;
192 }
193 }
194
195 @Override
196 public Map<String, String[]> getParameterMap() {
197 return _params;
198 }
199
200 @Override
201 public Set<String> getParametersIncludedInPath() {
202 return _parametersIncludedInPath;
203 }
204
205 @Override
206 public long getPlid() {
207 return _plid;
208 }
209
210 public Portlet getPortlet() {
211 if (_portlet == null) {
212 try {
213 _portlet = PortletLocalServiceUtil.getPortletById(
214 PortalUtil.getCompanyId(_request), _portletId);
215 }
216 catch (SystemException se) {
217 _log.error(se.getMessage());
218 }
219 }
220
221 return _portlet;
222 }
223
224 public String getPortletFriendlyURLPath() {
225 String portletFriendlyURLPath = null;
226
227 Portlet portlet = getPortlet();
228
229 if (portlet != null) {
230 if (portlet.isUndeployedPortlet()) {
231 return portletFriendlyURLPath;
232 }
233
234 FriendlyURLMapper friendlyURLMapper =
235 portlet.getFriendlyURLMapperInstance();
236
237 if (friendlyURLMapper != null) {
238 portletFriendlyURLPath = friendlyURLMapper.buildPath(this);
239
240 if (_log.isDebugEnabled()) {
241 _log.debug(
242 "Portlet friendly URL path " + portletFriendlyURLPath);
243 }
244 }
245 }
246
247 return portletFriendlyURLPath;
248 }
249
250 @Override
251 public String getPortletId() {
252 return _portletId;
253 }
254
255 @Override
256 public PortletMode getPortletMode() {
257 if (_portletModeString == null) {
258 return null;
259 }
260
261 return PortletModeFactory.getPortletMode(_portletModeString);
262 }
263
264 public PortletRequest getPortletRequest() {
265 return _portletRequest;
266 }
267
268 @Override
269 public Set<String> getRemovedParameterNames() {
270 return _removedParameterNames;
271 }
272
273 @Override
274 public Map<String, String> getReservedParameterMap() {
275 if (_reservedParameters != null) {
276 return _reservedParameters;
277 }
278
279 _reservedParameters = new LinkedHashMap<>();
280
281 _reservedParameters.put("p_p_id", _portletId);
282
283 if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
284 _reservedParameters.put("p_p_lifecycle", "1");
285 }
286 else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
287 _reservedParameters.put("p_p_lifecycle", "0");
288 }
289 else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
290 _reservedParameters.put("p_p_lifecycle", "2");
291 }
292
293 if (_windowStateString != null) {
294 _reservedParameters.put("p_p_state", _windowStateString);
295 }
296
297 if (_windowStateRestoreCurrentView) {
298 _reservedParameters.put("p_p_state_rcv", "1");
299 }
300
301 if (_portletModeString != null) {
302 _reservedParameters.put("p_p_mode", _portletModeString);
303 }
304
305 if (_resourceID != null) {
306 _reservedParameters.put("p_p_resource_id", _resourceID);
307 }
308
309 if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
310 _reservedParameters.put("p_p_cacheability", _cacheability);
311 }
312
313 ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
314 WebKeys.THEME_DISPLAY);
315
316 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
317
318 if (Validator.isNotNull(portletDisplay.getColumnId())) {
319 _reservedParameters.put("p_p_col_id", portletDisplay.getColumnId());
320 }
321
322 if (portletDisplay.getColumnPos() > 0) {
323 _reservedParameters.put(
324 "p_p_col_pos", String.valueOf(portletDisplay.getColumnPos()));
325 }
326
327 if (portletDisplay.getColumnCount() > 0) {
328 _reservedParameters.put(
329 "p_p_col_count",
330 String.valueOf(portletDisplay.getColumnCount()));
331 }
332
333 _reservedParameters = Collections.unmodifiableMap(_reservedParameters);
334
335 return _reservedParameters;
336 }
337
338 @Override
339 public String getResourceID() {
340 return _resourceID;
341 }
342
343 @Override
344 public WindowState getWindowState() {
345 if (_windowStateString == null) {
346 return null;
347 }
348
349 return WindowStateFactory.getWindowState(_windowStateString);
350 }
351
352 @Override
353 public boolean isAnchor() {
354 return _anchor;
355 }
356
357 @Override
358 public boolean isCopyCurrentRenderParameters() {
359 return _copyCurrentRenderParameters;
360 }
361
362 @Override
363 public boolean isEncrypt() {
364 return _encrypt;
365 }
366
367 @Override
368 public boolean isEscapeXml() {
369 return _escapeXml;
370 }
371
372 @Override
373 public boolean isParameterIncludedInPath(String name) {
374 if (_parametersIncludedInPath.contains(name)) {
375 return true;
376 }
377 else {
378 return false;
379 }
380 }
381
382 @Override
383 public boolean isSecure() {
384 return _secure;
385 }
386
387 @Override
388 public void removePublicRenderParameter(String name) {
389 if (name == null) {
390 throw new IllegalArgumentException();
391 }
392
393 Portlet portlet = getPortlet();
394
395 if (portlet == null) {
396 return;
397 }
398
399 PublicRenderParameter publicRenderParameter =
400 portlet.getPublicRenderParameter(name);
401
402 if (publicRenderParameter == null) {
403 if (_log.isWarnEnabled()) {
404 _log.warn("Public parameter " + name + "does not exist");
405 }
406
407 return;
408 }
409
410 QName qName = publicRenderParameter.getQName();
411
412 _removePublicRenderParameters.put(
413 PortletQNameUtil.getRemovePublicRenderParameterName(qName),
414 new String[] {"1"});
415 }
416
417 @Override
418 public void setAnchor(boolean anchor) {
419 _anchor = anchor;
420
421 clearCache();
422 }
423
424 @Override
425 public void setCacheability(String cacheability) {
426 if (cacheability == null) {
427 throw new IllegalArgumentException("Cacheability is null");
428 }
429
430 if (!cacheability.equals(FULL) && !cacheability.equals(PORTLET) &&
431 !cacheability.equals(PAGE)) {
432
433 throw new IllegalArgumentException(
434 "Cacheability " + cacheability + " is not " + FULL + ", " +
435 PORTLET + ", or " + PAGE);
436 }
437
438 if (_portletRequest instanceof ResourceRequest) {
439 ResourceRequest resourceRequest = (ResourceRequest)_portletRequest;
440
441 String parentCacheability = resourceRequest.getCacheability();
442
443 if (parentCacheability.equals(FULL)) {
444 if (!cacheability.equals(FULL)) {
445 throw new IllegalStateException(
446 "Unable to set a weaker cacheability " + cacheability);
447 }
448 }
449 else if (parentCacheability.equals(PORTLET)) {
450 if (!cacheability.equals(FULL) &&
451 !cacheability.equals(PORTLET)) {
452
453 throw new IllegalStateException(
454 "Unable to set a weaker cacheability " + cacheability);
455 }
456 }
457 }
458
459 _cacheability = cacheability;
460
461 clearCache();
462 }
463
464 @Override
465 public void setCopyCurrentRenderParameters(
466 boolean copyCurrentRenderParameters) {
467
468 _copyCurrentRenderParameters = copyCurrentRenderParameters;
469 }
470
471 @Override
472 public void setDoAsGroupId(long doAsGroupId) {
473 _doAsGroupId = doAsGroupId;
474
475 clearCache();
476 }
477
478 @Override
479 public void setDoAsUserId(long doAsUserId) {
480 _doAsUserId = doAsUserId;
481
482 clearCache();
483 }
484
485 @Override
486 public void setDoAsUserLanguageId(String doAsUserLanguageId) {
487 _doAsUserLanguageId = doAsUserLanguageId;
488
489 clearCache();
490 }
491
492 @Override
493 public void setEncrypt(boolean encrypt) {
494 _encrypt = encrypt;
495
496 clearCache();
497 }
498
499 @Override
500 public void setEscapeXml(boolean escapeXml) {
501 _escapeXml = escapeXml;
502
503 clearCache();
504 }
505
506 @Override
507 public void setLifecycle(String lifecycle) {
508 _lifecycle = lifecycle;
509
510 clearCache();
511 }
512
513 @Override
514 public void setParameter(String name, String value) {
515 setParameter(name, value, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
516 }
517
518 @Override
519 public void setParameter(String name, String value, boolean append) {
520 if (name == null) {
521 throw new IllegalArgumentException();
522 }
523
524 if (value == null) {
525 removeParameter(name);
526
527 return;
528 }
529
530 setParameter(name, new String[] {value}, append);
531 }
532
533 @Override
534 public void setParameter(String name, String[] values) {
535 setParameter(name, values, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
536 }
537
538 @Override
539 public void setParameter(String name, String[] values, boolean append) {
540 if ((name == null) || (values == null)) {
541 throw new IllegalArgumentException();
542 }
543
544 for (String value : values) {
545 if (value == null) {
546 throw new IllegalArgumentException();
547 }
548 }
549
550 if (!append) {
551 _params.put(name, values);
552 }
553 else {
554 String[] oldValues = _params.get(name);
555
556 if (oldValues == null) {
557 _params.put(name, values);
558 }
559 else {
560 String[] newValues = ArrayUtil.append(oldValues, values);
561
562 _params.put(name, newValues);
563 }
564 }
565
566 clearCache();
567 }
568
569 @Override
570 public void setParameters(Map<String, String[]> params) {
571 if (params == null) {
572 throw new IllegalArgumentException();
573 }
574 else {
575 Map<String, String[]> newParams = new LinkedHashMap<>();
576
577 for (Map.Entry<String, String[]> entry : params.entrySet()) {
578 try {
579 String key = entry.getKey();
580 String[] value = entry.getValue();
581
582 if (key == null) {
583 throw new IllegalArgumentException();
584 }
585 else if (value == null) {
586 throw new IllegalArgumentException();
587 }
588
589 newParams.put(key, value);
590 }
591 catch (ClassCastException cce) {
592 throw new IllegalArgumentException(cce);
593 }
594 }
595
596 _params = newParams;
597 }
598
599 clearCache();
600 }
601
602 @Override
603 public void setPlid(long plid) {
604 _plid = plid;
605
606 clearCache();
607 }
608
609 @Override
610 public void setPortletId(String portletId) {
611 _portletId = portletId;
612
613 clearCache();
614 }
615
616 @Override
617 public void setPortletMode(PortletMode portletMode)
618 throws PortletModeException {
619
620 if (_portletRequest != null) {
621 Portlet portlet = getPortlet();
622
623 if ((portlet != null) &&
624 !portlet.hasPortletMode(
625 _portletRequest.getResponseContentType(), portletMode)) {
626
627 throw new PortletModeException(
628 portletMode.toString(), portletMode);
629 }
630 }
631
632 _portletModeString = portletMode.toString();
633
634 clearCache();
635 }
636
637 public void setPortletMode(String portletMode) throws PortletModeException {
638 setPortletMode(PortletModeFactory.getPortletMode(portletMode));
639 }
640
641 @Override
642 public void setProperty(String key, String value) {
643 if (key == null) {
644 throw new IllegalArgumentException();
645 }
646 }
647
648 @Override
649 public void setRefererGroupId(long refererGroupId) {
650 _refererGroupId = refererGroupId;
651
652 clearCache();
653 }
654
655 @Override
656 public void setRefererPlid(long refererPlid) {
657 _refererPlid = refererPlid;
658
659 clearCache();
660 }
661
662 @Override
663 public void setRemovedParameterNames(Set<String> removedParameterNames) {
664 _removedParameterNames = removedParameterNames;
665
666 clearCache();
667 }
668
669 @Override
670 public void setResourceID(String resourceID) {
671 _resourceID = resourceID;
672 }
673
674 @Override
675 public void setSecure(boolean secure) {
676 _secure = secure;
677
678 clearCache();
679 }
680
681 public void setWindowState(String windowState) throws WindowStateException {
682 setWindowState(WindowStateFactory.getWindowState(windowState));
683 }
684
685 @Override
686 public void setWindowState(WindowState windowState)
687 throws WindowStateException {
688
689 if (_portletRequest != null) {
690 if (!_portletRequest.isWindowStateAllowed(windowState)) {
691 throw new WindowStateException(
692 windowState.toString(), windowState);
693 }
694 }
695
696 if (LiferayWindowState.isWindowStatePreserved(
697 getWindowState(), windowState)) {
698
699 _windowStateString = windowState.toString();
700 }
701
702 clearCache();
703 }
704
705 public void setWindowStateRestoreCurrentView(
706 boolean windowStateRestoreCurrentView) {
707
708 _windowStateRestoreCurrentView = windowStateRestoreCurrentView;
709 }
710
711 @Override
712 public String toString() {
713 if (_toString != null) {
714 return _toString;
715 }
716
717 _toString = DoPrivilegedUtil.wrap(new ToStringPrivilegedAction());
718
719 return _toString;
720 }
721
722 @Override
723 public void write(Writer writer) throws IOException {
724 write(writer, _escapeXml);
725 }
726
727 @Override
728 public void write(Writer writer, boolean escapeXml) throws IOException {
729 String toString = toString();
730
731 if (escapeXml && !_escapeXml) {
732 toString = HtmlUtil.escape(toString);
733 }
734
735 writer.write(toString);
736 }
737
738 protected PortletURLImpl(
739 HttpServletRequest request, String portletId,
740 PortletRequest portletRequest, long plid, String lifecycle) {
741
742 _request = request;
743 _portletId = portletId;
744 _portletRequest = portletRequest;
745 _plid = plid;
746 _lifecycle = lifecycle;
747 _parametersIncludedInPath = new LinkedHashSet<>();
748 _params = new LinkedHashMap<>();
749 _removePublicRenderParameters = new LinkedHashMap<>();
750 _secure = PortalUtil.isSecure(request);
751 _wsrp = ParamUtil.getBoolean(request, "wsrp");
752
753 Portlet portlet = getPortlet();
754
755 if (portlet != null) {
756 Set<String> autopropagatedParameters =
757 portlet.getAutopropagatedParameters();
758
759 for (String autopropagatedParameter : autopropagatedParameters) {
760 if (PortalUtil.isReservedParameter(autopropagatedParameter)) {
761 continue;
762 }
763
764 String value = request.getParameter(autopropagatedParameter);
765
766 if (value != null) {
767 setParameter(autopropagatedParameter, value);
768 }
769 }
770
771 PortletApp portletApp = portlet.getPortletApp();
772
773 _escapeXml = MapUtil.getBoolean(
774 portletApp.getContainerRuntimeOptions(),
775 LiferayPortletConfig.RUNTIME_OPTION_ESCAPE_XML,
776 PropsValues.PORTLET_URL_ESCAPE_XML);
777 }
778
779 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
780
781 if ((layout != null) && (layout.getPlid() == _plid) &&
782 (layout instanceof VirtualLayout)) {
783
784 _layout = layout;
785 }
786 }
787
788 protected void addPortalAuthToken(StringBundler sb, Key key) {
789 AuthTokenUtil.addCSRFToken(_request, this);
790 }
791
792 protected void addPortletAuthToken(StringBundler sb, Key key) {
793 AuthTokenUtil.addPortletInvocationToken(_request, this);
794 }
795
796 protected void clearCache() {
797 _reservedParameters = null;
798 _toString = null;
799 }
800
801 protected String generateToString() {
802 StringBundler sb = new StringBundler(64);
803
804 ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
805 WebKeys.THEME_DISPLAY);
806
807 if (themeDisplay == null) {
808 if (_log.isWarnEnabled()) {
809 _log.warn(
810 "Unable to generate string because theme display is null");
811 }
812
813 return StringPool.BLANK;
814 }
815
816 String portalURL = null;
817
818 if (themeDisplay.isFacebook()) {
819 portalURL =
820 FacebookUtil.FACEBOOK_APPS_URL +
821 themeDisplay.getFacebookCanvasPageURL();
822 }
823 else {
824 portalURL = PortalUtil.getPortalURL(_request, _secure);
825 }
826
827 try {
828 if (_layoutFriendlyURL == null) {
829 Layout layout = getLayout();
830
831 if (layout != null) {
832 _layoutFriendlyURL = GetterUtil.getString(
833 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
834
835 if (_secure) {
836 _layoutFriendlyURL = HttpUtil.protocolize(
837 _layoutFriendlyURL,
838 PropsValues.WEB_SERVER_HTTPS_PORT, true);
839 }
840 }
841 }
842 }
843 catch (Exception e) {
844 _log.error(e);
845 }
846
847 Key key = null;
848
849 try {
850 if (_encrypt) {
851 Company company = PortalUtil.getCompany(_request);
852
853 key = company.getKeyObj();
854 }
855 }
856 catch (Exception e) {
857 _log.error(e);
858 }
859
860 if (Validator.isNull(_layoutFriendlyURL)) {
861 sb.append(portalURL);
862 sb.append(themeDisplay.getPathMain());
863 sb.append("/portal/layout?");
864
865 addPortalAuthToken(sb, key);
866
867 sb.append("p_l_id");
868 sb.append(StringPool.EQUAL);
869 sb.append(processValue(key, _plid));
870 sb.append(StringPool.AMPERSAND);
871 }
872 else {
873 if (themeDisplay.isFacebook()) {
874 sb.append(portalURL);
875 }
876 else {
877
878
879
880
881
882 if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
883 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
884
885 sb.append(portalURL);
886 }
887
888 sb.append(_layoutFriendlyURL);
889 }
890
891 String friendlyURLPath = getPortletFriendlyURLPath();
892
893 if (Validator.isNotNull(friendlyURLPath)) {
894 if (themeDisplay.isFacebook()) {
895 int pos = friendlyURLPath.indexOf(CharPool.SLASH, 1);
896
897 if (pos != -1) {
898 sb.append(friendlyURLPath.substring(pos));
899 }
900 else {
901 sb.append(friendlyURLPath);
902 }
903 }
904 else {
905 sb.append("/-");
906 sb.append(friendlyURLPath);
907 }
908 }
909
910 sb.append(StringPool.QUESTION);
911
912 addPortalAuthToken(sb, key);
913 }
914
915 addPortletAuthToken(sb, key);
916
917 for (Map.Entry<String, String> entry :
918 getReservedParameterMap().entrySet()) {
919
920 String name = entry.getKey();
921
922 if (!isParameterIncludedInPath(name)) {
923 sb.append(HttpUtil.encodeURL(name));
924 sb.append(StringPool.EQUAL);
925 sb.append(processValue(key, entry.getValue()));
926 sb.append(StringPool.AMPERSAND);
927 }
928 }
929
930 if (_doAsUserId > 0) {
931 try {
932 Company company = PortalUtil.getCompany(_request);
933
934 sb.append("doAsUserId");
935 sb.append(StringPool.EQUAL);
936 sb.append(processValue(company.getKeyObj(), _doAsUserId));
937 sb.append(StringPool.AMPERSAND);
938 }
939 catch (Exception e) {
940 _log.error(e);
941 }
942 }
943 else {
944 String doAsUserId = themeDisplay.getDoAsUserId();
945
946 if (Validator.isNotNull(doAsUserId)) {
947 sb.append("doAsUserId");
948 sb.append(StringPool.EQUAL);
949 sb.append(processValue(key, doAsUserId));
950 sb.append(StringPool.AMPERSAND);
951 }
952 }
953
954 String doAsUserLanguageId = _doAsUserLanguageId;
955
956 if (Validator.isNull(doAsUserLanguageId)) {
957 doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
958 }
959
960 if (Validator.isNotNull(doAsUserLanguageId)) {
961 sb.append("doAsUserLanguageId");
962 sb.append(StringPool.EQUAL);
963 sb.append(processValue(key, doAsUserLanguageId));
964 sb.append(StringPool.AMPERSAND);
965 }
966
967 long doAsGroupId = _doAsGroupId;
968
969 if (doAsGroupId <= 0) {
970 doAsGroupId = themeDisplay.getDoAsGroupId();
971 }
972
973 if (doAsGroupId > 0) {
974 sb.append("doAsGroupId");
975 sb.append(StringPool.EQUAL);
976 sb.append(processValue(key, doAsGroupId));
977 sb.append(StringPool.AMPERSAND);
978 }
979
980 long refererGroupId = _refererGroupId;
981
982 if (refererGroupId <= 0) {
983 refererGroupId = themeDisplay.getRefererGroupId();
984 }
985
986 if (refererGroupId > 0) {
987 sb.append("refererGroupId");
988 sb.append(StringPool.EQUAL);
989 sb.append(processValue(key, refererGroupId));
990 sb.append(StringPool.AMPERSAND);
991 }
992
993 long refererPlid = _refererPlid;
994
995 if (refererPlid <= 0) {
996 refererPlid = themeDisplay.getRefererPlid();
997 }
998
999 if (refererPlid > 0) {
1000 sb.append("refererPlid");
1001 sb.append(StringPool.EQUAL);
1002 sb.append(processValue(key, refererPlid));
1003 sb.append(StringPool.AMPERSAND);
1004 }
1005
1006 for (Map.Entry<String, String[]> entry :
1007 _removePublicRenderParameters.entrySet()) {
1008
1009 String lastString = sb.stringAt(sb.index() - 1);
1010
1011 if (lastString.charAt(lastString.length() - 1) !=
1012 CharPool.AMPERSAND) {
1013
1014 sb.append(StringPool.AMPERSAND);
1015 }
1016
1017 sb.append(HttpUtil.encodeURL(entry.getKey()));
1018 sb.append(StringPool.EQUAL);
1019 sb.append(processValue(key, entry.getValue()[0]));
1020 sb.append(StringPool.AMPERSAND);
1021 }
1022
1023 if (_copyCurrentRenderParameters) {
1024 mergeRenderParameters();
1025 }
1026
1027 int previousSbIndex = sb.index();
1028
1029 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1030 String name = entry.getKey();
1031 String[] values = entry.getValue();
1032
1033 if (isParameterIncludedInPath(name)) {
1034 continue;
1035 }
1036
1037 String publicRenderParameterName = getPublicRenderParameterName(
1038 name);
1039
1040 if (Validator.isNotNull(publicRenderParameterName)) {
1041 name = publicRenderParameterName;
1042 }
1043
1044 name = HttpUtil.encodeURL(prependNamespace(name));
1045
1046 for (String value : values) {
1047 sb.append(name);
1048 sb.append(StringPool.EQUAL);
1049 sb.append(processValue(key, value));
1050 sb.append(StringPool.AMPERSAND);
1051 }
1052 }
1053
1054 if (sb.index() > previousSbIndex) {
1055 sb.setIndex(sb.index() - 1);
1056 }
1057
1058 if (_encrypt) {
1059 sb.append(StringPool.AMPERSAND);
1060 sb.append(WebKeys.ENCRYPT);
1061 sb.append("=1");
1062 }
1063
1064 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1065 if (_anchor && (_windowStateString != null) &&
1066 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1067 !_windowStateString.equals(
1068 LiferayWindowState.EXCLUSIVE.toString()) &&
1069 !_windowStateString.equals(
1070 LiferayWindowState.POP_UP.toString())) {
1071
1072 String lastString = sb.stringAt(sb.index() - 1);
1073
1074 if (lastString.charAt(lastString.length() - 1) !=
1075 CharPool.AMPERSAND) {
1076
1077 sb.append(StringPool.AMPERSAND);
1078 }
1079
1080 sb.append("#p_");
1081 sb.append(HttpUtil.encodeURL(_portletId));
1082 }
1083 }
1084
1085 String result = sb.toString();
1086
1087 if (result.endsWith(StringPool.AMPERSAND) ||
1088 result.endsWith(StringPool.QUESTION)) {
1089
1090 result = result.substring(0, result.length() - 1);
1091 }
1092
1093 if (themeDisplay.isFacebook()) {
1094
1095
1096
1097 int pos = result.indexOf(CharPool.QUESTION);
1098
1099 if (pos == -1) {
1100 if (!result.endsWith(StringPool.SLASH)) {
1101 result += StringPool.SLASH;
1102 }
1103 }
1104 else {
1105 String path = result.substring(0, pos);
1106
1107 if (!result.endsWith(StringPool.SLASH)) {
1108 result = path + StringPool.SLASH + result.substring(pos);
1109 }
1110 }
1111 }
1112 else if (!CookieKeys.hasSessionId(_request)) {
1113 result = PortalUtil.getURLWithSessionId(
1114 result, _request.getSession().getId());
1115 }
1116
1117 if (_escapeXml) {
1118 result = HtmlUtil.escape(result);
1119 }
1120
1121 if (result.length() > Http.URL_MAXIMUM_LENGTH) {
1122 result = HttpUtil.shortenURL(result, 2);
1123 }
1124
1125 return result;
1126 }
1127
1128 protected String generateWSRPToString() {
1129 StringBundler sb = new StringBundler("wsrp_rewrite?");
1130
1131 sb.append("wsrp-urlType");
1132 sb.append(StringPool.EQUAL);
1133
1134 if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
1135 sb.append(HttpUtil.encodeURL("blockingAction"));
1136 }
1137 else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
1138 sb.append(HttpUtil.encodeURL("render"));
1139 }
1140 else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1141 sb.append(HttpUtil.encodeURL("resource"));
1142 }
1143
1144 sb.append(StringPool.AMPERSAND);
1145
1146 if (_windowStateString != null) {
1147 sb.append("wsrp-windowState");
1148 sb.append(StringPool.EQUAL);
1149 sb.append(HttpUtil.encodeURL("wsrp:" + _windowStateString));
1150 sb.append(StringPool.AMPERSAND);
1151 }
1152
1153 if (_portletModeString != null) {
1154 sb.append("wsrp-mode");
1155 sb.append(StringPool.EQUAL);
1156 sb.append(HttpUtil.encodeURL("wsrp:" + _portletModeString));
1157 sb.append(StringPool.AMPERSAND);
1158 }
1159
1160 if (_resourceID != null) {
1161 sb.append("wsrp-resourceID");
1162 sb.append(StringPool.EQUAL);
1163 sb.append(HttpUtil.encodeURL(_resourceID));
1164 sb.append(StringPool.AMPERSAND);
1165 }
1166
1167 if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1168 sb.append("wsrp-resourceCacheability");
1169 sb.append(StringPool.EQUAL);
1170 sb.append(HttpUtil.encodeURL(_cacheability));
1171 sb.append(StringPool.AMPERSAND);
1172 }
1173
1174 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1175 if (_anchor && (_windowStateString != null) &&
1176 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1177 !_windowStateString.equals(
1178 LiferayWindowState.EXCLUSIVE.toString()) &&
1179 !_windowStateString.equals(
1180 LiferayWindowState.POP_UP.toString())) {
1181
1182 sb.append("wsrp-fragmentID");
1183 sb.append(StringPool.EQUAL);
1184 sb.append("#p_");
1185 sb.append(HttpUtil.encodeURL(_portletId));
1186 sb.append(StringPool.AMPERSAND);
1187 }
1188 }
1189
1190 if (_copyCurrentRenderParameters) {
1191 mergeRenderParameters();
1192 }
1193
1194 StringBundler parameterSb = new StringBundler();
1195
1196 int previousSbIndex = sb.index();
1197
1198 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1199 String name = entry.getKey();
1200 String[] values = entry.getValue();
1201
1202 if (isParameterIncludedInPath(name)) {
1203 continue;
1204 }
1205
1206 String publicRenderParameterName = getPublicRenderParameterName(
1207 name);
1208
1209 if (Validator.isNotNull(publicRenderParameterName)) {
1210 name = publicRenderParameterName;
1211 }
1212
1213 name = HttpUtil.encodeURL(prependNamespace(name));
1214
1215 for (String value : values) {
1216 parameterSb.append(name);
1217 parameterSb.append(StringPool.EQUAL);
1218 parameterSb.append(HttpUtil.encodeURL(value));
1219 parameterSb.append(StringPool.AMPERSAND);
1220 }
1221 }
1222
1223 if (sb.index() > previousSbIndex) {
1224 sb.setIndex(sb.index() - 1);
1225 }
1226
1227 sb.append("wsrp-navigationalState");
1228 sb.append(StringPool.EQUAL);
1229
1230 byte[] parameterBytes = null;
1231
1232 try {
1233 String parameterString = parameterSb.toString();
1234
1235 parameterBytes = parameterString.getBytes(StringPool.UTF8);
1236 }
1237 catch (UnsupportedEncodingException uee) {
1238 if (_log.isWarnEnabled()) {
1239 _log.warn(uee, uee);
1240 }
1241 }
1242
1243 String navigationalState = Base64.toURLSafe(
1244 Base64.encode(parameterBytes));
1245
1246 sb.append(navigationalState);
1247
1248 sb.append("/wsrp_rewrite");
1249
1250 return sb.toString();
1251 }
1252
1253 protected String getPublicRenderParameterName(String name) {
1254 Portlet portlet = getPortlet();
1255
1256 String publicRenderParameterName = null;
1257
1258 if (portlet != null) {
1259 PublicRenderParameter publicRenderParameter =
1260 portlet.getPublicRenderParameter(name);
1261
1262 if (publicRenderParameter != null) {
1263 QName qName = publicRenderParameter.getQName();
1264
1265 publicRenderParameterName =
1266 PortletQNameUtil.getPublicRenderParameterName(qName);
1267 }
1268 }
1269
1270 return publicRenderParameterName;
1271 }
1272
1273 protected boolean isBlankValue(String[] value) {
1274 if ((value != null) && (value.length == 1) &&
1275 value[0].equals(StringPool.BLANK)) {
1276
1277 return true;
1278 }
1279 else {
1280 return false;
1281 }
1282 }
1283
1284 protected void mergeRenderParameters() {
1285 String namespace = getNamespace();
1286
1287 Layout layout = getLayout();
1288
1289 Map<String, String[]> renderParameters = RenderParametersPool.get(
1290 _request, layout.getPlid(), getPortlet().getPortletId());
1291
1292 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1293 String name = entry.getKey();
1294
1295 if (name.contains(namespace)) {
1296 name = name.substring(namespace.length());
1297 }
1298
1299 if (!_lifecycle.equals(PortletRequest.RESOURCE_PHASE) &&
1300 (_removedParameterNames != null) &&
1301 _removedParameterNames.contains(name)) {
1302
1303 continue;
1304 }
1305
1306 String[] oldValues = entry.getValue();
1307 String[] newValues = _params.get(name);
1308
1309 if (newValues == null) {
1310 _params.put(name, oldValues);
1311 }
1312 else if (isBlankValue(newValues)) {
1313 _params.remove(name);
1314 }
1315 else {
1316 newValues = ArrayUtil.append(newValues, oldValues);
1317
1318 _params.put(name, newValues);
1319 }
1320 }
1321 }
1322
1323 protected String prependNamespace(String name) {
1324 String namespace = getNamespace();
1325
1326 if (!PortalUtil.isReservedParameter(name) &&
1327 !name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) &&
1328 !name.startsWith(namespace)) {
1329
1330 return namespace.concat(name);
1331 }
1332 else {
1333 return name;
1334 }
1335 }
1336
1337 protected String processValue(Key key, int value) {
1338 return processValue(key, String.valueOf(value));
1339 }
1340
1341 protected String processValue(Key key, long value) {
1342 return processValue(key, String.valueOf(value));
1343 }
1344
1345 protected String processValue(Key key, String value) {
1346 if (key == null) {
1347 return HttpUtil.encodeURL(value);
1348 }
1349
1350 try {
1351 return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1352 }
1353 catch (EncryptorException ee) {
1354 return value;
1355 }
1356 }
1357
1358 protected void removeParameter(String name) {
1359 if (_params.containsKey(name)) {
1360 _params.remove(name);
1361 }
1362 }
1363
1364 private static final Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1365
1366 private boolean _anchor = true;
1367 private String _cacheability = ResourceURL.PAGE;
1368 private boolean _copyCurrentRenderParameters;
1369 private long _doAsGroupId;
1370 private long _doAsUserId;
1371 private String _doAsUserLanguageId;
1372 private boolean _encrypt;
1373 private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1374 private Layout _layout;
1375 private String _layoutFriendlyURL;
1376 private String _lifecycle;
1377 private String _namespace;
1378 private final Set<String> _parametersIncludedInPath;
1379 private Map<String, String[]> _params;
1380 private long _plid;
1381 private Portlet _portlet;
1382 private String _portletId;
1383 private String _portletModeString;
1384 private final PortletRequest _portletRequest;
1385 private long _refererGroupId;
1386 private long _refererPlid;
1387 private Set<String> _removedParameterNames;
1388 private final Map<String, String[]> _removePublicRenderParameters;
1389 private final HttpServletRequest _request;
1390 private Map<String, String> _reservedParameters;
1391 private String _resourceID;
1392 private boolean _secure;
1393 private String _toString;
1394 private boolean _windowStateRestoreCurrentView;
1395 private String _windowStateString;
1396 private final boolean _wsrp;
1397
1398 private class ToStringPrivilegedAction implements PrivilegedAction<String> {
1399
1400 @Override
1401 public String run() {
1402 if (_wsrp) {
1403 return generateWSRPToString();
1404 }
1405
1406 return generateToString();
1407 }
1408
1409 }
1410
1411 }