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