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.security.auth.AuthTokenUtil;
027 import com.liferay.portal.kernel.util.ArrayUtil;
028 import com.liferay.portal.kernel.util.Base64;
029 import com.liferay.portal.kernel.util.CharPool;
030 import com.liferay.portal.kernel.util.CookieKeys;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.HtmlUtil;
033 import com.liferay.portal.kernel.util.Http;
034 import com.liferay.portal.kernel.util.HttpUtil;
035 import com.liferay.portal.kernel.util.MapUtil;
036 import com.liferay.portal.kernel.util.ParamUtil;
037 import com.liferay.portal.kernel.util.StringBundler;
038 import com.liferay.portal.kernel.util.StringPool;
039 import com.liferay.portal.kernel.util.Validator;
040 import com.liferay.portal.kernel.util.WebKeys;
041 import com.liferay.portal.kernel.xml.QName;
042 import com.liferay.portal.model.Company;
043 import com.liferay.portal.model.Layout;
044 import com.liferay.portal.model.Portlet;
045 import com.liferay.portal.model.PortletApp;
046 import com.liferay.portal.model.PublicRenderParameter;
047 import com.liferay.portal.model.impl.VirtualLayout;
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 try {
817 if (_layoutFriendlyURL == null) {
818 Layout layout = getLayout();
819
820 if (layout != null) {
821 _layoutFriendlyURL = GetterUtil.getString(
822 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
823
824 if (_secure) {
825 _layoutFriendlyURL = HttpUtil.protocolize(
826 _layoutFriendlyURL,
827 PropsValues.WEB_SERVER_HTTPS_PORT, true);
828 }
829 }
830 }
831 }
832 catch (Exception e) {
833 _log.error(e);
834 }
835
836 Key key = null;
837
838 try {
839 if (_encrypt) {
840 Company company = PortalUtil.getCompany(_request);
841
842 key = company.getKeyObj();
843 }
844 }
845 catch (Exception e) {
846 _log.error(e);
847 }
848
849 if (Validator.isNull(_layoutFriendlyURL)) {
850 sb.append(PortalUtil.getPortalURL(_request, _secure));
851 sb.append(themeDisplay.getPathMain());
852 sb.append("/portal/layout?");
853
854 addPortalAuthToken(sb, key);
855
856 sb.append("p_l_id");
857 sb.append(StringPool.EQUAL);
858 sb.append(processValue(key, _plid));
859 sb.append(StringPool.AMPERSAND);
860 }
861 else {
862 if (themeDisplay.isFacebook()) {
863 sb.append(FacebookUtil.FACEBOOK_APPS_URL);
864 sb.append(themeDisplay.getFacebookCanvasPageURL());
865 }
866 else {
867
868
869
870
871
872 if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
873 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
874
875 sb.append(PortalUtil.getPortalURL(_request, _secure));
876 }
877
878 sb.append(_layoutFriendlyURL);
879 }
880
881 String friendlyURLPath = getPortletFriendlyURLPath();
882
883 if (Validator.isNotNull(friendlyURLPath)) {
884 if (themeDisplay.isFacebook()) {
885 int pos = friendlyURLPath.indexOf(CharPool.SLASH, 1);
886
887 if (pos != -1) {
888 sb.append(friendlyURLPath.substring(pos));
889 }
890 else {
891 sb.append(friendlyURLPath);
892 }
893 }
894 else {
895 sb.append("/-");
896 sb.append(friendlyURLPath);
897 }
898 }
899
900 sb.append(StringPool.QUESTION);
901
902 addPortalAuthToken(sb, key);
903 }
904
905 addPortletAuthToken(sb, key);
906
907 for (Map.Entry<String, String> entry :
908 getReservedParameterMap().entrySet()) {
909
910 String name = entry.getKey();
911
912 if (!isParameterIncludedInPath(name)) {
913 sb.append(HttpUtil.encodeURL(name));
914 sb.append(StringPool.EQUAL);
915 sb.append(processValue(key, entry.getValue()));
916 sb.append(StringPool.AMPERSAND);
917 }
918 }
919
920 if (_doAsUserId > 0) {
921 try {
922 Company company = PortalUtil.getCompany(_request);
923
924 sb.append("doAsUserId");
925 sb.append(StringPool.EQUAL);
926 sb.append(processValue(company.getKeyObj(), _doAsUserId));
927 sb.append(StringPool.AMPERSAND);
928 }
929 catch (Exception e) {
930 _log.error(e);
931 }
932 }
933 else {
934 String doAsUserId = themeDisplay.getDoAsUserId();
935
936 if (Validator.isNotNull(doAsUserId)) {
937 sb.append("doAsUserId");
938 sb.append(StringPool.EQUAL);
939 sb.append(processValue(key, doAsUserId));
940 sb.append(StringPool.AMPERSAND);
941 }
942 }
943
944 String doAsUserLanguageId = _doAsUserLanguageId;
945
946 if (Validator.isNull(doAsUserLanguageId)) {
947 doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
948 }
949
950 if (Validator.isNotNull(doAsUserLanguageId)) {
951 sb.append("doAsUserLanguageId");
952 sb.append(StringPool.EQUAL);
953 sb.append(processValue(key, doAsUserLanguageId));
954 sb.append(StringPool.AMPERSAND);
955 }
956
957 long doAsGroupId = _doAsGroupId;
958
959 if (doAsGroupId <= 0) {
960 doAsGroupId = themeDisplay.getDoAsGroupId();
961 }
962
963 if (doAsGroupId > 0) {
964 sb.append("doAsGroupId");
965 sb.append(StringPool.EQUAL);
966 sb.append(processValue(key, doAsGroupId));
967 sb.append(StringPool.AMPERSAND);
968 }
969
970 long refererGroupId = _refererGroupId;
971
972 if (refererGroupId <= 0) {
973 refererGroupId = themeDisplay.getRefererGroupId();
974 }
975
976 if (refererGroupId > 0) {
977 sb.append("refererGroupId");
978 sb.append(StringPool.EQUAL);
979 sb.append(processValue(key, refererGroupId));
980 sb.append(StringPool.AMPERSAND);
981 }
982
983 long refererPlid = _refererPlid;
984
985 if (refererPlid <= 0) {
986 refererPlid = themeDisplay.getRefererPlid();
987 }
988
989 if (refererPlid > 0) {
990 sb.append("refererPlid");
991 sb.append(StringPool.EQUAL);
992 sb.append(processValue(key, refererPlid));
993 sb.append(StringPool.AMPERSAND);
994 }
995
996 for (Map.Entry<String, String[]> entry :
997 _removePublicRenderParameters.entrySet()) {
998
999 String lastString = sb.stringAt(sb.index() - 1);
1000
1001 if (lastString.charAt(lastString.length() - 1) !=
1002 CharPool.AMPERSAND) {
1003
1004 sb.append(StringPool.AMPERSAND);
1005 }
1006
1007 sb.append(HttpUtil.encodeURL(entry.getKey()));
1008 sb.append(StringPool.EQUAL);
1009 sb.append(processValue(key, entry.getValue()[0]));
1010 sb.append(StringPool.AMPERSAND);
1011 }
1012
1013 if (_copyCurrentRenderParameters) {
1014 mergeRenderParameters();
1015 }
1016
1017 int previousSbIndex = sb.index();
1018
1019 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1020 String name = entry.getKey();
1021 String[] values = entry.getValue();
1022
1023 if (isParameterIncludedInPath(name)) {
1024 continue;
1025 }
1026
1027 String publicRenderParameterName = getPublicRenderParameterName(
1028 name);
1029
1030 if (Validator.isNotNull(publicRenderParameterName)) {
1031 name = publicRenderParameterName;
1032 }
1033
1034 name = HttpUtil.encodeURL(prependNamespace(name));
1035
1036 for (String value : values) {
1037 sb.append(name);
1038 sb.append(StringPool.EQUAL);
1039 sb.append(processValue(key, value));
1040 sb.append(StringPool.AMPERSAND);
1041 }
1042 }
1043
1044 if (sb.index() > previousSbIndex) {
1045 sb.setIndex(sb.index() - 1);
1046 }
1047
1048 if (_encrypt) {
1049 sb.append(StringPool.AMPERSAND);
1050 sb.append(WebKeys.ENCRYPT);
1051 sb.append("=1");
1052 }
1053
1054 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1055 if (_anchor && (_windowStateString != null) &&
1056 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1057 !_windowStateString.equals(
1058 LiferayWindowState.EXCLUSIVE.toString()) &&
1059 !_windowStateString.equals(
1060 LiferayWindowState.POP_UP.toString())) {
1061
1062 String lastString = sb.stringAt(sb.index() - 1);
1063
1064 char lastChar = lastString.charAt(lastString.length() - 1);
1065
1066 if ((lastChar != CharPool.AMPERSAND) &&
1067 (lastChar != CharPool.QUESTION)) {
1068
1069 sb.append(StringPool.AMPERSAND);
1070 }
1071
1072 sb.append("#p_");
1073 sb.append(HttpUtil.encodeURL(_portletId));
1074 }
1075 }
1076
1077 String result = sb.toString();
1078
1079 if (result.endsWith(StringPool.AMPERSAND) ||
1080 result.endsWith(StringPool.QUESTION)) {
1081
1082 result = result.substring(0, result.length() - 1);
1083 }
1084
1085 if (themeDisplay.isFacebook()) {
1086
1087
1088
1089 int pos = result.indexOf(CharPool.QUESTION);
1090
1091 if (pos == -1) {
1092 if (!result.endsWith(StringPool.SLASH)) {
1093 result += StringPool.SLASH;
1094 }
1095 }
1096 else {
1097 String path = result.substring(0, pos);
1098
1099 if (!result.endsWith(StringPool.SLASH)) {
1100 result = path + StringPool.SLASH + result.substring(pos);
1101 }
1102 }
1103 }
1104 else if (!CookieKeys.hasSessionId(_request)) {
1105 result = PortalUtil.getURLWithSessionId(
1106 result, _request.getSession().getId());
1107 }
1108
1109 if (_escapeXml) {
1110 result = HtmlUtil.escape(result);
1111 }
1112
1113 if (result.length() > Http.URL_MAXIMUM_LENGTH) {
1114 result = HttpUtil.shortenURL(result, 2);
1115 }
1116
1117 return result;
1118 }
1119
1120 protected String generateWSRPToString() {
1121 StringBundler sb = new StringBundler("wsrp_rewrite?");
1122
1123 sb.append("wsrp-urlType");
1124 sb.append(StringPool.EQUAL);
1125
1126 if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
1127 sb.append(HttpUtil.encodeURL("blockingAction"));
1128 }
1129 else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
1130 sb.append(HttpUtil.encodeURL("render"));
1131 }
1132 else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1133 sb.append(HttpUtil.encodeURL("resource"));
1134 }
1135
1136 sb.append(StringPool.AMPERSAND);
1137
1138 if (_windowStateString != null) {
1139 sb.append("wsrp-windowState");
1140 sb.append(StringPool.EQUAL);
1141 sb.append(HttpUtil.encodeURL("wsrp:" + _windowStateString));
1142 sb.append(StringPool.AMPERSAND);
1143 }
1144
1145 if (_portletModeString != null) {
1146 sb.append("wsrp-mode");
1147 sb.append(StringPool.EQUAL);
1148 sb.append(HttpUtil.encodeURL("wsrp:" + _portletModeString));
1149 sb.append(StringPool.AMPERSAND);
1150 }
1151
1152 if (_resourceID != null) {
1153 sb.append("wsrp-resourceID");
1154 sb.append(StringPool.EQUAL);
1155 sb.append(HttpUtil.encodeURL(_resourceID));
1156 sb.append(StringPool.AMPERSAND);
1157 }
1158
1159 if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1160 sb.append("wsrp-resourceCacheability");
1161 sb.append(StringPool.EQUAL);
1162 sb.append(HttpUtil.encodeURL(_cacheability));
1163 sb.append(StringPool.AMPERSAND);
1164 }
1165
1166 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1167 if (_anchor && (_windowStateString != null) &&
1168 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1169 !_windowStateString.equals(
1170 LiferayWindowState.EXCLUSIVE.toString()) &&
1171 !_windowStateString.equals(
1172 LiferayWindowState.POP_UP.toString())) {
1173
1174 sb.append("wsrp-fragmentID");
1175 sb.append(StringPool.EQUAL);
1176 sb.append("#p_");
1177 sb.append(HttpUtil.encodeURL(_portletId));
1178 sb.append(StringPool.AMPERSAND);
1179 }
1180 }
1181
1182 if (_copyCurrentRenderParameters) {
1183 mergeRenderParameters();
1184 }
1185
1186 StringBundler parameterSb = new StringBundler();
1187
1188 int previousSbIndex = sb.index();
1189
1190 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1191 String name = entry.getKey();
1192 String[] values = entry.getValue();
1193
1194 if (isParameterIncludedInPath(name)) {
1195 continue;
1196 }
1197
1198 String publicRenderParameterName = getPublicRenderParameterName(
1199 name);
1200
1201 if (Validator.isNotNull(publicRenderParameterName)) {
1202 name = publicRenderParameterName;
1203 }
1204
1205 name = HttpUtil.encodeURL(prependNamespace(name));
1206
1207 for (String value : values) {
1208 parameterSb.append(name);
1209 parameterSb.append(StringPool.EQUAL);
1210 parameterSb.append(HttpUtil.encodeURL(value));
1211 parameterSb.append(StringPool.AMPERSAND);
1212 }
1213 }
1214
1215 if (sb.index() > previousSbIndex) {
1216 sb.setIndex(sb.index() - 1);
1217 }
1218
1219 sb.append("wsrp-navigationalState");
1220 sb.append(StringPool.EQUAL);
1221
1222 byte[] parameterBytes = null;
1223
1224 try {
1225 String parameterString = parameterSb.toString();
1226
1227 parameterBytes = parameterString.getBytes(StringPool.UTF8);
1228 }
1229 catch (UnsupportedEncodingException uee) {
1230 if (_log.isWarnEnabled()) {
1231 _log.warn(uee, uee);
1232 }
1233 }
1234
1235 String navigationalState = Base64.toURLSafe(
1236 Base64.encode(parameterBytes));
1237
1238 sb.append(navigationalState);
1239
1240 sb.append("/wsrp_rewrite");
1241
1242 return sb.toString();
1243 }
1244
1245 protected String getPublicRenderParameterName(String name) {
1246 Portlet portlet = getPortlet();
1247
1248 String publicRenderParameterName = null;
1249
1250 if (portlet != null) {
1251 PublicRenderParameter publicRenderParameter =
1252 portlet.getPublicRenderParameter(name);
1253
1254 if (publicRenderParameter != null) {
1255 QName qName = publicRenderParameter.getQName();
1256
1257 publicRenderParameterName =
1258 PortletQNameUtil.getPublicRenderParameterName(qName);
1259 }
1260 }
1261
1262 return publicRenderParameterName;
1263 }
1264
1265 protected boolean isBlankValue(String[] value) {
1266 if ((value != null) && (value.length == 1) &&
1267 value[0].equals(StringPool.BLANK)) {
1268
1269 return true;
1270 }
1271 else {
1272 return false;
1273 }
1274 }
1275
1276 protected void mergeRenderParameters() {
1277 String namespace = getNamespace();
1278
1279 Layout layout = getLayout();
1280
1281 Map<String, String[]> renderParameters = RenderParametersPool.get(
1282 _request, layout.getPlid(), getPortlet().getPortletId());
1283
1284 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1285 String name = entry.getKey();
1286
1287 if (name.contains(namespace)) {
1288 name = name.substring(namespace.length());
1289 }
1290
1291 if (!_lifecycle.equals(PortletRequest.RESOURCE_PHASE) &&
1292 (_removedParameterNames != null) &&
1293 _removedParameterNames.contains(name)) {
1294
1295 continue;
1296 }
1297
1298 String[] oldValues = entry.getValue();
1299 String[] newValues = _params.get(name);
1300
1301 if (newValues == null) {
1302 _params.put(name, oldValues);
1303 }
1304 else if (isBlankValue(newValues)) {
1305 _params.remove(name);
1306 }
1307 else {
1308 newValues = ArrayUtil.append(newValues, oldValues);
1309
1310 _params.put(name, newValues);
1311 }
1312 }
1313 }
1314
1315 protected String prependNamespace(String name) {
1316 String namespace = getNamespace();
1317
1318 if (!name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) &&
1319 !name.startsWith(namespace) &&
1320 !PortalUtil.isReservedParameter(name)) {
1321
1322 return namespace.concat(name);
1323 }
1324
1325 return name;
1326 }
1327
1328 protected String processValue(Key key, int value) {
1329 return processValue(key, String.valueOf(value));
1330 }
1331
1332 protected String processValue(Key key, long value) {
1333 return processValue(key, String.valueOf(value));
1334 }
1335
1336 protected String processValue(Key key, String value) {
1337 if (key == null) {
1338 return HttpUtil.encodeURL(value);
1339 }
1340
1341 try {
1342 return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1343 }
1344 catch (EncryptorException ee) {
1345 return value;
1346 }
1347 }
1348
1349 protected void removeParameter(String name) {
1350 if (_params.containsKey(name)) {
1351 _params.remove(name);
1352 }
1353 }
1354
1355 private static final Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1356
1357 private boolean _anchor = true;
1358 private String _cacheability = ResourceURL.PAGE;
1359 private boolean _copyCurrentRenderParameters;
1360 private long _doAsGroupId;
1361 private long _doAsUserId;
1362 private String _doAsUserLanguageId;
1363 private boolean _encrypt;
1364 private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1365 private Layout _layout;
1366 private String _layoutFriendlyURL;
1367 private String _lifecycle;
1368 private String _namespace;
1369 private final Set<String> _parametersIncludedInPath;
1370 private Map<String, String[]> _params;
1371 private long _plid;
1372 private Portlet _portlet;
1373 private String _portletId;
1374 private String _portletModeString;
1375 private final PortletRequest _portletRequest;
1376 private long _refererGroupId;
1377 private long _refererPlid;
1378 private Set<String> _removedParameterNames;
1379 private final Map<String, String[]> _removePublicRenderParameters;
1380 private final HttpServletRequest _request;
1381 private Map<String, String> _reservedParameters;
1382 private String _resourceID;
1383 private boolean _secure;
1384 private String _toString;
1385 private boolean _windowStateRestoreCurrentView;
1386 private String _windowStateString;
1387 private final boolean _wsrp;
1388
1389 private class ToStringPrivilegedAction implements PrivilegedAction<String> {
1390
1391 @Override
1392 public String run() {
1393 if (_wsrp) {
1394 return generateWSRPToString();
1395 }
1396
1397 return generateToString();
1398 }
1399
1400 }
1401
1402 }