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