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