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