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