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 String getRegularURL(HttpServletRequest request)
314 throws PortalException, SystemException {
315
316 return _getURL(request, false, false);
317 }
318
319 public String getResetLayoutURL(HttpServletRequest request)
320 throws PortalException, SystemException {
321
322 return _getURL(request, true, true);
323 }
324
325 public String getResetMaxStateURL(HttpServletRequest request)
326 throws PortalException, SystemException {
327
328 return _getURL(request, true, false);
329 }
330
331 public Group getScopeGroup() throws PortalException, SystemException {
332 Group group = null;
333
334 try {
335 group = GroupLocalServiceUtil.getLayoutGroup(
336 getCompanyId(), getPlid());
337 }
338 catch (NoSuchGroupException nsge) {
339 }
340
341 return group;
342 }
343
344 public String getTarget() {
345 return PortalUtil.getLayoutTarget(this);
346 }
347
348 public Theme getTheme() throws PortalException, SystemException {
349 if (isInheritLookAndFeel()) {
350 return getLayoutSet().getTheme();
351 }
352 else {
353 return ThemeLocalServiceUtil.getTheme(
354 getCompanyId(), getThemeId(), false);
355 }
356 }
357
358 public String getTitle(Locale locale) {
359 String localeLanguageId = LocaleUtil.toLanguageId(locale);
360
361 return getTitle(localeLanguageId);
362 }
363
364 public String getTitle(Locale locale, boolean useDefault) {
365 String localeLanguageId = LocaleUtil.toLanguageId(locale);
366
367 return getTitle(localeLanguageId, useDefault);
368 }
369
370 public String getTitle(String localeLanguageId) {
371 return LocalizationUtil.getLocalization(getTitle(), localeLanguageId);
372 }
373
374 public String getTitle(String localeLanguageId, boolean useDefault) {
375 return LocalizationUtil.getLocalization(
376 getTitle(), localeLanguageId, useDefault);
377 }
378
379 public String getTypeSettings() {
380 if (_typeSettingsProperties == null) {
381 return super.getTypeSettings();
382 }
383 else {
384 return _typeSettingsProperties.toString();
385 }
386 }
387
388 public UnicodeProperties getTypeSettingsProperties() {
389 if (_typeSettingsProperties == null) {
390 _typeSettingsProperties = new UnicodeProperties(true);
391
392 _typeSettingsProperties.fastLoad(super.getTypeSettings());
393 }
394
395 return _typeSettingsProperties;
396 }
397
398 public ColorScheme getWapColorScheme()
399 throws PortalException, SystemException {
400
401 if (isInheritLookAndFeel()) {
402 return getLayoutSet().getWapColorScheme();
403 }
404 else {
405 return ThemeLocalServiceUtil.getColorScheme(
406 getCompanyId(), getWapTheme().getThemeId(),
407 getWapColorSchemeId(), true);
408 }
409 }
410
411 public Theme getWapTheme() throws PortalException, SystemException {
412 if (isInheritWapLookAndFeel()) {
413 return getLayoutSet().getWapTheme();
414 }
415 else {
416 return ThemeLocalServiceUtil.getTheme(
417 getCompanyId(), getWapThemeId(), true);
418 }
419 }
420
421 public boolean hasAncestor(long layoutId)
422 throws PortalException, SystemException {
423
424 long parentLayoutId = getParentLayoutId();
425
426 while (isRootLayout()) {
427 if (parentLayoutId == layoutId) {
428 return true;
429 }
430 else {
431 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
432 getGroupId(), isPrivateLayout(), parentLayoutId);
433
434 parentLayoutId = parentLayout.getParentLayoutId();
435 }
436 }
437
438 return false;
439 }
440
441 public boolean hasChildren() throws SystemException {
442 return LayoutLocalServiceUtil.hasLayouts(
443 getGroupId(), isPrivateLayout(), getLayoutId());
444 }
445
446 public boolean hasScopeGroup() throws PortalException, SystemException {
447 Group group = getScopeGroup();
448
449 if (group != null) {
450 return true;
451 }
452 else {
453 return false;
454 }
455 }
456
457 public boolean isChildSelected(boolean selectable, Layout layout)
458 throws PortalException, SystemException {
459
460 if (selectable) {
461 long plid = getPlid();
462
463 List<Layout> ancestors = layout.getAncestors();
464
465 for (Layout curLayout : ancestors) {
466 if (plid == curLayout.getPlid()) {
467 return true;
468 }
469 }
470 }
471
472 return false;
473 }
474
475 public boolean isFirstChild() {
476 if (getPriority() == 0) {
477 return true;
478 }
479 else {
480 return false;
481 }
482 }
483
484 public boolean isFirstParent() {
485 if (isFirstChild() && isRootLayout()) {
486 return true;
487 }
488 else {
489 return false;
490 }
491 }
492
493 public boolean isInheritLookAndFeel() {
494 if (Validator.isNull(getThemeId()) ||
495 Validator.isNull(getColorSchemeId())) {
496
497 return true;
498 }
499 else {
500 return false;
501 }
502 }
503
504 public boolean isInheritWapLookAndFeel() {
505 if (Validator.isNull(getWapThemeId()) ||
506 Validator.isNull(getWapColorSchemeId())) {
507
508 return true;
509 }
510 else {
511 return false;
512 }
513 }
514
515 public boolean isPublicLayout() {
516 return !isPrivateLayout();
517 }
518
519 public boolean isRootLayout() {
520 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
521 return true;
522 }
523 else {
524 return false;
525 }
526 }
527
528 public boolean isSelected(
529 boolean selectable, Layout layout, long ancestorPlid) {
530
531 if (selectable) {
532 long plid = getPlid();
533
534 if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
535 return true;
536 }
537 }
538
539 return false;
540 }
541
542 public boolean isTypeArticle() {
543 if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
544 return true;
545 }
546 else {
547 return false;
548 }
549 }
550
551 public boolean isTypeControlPanel() {
552 if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
553 return true;
554 }
555 else {
556 return false;
557 }
558 }
559
560 public boolean isTypeEmbedded() {
561 if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
562 return true;
563 }
564 else {
565 return false;
566 }
567 }
568
569 public boolean isTypeLinkToLayout() {
570 if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
571 return true;
572 }
573 else {
574 return false;
575 }
576 }
577
578 public boolean isTypePanel() {
579 if (getType().equals(LayoutConstants.TYPE_PANEL)) {
580 return true;
581 }
582 else {
583 return false;
584 }
585 }
586
587 public boolean isTypePortlet() {
588 if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
589 return true;
590 }
591 else {
592 return false;
593 }
594 }
595
596 public boolean isTypeURL() {
597 if (getType().equals(LayoutConstants.TYPE_URL)) {
598 return true;
599 }
600 else {
601 return false;
602 }
603 }
604
605 public void setName(String name, Locale locale) {
606 String localeLanguageId = LocaleUtil.toLanguageId(locale);
607
608 if (Validator.isNotNull(name)) {
609 setName(
610 LocalizationUtil.updateLocalization(
611 getName(), "name", name, localeLanguageId));
612 }
613 else {
614 setName(
615 LocalizationUtil.removeLocalization(
616 getName(), "name", localeLanguageId));
617 }
618 }
619
620 public void setTitle(String title, Locale locale) {
621 String localeLanguageId = LocaleUtil.toLanguageId(locale);
622
623 if (Validator.isNotNull(title)) {
624 setTitle(
625 LocalizationUtil.updateLocalization(
626 getTitle(), "title", title, localeLanguageId));
627 }
628 else {
629 setTitle(
630 LocalizationUtil.removeLocalization(
631 getTitle(), "title", localeLanguageId));
632 }
633 }
634
635 public void setTypeSettings(String typeSettings) {
636 _typeSettingsProperties = null;
637
638 super.setTypeSettings(typeSettings);
639 }
640
641 public void setTypeSettingsProperties(
642 UnicodeProperties typeSettingsProperties) {
643
644 _typeSettingsProperties = typeSettingsProperties;
645
646 super.setTypeSettings(_typeSettingsProperties.toString());
647 }
648
649 private LayoutTypePortlet _getLayoutTypePortletClone(
650 HttpServletRequest request)
651 throws IOException {
652
653 LayoutTypePortlet layoutTypePortlet = null;
654
655 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
656
657 if (layoutClone != null) {
658 String typeSettings = layoutClone.get(request, getPlid());
659
660 if (typeSettings != null) {
661 UnicodeProperties props = new UnicodeProperties(true);
662
663 props.load(typeSettings);
664
665 String stateMax = props.getProperty(
666 LayoutTypePortletConstants.STATE_MAX);
667 String stateMin = props.getProperty(
668 LayoutTypePortletConstants.STATE_MIN);
669
670 Layout layout = (Layout)this.clone();
671
672 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
673
674 layoutTypePortlet.setStateMax(stateMax);
675 layoutTypePortlet.setStateMin(stateMin);
676 }
677 }
678
679 if (layoutTypePortlet == null) {
680 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
681 }
682
683 return layoutTypePortlet;
684 }
685
686 private String _getURL(
687 HttpServletRequest request, boolean resetMaxState,
688 boolean resetRenderParameters)
689 throws PortalException, SystemException {
690
691 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
692 WebKeys.THEME_DISPLAY);
693
694 if (resetMaxState) {
695 Layout layout = themeDisplay.getLayout();
696
697 LayoutTypePortlet layoutTypePortlet = null;
698
699 if (layout.equals(this)) {
700 layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
701 }
702 else {
703 try {
704 layoutTypePortlet = _getLayoutTypePortletClone(request);
705 }
706 catch (IOException ioe) {
707 _log.error("Unable to clone layout settings", ioe);
708
709 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
710 }
711 }
712
713 if (layoutTypePortlet.hasStateMax()) {
714 String portletId =
715 StringUtil.split(layoutTypePortlet.getStateMax())[0];
716
717 PortletURLImpl portletURLImpl = new PortletURLImpl(
718 request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
719
720 try {
721 portletURLImpl.setWindowState(WindowState.NORMAL);
722 portletURLImpl.setPortletMode(PortletMode.VIEW);
723 }
724 catch (PortletException pe) {
725 throw new SystemException(pe);
726 }
727
728 portletURLImpl.setAnchor(false);
729
730 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
731 !resetRenderParameters) {
732
733 portletURLImpl.setParameter("p_l_reset", "0");
734 }
735 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
736 resetRenderParameters) {
737
738 portletURLImpl.setParameter("p_l_reset", "1");
739 }
740
741 return portletURLImpl.toString();
742 }
743 }
744
745 String url = PortalUtil.getLayoutURL(this, themeDisplay);
746
747 if (!CookieKeys.hasSessionId(request)) {
748 url = PortalUtil.getURLWithSessionId(
749 url, request.getSession().getId());
750 }
751
752 if (!resetMaxState && !resetMaxState) {
753 return url;
754 }
755
756 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
757 url = HttpUtil.addParameter(url, "p_l_reset", 0);
758 }
759 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
760 resetRenderParameters) {
761
762 url = HttpUtil.addParameter(url, "p_l_reset", 1);
763 }
764
765 return url;
766 }
767
768 private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
769
770 private UnicodeProperties _typeSettingsProperties;
771
772 }