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