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