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