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.portal.model.impl;
022:
023: import com.liferay.portal.LayoutFriendlyURLException;
024: import com.liferay.portal.PortalException;
025: import com.liferay.portal.SystemException;
026: import com.liferay.portal.kernel.security.permission.ActionKeys;
027: import com.liferay.portal.kernel.security.permission.PermissionChecker;
028: import com.liferay.portal.kernel.util.LocaleUtil;
029: import com.liferay.portal.kernel.util.NullSafeProperties;
030: import com.liferay.portal.kernel.util.PropertiesUtil;
031: import com.liferay.portal.kernel.util.StringPool;
032: import com.liferay.portal.kernel.util.StringUtil;
033: import com.liferay.portal.kernel.util.Validator;
034: import com.liferay.portal.model.ColorScheme;
035: import com.liferay.portal.model.Group;
036: import com.liferay.portal.model.Layout;
037: import com.liferay.portal.model.LayoutSet;
038: import com.liferay.portal.model.LayoutType;
039: import com.liferay.portal.model.LayoutTypePortlet;
040: import com.liferay.portal.model.Theme;
041: import com.liferay.portal.service.GroupLocalServiceUtil;
042: import com.liferay.portal.service.LayoutLocalServiceUtil;
043: import com.liferay.portal.service.LayoutSetLocalServiceUtil;
044: import com.liferay.portal.service.impl.ThemeLocalUtil;
045: import com.liferay.portal.service.permission.LayoutPermissionUtil;
046: import com.liferay.portal.theme.ThemeDisplay;
047: import com.liferay.portal.util.CookieKeys;
048: import com.liferay.portal.util.LayoutClone;
049: import com.liferay.portal.util.LayoutCloneFactory;
050: import com.liferay.portal.util.PortalUtil;
051: import com.liferay.portal.util.PropsUtil;
052: import com.liferay.portal.util.PropsValues;
053: import com.liferay.portal.util.WebKeys;
054: import com.liferay.portlet.PortletURLImpl;
055: import com.liferay.util.Http;
056: import com.liferay.util.LocalizationUtil;
057:
058: import java.io.IOException;
059:
060: import java.util.ArrayList;
061: import java.util.Iterator;
062: import java.util.List;
063: import java.util.Locale;
064: import java.util.Properties;
065:
066: import javax.portlet.PortletException;
067: import javax.portlet.PortletMode;
068: import javax.portlet.WindowState;
069:
070: import javax.servlet.http.HttpServletRequest;
071:
072: import org.apache.commons.logging.Log;
073: import org.apache.commons.logging.LogFactory;
074:
075: /**
076: * <a href="LayoutImpl.java.html"><b><i>View Source</i></b></a>
077: *
078: * @author Brian Wing Shun Chan
079: *
080: */
081: public class LayoutImpl extends LayoutModelImpl implements Layout {
082:
083: public static final long DEFAULT_PLID = 0;
084:
085: public static final long DEFAULT_PARENT_LAYOUT_ID = 0;
086:
087: public static final String[] TYPES = PropsUtil
088: .getArray(PropsUtil.LAYOUT_TYPES);
089:
090: public static final String TYPE_PORTLET = "portlet";
091:
092: public static final String TYPE_EMBEDDED = "embedded";
093:
094: public static final String TYPE_URL = "url";
095:
096: public static final String TYPE_ARTICLE = "article";
097:
098: public static int validateFriendlyURL(String friendlyURL) {
099: if (friendlyURL.length() < 2) {
100: return LayoutFriendlyURLException.TOO_SHORT;
101: }
102:
103: if (!friendlyURL.startsWith(StringPool.SLASH)) {
104: return LayoutFriendlyURLException.DOES_NOT_START_WITH_SLASH;
105: }
106:
107: if (friendlyURL.endsWith(StringPool.SLASH)) {
108: return LayoutFriendlyURLException.ENDS_WITH_SLASH;
109: }
110:
111: if (friendlyURL.indexOf(StringPool.DOUBLE_SLASH) != -1) {
112: return LayoutFriendlyURLException.ADJACENT_SLASHES;
113: }
114:
115: char[] c = friendlyURL.toCharArray();
116:
117: for (int i = 0; i < c.length; i++) {
118: if ((!Validator.isChar(c[i])) && (!Validator.isDigit(c[i]))
119: && (c[i] != '/') && (c[i] != '-') && (c[i] != '_')
120: && (c[i] != '.')) {
121:
122: return LayoutFriendlyURLException.INVALID_CHARACTERS;
123: }
124: }
125:
126: return -1;
127: }
128:
129: public static void validateFriendlyURLKeyword(String friendlyURL)
130: throws LayoutFriendlyURLException {
131:
132: String[] keywords = PropsUtil
133: .getArray(PropsUtil.LAYOUT_FRIENDLY_URL_KEYWORDS);
134:
135: for (int i = 0; i < keywords.length; i++) {
136: String keyword = keywords[i];
137:
138: if ((friendlyURL.indexOf(StringPool.SLASH + keyword
139: + StringPool.SLASH) != -1)
140: || (friendlyURL
141: .endsWith(StringPool.SLASH + keyword))) {
142:
143: LayoutFriendlyURLException lfurle = new LayoutFriendlyURLException(
144: LayoutFriendlyURLException.KEYWORD_CONFLICT);
145:
146: lfurle.setKeywordConflict(keyword);
147:
148: throw lfurle;
149: }
150: }
151: }
152:
153: public LayoutImpl() {
154: }
155:
156: public Group getGroup() {
157: Group group = null;
158:
159: try {
160: group = GroupLocalServiceUtil.getGroup(getGroupId());
161: } catch (Exception e) {
162: group = new GroupImpl();
163:
164: _log.error(e);
165: }
166:
167: return group;
168: }
169:
170: /**
171: * @deprecated Will always return true.
172: */
173: public boolean isShared() {
174: return true;
175: }
176:
177: public long getAncestorPlid() {
178: long ancestorPlid = 0;
179:
180: try {
181: Layout ancestorLayout = this ;
182:
183: while (true) {
184: if (!ancestorLayout.isRootLayout()) {
185: ancestorLayout = LayoutLocalServiceUtil.getLayout(
186: ancestorLayout.getGroupId(), ancestorLayout
187: .isPrivateLayout(), ancestorLayout
188: .getParentLayoutId());
189: } else {
190: ancestorPlid = ancestorLayout.getPlid();
191:
192: break;
193: }
194: }
195: } catch (Exception e) {
196: _log.error(e);
197: }
198:
199: return ancestorPlid;
200: }
201:
202: public long getAncestorLayoutId() {
203: long ancestorLayoutId = 0;
204:
205: try {
206: Layout ancestorLayout = this ;
207:
208: while (true) {
209: if (!ancestorLayout.isRootLayout()) {
210: ancestorLayout = LayoutLocalServiceUtil.getLayout(
211: ancestorLayout.getGroupId(), ancestorLayout
212: .isPrivateLayout(), ancestorLayout
213: .getParentLayoutId());
214: } else {
215: ancestorLayoutId = ancestorLayout.getLayoutId();
216:
217: break;
218: }
219: }
220: } catch (Exception e) {
221: _log.error(e);
222: }
223:
224: return ancestorLayoutId;
225: }
226:
227: public List getAncestors() throws SystemException, PortalException {
228: List ancestors = new ArrayList();
229:
230: Layout layout = this ;
231:
232: while (true) {
233: if (!layout.isRootLayout()) {
234: layout = LayoutLocalServiceUtil.getLayout(layout
235: .getGroupId(), layout.isPrivateLayout(), layout
236: .getParentLayoutId());
237:
238: ancestors.add(layout);
239: } else {
240: break;
241: }
242: }
243:
244: return ancestors;
245: }
246:
247: public boolean hasAncestor(long layoutId) throws PortalException,
248: SystemException {
249:
250: long parentLayoutId = getParentLayoutId();
251:
252: while (isRootLayout()) {
253: if (parentLayoutId == layoutId) {
254: return true;
255: } else {
256: Layout parentLayout = LayoutLocalServiceUtil
257: .getLayout(getGroupId(), isPrivateLayout(),
258: parentLayoutId);
259:
260: parentLayoutId = parentLayout.getParentLayoutId();
261: }
262: }
263:
264: return false;
265: }
266:
267: public boolean isFirstParent() {
268: if (isFirstChild() && isRootLayout()) {
269: return true;
270: } else {
271: return false;
272: }
273: }
274:
275: public boolean isFirstChild() {
276: if (getPriority() == 0) {
277: return true;
278: } else {
279: return false;
280: }
281: }
282:
283: public boolean isRootLayout() {
284: if (this .getParentLayoutId() == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
285: return true;
286: } else {
287: return false;
288: }
289: }
290:
291: public List getChildren() throws PortalException, SystemException {
292: return LayoutLocalServiceUtil.getLayouts(getGroupId(),
293: isPrivateLayout(), getLayoutId());
294: }
295:
296: public List getAllChildren() throws PortalException,
297: SystemException {
298: List allChildren = new ArrayList();
299:
300: Iterator itr = getChildren().iterator();
301:
302: while (itr.hasNext()) {
303: Layout child = (Layout) itr.next();
304:
305: allChildren.add(child);
306: allChildren.addAll(child.getChildren());
307: }
308:
309: return allChildren;
310: }
311:
312: public List getChildren(PermissionChecker permissionChecker)
313: throws PortalException, SystemException {
314:
315: List layouts = getChildren();
316:
317: Iterator itr = layouts.iterator();
318:
319: while (itr.hasNext()) {
320: Layout layout = (Layout) itr.next();
321:
322: if (layout.isHidden()
323: || !LayoutPermissionUtil.contains(
324: permissionChecker, layout, ActionKeys.VIEW)) {
325:
326: itr.remove();
327: }
328: }
329:
330: return layouts;
331: }
332:
333: public String getName(Locale locale) {
334: String localeLanguageId = LocaleUtil.toLanguageId(locale);
335:
336: return getName(localeLanguageId);
337: }
338:
339: public String getName(String localeLanguageId) {
340: return LocalizationUtil.getLocalization(getName(),
341: localeLanguageId);
342: }
343:
344: public String getName(Locale locale, boolean useDefault) {
345: String localeLanguageId = LocaleUtil.toLanguageId(locale);
346:
347: return getName(localeLanguageId, useDefault);
348: }
349:
350: public String getName(String localeLanguageId, boolean useDefault) {
351: return LocalizationUtil.getLocalization(getName(),
352: localeLanguageId, useDefault);
353: }
354:
355: public void setName(String name, Locale locale) {
356: String localeLanguageId = LocaleUtil.toLanguageId(locale);
357:
358: setName(LocalizationUtil.updateLocalization(getName(), "name",
359: name, localeLanguageId));
360: }
361:
362: public String getTitle(Locale locale) {
363: String localeLanguageId = LocaleUtil.toLanguageId(locale);
364:
365: return getTitle(localeLanguageId);
366: }
367:
368: public String getTitle(String localeLanguageId) {
369: return LocalizationUtil.getLocalization(getTitle(),
370: localeLanguageId);
371: }
372:
373: public String getTitle(Locale locale, boolean useDefault) {
374: String localeLanguageId = LocaleUtil.toLanguageId(locale);
375:
376: return getTitle(localeLanguageId, useDefault);
377: }
378:
379: public String getTitle(String localeLanguageId, boolean useDefault) {
380: return LocalizationUtil.getLocalization(getTitle(),
381: localeLanguageId, useDefault);
382: }
383:
384: public String getHTMLTitle(Locale locale) {
385: String localeLanguageId = LocaleUtil.toLanguageId(locale);
386:
387: return getHTMLTitle(localeLanguageId);
388: }
389:
390: public String getHTMLTitle(String localeLanguageId) {
391: String htmlTitle = getTitle(localeLanguageId);
392:
393: if (Validator.isNull(htmlTitle)) {
394: htmlTitle = getName(localeLanguageId);
395: }
396:
397: return htmlTitle;
398: }
399:
400: public void setTitle(String title, Locale locale) {
401: String localeLanguageId = LocaleUtil.toLanguageId(locale);
402:
403: setTitle(LocalizationUtil.updateLocalization(getTitle(),
404: "title", title, localeLanguageId));
405: }
406:
407: public LayoutType getLayoutType() {
408: return new LayoutTypePortletImpl(this );
409: }
410:
411: public String getTypeSettings() {
412: if (_typeSettingsProperties == null) {
413: return super .getTypeSettings();
414: } else {
415: return PropertiesUtil.toString(_typeSettingsProperties);
416: }
417: }
418:
419: public void setTypeSettings(String typeSettings) {
420: _typeSettingsProperties = null;
421:
422: super .setTypeSettings(typeSettings);
423: }
424:
425: public Properties getTypeSettingsProperties() {
426: if (_typeSettingsProperties == null) {
427: _typeSettingsProperties = new NullSafeProperties();
428:
429: try {
430: PropertiesUtil.load(_typeSettingsProperties, super
431: .getTypeSettings());
432: } catch (IOException ioe) {
433: _log.error(ioe);
434: }
435: }
436:
437: return _typeSettingsProperties;
438: }
439:
440: public void setTypeSettingsProperties(
441: Properties typeSettingsProperties) {
442: _typeSettingsProperties = typeSettingsProperties;
443:
444: super .setTypeSettings(PropertiesUtil
445: .toString(_typeSettingsProperties));
446: }
447:
448: public String getDefaultFriendlyURL() {
449: return StringPool.SLASH + getLayoutId();
450: }
451:
452: public LayoutSet getLayoutSet() {
453: LayoutSet layoutSet = null;
454:
455: try {
456: layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
457: getGroupId(), isPrivateLayout());
458: } catch (Exception e) {
459: layoutSet = new LayoutSetImpl();
460:
461: _log.error(e);
462: }
463:
464: return layoutSet;
465: }
466:
467: public boolean isInheritLookAndFeel() {
468: if (Validator.isNull(getThemeId())
469: || Validator.isNull(getColorSchemeId())) {
470:
471: return true;
472: } else {
473: return false;
474: }
475: }
476:
477: public Theme getTheme() throws PortalException, SystemException {
478: if (isInheritLookAndFeel()) {
479: return getLayoutSet().getTheme();
480: } else {
481: return ThemeLocalUtil.getTheme(getCompanyId(),
482: getThemeId(), false);
483: }
484: }
485:
486: public ColorScheme getColorScheme() throws PortalException,
487: SystemException {
488:
489: if (isInheritLookAndFeel()) {
490: return getLayoutSet().getColorScheme();
491: } else {
492: return ThemeLocalUtil.getColorScheme(getCompanyId(),
493: getTheme().getThemeId(), getColorSchemeId(), false);
494: }
495: }
496:
497: public boolean isInheritWapLookAndFeel() {
498: if (Validator.isNull(getWapThemeId())
499: || Validator.isNull(getWapColorSchemeId())) {
500:
501: return true;
502: } else {
503: return false;
504: }
505: }
506:
507: public Theme getWapTheme() throws PortalException, SystemException {
508: if (isInheritWapLookAndFeel()) {
509: return getLayoutSet().getWapTheme();
510: } else {
511: return ThemeLocalUtil.getTheme(getCompanyId(),
512: getWapThemeId(), true);
513: }
514: }
515:
516: public ColorScheme getWapColorScheme() throws PortalException,
517: SystemException {
518:
519: if (isInheritLookAndFeel()) {
520: return getLayoutSet().getWapColorScheme();
521: } else {
522: return ThemeLocalUtil.getColorScheme(getCompanyId(),
523: getWapTheme().getThemeId(), getWapColorSchemeId(),
524: true);
525: }
526: }
527:
528: public String getCssText() throws PortalException, SystemException {
529: if (isInheritLookAndFeel()) {
530: return getLayoutSet().getCss();
531: } else {
532: return getCss();
533: }
534: }
535:
536: public String getRegularURL(HttpServletRequest req)
537: throws PortalException, SystemException {
538:
539: return _getURL(req, false, false);
540: }
541:
542: public String getResetMaxStateURL(HttpServletRequest req)
543: throws PortalException, SystemException {
544:
545: return _getURL(req, true, false);
546: }
547:
548: public String getResetLayoutURL(HttpServletRequest req)
549: throws PortalException, SystemException {
550:
551: return _getURL(req, true, true);
552: }
553:
554: public String getTarget() {
555: return PortalUtil.getLayoutTarget(this );
556: }
557:
558: public boolean isSelected(boolean selectable, Layout layout,
559: long ancestorPlid) {
560:
561: if (selectable) {
562: long plid = getPlid();
563:
564: if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
565: return true;
566: }
567: }
568:
569: return false;
570: }
571:
572: private LayoutTypePortlet _getLayoutTypePortletClone(
573: HttpServletRequest req) throws IOException {
574:
575: LayoutTypePortlet layoutTypePortlet = null;
576:
577: LayoutClone layoutClone = LayoutCloneFactory.getInstance();
578:
579: if (layoutClone != null) {
580: String typeSettings = layoutClone.get(req, getPlid());
581:
582: if (typeSettings != null) {
583: Properties props = new NullSafeProperties();
584:
585: PropertiesUtil.load(props, typeSettings);
586:
587: String stateMax = props
588: .getProperty(LayoutTypePortletImpl.STATE_MAX);
589: String stateMin = props
590: .getProperty(LayoutTypePortletImpl.STATE_MIN);
591:
592: Layout layout = (Layout) ((LayoutImpl) this ).clone();
593:
594: layoutTypePortlet = (LayoutTypePortlet) layout
595: .getLayoutType();
596:
597: layoutTypePortlet.setStateMax(stateMax);
598: layoutTypePortlet.setStateMin(stateMin);
599: }
600: }
601:
602: if (layoutTypePortlet == null) {
603: layoutTypePortlet = (LayoutTypePortlet) getLayoutType();
604: }
605:
606: return layoutTypePortlet;
607: }
608:
609: private String _getURL(HttpServletRequest req,
610: boolean resetMaxState, boolean resetRenderParameters)
611: throws PortalException, SystemException {
612:
613: ThemeDisplay themeDisplay = (ThemeDisplay) req
614: .getAttribute(WebKeys.THEME_DISPLAY);
615:
616: if (resetMaxState) {
617: Layout layout = themeDisplay.getLayout();
618:
619: LayoutTypePortlet layoutTypePortlet = null;
620:
621: if (layout.equals(this )) {
622: layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
623: } else {
624: try {
625: layoutTypePortlet = _getLayoutTypePortletClone(req);
626: } catch (IOException ioe) {
627: _log.error("Unable to clone layout settings", ioe);
628:
629: layoutTypePortlet = (LayoutTypePortlet) getLayoutType();
630: }
631: }
632:
633: if (layoutTypePortlet.hasStateMax()) {
634: String portletId = StringUtil.split(layoutTypePortlet
635: .getStateMax())[0];
636:
637: PortletURLImpl portletURLImpl = new PortletURLImpl(req,
638: portletId, getPlid(), true);
639:
640: try {
641: portletURLImpl.setWindowState(WindowState.NORMAL);
642: portletURLImpl.setPortletMode(PortletMode.VIEW);
643: } catch (PortletException pe) {
644: throw new SystemException(pe);
645: }
646:
647: portletURLImpl.setAnchor(false);
648:
649: if (PropsValues.LAYOUT_DEFAULT_P_L_RESET
650: && !resetRenderParameters) {
651:
652: portletURLImpl.setParameter("p_l_reset", "0");
653: } else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET
654: && resetRenderParameters) {
655:
656: portletURLImpl.setParameter("p_l_reset", "1");
657: }
658:
659: return portletURLImpl.toString();
660: }
661: }
662:
663: String url = PortalUtil.getLayoutURL(this , themeDisplay);
664:
665: if (!CookieKeys.hasSessionId(req)) {
666: url = PortalUtil.getURLWithSessionId(url, req.getSession()
667: .getId());
668: }
669:
670: if (!resetMaxState && !resetMaxState) {
671: return url;
672: }
673:
674: if (PropsValues.LAYOUT_DEFAULT_P_L_RESET
675: && !resetRenderParameters) {
676: url = Http.addParameter(url, "p_l_reset", 0);
677: } else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET
678: && resetRenderParameters) {
679:
680: url = Http.addParameter(url, "p_l_reset", 1);
681: }
682:
683: return url;
684: }
685:
686: private static Log _log = LogFactory.getLog(LayoutImpl.class);
687:
688: private Properties _typeSettingsProperties = null;
689:
690: }
|