1
22
23 package com.liferay.portlet;
24
25 import com.liferay.portal.SystemException;
26 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
27 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
28 import com.liferay.portal.kernel.portlet.LiferayWindowState;
29 import com.liferay.portal.kernel.util.ArrayUtil;
30 import com.liferay.portal.kernel.util.GetterUtil;
31 import com.liferay.portal.kernel.util.StringMaker;
32 import com.liferay.portal.kernel.util.StringPool;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.model.Company;
35 import com.liferay.portal.model.Layout;
36 import com.liferay.portal.model.Portlet;
37 import com.liferay.portal.service.LayoutLocalServiceUtil;
38 import com.liferay.portal.service.PortletLocalServiceUtil;
39 import com.liferay.portal.theme.PortletDisplay;
40 import com.liferay.portal.theme.ThemeDisplay;
41 import com.liferay.portal.util.PortalUtil;
42 import com.liferay.portal.util.PropsUtil;
43 import com.liferay.portal.util.WebKeys;
44 import com.liferay.util.Encryptor;
45 import com.liferay.util.EncryptorException;
46 import com.liferay.util.Http;
47 import com.liferay.util.HttpUtil;
48
49 import java.io.Serializable;
50
51 import java.security.Key;
52
53 import java.util.Iterator;
54 import java.util.LinkedHashMap;
55 import java.util.LinkedHashSet;
56 import java.util.Map;
57 import java.util.Set;
58
59 import javax.portlet.PortletMode;
60 import javax.portlet.PortletModeException;
61 import javax.portlet.PortletRequest;
62 import javax.portlet.PortletSecurityException;
63 import javax.portlet.WindowState;
64 import javax.portlet.WindowStateException;
65
66 import javax.servlet.http.HttpServletRequest;
67
68 import org.apache.commons.logging.Log;
69 import org.apache.commons.logging.LogFactory;
70
71
78 public class PortletURLImpl implements LiferayPortletURL, Serializable {
79
80 public static final boolean APPEND_PARAMETERS = GetterUtil.getBoolean(
81 PropsUtil.get(PropsUtil.PORTLET_URL_APPEND_PARAMETERS));
82
83 public PortletURLImpl(
84 ActionRequestImpl req, String portletId, long plid, boolean action) {
85
86 this(req.getHttpServletRequest(), portletId, plid, action);
87
88 _portletReq = req;
89 }
90
91 public PortletURLImpl(
92 RenderRequestImpl req, String portletId, long plid, boolean action) {
93
94 this(req.getHttpServletRequest(), portletId, plid, action);
95
96 _portletReq = req;
97 }
98
99 public PortletURLImpl(
100 HttpServletRequest req, String portletId, long plid, boolean action) {
101
102 _req = req;
103 _portletId = portletId;
104 _plid = plid;
105 _secure = req.isSecure();
106 _action = action;
107 _params = new LinkedHashMap();
108 _parametersIncludedInPath = new LinkedHashSet();
109 }
110
111 public HttpServletRequest getReq() {
112 return _req;
113 }
114
115 public PortletRequest getPortletReq() {
116 return _portletReq;
117 }
118
119 public String getPortletId() {
120 return _portletId;
121 }
122
123 public void setPortletId(String portletId) {
124 _portletId = portletId;
125
126
128 _toString = null;
129 }
130
131
134 public String getPortletName() {
135 return getPortletId();
136 }
137
138
141 public void setPortletName(String portletName) {
142 setPortletId(portletName);
143 }
144
145 public Portlet getPortlet() {
146 if (_portlet == null) {
147 try {
148 _portlet = PortletLocalServiceUtil.getPortletById(
149 PortalUtil.getCompanyId(_req), _portletId);
150 }
151 catch (SystemException se) {
152 _log.error(se.getMessage());
153 }
154 }
155
156 return _portlet;
157 }
158
159 public String getPortletFriendlyURLPath() {
160 String portletFriendlyURLPath = null;
161
162 Portlet portlet = getPortlet();
163
164 if (portlet != null) {
165 FriendlyURLMapper mapper = portlet.getFriendlyURLMapperInstance();
166
167 if (mapper != null) {
168 portletFriendlyURLPath = mapper.buildPath(this);
169
170 if (_log.isDebugEnabled()) {
171 _log.debug(
172 "Portlet friendly URL path " + portletFriendlyURLPath);
173 }
174 }
175 }
176
177 return portletFriendlyURLPath;
178 }
179
180 public String getNamespace() {
181 if (_namespace == null) {
182 _namespace = PortalUtil.getPortletNamespace(_portletId);
183 }
184
185 return _namespace;
186 }
187
188 public long getPlid() {
189 return _plid;
190 }
191
192 public Layout getLayout() {
193 if (_layout == null) {
194 try {
195 if (_plid > 0) {
196 _layout = LayoutLocalServiceUtil.getLayout(_plid);
197 }
198 }
199 catch (Exception e) {
200 if (_log.isWarnEnabled()) {
201 _log.warn("Layout cannot be found for " + _plid);
202 }
203 }
204 }
205
206 return _layout;
207 }
208
209 public String getLayoutFriendlyURL() {
210 return _layoutFriendlyURL;
211 }
212
213 public boolean isAction() {
214 return _action;
215 }
216
217 public void setAction(boolean action) {
218 _action = action;
219
220
222 _toString = null;
223 }
224
225 public WindowState getWindowState() {
226 return _windowState;
227 }
228
229 public void setWindowState(WindowState windowState)
230 throws WindowStateException {
231
232 if (_portletReq != null) {
233 if (!_portletReq.isWindowStateAllowed(windowState)) {
234 throw new WindowStateException(
235 windowState.toString(), windowState);
236 }
237 }
238
239 if (LiferayWindowState.isWindowStatePreserved(
240 getWindowState(), windowState)) {
241
242 _windowState = windowState;
243 }
244
245
247 _toString = null;
248 }
249
250 public void setWindowState(String windowState)
251 throws WindowStateException {
252
253 setWindowState(new WindowState(windowState));
254 }
255
256 public PortletMode getPortletMode() {
257 return _portletMode;
258 }
259
260 public void setPortletMode(PortletMode portletMode)
261 throws PortletModeException {
262
263 if (_portletReq != null) {
264 if (!getPortlet().hasPortletMode(
265 _portletReq.getResponseContentType(), portletMode)) {
266
267 throw new PortletModeException(
268 portletMode.toString(), portletMode);
269 }
270 }
271
272 _portletMode = portletMode;
273
274
276 _toString = null;
277 }
278
279 public void setPortletMode(String portletMode)
280 throws PortletModeException {
281
282 setPortletMode(new PortletMode(portletMode));
283 }
284
285 public String getParameter(String name) {
286 String[] values = (String[])_params.get(name);
287
288 if ((values != null) && (values.length > 0)) {
289 return values[0];
290 }
291 else {
292 return null;
293 }
294 }
295
296 public void setParameter(String name, String value) {
297 setParameter(name, value, APPEND_PARAMETERS);
298 }
299
300 public void setParameter(String name, String value, boolean append) {
301 if ((name == null) || (value == null)) {
302 throw new IllegalArgumentException();
303 }
304
305 setParameter(name, new String[] {value}, append);
306 }
307
308 public void setParameter(String name, String[] values) {
309 setParameter(name, values, APPEND_PARAMETERS);
310 }
311
312 public void setParameter(String name, String[] values, boolean append) {
313 if ((name == null) || (values == null)) {
314 throw new IllegalArgumentException();
315 }
316
317 for (int i = 0; i < values.length; i++) {
318 if (values[i] == null) {
319 throw new IllegalArgumentException();
320 }
321 }
322
323 if (append && _params.containsKey(name)) {
324 String[] oldValues = (String[])_params.get(name);
325
326 String[] newValues = ArrayUtil.append(oldValues, values);
327
328 _params.put(name, newValues);
329 }
330 else {
331 _params.put(name, values);
332 }
333
334
336 _toString = null;
337 }
338
339 public void setParameters(Map params) {
340 if (params == null) {
341 throw new IllegalArgumentException();
342 }
343 else {
344 Map newParams = new LinkedHashMap();
345
346 Iterator itr = params.entrySet().iterator();
347
348 while (itr.hasNext()) {
349 Map.Entry entry = (Map.Entry)itr.next();
350
351 Object key = entry.getKey();
352 Object value = entry.getValue();
353
354 if (key == null) {
355 throw new IllegalArgumentException();
356 }
357 else if (value == null) {
358 throw new IllegalArgumentException();
359 }
360
361 if (value instanceof String[]) {
362 newParams.put(key, value);
363 }
364 else {
365 throw new IllegalArgumentException();
366 }
367 }
368
369 _params = newParams;
370 }
371
372
374 _toString = null;
375 }
376
377 public Map getParameterMap() {
378 return _params;
379 }
380
381 public Set getParametersIncludedInPath() {
382 return _parametersIncludedInPath;
383 }
384
385 public void addParameterIncludedInPath(String name) {
386 _parametersIncludedInPath.add(name);
387 }
388
389 public boolean isParameterIncludedInPath(String name) {
390 if (_parametersIncludedInPath.contains(name)) {
391 return true;
392 }
393 else {
394 return false;
395 }
396 }
397
398 public boolean isSecure() {
399 return _secure;
400 }
401
402 public void setSecure(boolean secure) throws PortletSecurityException {
403 _secure = secure;
404
405
407 _toString = null;
408 }
409
410 public boolean isAnchor() {
411 return _anchor;
412 }
413
414 public void setAnchor(boolean anchor) {
415 _anchor = anchor;
416
417
419 _toString = null;
420 }
421
422 public boolean isEncrypt() {
423 return _encrypt;
424 }
425
426 public void setEncrypt(boolean encrypt) {
427 _encrypt = encrypt;
428
429
431 _toString = null;
432 }
433
434 public void setDoAsUserId(long doAsUserId) {
435 _doAsUserId = doAsUserId;
436
437
439 _toString = null;
440 }
441
442 public String toString() {
443 if (_toString != null) {
444 return _toString;
445 }
446
447 _toString = generateToString();
448
449 return _toString;
450 }
451
452 protected String generateToString() {
453 StringMaker sm = new StringMaker();
454
455 ThemeDisplay themeDisplay =
456 (ThemeDisplay)_req.getAttribute(WebKeys.THEME_DISPLAY);
457
458 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
459
460 String portalURL = PortalUtil.getPortalURL(_req, _secure);
461
462 try {
463 if (_layoutFriendlyURL == null) {
464 Layout layout = getLayout();
465
466 if (layout != null) {
467 _layoutFriendlyURL = GetterUtil.getString(
468 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
469 }
470 }
471 }
472 catch (Exception e) {
473 _log.error(e);
474 }
475
476 Key key = null;
477
478 try {
479 if (_encrypt) {
480 Company company = PortalUtil.getCompany(_req);
481
482 key = company.getKeyObj();
483 }
484 }
485 catch (Exception e) {
486 _log.error(e);
487 }
488
489 if (Validator.isNull(_layoutFriendlyURL)) {
490 sm.append(portalURL);
491 sm.append(themeDisplay.getPathMain());
492 sm.append("/portal/layout?");
493
494 sm.append("p_l_id");
495 sm.append(StringPool.EQUAL);
496 sm.append(processValue(key, _plid));
497 sm.append(StringPool.AMPERSAND);
498 }
499 else {
500
501
505 if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
506 !_layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
507
508 sm.append(portalURL);
509 }
510
511 sm.append(_layoutFriendlyURL);
512
513 String friendlyURLPath = getPortletFriendlyURLPath();
514
515 if (Validator.isNotNull(friendlyURLPath)) {
516 sm.append(friendlyURLPath);
517
518 if (!isAction()) {
519 addParameterIncludedInPath("p_p_action");
520 }
521
522
525 addParameterIncludedInPath("p_p_state");
526
528
531 addParameterIncludedInPath("p_p_mode");
532
534 addParameterIncludedInPath("p_p_col_id");
535 addParameterIncludedInPath("p_p_col_pos");
536 addParameterIncludedInPath("p_p_col_count");
537 }
538
539 sm.append(StringPool.QUESTION);
540 }
541
542 if (!isParameterIncludedInPath("p_p_id")) {
543 sm.append("p_p_id");
544 sm.append(StringPool.EQUAL);
545 sm.append(processValue(key, _portletId));
546 sm.append(StringPool.AMPERSAND);
547 }
548
549 if (!isParameterIncludedInPath("p_p_action")) {
550 sm.append("p_p_action");
551 sm.append(StringPool.EQUAL);
552
553 if (_action) {
554 sm.append(processValue(key, "1"));
555 }
556 else {
557 sm.append(processValue(key, "0"));
558 }
559
560 sm.append(StringPool.AMPERSAND);
561 }
562
563 if (!isParameterIncludedInPath("p_p_state")) {
564 if (_windowState != null) {
565 sm.append("p_p_state");
566 sm.append(StringPool.EQUAL);
567 sm.append(processValue(key, _windowState.toString()));
568 sm.append(StringPool.AMPERSAND);
569 }
570 }
571
572 if (!isParameterIncludedInPath("p_p_mode")) {
573 if (_portletMode != null) {
574 sm.append("p_p_mode");
575 sm.append(StringPool.EQUAL);
576 sm.append(processValue(key, _portletMode.toString()));
577 sm.append(StringPool.AMPERSAND);
578 }
579 }
580
581 if (!isParameterIncludedInPath("p_p_col_id")) {
582 if (Validator.isNotNull(portletDisplay.getColumnId())) {
583 sm.append("p_p_col_id");
584 sm.append(StringPool.EQUAL);
585 sm.append(processValue(key, portletDisplay.getColumnId()));
586 sm.append(StringPool.AMPERSAND);
587 }
588 }
589
590 if (!isParameterIncludedInPath("p_p_col_pos")) {
591 if (portletDisplay.getColumnPos() > 0) {
592 sm.append("p_p_col_pos");
593 sm.append(StringPool.EQUAL);
594 sm.append(processValue(key, portletDisplay.getColumnPos()));
595 sm.append(StringPool.AMPERSAND);
596 }
597 }
598
599 if (!isParameterIncludedInPath("p_p_col_count")) {
600 if (portletDisplay.getColumnCount() > 0) {
601 sm.append("p_p_col_count");
602 sm.append(StringPool.EQUAL);
603 sm.append(processValue(key, portletDisplay.getColumnCount()));
604 sm.append(StringPool.AMPERSAND);
605 }
606 }
607
608 if (_doAsUserId > 0) {
609 try {
610 Company company = PortalUtil.getCompany(_req);
611
612 sm.append("doAsUserId");
613 sm.append(StringPool.EQUAL);
614 sm.append(processValue(company.getKeyObj(), _doAsUserId));
615 sm.append(StringPool.AMPERSAND);
616 }
617 catch (Exception e) {
618 _log.error(e);
619 }
620 }
621 else {
622 String doAsUserId = themeDisplay.getDoAsUserId();
623
624 if (Validator.isNotNull(doAsUserId)) {
625 sm.append("doAsUserId");
626 sm.append(StringPool.EQUAL);
627 sm.append(processValue(key, doAsUserId));
628 sm.append(StringPool.AMPERSAND);
629 }
630 }
631
632 Iterator itr = _params.entrySet().iterator();
633
634 while (itr.hasNext()) {
635 Map.Entry entry = (Map.Entry)itr.next();
636
637 String name = (String)entry.getKey();
638 String[] values = (String[])entry.getValue();
639
640 for (int i = 0; i < values.length; i++) {
641 if (isParameterIncludedInPath(name)) {
642 continue;
643 }
644
645 if (!PortalUtil.isReservedParameter(name)) {
646 sm.append(getNamespace());
647 }
648
649 sm.append(name);
650 sm.append(StringPool.EQUAL);
651 sm.append(processValue(key, values[i]));
652
653 if ((i + 1 < values.length) || itr.hasNext()) {
654 sm.append(StringPool.AMPERSAND);
655 }
656 }
657 }
658
659 if (_encrypt) {
660 sm.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
661 }
662
663 if (GetterUtil.getBoolean(PropsUtil.get(
664 PropsUtil.PORTLET_URL_ANCHOR_ENABLE))) {
665
666 if (_anchor && (_windowState != null) &&
667 (!_windowState.equals(WindowState.MAXIMIZED)) &&
668 (!_windowState.equals(LiferayWindowState.EXCLUSIVE)) &&
669 (!_windowState.equals(LiferayWindowState.POP_UP))) {
670
671 if (sm.lastIndexOf(StringPool.AMPERSAND) != (sm.length() - 1)) {
672 sm.append(StringPool.AMPERSAND);
673 }
674
675 sm.append("#p_").append(_portletId);
676 }
677 }
678
679
681 String result = sm.toString();
682
683 if (result.endsWith(StringPool.QUESTION)) {
684 result = result.substring(0, result.length() - 1);
685 }
686
687 return result;
688 }
689
690 protected String processValue(Key key, int value) {
691 return processValue(key, String.valueOf(value));
692 }
693
694 protected String processValue(Key key, long value) {
695 return processValue(key, String.valueOf(value));
696 }
697
698 protected String processValue(Key key, String value) {
699 if (key == null) {
700 return HttpUtil.encodeURL(value);
701 }
702 else {
703 try {
704 return HttpUtil.encodeURL(Encryptor.encrypt(key, value));
705 }
706 catch (EncryptorException ee) {
707 return value;
708 }
709 }
710 }
711
712 private static Log _log = LogFactory.getLog(PortletURLImpl.class);
713
714 private HttpServletRequest _req;
715 private PortletRequest _portletReq;
716 private String _portletId;
717 private Portlet _portlet;
718 private String _namespace;
719 private long _plid;
720 private Layout _layout;
721 private String _layoutFriendlyURL;
722 private boolean _action;
723 private WindowState _windowState;
724 private PortletMode _portletMode;
725 private Map _params;
726 private Set _parametersIncludedInPath;
727 private boolean _secure;
728 private boolean _anchor = true;
729 private boolean _encrypt = false;
730 private long _doAsUserId;
731 private String _toString;
732
733 }