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