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.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) || (value == null)) {
525 throw new IllegalArgumentException();
526 }
527
528 setParameter(name, new String[] {value}, append);
529 }
530
531 @Override
532 public void setParameter(String name, String[] values) {
533 setParameter(name, values, PropsValues.PORTLET_URL_APPEND_PARAMETERS);
534 }
535
536 @Override
537 public void setParameter(String name, String[] values, boolean append) {
538 if ((name == null) || (values == null)) {
539 throw new IllegalArgumentException();
540 }
541
542 for (String value : values) {
543 if (value == null) {
544 throw new IllegalArgumentException();
545 }
546 }
547
548 if (!append) {
549 _params.put(name, values);
550 }
551 else {
552 String[] oldValues = _params.get(name);
553
554 if (oldValues == null) {
555 _params.put(name, values);
556 }
557 else {
558 String[] newValues = ArrayUtil.append(oldValues, values);
559
560 _params.put(name, newValues);
561 }
562 }
563
564 clearCache();
565 }
566
567 @Override
568 public void setParameters(Map<String, String[]> params) {
569 if (params == null) {
570 throw new IllegalArgumentException();
571 }
572 else {
573 Map<String, String[]> newParams = new LinkedHashMap<>();
574
575 for (Map.Entry<String, String[]> entry : params.entrySet()) {
576 try {
577 String key = entry.getKey();
578 String[] value = entry.getValue();
579
580 if (key == null) {
581 throw new IllegalArgumentException();
582 }
583 else if (value == null) {
584 throw new IllegalArgumentException();
585 }
586
587 newParams.put(key, value);
588 }
589 catch (ClassCastException cce) {
590 throw new IllegalArgumentException(cce);
591 }
592 }
593
594 _params = newParams;
595 }
596
597 clearCache();
598 }
599
600 @Override
601 public void setPlid(long plid) {
602 _plid = plid;
603
604 clearCache();
605 }
606
607 @Override
608 public void setPortletId(String portletId) {
609 _portletId = portletId;
610
611 clearCache();
612 }
613
614 @Override
615 public void setPortletMode(PortletMode portletMode)
616 throws PortletModeException {
617
618 if (_portletRequest != null) {
619 Portlet portlet = getPortlet();
620
621 if ((portlet != null) &&
622 !portlet.hasPortletMode(
623 _portletRequest.getResponseContentType(), portletMode)) {
624
625 throw new PortletModeException(
626 portletMode.toString(), portletMode);
627 }
628 }
629
630 _portletModeString = portletMode.toString();
631
632 clearCache();
633 }
634
635 public void setPortletMode(String portletMode) throws PortletModeException {
636 setPortletMode(PortletModeFactory.getPortletMode(portletMode));
637 }
638
639 @Override
640 public void setProperty(String key, String value) {
641 if (key == null) {
642 throw new IllegalArgumentException();
643 }
644 }
645
646 public void setRefererGroupId(long refererGroupId) {
647 _refererGroupId = refererGroupId;
648
649 clearCache();
650 }
651
652 @Override
653 public void setRefererPlid(long refererPlid) {
654 _refererPlid = refererPlid;
655
656 clearCache();
657 }
658
659 @Override
660 public void setRemovedParameterNames(Set<String> removedParameterNames) {
661 _removedParameterNames = removedParameterNames;
662
663 clearCache();
664 }
665
666 @Override
667 public void setResourceID(String resourceID) {
668 _resourceID = resourceID;
669 }
670
671 @Override
672 public void setSecure(boolean secure) {
673 _secure = secure;
674
675 clearCache();
676 }
677
678 public void setWindowState(String windowState) throws WindowStateException {
679 setWindowState(WindowStateFactory.getWindowState(windowState));
680 }
681
682 @Override
683 public void setWindowState(WindowState windowState)
684 throws WindowStateException {
685
686 if (_portletRequest != null) {
687 if (!_portletRequest.isWindowStateAllowed(windowState)) {
688 throw new WindowStateException(
689 windowState.toString(), windowState);
690 }
691 }
692
693 if (LiferayWindowState.isWindowStatePreserved(
694 getWindowState(), windowState)) {
695
696 _windowStateString = windowState.toString();
697 }
698
699 clearCache();
700 }
701
702 public void setWindowStateRestoreCurrentView(
703 boolean windowStateRestoreCurrentView) {
704
705 _windowStateRestoreCurrentView = windowStateRestoreCurrentView;
706 }
707
708 @Override
709 public String toString() {
710 if (_toString != null) {
711 return _toString;
712 }
713
714 _toString = DoPrivilegedUtil.wrap(new ToStringPrivilegedAction());
715
716 return _toString;
717 }
718
719 @Override
720 public void write(Writer writer) throws IOException {
721 write(writer, _escapeXml);
722 }
723
724 @Override
725 public void write(Writer writer, boolean escapeXml) throws IOException {
726 String toString = toString();
727
728 if (escapeXml && !_escapeXml) {
729 toString = HtmlUtil.escape(toString);
730 }
731
732 writer.write(toString);
733 }
734
735 protected PortletURLImpl(
736 HttpServletRequest request, String portletId,
737 PortletRequest portletRequest, long plid, String lifecycle) {
738
739 _request = request;
740 _portletId = portletId;
741 _portletRequest = portletRequest;
742 _plid = plid;
743 _lifecycle = lifecycle;
744 _parametersIncludedInPath = new LinkedHashSet<>();
745 _params = new LinkedHashMap<>();
746 _removePublicRenderParameters = new LinkedHashMap<>();
747 _secure = PortalUtil.isSecure(request);
748 _wsrp = ParamUtil.getBoolean(request, "wsrp");
749
750 Portlet portlet = getPortlet();
751
752 if (portlet != null) {
753 Set<String> autopropagatedParameters =
754 portlet.getAutopropagatedParameters();
755
756 for (String autopropagatedParameter : autopropagatedParameters) {
757 if (PortalUtil.isReservedParameter(autopropagatedParameter)) {
758 continue;
759 }
760
761 String value = request.getParameter(autopropagatedParameter);
762
763 if (value != null) {
764 setParameter(autopropagatedParameter, value);
765 }
766 }
767
768 PortletApp portletApp = portlet.getPortletApp();
769
770 _escapeXml = MapUtil.getBoolean(
771 portletApp.getContainerRuntimeOptions(),
772 LiferayPortletConfig.RUNTIME_OPTION_ESCAPE_XML,
773 PropsValues.PORTLET_URL_ESCAPE_XML);
774 }
775
776 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
777
778 if ((layout != null) && (layout.getPlid() == _plid) &&
779 (layout instanceof VirtualLayout)) {
780
781 _layout = layout;
782 }
783 }
784
785 protected void addPortalAuthToken(StringBundler sb, Key key) {
786 if (!PropsValues.AUTH_TOKEN_CHECK_ENABLED ||
787 !_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
788
789 return;
790 }
791
792 Portlet portlet = getPortlet();
793
794 if (portlet == null) {
795 return;
796 }
797
798 String strutsAction = getParameter("struts_action");
799
800 if (AuthTokenWhitelistUtil.isPortletCSRFWhitelisted(
801 portlet.getCompanyId(), _portletId, strutsAction)) {
802
803 return;
804 }
805
806 sb.append("p_auth");
807 sb.append(StringPool.EQUAL);
808 sb.append(processValue(key, AuthTokenUtil.getToken(_request)));
809 sb.append(StringPool.AMPERSAND);
810 }
811
812 protected void addPortletAuthToken(StringBundler sb, Key key) {
813 if (!PropsValues.PORTLET_ADD_DEFAULT_RESOURCE_CHECK_ENABLED) {
814 return;
815 }
816
817 Portlet portlet = getPortlet();
818
819 if (portlet == null) {
820 return;
821 }
822
823 if (!portlet.isAddDefaultResource()) {
824 return;
825 }
826
827 String strutsAction = getParameter("struts_action");
828
829 if (AuthTokenWhitelistUtil.isPortletInvocationWhitelisted(
830 portlet.getCompanyId(), _portletId, strutsAction)) {
831
832 return;
833 }
834
835 try {
836 LayoutTypePortlet targetLayoutTypePortlet =
837 (LayoutTypePortlet)getLayout().getLayoutType();
838
839 if (targetLayoutTypePortlet.hasPortletId(_portletId)) {
840 return;
841 }
842 }
843 catch (Exception e) {
844 if (_log.isDebugEnabled()) {
845 _log.debug(e.getMessage(), e);
846 }
847 }
848
849 String controlPanelMenuPortletId = PortletProviderUtil.getPortletId(
850 PortalProductMenuApplicationType.ProductMenu.CLASS_NAME,
851 PortletProvider.Action.VIEW);
852
853 if (_portletId.equals(controlPanelMenuPortletId)) {
854 return;
855 }
856
857 sb.append("p_p_auth");
858 sb.append(StringPool.EQUAL);
859 sb.append(
860 processValue(
861 key, AuthTokenUtil.getToken(_request, _plid, _portletId)));
862 sb.append(StringPool.AMPERSAND);
863 }
864
865 protected void clearCache() {
866 _reservedParameters = null;
867 _toString = null;
868 }
869
870 protected String generateToString() {
871 StringBundler sb = new StringBundler(64);
872
873 ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
874 WebKeys.THEME_DISPLAY);
875
876 if (themeDisplay == null) {
877 if (_log.isWarnEnabled()) {
878 _log.warn(
879 "Unable to generate string because theme display is null");
880 }
881
882 return StringPool.BLANK;
883 }
884
885 String portalURL = null;
886
887 if (themeDisplay.isFacebook()) {
888 portalURL =
889 FacebookUtil.FACEBOOK_APPS_URL +
890 themeDisplay.getFacebookCanvasPageURL();
891 }
892 else {
893 portalURL = PortalUtil.getPortalURL(_request, _secure);
894 }
895
896 try {
897 if (_layoutFriendlyURL == null) {
898 Layout layout = getLayout();
899
900 if (layout != null) {
901 _layoutFriendlyURL = GetterUtil.getString(
902 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
903
904 if (_secure) {
905 _layoutFriendlyURL = HttpUtil.protocolize(
906 _layoutFriendlyURL,
907 PropsValues.WEB_SERVER_HTTPS_PORT, true);
908 }
909 }
910 }
911 }
912 catch (Exception e) {
913 _log.error(e);
914 }
915
916 Key key = null;
917
918 try {
919 if (_encrypt) {
920 Company company = PortalUtil.getCompany(_request);
921
922 key = company.getKeyObj();
923 }
924 }
925 catch (Exception e) {
926 _log.error(e);
927 }
928
929 if (Validator.isNull(_layoutFriendlyURL)) {
930 sb.append(portalURL);
931 sb.append(themeDisplay.getPathMain());
932 sb.append("/portal/layout?");
933
934 addPortalAuthToken(sb, key);
935
936 sb.append("p_l_id");
937 sb.append(StringPool.EQUAL);
938 sb.append(processValue(key, _plid));
939 sb.append(StringPool.AMPERSAND);
940 }
941 else {
942 if (themeDisplay.isFacebook()) {
943 sb.append(portalURL);
944 }
945 else {
946
947
948
949
950
951 if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
952 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
953
954 sb.append(portalURL);
955 }
956
957 sb.append(_layoutFriendlyURL);
958 }
959
960 String friendlyURLPath = getPortletFriendlyURLPath();
961
962 if (Validator.isNotNull(friendlyURLPath)) {
963 if (themeDisplay.isFacebook()) {
964 int pos = friendlyURLPath.indexOf(CharPool.SLASH, 1);
965
966 if (pos != -1) {
967 sb.append(friendlyURLPath.substring(pos));
968 }
969 else {
970 sb.append(friendlyURLPath);
971 }
972 }
973 else {
974 sb.append("/-");
975 sb.append(friendlyURLPath);
976 }
977 }
978
979 sb.append(StringPool.QUESTION);
980
981 addPortalAuthToken(sb, key);
982 }
983
984 addPortletAuthToken(sb, key);
985
986 for (Map.Entry<String, String> entry :
987 getReservedParameterMap().entrySet()) {
988
989 String name = entry.getKey();
990
991 if (!isParameterIncludedInPath(name)) {
992 sb.append(HttpUtil.encodeURL(name));
993 sb.append(StringPool.EQUAL);
994 sb.append(processValue(key, entry.getValue()));
995 sb.append(StringPool.AMPERSAND);
996 }
997 }
998
999 if (_doAsUserId > 0) {
1000 try {
1001 Company company = PortalUtil.getCompany(_request);
1002
1003 sb.append("doAsUserId");
1004 sb.append(StringPool.EQUAL);
1005 sb.append(processValue(company.getKeyObj(), _doAsUserId));
1006 sb.append(StringPool.AMPERSAND);
1007 }
1008 catch (Exception e) {
1009 _log.error(e);
1010 }
1011 }
1012 else {
1013 String doAsUserId = themeDisplay.getDoAsUserId();
1014
1015 if (Validator.isNotNull(doAsUserId)) {
1016 sb.append("doAsUserId");
1017 sb.append(StringPool.EQUAL);
1018 sb.append(processValue(key, doAsUserId));
1019 sb.append(StringPool.AMPERSAND);
1020 }
1021 }
1022
1023 String doAsUserLanguageId = _doAsUserLanguageId;
1024
1025 if (Validator.isNull(doAsUserLanguageId)) {
1026 doAsUserLanguageId = themeDisplay.getDoAsUserLanguageId();
1027 }
1028
1029 if (Validator.isNotNull(doAsUserLanguageId)) {
1030 sb.append("doAsUserLanguageId");
1031 sb.append(StringPool.EQUAL);
1032 sb.append(processValue(key, doAsUserLanguageId));
1033 sb.append(StringPool.AMPERSAND);
1034 }
1035
1036 long doAsGroupId = _doAsGroupId;
1037
1038 if (doAsGroupId <= 0) {
1039 doAsGroupId = themeDisplay.getDoAsGroupId();
1040 }
1041
1042 if (doAsGroupId > 0) {
1043 sb.append("doAsGroupId");
1044 sb.append(StringPool.EQUAL);
1045 sb.append(processValue(key, doAsGroupId));
1046 sb.append(StringPool.AMPERSAND);
1047 }
1048
1049 long refererGroupId = _refererGroupId;
1050
1051 if (refererGroupId <= 0) {
1052 refererGroupId = themeDisplay.getRefererGroupId();
1053 }
1054
1055 if (refererGroupId > 0) {
1056 sb.append("refererGroupId");
1057 sb.append(StringPool.EQUAL);
1058 sb.append(processValue(key, refererGroupId));
1059 sb.append(StringPool.AMPERSAND);
1060 }
1061
1062 long refererPlid = _refererPlid;
1063
1064 if (refererPlid <= 0) {
1065 refererPlid = themeDisplay.getRefererPlid();
1066 }
1067
1068 if (refererPlid > 0) {
1069 sb.append("refererPlid");
1070 sb.append(StringPool.EQUAL);
1071 sb.append(processValue(key, refererPlid));
1072 sb.append(StringPool.AMPERSAND);
1073 }
1074
1075 for (Map.Entry<String, String[]> entry :
1076 _removePublicRenderParameters.entrySet()) {
1077
1078 String lastString = sb.stringAt(sb.index() - 1);
1079
1080 if (lastString.charAt(lastString.length() - 1) !=
1081 CharPool.AMPERSAND) {
1082
1083 sb.append(StringPool.AMPERSAND);
1084 }
1085
1086 sb.append(HttpUtil.encodeURL(entry.getKey()));
1087 sb.append(StringPool.EQUAL);
1088 sb.append(processValue(key, entry.getValue()[0]));
1089 sb.append(StringPool.AMPERSAND);
1090 }
1091
1092 if (_copyCurrentRenderParameters) {
1093 mergeRenderParameters();
1094 }
1095
1096 int previousSbIndex = sb.index();
1097
1098 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1099 String name = entry.getKey();
1100 String[] values = entry.getValue();
1101
1102 if (isParameterIncludedInPath(name)) {
1103 continue;
1104 }
1105
1106 String publicRenderParameterName = getPublicRenderParameterName(
1107 name);
1108
1109 if (Validator.isNotNull(publicRenderParameterName)) {
1110 name = publicRenderParameterName;
1111 }
1112
1113 name = HttpUtil.encodeURL(prependNamespace(name));
1114
1115 for (String value : values) {
1116 sb.append(name);
1117 sb.append(StringPool.EQUAL);
1118 sb.append(processValue(key, value));
1119 sb.append(StringPool.AMPERSAND);
1120 }
1121 }
1122
1123 if (sb.index() > previousSbIndex) {
1124 sb.setIndex(sb.index() - 1);
1125 }
1126
1127 if (_encrypt) {
1128 sb.append(StringPool.AMPERSAND);
1129 sb.append(WebKeys.ENCRYPT);
1130 sb.append("=1");
1131 }
1132
1133 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1134 if (_anchor && (_windowStateString != null) &&
1135 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1136 !_windowStateString.equals(
1137 LiferayWindowState.EXCLUSIVE.toString()) &&
1138 !_windowStateString.equals(
1139 LiferayWindowState.POP_UP.toString())) {
1140
1141 String lastString = sb.stringAt(sb.index() - 1);
1142
1143 if (lastString.charAt(lastString.length() - 1) !=
1144 CharPool.AMPERSAND) {
1145
1146 sb.append(StringPool.AMPERSAND);
1147 }
1148
1149 sb.append("#p_");
1150 sb.append(HttpUtil.encodeURL(_portletId));
1151 }
1152 }
1153
1154 String result = sb.toString();
1155
1156 if (result.endsWith(StringPool.AMPERSAND) ||
1157 result.endsWith(StringPool.QUESTION)) {
1158
1159 result = result.substring(0, result.length() - 1);
1160 }
1161
1162 if (themeDisplay.isFacebook()) {
1163
1164
1165
1166 int pos = result.indexOf(CharPool.QUESTION);
1167
1168 if (pos == -1) {
1169 if (!result.endsWith(StringPool.SLASH)) {
1170 result += StringPool.SLASH;
1171 }
1172 }
1173 else {
1174 String path = result.substring(0, pos);
1175
1176 if (!result.endsWith(StringPool.SLASH)) {
1177 result = path + StringPool.SLASH + result.substring(pos);
1178 }
1179 }
1180 }
1181 else if (!CookieKeys.hasSessionId(_request)) {
1182 result = PortalUtil.getURLWithSessionId(
1183 result, _request.getSession().getId());
1184 }
1185
1186 if (_escapeXml) {
1187 result = HtmlUtil.escape(result);
1188 }
1189
1190 if (result.length() > Http.URL_MAXIMUM_LENGTH) {
1191 result = HttpUtil.shortenURL(result, 2);
1192 }
1193
1194 return result;
1195 }
1196
1197 protected String generateWSRPToString() {
1198 StringBundler sb = new StringBundler("wsrp_rewrite?");
1199
1200 sb.append("wsrp-urlType");
1201 sb.append(StringPool.EQUAL);
1202
1203 if (_lifecycle.equals(PortletRequest.ACTION_PHASE)) {
1204 sb.append(HttpUtil.encodeURL("blockingAction"));
1205 }
1206 else if (_lifecycle.equals(PortletRequest.RENDER_PHASE)) {
1207 sb.append(HttpUtil.encodeURL("render"));
1208 }
1209 else if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1210 sb.append(HttpUtil.encodeURL("resource"));
1211 }
1212
1213 sb.append(StringPool.AMPERSAND);
1214
1215 if (_windowStateString != null) {
1216 sb.append("wsrp-windowState");
1217 sb.append(StringPool.EQUAL);
1218 sb.append(HttpUtil.encodeURL("wsrp:" + _windowStateString));
1219 sb.append(StringPool.AMPERSAND);
1220 }
1221
1222 if (_portletModeString != null) {
1223 sb.append("wsrp-mode");
1224 sb.append(StringPool.EQUAL);
1225 sb.append(HttpUtil.encodeURL("wsrp:" + _portletModeString));
1226 sb.append(StringPool.AMPERSAND);
1227 }
1228
1229 if (_resourceID != null) {
1230 sb.append("wsrp-resourceID");
1231 sb.append(StringPool.EQUAL);
1232 sb.append(HttpUtil.encodeURL(_resourceID));
1233 sb.append(StringPool.AMPERSAND);
1234 }
1235
1236 if (_lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1237 sb.append("wsrp-resourceCacheability");
1238 sb.append(StringPool.EQUAL);
1239 sb.append(HttpUtil.encodeURL(_cacheability));
1240 sb.append(StringPool.AMPERSAND);
1241 }
1242
1243 if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
1244 if (_anchor && (_windowStateString != null) &&
1245 !_windowStateString.equals(WindowState.MAXIMIZED.toString()) &&
1246 !_windowStateString.equals(
1247 LiferayWindowState.EXCLUSIVE.toString()) &&
1248 !_windowStateString.equals(
1249 LiferayWindowState.POP_UP.toString())) {
1250
1251 sb.append("wsrp-fragmentID");
1252 sb.append(StringPool.EQUAL);
1253 sb.append("#p_");
1254 sb.append(HttpUtil.encodeURL(_portletId));
1255 sb.append(StringPool.AMPERSAND);
1256 }
1257 }
1258
1259 if (_copyCurrentRenderParameters) {
1260 mergeRenderParameters();
1261 }
1262
1263 StringBundler parameterSb = new StringBundler();
1264
1265 int previousSbIndex = sb.index();
1266
1267 for (Map.Entry<String, String[]> entry : _params.entrySet()) {
1268 String name = entry.getKey();
1269 String[] values = entry.getValue();
1270
1271 if (isParameterIncludedInPath(name)) {
1272 continue;
1273 }
1274
1275 String publicRenderParameterName = getPublicRenderParameterName(
1276 name);
1277
1278 if (Validator.isNotNull(publicRenderParameterName)) {
1279 name = publicRenderParameterName;
1280 }
1281
1282 name = HttpUtil.encodeURL(prependNamespace(name));
1283
1284 for (String value : values) {
1285 parameterSb.append(name);
1286 parameterSb.append(StringPool.EQUAL);
1287 parameterSb.append(HttpUtil.encodeURL(value));
1288 parameterSb.append(StringPool.AMPERSAND);
1289 }
1290 }
1291
1292 if (sb.index() > previousSbIndex) {
1293 sb.setIndex(sb.index() - 1);
1294 }
1295
1296 sb.append("wsrp-navigationalState");
1297 sb.append(StringPool.EQUAL);
1298
1299 byte[] parameterBytes = null;
1300
1301 try {
1302 String parameterString = parameterSb.toString();
1303
1304 parameterBytes = parameterString.getBytes(StringPool.UTF8);
1305 }
1306 catch (UnsupportedEncodingException uee) {
1307 if (_log.isWarnEnabled()) {
1308 _log.warn(uee, uee);
1309 }
1310 }
1311
1312 String navigationalState = Base64.toURLSafe(
1313 Base64.encode(parameterBytes));
1314
1315 sb.append(navigationalState);
1316
1317 sb.append("/wsrp_rewrite");
1318
1319 return sb.toString();
1320 }
1321
1322 protected String getPublicRenderParameterName(String name) {
1323 Portlet portlet = getPortlet();
1324
1325 String publicRenderParameterName = null;
1326
1327 if (portlet != null) {
1328 PublicRenderParameter publicRenderParameter =
1329 portlet.getPublicRenderParameter(name);
1330
1331 if (publicRenderParameter != null) {
1332 QName qName = publicRenderParameter.getQName();
1333
1334 publicRenderParameterName =
1335 PortletQNameUtil.getPublicRenderParameterName(qName);
1336 }
1337 }
1338
1339 return publicRenderParameterName;
1340 }
1341
1342 protected boolean isBlankValue(String[] value) {
1343 if ((value != null) && (value.length == 1) &&
1344 value[0].equals(StringPool.BLANK)) {
1345
1346 return true;
1347 }
1348 else {
1349 return false;
1350 }
1351 }
1352
1353 protected void mergeRenderParameters() {
1354 String namespace = getNamespace();
1355
1356 Layout layout = getLayout();
1357
1358 Map<String, String[]> renderParameters = RenderParametersPool.get(
1359 _request, layout.getPlid(), getPortlet().getPortletId());
1360
1361 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1362 String name = entry.getKey();
1363
1364 if (name.contains(namespace)) {
1365 name = name.substring(namespace.length());
1366 }
1367
1368 if (!_lifecycle.equals(PortletRequest.RESOURCE_PHASE) &&
1369 (_removedParameterNames != null) &&
1370 _removedParameterNames.contains(name)) {
1371
1372 continue;
1373 }
1374
1375 String[] oldValues = entry.getValue();
1376 String[] newValues = _params.get(name);
1377
1378 if (newValues == null) {
1379 _params.put(name, oldValues);
1380 }
1381 else if (isBlankValue(newValues)) {
1382 _params.remove(name);
1383 }
1384 else {
1385 newValues = ArrayUtil.append(newValues, oldValues);
1386
1387 _params.put(name, newValues);
1388 }
1389 }
1390 }
1391
1392 protected String prependNamespace(String name) {
1393 String namespace = getNamespace();
1394
1395 if (!PortalUtil.isReservedParameter(name) &&
1396 !name.startsWith(PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE) &&
1397 !name.startsWith(namespace)) {
1398
1399 return namespace.concat(name);
1400 }
1401 else {
1402 return name;
1403 }
1404 }
1405
1406 protected String processValue(Key key, int value) {
1407 return processValue(key, String.valueOf(value));
1408 }
1409
1410 protected String processValue(Key key, long value) {
1411 return processValue(key, String.valueOf(value));
1412 }
1413
1414 protected String processValue(Key key, String value) {
1415 if (key == null) {
1416 return HttpUtil.encodeURL(value);
1417 }
1418
1419 try {
1420 return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
1421 }
1422 catch (EncryptorException ee) {
1423 return value;
1424 }
1425 }
1426
1427 private static final Log _log = LogFactoryUtil.getLog(PortletURLImpl.class);
1428
1429 private boolean _anchor = true;
1430 private String _cacheability = ResourceURL.PAGE;
1431 private boolean _copyCurrentRenderParameters;
1432 private long _doAsGroupId;
1433 private long _doAsUserId;
1434 private String _doAsUserLanguageId;
1435 private boolean _encrypt;
1436 private boolean _escapeXml = PropsValues.PORTLET_URL_ESCAPE_XML;
1437 private Layout _layout;
1438 private String _layoutFriendlyURL;
1439 private String _lifecycle;
1440 private String _namespace;
1441 private final Set<String> _parametersIncludedInPath;
1442 private Map<String, String[]> _params;
1443 private long _plid;
1444 private Portlet _portlet;
1445 private String _portletId;
1446 private String _portletModeString;
1447 private final PortletRequest _portletRequest;
1448 private long _refererGroupId;
1449 private long _refererPlid;
1450 private Set<String> _removedParameterNames;
1451 private final Map<String, String[]> _removePublicRenderParameters;
1452 private final HttpServletRequest _request;
1453 private Map<String, String> _reservedParameters;
1454 private String _resourceID;
1455 private boolean _secure;
1456 private String _toString;
1457 private boolean _windowStateRestoreCurrentView;
1458 private String _windowStateString;
1459 private final boolean _wsrp;
1460
1461 private class ToStringPrivilegedAction implements PrivilegedAction<String> {
1462
1463 @Override
1464 public String run() {
1465 if (_wsrp) {
1466 return generateWSRPToString();
1467 }
1468
1469 return generateToString();
1470 }
1471
1472 }
1473
1474 }