1
14
15 package com.liferay.portal.model.impl;
16
17 import com.liferay.portal.LayoutFriendlyURLException;
18 import com.liferay.portal.NoSuchGroupException;
19 import com.liferay.portal.PortalException;
20 import com.liferay.portal.SystemException;
21 import com.liferay.portal.kernel.log.Log;
22 import com.liferay.portal.kernel.log.LogFactoryUtil;
23 import com.liferay.portal.kernel.util.CharPool;
24 import com.liferay.portal.kernel.util.HttpUtil;
25 import com.liferay.portal.kernel.util.ListUtil;
26 import com.liferay.portal.kernel.util.LocaleUtil;
27 import com.liferay.portal.kernel.util.LocalizationUtil;
28 import com.liferay.portal.kernel.util.PropsKeys;
29 import com.liferay.portal.kernel.util.StringPool;
30 import com.liferay.portal.kernel.util.StringUtil;
31 import com.liferay.portal.kernel.util.UnicodeProperties;
32 import com.liferay.portal.kernel.util.Validator;
33 import com.liferay.portal.model.ColorScheme;
34 import com.liferay.portal.model.Group;
35 import com.liferay.portal.model.Layout;
36 import com.liferay.portal.model.LayoutConstants;
37 import com.liferay.portal.model.LayoutSet;
38 import com.liferay.portal.model.LayoutType;
39 import com.liferay.portal.model.LayoutTypePortlet;
40 import com.liferay.portal.model.Theme;
41 import com.liferay.portal.security.permission.ActionKeys;
42 import com.liferay.portal.security.permission.PermissionChecker;
43 import com.liferay.portal.service.GroupLocalServiceUtil;
44 import com.liferay.portal.service.LayoutLocalServiceUtil;
45 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
46 import com.liferay.portal.service.ThemeLocalServiceUtil;
47 import com.liferay.portal.service.permission.LayoutPermissionUtil;
48 import com.liferay.portal.theme.ThemeDisplay;
49 import com.liferay.portal.util.CookieKeys;
50 import com.liferay.portal.util.LayoutClone;
51 import com.liferay.portal.util.LayoutCloneFactory;
52 import com.liferay.portal.util.PortalUtil;
53 import com.liferay.portal.util.PropsUtil;
54 import com.liferay.portal.util.PropsValues;
55 import com.liferay.portal.util.WebKeys;
56 import com.liferay.portlet.PortletURLImpl;
57
58 import java.io.IOException;
59
60 import java.util.ArrayList;
61 import java.util.Iterator;
62 import java.util.List;
63 import java.util.Locale;
64
65 import javax.portlet.PortletException;
66 import javax.portlet.PortletMode;
67 import javax.portlet.PortletRequest;
68 import javax.portlet.WindowState;
69
70 import javax.servlet.http.HttpServletRequest;
71
72
77 public class LayoutImpl extends LayoutModelImpl implements Layout {
78
79 public static int validateFriendlyURL(String friendlyURL) {
80 if (friendlyURL.length() < 2) {
81 return LayoutFriendlyURLException.TOO_SHORT;
82 }
83
84 if (!friendlyURL.startsWith(StringPool.SLASH)) {
85 return LayoutFriendlyURLException.DOES_NOT_START_WITH_SLASH;
86 }
87
88 if (friendlyURL.endsWith(StringPool.SLASH)) {
89 return LayoutFriendlyURLException.ENDS_WITH_SLASH;
90 }
91
92 if (friendlyURL.indexOf(StringPool.DOUBLE_SLASH) != -1) {
93 return LayoutFriendlyURLException.ADJACENT_SLASHES;
94 }
95
96 for (char c : friendlyURL.toCharArray()) {
97 if ((!Validator.isChar(c)) && (!Validator.isDigit(c)) &&
98 (c != CharPool.DASH) && (c != CharPool.PERCENT) &&
99 (c != CharPool.PERIOD) && (c != CharPool.PLUS) &&
100 (c != CharPool.SLASH) && (c != CharPool.UNDERLINE)) {
101
102 return LayoutFriendlyURLException.INVALID_CHARACTERS;
103 }
104 }
105
106 return -1;
107 }
108
109 public static void validateFriendlyURLKeyword(String friendlyURL)
110 throws LayoutFriendlyURLException {
111
112 String[] keywords = PropsUtil.getArray(
113 PropsKeys.LAYOUT_FRIENDLY_URL_KEYWORDS);
114
115 for (int i = 0; i < keywords.length; i++) {
116 String keyword = keywords[i];
117
118 if ((friendlyURL.indexOf(
119 StringPool.SLASH + keyword + StringPool.SLASH) != -1) ||
120 (friendlyURL.endsWith(StringPool.SLASH + keyword))) {
121
122 LayoutFriendlyURLException lfurle =
123 new LayoutFriendlyURLException(
124 LayoutFriendlyURLException.KEYWORD_CONFLICT);
125
126 lfurle.setKeywordConflict(keyword);
127
128 throw lfurle;
129 }
130 }
131 }
132
133 public LayoutImpl() {
134 }
135
136 public List<Layout> getAllChildren() throws SystemException {
137 List<Layout> layouts = new ArrayList<Layout>();
138
139 Iterator<Layout> itr = getChildren().iterator();
140
141 while (itr.hasNext()) {
142 Layout layout = itr.next();
143
144 layouts.add(layout);
145 layouts.addAll(layout.getChildren());
146 }
147
148 return layouts;
149 }
150
151 public long getAncestorLayoutId() {
152 long layoutId = 0;
153
154 try {
155 Layout layout = this;
156
157 while (true) {
158 if (!layout.isRootLayout()) {
159 layout = LayoutLocalServiceUtil.getLayout(
160 layout.getGroupId(), layout.isPrivateLayout(),
161 layout.getParentLayoutId());
162 }
163 else {
164 layoutId = layout.getLayoutId();
165
166 break;
167 }
168 }
169 }
170 catch (Exception e) {
171 _log.error(e, e);
172 }
173
174 return layoutId;
175 }
176
177 public long getAncestorPlid() {
178 long plid = 0;
179
180 try {
181 Layout layout = this;
182
183 while (true) {
184 if (!layout.isRootLayout()) {
185 layout = LayoutLocalServiceUtil.getLayout(
186 layout.getGroupId(), layout.isPrivateLayout(),
187 layout.getParentLayoutId());
188 }
189 else {
190 plid = layout.getPlid();
191
192 break;
193 }
194 }
195 }
196 catch (Exception e) {
197 _log.error(e, e);
198 }
199
200 return plid;
201 }
202
203 public List<Layout> getAncestors() throws PortalException, SystemException {
204 List<Layout> layouts = new ArrayList<Layout>();
205
206 Layout layout = this;
207
208 while (true) {
209 if (!layout.isRootLayout()) {
210 layout = LayoutLocalServiceUtil.getLayout(
211 layout.getGroupId(), layout.isPrivateLayout(),
212 layout.getParentLayoutId());
213
214 layouts.add(layout);
215 }
216 else {
217 break;
218 }
219 }
220
221 return layouts;
222 }
223
224 public List<Layout> getChildren() throws SystemException {
225 return LayoutLocalServiceUtil.getLayouts(
226 getGroupId(), isPrivateLayout(), getLayoutId());
227 }
228
229 public List<Layout> getChildren(PermissionChecker permissionChecker)
230 throws PortalException, SystemException {
231
232 List<Layout> layouts = ListUtil.copy(getChildren());
233
234 Iterator<Layout> itr = layouts.iterator();
235
236 while (itr.hasNext()) {
237 Layout layout = itr.next();
238
239 if (layout.isHidden() ||
240 !LayoutPermissionUtil.contains(
241 permissionChecker, layout, ActionKeys.VIEW)) {
242
243 itr.remove();
244 }
245 }
246
247 return layouts;
248 }
249
250 public ColorScheme getColorScheme() throws SystemException {
251 if (isInheritLookAndFeel()) {
252 return getLayoutSet().getColorScheme();
253 }
254 else {
255 return ThemeLocalServiceUtil.getColorScheme(
256 getCompanyId(), getTheme().getThemeId(), getColorSchemeId(),
257 false);
258 }
259 }
260
261 public String getCssText() {
262 if (isInheritLookAndFeel()) {
263 return getLayoutSet().getCss();
264 }
265 else {
266 return getCss();
267 }
268 }
269
270 public Group getGroup() {
271 Group group = null;
272
273 try {
274 group = GroupLocalServiceUtil.getGroup(getGroupId());
275 }
276 catch (Exception e) {
277 group = new GroupImpl();
278
279 _log.error(e, e);
280 }
281
282 return group;
283 }
284
285 public String getHTMLTitle(Locale locale) {
286 String localeLanguageId = LocaleUtil.toLanguageId(locale);
287
288 return getHTMLTitle(localeLanguageId);
289 }
290
291 public String getHTMLTitle(String localeLanguageId) {
292 String htmlTitle = getTitle(localeLanguageId);
293
294 if (Validator.isNull(htmlTitle)) {
295 htmlTitle = getName(localeLanguageId);
296 }
297
298 return htmlTitle;
299 }
300
301 public LayoutSet getLayoutSet() {
302 LayoutSet layoutSet = null;
303
304 try {
305 layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
306 getGroupId(), isPrivateLayout());
307 }
308 catch (Exception e) {
309 layoutSet = new LayoutSetImpl();
310
311 _log.error(e, e);
312 }
313
314 return layoutSet;
315 }
316
317 public LayoutType getLayoutType() {
318 return new LayoutTypePortletImpl(this);
319 }
320
321 public String getName(Locale locale) {
322 String localeLanguageId = LocaleUtil.toLanguageId(locale);
323
324 return getName(localeLanguageId);
325 }
326
327 public String getName(Locale locale, boolean useDefault) {
328 String localeLanguageId = LocaleUtil.toLanguageId(locale);
329
330 return getName(localeLanguageId, useDefault);
331 }
332
333 public String getName(String localeLanguageId) {
334 return LocalizationUtil.getLocalization(getName(), localeLanguageId);
335 }
336
337 public String getName(String localeLanguageId, boolean useDefault) {
338 return LocalizationUtil.getLocalization(
339 getName(), localeLanguageId, useDefault);
340 }
341
342 public String getRegularURL(HttpServletRequest request)
343 throws SystemException {
344
345 return _getURL(request, false, false);
346 }
347
348 public String getResetLayoutURL(HttpServletRequest request)
349 throws SystemException {
350
351 return _getURL(request, true, true);
352 }
353
354 public String getResetMaxStateURL(HttpServletRequest request)
355 throws SystemException {
356
357 return _getURL(request, true, false);
358 }
359
360 public Group getScopeGroup() throws PortalException, SystemException {
361 Group group = null;
362
363 try {
364 group = GroupLocalServiceUtil.getLayoutGroup(
365 getCompanyId(), getPlid());
366 }
367 catch (NoSuchGroupException nsge) {
368 }
369
370 return group;
371 }
372
373 public String getTarget() {
374 return PortalUtil.getLayoutTarget(this);
375 }
376
377 public Theme getTheme() throws SystemException {
378 if (isInheritLookAndFeel()) {
379 return getLayoutSet().getTheme();
380 }
381 else {
382 return ThemeLocalServiceUtil.getTheme(
383 getCompanyId(), getThemeId(), false);
384 }
385 }
386
387 public String getTitle(Locale locale) {
388 String localeLanguageId = LocaleUtil.toLanguageId(locale);
389
390 return getTitle(localeLanguageId);
391 }
392
393 public String getTitle(Locale locale, boolean useDefault) {
394 String localeLanguageId = LocaleUtil.toLanguageId(locale);
395
396 return getTitle(localeLanguageId, useDefault);
397 }
398
399 public String getTitle(String localeLanguageId) {
400 return LocalizationUtil.getLocalization(getTitle(), localeLanguageId);
401 }
402
403 public String getTitle(String localeLanguageId, boolean useDefault) {
404 return LocalizationUtil.getLocalization(
405 getTitle(), localeLanguageId, useDefault);
406 }
407
408 public String getTypeSettings() {
409 if (_typeSettingsProperties == null) {
410 return super.getTypeSettings();
411 }
412 else {
413 return _typeSettingsProperties.toString();
414 }
415 }
416
417 public UnicodeProperties getTypeSettingsProperties() {
418 if (_typeSettingsProperties == null) {
419 _typeSettingsProperties = new UnicodeProperties(true);
420
421 _typeSettingsProperties.fastLoad(super.getTypeSettings());
422 }
423
424 return _typeSettingsProperties;
425 }
426
427 public ColorScheme getWapColorScheme() throws SystemException {
428 if (isInheritLookAndFeel()) {
429 return getLayoutSet().getWapColorScheme();
430 }
431 else {
432 return ThemeLocalServiceUtil.getColorScheme(
433 getCompanyId(), getWapTheme().getThemeId(),
434 getWapColorSchemeId(), true);
435 }
436 }
437
438 public Theme getWapTheme() throws SystemException {
439 if (isInheritWapLookAndFeel()) {
440 return getLayoutSet().getWapTheme();
441 }
442 else {
443 return ThemeLocalServiceUtil.getTheme(
444 getCompanyId(), getWapThemeId(), true);
445 }
446 }
447
448 public boolean hasAncestor(long layoutId)
449 throws PortalException, SystemException {
450
451 long parentLayoutId = getParentLayoutId();
452
453 while (isRootLayout()) {
454 if (parentLayoutId == layoutId) {
455 return true;
456 }
457 else {
458 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
459 getGroupId(), isPrivateLayout(), parentLayoutId);
460
461 parentLayoutId = parentLayout.getParentLayoutId();
462 }
463 }
464
465 return false;
466 }
467
468 public boolean hasScopeGroup() throws PortalException, SystemException {
469 Group group = getScopeGroup();
470
471 if (group != null) {
472 return true;
473 }
474 else {
475 return false;
476 }
477 }
478
479 public boolean isChildSelected(boolean selectable, Layout layout) {
480 if (selectable) {
481 long plid = getPlid();
482
483 try {
484 List<Layout> ancestors = layout.getAncestors();
485
486 for (Layout curLayout : ancestors) {
487 if (plid == curLayout.getPlid()) {
488 return true;
489 }
490 }
491 }
492 catch (Exception e) {
493 _log.error(e, e);
494 }
495 }
496
497 return false;
498 }
499
500 public boolean isFirstChild() {
501 if (getPriority() == 0) {
502 return true;
503 }
504 else {
505 return false;
506 }
507 }
508
509 public boolean isFirstParent() {
510 if (isFirstChild() && isRootLayout()) {
511 return true;
512 }
513 else {
514 return false;
515 }
516 }
517
518 public boolean isInheritLookAndFeel() {
519 if (Validator.isNull(getThemeId()) ||
520 Validator.isNull(getColorSchemeId())) {
521
522 return true;
523 }
524 else {
525 return false;
526 }
527 }
528
529 public boolean isInheritWapLookAndFeel() {
530 if (Validator.isNull(getWapThemeId()) ||
531 Validator.isNull(getWapColorSchemeId())) {
532
533 return true;
534 }
535 else {
536 return false;
537 }
538 }
539
540 public boolean isPublicLayout() {
541 return !isPrivateLayout();
542 }
543
544 public boolean isRootLayout() {
545 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
546 return true;
547 }
548 else {
549 return false;
550 }
551 }
552
553 public boolean isSelected(
554 boolean selectable, Layout layout, long ancestorPlid) {
555
556 if (selectable) {
557 long plid = getPlid();
558
559 if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
560 return true;
561 }
562 }
563
564 return false;
565 }
566
567 public boolean isTypeArticle() {
568 if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
569 return true;
570 }
571 else {
572 return false;
573 }
574 }
575
576 public boolean isTypeControlPanel() {
577 if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
578 return true;
579 }
580 else {
581 return false;
582 }
583 }
584
585 public boolean isTypeEmbedded() {
586 if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
587 return true;
588 }
589 else {
590 return false;
591 }
592 }
593
594 public boolean isTypeLinkToLayout() {
595 if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
596 return true;
597 }
598 else {
599 return false;
600 }
601 }
602
603 public boolean isTypePanel() {
604 if (getType().equals(LayoutConstants.TYPE_PANEL)) {
605 return true;
606 }
607 else {
608 return false;
609 }
610 }
611
612 public boolean isTypePortlet() {
613 if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
614 return true;
615 }
616 else {
617 return false;
618 }
619 }
620
621 public boolean isTypeURL() {
622 if (getType().equals(LayoutConstants.TYPE_URL)) {
623 return true;
624 }
625 else {
626 return false;
627 }
628 }
629
630 public void setName(String name, Locale locale) {
631 String localeLanguageId = LocaleUtil.toLanguageId(locale);
632
633 if (Validator.isNotNull(name)) {
634 setName(
635 LocalizationUtil.updateLocalization(
636 getName(), "name", name, localeLanguageId));
637 }
638 else {
639 setName(
640 LocalizationUtil.removeLocalization(
641 getName(), "name", localeLanguageId));
642 }
643 }
644
645 public void setTitle(String title, Locale locale) {
646 String localeLanguageId = LocaleUtil.toLanguageId(locale);
647
648 if (Validator.isNotNull(title)) {
649 setTitle(
650 LocalizationUtil.updateLocalization(
651 getTitle(), "title", title, localeLanguageId));
652 }
653 else {
654 setTitle(
655 LocalizationUtil.removeLocalization(
656 getTitle(), "title", localeLanguageId));
657 }
658 }
659
660 public void setTypeSettings(String typeSettings) {
661 _typeSettingsProperties = null;
662
663 super.setTypeSettings(typeSettings);
664 }
665
666 public void setTypeSettingsProperties(
667 UnicodeProperties typeSettingsProperties) {
668
669 _typeSettingsProperties = typeSettingsProperties;
670
671 super.setTypeSettings(_typeSettingsProperties.toString());
672 }
673
674 private LayoutTypePortlet _getLayoutTypePortletClone(
675 HttpServletRequest request)
676 throws IOException {
677
678 LayoutTypePortlet layoutTypePortlet = null;
679
680 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
681
682 if (layoutClone != null) {
683 String typeSettings = layoutClone.get(request, getPlid());
684
685 if (typeSettings != null) {
686 UnicodeProperties props = new UnicodeProperties(true);
687
688 props.load(typeSettings);
689
690 String stateMax = props.getProperty(
691 LayoutTypePortletImpl.STATE_MAX);
692 String stateMin = props.getProperty(
693 LayoutTypePortletImpl.STATE_MIN);
694
695 Layout layout = (Layout)this.clone();
696
697 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
698
699 layoutTypePortlet.setStateMax(stateMax);
700 layoutTypePortlet.setStateMin(stateMin);
701 }
702 }
703
704 if (layoutTypePortlet == null) {
705 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
706 }
707
708 return layoutTypePortlet;
709 }
710
711 private String _getURL(
712 HttpServletRequest request, boolean resetMaxState,
713 boolean resetRenderParameters)
714 throws SystemException {
715
716 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
717 WebKeys.THEME_DISPLAY);
718
719 if (resetMaxState) {
720 Layout layout = themeDisplay.getLayout();
721
722 LayoutTypePortlet layoutTypePortlet = null;
723
724 if (layout.equals(this)) {
725 layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
726 }
727 else {
728 try {
729 layoutTypePortlet = _getLayoutTypePortletClone(request);
730 }
731 catch (IOException ioe) {
732 _log.error("Unable to clone layout settings", ioe);
733
734 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
735 }
736 }
737
738 if (layoutTypePortlet.hasStateMax()) {
739 String portletId =
740 StringUtil.split(layoutTypePortlet.getStateMax())[0];
741
742 PortletURLImpl portletURLImpl = new PortletURLImpl(
743 request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
744
745 try {
746 portletURLImpl.setWindowState(WindowState.NORMAL);
747 portletURLImpl.setPortletMode(PortletMode.VIEW);
748 }
749 catch (PortletException pe) {
750 throw new SystemException(pe);
751 }
752
753 portletURLImpl.setAnchor(false);
754
755 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
756 !resetRenderParameters) {
757
758 portletURLImpl.setParameter("p_l_reset", "0");
759 }
760 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
761 resetRenderParameters) {
762
763 portletURLImpl.setParameter("p_l_reset", "1");
764 }
765
766 return portletURLImpl.toString();
767 }
768 }
769
770 String url = PortalUtil.getLayoutURL(this, themeDisplay);
771
772 if (!CookieKeys.hasSessionId(request)) {
773 url = PortalUtil.getURLWithSessionId(
774 url, request.getSession().getId());
775 }
776
777 if (!resetMaxState && !resetMaxState) {
778 return url;
779 }
780
781 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
782 url = HttpUtil.addParameter(url, "p_l_reset", 0);
783 }
784 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
785 resetRenderParameters) {
786
787 url = HttpUtil.addParameter(url, "p_l_reset", 1);
788 }
789
790 return url;
791 }
792
793 private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
794
795 private UnicodeProperties _typeSettingsProperties;
796
797 }