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