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