001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portlet;
022:
023: import com.liferay.portal.SystemException;
024: import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
025: import com.liferay.portal.kernel.portlet.LiferayPortletURL;
026: import com.liferay.portal.kernel.portlet.LiferayWindowState;
027: import com.liferay.portal.kernel.util.ArrayUtil;
028: import com.liferay.portal.kernel.util.GetterUtil;
029: import com.liferay.portal.kernel.util.StringMaker;
030: import com.liferay.portal.kernel.util.StringPool;
031: import com.liferay.portal.kernel.util.Validator;
032: import com.liferay.portal.model.Company;
033: import com.liferay.portal.model.Layout;
034: import com.liferay.portal.model.Portlet;
035: import com.liferay.portal.service.LayoutLocalServiceUtil;
036: import com.liferay.portal.service.PortletLocalServiceUtil;
037: import com.liferay.portal.theme.PortletDisplay;
038: import com.liferay.portal.theme.ThemeDisplay;
039: import com.liferay.portal.util.CookieKeys;
040: import com.liferay.portal.util.PortalUtil;
041: import com.liferay.portal.util.PropsUtil;
042: import com.liferay.portal.util.PropsValues;
043: import com.liferay.portal.util.WebKeys;
044: import com.liferay.util.Encryptor;
045: import com.liferay.util.EncryptorException;
046: import com.liferay.util.Http;
047: import com.liferay.util.HttpUtil;
048:
049: import java.io.Serializable;
050:
051: import java.security.Key;
052:
053: import java.util.Iterator;
054: import java.util.LinkedHashMap;
055: import java.util.LinkedHashSet;
056: import java.util.Map;
057: import java.util.Set;
058:
059: import javax.portlet.PortletMode;
060: import javax.portlet.PortletModeException;
061: import javax.portlet.PortletRequest;
062: import javax.portlet.PortletSecurityException;
063: import javax.portlet.WindowState;
064: import javax.portlet.WindowStateException;
065:
066: import javax.servlet.http.HttpServletRequest;
067:
068: import org.apache.commons.logging.Log;
069: import org.apache.commons.logging.LogFactory;
070:
071: /**
072: * <a href="PortletURLImpl.java.html"><b><i>View Source</i></b></a>
073: *
074: * @author Brian Wing Shun Chan
075: * @author Jorge Ferrer
076: *
077: */
078: public class PortletURLImpl implements LiferayPortletURL, Serializable {
079:
080: public static final boolean APPEND_PARAMETERS = GetterUtil
081: .getBoolean(PropsUtil
082: .get(PropsUtil.PORTLET_URL_APPEND_PARAMETERS));
083:
084: public PortletURLImpl(ActionRequestImpl req, String portletId,
085: long plid, boolean action) {
086:
087: this (req.getHttpServletRequest(), portletId, plid, action);
088:
089: _portletReq = req;
090: }
091:
092: public PortletURLImpl(RenderRequestImpl req, String portletId,
093: long plid, boolean action) {
094:
095: this (req.getHttpServletRequest(), portletId, plid, action);
096:
097: _portletReq = req;
098: }
099:
100: public PortletURLImpl(HttpServletRequest req, String portletId,
101: long plid, boolean action) {
102:
103: _req = req;
104: _portletId = portletId;
105: _plid = plid;
106: _secure = req.isSecure();
107: _action = action;
108: _params = new LinkedHashMap();
109: _parametersIncludedInPath = new LinkedHashSet();
110: }
111:
112: public HttpServletRequest getReq() {
113: return _req;
114: }
115:
116: public PortletRequest getPortletReq() {
117: return _portletReq;
118: }
119:
120: public String getPortletId() {
121: return _portletId;
122: }
123:
124: public void setPortletId(String portletId) {
125: _portletId = portletId;
126:
127: // Clear cache
128:
129: _toString = null;
130: }
131:
132: /**
133: * @deprecated Use <code>getPortletId</code>.
134: */
135: public String getPortletName() {
136: return getPortletId();
137: }
138:
139: /**
140: * @deprecated Use <code>setPortletId</code>.
141: */
142: public void setPortletName(String portletName) {
143: setPortletId(portletName);
144: }
145:
146: public Portlet getPortlet() {
147: if (_portlet == null) {
148: try {
149: _portlet = PortletLocalServiceUtil.getPortletById(
150: PortalUtil.getCompanyId(_req), _portletId);
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
166: .getFriendlyURLMapperInstance();
167:
168: if (mapper != null) {
169: portletFriendlyURLPath = mapper.buildPath(this );
170:
171: if (_log.isDebugEnabled()) {
172: _log.debug("Portlet friendly URL path "
173: + portletFriendlyURLPath);
174: }
175: }
176: }
177:
178: return portletFriendlyURLPath;
179: }
180:
181: public String getNamespace() {
182: if (_namespace == null) {
183: _namespace = PortalUtil.getPortletNamespace(_portletId);
184: }
185:
186: return _namespace;
187: }
188:
189: public long getPlid() {
190: return _plid;
191: }
192:
193: public Layout getLayout() {
194: if (_layout == null) {
195: try {
196: if (_plid > 0) {
197: _layout = LayoutLocalServiceUtil.getLayout(_plid);
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: // Clear cache
221:
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(windowState.toString(),
235: windowState);
236: }
237: }
238:
239: if (LiferayWindowState.isWindowStatePreserved(getWindowState(),
240: windowState)) {
241:
242: _windowState = windowState;
243: }
244:
245: // Clear cache
246:
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(portletMode.toString(),
268: portletMode);
269: }
270: }
271:
272: _portletMode = portletMode;
273:
274: // Clear cache
275:
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: } else {
291: return null;
292: }
293: }
294:
295: public void setParameter(String name, String value) {
296: setParameter(name, value, APPEND_PARAMETERS);
297: }
298:
299: public void setParameter(String name, String value, boolean append) {
300: if ((name == null) || (value == null)) {
301: throw new IllegalArgumentException();
302: }
303:
304: setParameter(name, new String[] { value }, append);
305: }
306:
307: public void setParameter(String name, String[] values) {
308: setParameter(name, values, APPEND_PARAMETERS);
309: }
310:
311: public void setParameter(String name, String[] values,
312: 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: } else {
330: _params.put(name, values);
331: }
332:
333: // Clear cache
334:
335: _toString = null;
336: }
337:
338: public void setParameters(Map params) {
339: if (params == null) {
340: throw new IllegalArgumentException();
341: } else {
342: Map newParams = new LinkedHashMap();
343:
344: Iterator itr = params.entrySet().iterator();
345:
346: while (itr.hasNext()) {
347: Map.Entry entry = (Map.Entry) itr.next();
348:
349: Object key = entry.getKey();
350: Object value = entry.getValue();
351:
352: if (key == null) {
353: throw new IllegalArgumentException();
354: } else if (value == null) {
355: throw new IllegalArgumentException();
356: }
357:
358: if (value instanceof String[]) {
359: newParams.put(key, value);
360: } else {
361: throw new IllegalArgumentException();
362: }
363: }
364:
365: _params = newParams;
366: }
367:
368: // Clear cache
369:
370: _toString = null;
371: }
372:
373: public Map getParameterMap() {
374: return _params;
375: }
376:
377: public Set getParametersIncludedInPath() {
378: return _parametersIncludedInPath;
379: }
380:
381: public void addParameterIncludedInPath(String name) {
382: _parametersIncludedInPath.add(name);
383: }
384:
385: public boolean isParameterIncludedInPath(String name) {
386: if (_parametersIncludedInPath.contains(name)) {
387: return true;
388: } else {
389: return false;
390: }
391: }
392:
393: public boolean isSecure() {
394: return _secure;
395: }
396:
397: public void setSecure(boolean secure)
398: throws PortletSecurityException {
399: _secure = secure;
400:
401: // Clear cache
402:
403: _toString = null;
404: }
405:
406: public boolean isAnchor() {
407: return _anchor;
408: }
409:
410: public void setAnchor(boolean anchor) {
411: _anchor = anchor;
412:
413: // Clear cache
414:
415: _toString = null;
416: }
417:
418: public boolean isEncrypt() {
419: return _encrypt;
420: }
421:
422: public void setEncrypt(boolean encrypt) {
423: _encrypt = encrypt;
424:
425: // Clear cache
426:
427: _toString = null;
428: }
429:
430: public void setDoAsUserId(long doAsUserId) {
431: _doAsUserId = doAsUserId;
432:
433: // Clear cache
434:
435: _toString = null;
436: }
437:
438: public String toString() {
439: if (_toString != null) {
440: return _toString;
441: }
442:
443: _toString = generateToString();
444:
445: return _toString;
446: }
447:
448: protected String generateToString() {
449: StringMaker sm = new StringMaker();
450:
451: ThemeDisplay themeDisplay = (ThemeDisplay) _req
452: .getAttribute(WebKeys.THEME_DISPLAY);
453:
454: PortletDisplay portletDisplay = themeDisplay
455: .getPortletDisplay();
456:
457: String portalURL = PortalUtil.getPortalURL(_req, _secure);
458:
459: try {
460: if (_layoutFriendlyURL == null) {
461: Layout layout = getLayout();
462:
463: if (layout != null) {
464: _layoutFriendlyURL = GetterUtil
465: .getString(PortalUtil.getLayoutFriendlyURL(
466: layout, themeDisplay));
467: }
468: }
469: } catch (Exception e) {
470: _log.error(e);
471: }
472:
473: Key key = null;
474:
475: try {
476: if (_encrypt) {
477: Company company = PortalUtil.getCompany(_req);
478:
479: key = company.getKeyObj();
480: }
481: } catch (Exception e) {
482: _log.error(e);
483: }
484:
485: if (Validator.isNull(_layoutFriendlyURL)) {
486: sm.append(portalURL);
487: sm.append(themeDisplay.getPathMain());
488: sm.append("/portal/layout?");
489:
490: sm.append("p_l_id");
491: sm.append(StringPool.EQUAL);
492: sm.append(processValue(key, _plid));
493: sm.append(StringPool.AMPERSAND);
494: } else {
495:
496: // A virtual host URL will contain the complete path. Do not append
497: // the portal URL if the virtual host URL starts with "http://" or
498: // "https://".
499:
500: if (!_layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH)
501: && !_layoutFriendlyURL
502: .startsWith(Http.HTTPS_WITH_SLASH)) {
503:
504: sm.append(portalURL);
505: }
506:
507: sm.append(_layoutFriendlyURL);
508:
509: String friendlyURLPath = getPortletFriendlyURLPath();
510:
511: if (Validator.isNotNull(friendlyURLPath)) {
512: sm.append(friendlyURLPath);
513:
514: if (!isAction()) {
515: addParameterIncludedInPath("p_p_action");
516: }
517:
518: //if ((_windowState != null) &&
519: // _windowState.equals(WindowState.MAXIMIZED)) {
520:
521: addParameterIncludedInPath("p_p_state");
522: //}
523:
524: //if ((_portletMode != null) &&
525: // _portletMode.equals(PortletMode.VIEW)) {
526:
527: addParameterIncludedInPath("p_p_mode");
528: //}
529:
530: addParameterIncludedInPath("p_p_col_id");
531: addParameterIncludedInPath("p_p_col_pos");
532: addParameterIncludedInPath("p_p_col_count");
533: }
534:
535: sm.append(StringPool.QUESTION);
536: }
537:
538: if (!isParameterIncludedInPath("p_p_id")) {
539: sm.append("p_p_id");
540: sm.append(StringPool.EQUAL);
541: sm.append(processValue(key, _portletId));
542: sm.append(StringPool.AMPERSAND);
543: }
544:
545: if (!isParameterIncludedInPath("p_p_action")) {
546: sm.append("p_p_action");
547: sm.append(StringPool.EQUAL);
548:
549: if (_action) {
550: sm.append(processValue(key, "1"));
551: } else {
552: sm.append(processValue(key, "0"));
553: }
554:
555: sm.append(StringPool.AMPERSAND);
556: }
557:
558: if (!isParameterIncludedInPath("p_p_state")) {
559: if (_windowState != null) {
560: sm.append("p_p_state");
561: sm.append(StringPool.EQUAL);
562: sm.append(processValue(key, _windowState.toString()));
563: sm.append(StringPool.AMPERSAND);
564: }
565: }
566:
567: if (!isParameterIncludedInPath("p_p_mode")) {
568: if (_portletMode != null) {
569: sm.append("p_p_mode");
570: sm.append(StringPool.EQUAL);
571: sm.append(processValue(key, _portletMode.toString()));
572: sm.append(StringPool.AMPERSAND);
573: }
574: }
575:
576: if (!isParameterIncludedInPath("p_p_col_id")) {
577: if (Validator.isNotNull(portletDisplay.getColumnId())) {
578: sm.append("p_p_col_id");
579: sm.append(StringPool.EQUAL);
580: sm.append(processValue(key, portletDisplay
581: .getColumnId()));
582: sm.append(StringPool.AMPERSAND);
583: }
584: }
585:
586: if (!isParameterIncludedInPath("p_p_col_pos")) {
587: if (portletDisplay.getColumnPos() > 0) {
588: sm.append("p_p_col_pos");
589: sm.append(StringPool.EQUAL);
590: sm.append(processValue(key, portletDisplay
591: .getColumnPos()));
592: sm.append(StringPool.AMPERSAND);
593: }
594: }
595:
596: if (!isParameterIncludedInPath("p_p_col_count")) {
597: if (portletDisplay.getColumnCount() > 0) {
598: sm.append("p_p_col_count");
599: sm.append(StringPool.EQUAL);
600: sm.append(processValue(key, portletDisplay
601: .getColumnCount()));
602: sm.append(StringPool.AMPERSAND);
603: }
604: }
605:
606: if (_doAsUserId > 0) {
607: try {
608: Company company = PortalUtil.getCompany(_req);
609:
610: sm.append("doAsUserId");
611: sm.append(StringPool.EQUAL);
612: sm
613: .append(processValue(company.getKeyObj(),
614: _doAsUserId));
615: sm.append(StringPool.AMPERSAND);
616: } catch (Exception e) {
617: _log.error(e);
618: }
619: } else {
620: String doAsUserId = themeDisplay.getDoAsUserId();
621:
622: if (Validator.isNotNull(doAsUserId)) {
623: sm.append("doAsUserId");
624: sm.append(StringPool.EQUAL);
625: sm.append(processValue(key, doAsUserId));
626: sm.append(StringPool.AMPERSAND);
627: }
628: }
629:
630: Iterator itr = _params.entrySet().iterator();
631:
632: while (itr.hasNext()) {
633: Map.Entry entry = (Map.Entry) itr.next();
634:
635: String name = (String) entry.getKey();
636: String[] values = (String[]) entry.getValue();
637:
638: for (int i = 0; i < values.length; i++) {
639: if (isParameterIncludedInPath(name)) {
640: continue;
641: }
642:
643: if (!PortalUtil.isReservedParameter(name)) {
644: sm.append(getNamespace());
645: }
646:
647: sm.append(name);
648: sm.append(StringPool.EQUAL);
649: sm.append(processValue(key, values[i]));
650:
651: if ((i + 1 < values.length) || itr.hasNext()) {
652: sm.append(StringPool.AMPERSAND);
653: }
654: }
655: }
656:
657: if (_encrypt) {
658: sm.append(StringPool.AMPERSAND + WebKeys.ENCRYPT + "=1");
659: }
660:
661: if (PropsValues.PORTLET_URL_ANCHOR_ENABLE) {
662: if (_anchor
663: && (_windowState != null)
664: && (!_windowState.equals(WindowState.MAXIMIZED))
665: && (!_windowState
666: .equals(LiferayWindowState.EXCLUSIVE))
667: && (!_windowState.equals(LiferayWindowState.POP_UP))) {
668:
669: if (sm.lastIndexOf(StringPool.AMPERSAND) != (sm
670: .length() - 1)) {
671: sm.append(StringPool.AMPERSAND);
672: }
673:
674: sm.append("#p_").append(_portletId);
675: }
676: }
677:
678: String result = sm.toString();
679:
680: if (result.endsWith(StringPool.QUESTION)) {
681: result = result.substring(0, result.length() - 1);
682: }
683:
684: if (!CookieKeys.hasSessionId(_req)) {
685: result = PortalUtil.getURLWithSessionId(result, _req
686: .getSession().getId());
687: }
688:
689: return result;
690: }
691:
692: protected String processValue(Key key, int value) {
693: return processValue(key, String.valueOf(value));
694: }
695:
696: protected String processValue(Key key, long value) {
697: return processValue(key, String.valueOf(value));
698: }
699:
700: protected String processValue(Key key, String value) {
701: if (key == null) {
702: return HttpUtil.encodeURL(value);
703: } else {
704: try {
705: return HttpUtil
706: .encodeURL(Encryptor.encrypt(key, value));
707: } catch (EncryptorException ee) {
708: return value;
709: }
710: }
711: }
712:
713: private static Log _log = LogFactory.getLog(PortletURLImpl.class);
714:
715: private HttpServletRequest _req;
716: private PortletRequest _portletReq;
717: private String _portletId;
718: private Portlet _portlet;
719: private String _namespace;
720: private long _plid;
721: private Layout _layout;
722: private String _layoutFriendlyURL;
723: private boolean _action;
724: private WindowState _windowState;
725: private PortletMode _portletMode;
726: private Map _params;
727: private Set _parametersIncludedInPath;
728: private boolean _secure;
729: private boolean _anchor = true;
730: private boolean _encrypt = false;
731: private long _doAsUserId;
732: private String _toString;
733:
734: }
|