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