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 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 (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
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 isContentDisplayPage() {
476 UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
477
478 String defaultAssetPublisherPortletId =
479 typeSettingsProperties.getProperty(
480 LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID);
481
482 if (Validator.isNotNull(defaultAssetPublisherPortletId)) {
483 return true;
484 }
485 else {
486 return false;
487 }
488 }
489
490 public boolean isFirstChild() {
491 if (getPriority() == 0) {
492 return true;
493 }
494 else {
495 return false;
496 }
497 }
498
499 public boolean isFirstParent() {
500 if (isFirstChild() && isRootLayout()) {
501 return true;
502 }
503 else {
504 return false;
505 }
506 }
507
508 public boolean isInheritLookAndFeel() {
509 if (Validator.isNull(getThemeId()) ||
510 Validator.isNull(getColorSchemeId())) {
511
512 return true;
513 }
514 else {
515 return false;
516 }
517 }
518
519 public boolean isInheritWapLookAndFeel() {
520 if (Validator.isNull(getWapThemeId()) ||
521 Validator.isNull(getWapColorSchemeId())) {
522
523 return true;
524 }
525 else {
526 return false;
527 }
528 }
529
530 public boolean isPublicLayout() {
531 return !isPrivateLayout();
532 }
533
534 public boolean isRootLayout() {
535 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
536 return true;
537 }
538 else {
539 return false;
540 }
541 }
542
543 public boolean isSelected(
544 boolean selectable, Layout layout, long ancestorPlid) {
545
546 if (selectable) {
547 long plid = getPlid();
548
549 if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
550 return true;
551 }
552 }
553
554 return false;
555 }
556
557 public boolean isTypeArticle() {
558 if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
559 return true;
560 }
561 else {
562 return false;
563 }
564 }
565
566 public boolean isTypeControlPanel() {
567 if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
568 return true;
569 }
570 else {
571 return false;
572 }
573 }
574
575 public boolean isTypeEmbedded() {
576 if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
577 return true;
578 }
579 else {
580 return false;
581 }
582 }
583
584 public boolean isTypeLinkToLayout() {
585 if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
586 return true;
587 }
588 else {
589 return false;
590 }
591 }
592
593 public boolean isTypePanel() {
594 if (getType().equals(LayoutConstants.TYPE_PANEL)) {
595 return true;
596 }
597 else {
598 return false;
599 }
600 }
601
602 public boolean isTypePortlet() {
603 if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
604 return true;
605 }
606 else {
607 return false;
608 }
609 }
610
611 public boolean isTypeURL() {
612 if (getType().equals(LayoutConstants.TYPE_URL)) {
613 return true;
614 }
615 else {
616 return false;
617 }
618 }
619
620 @Override
621 public void setGroupId(long groupId) {
622 super.setGroupId(groupId);
623
624 _layoutSet = null;
625 }
626
627 public void setLayoutSet(LayoutSet layoutSet) {
628 _layoutSet = layoutSet;
629 }
630
631 @Override
632 public void setPrivateLayout(boolean privateLayout) {
633 super.setPrivateLayout(privateLayout);
634
635 _layoutSet = null;
636 }
637
638 @Override
639 public void setTypeSettings(String typeSettings) {
640 _typeSettingsProperties = null;
641
642 super.setTypeSettings(typeSettings);
643 }
644
645 public void setTypeSettingsProperties(
646 UnicodeProperties typeSettingsProperties) {
647
648 _typeSettingsProperties = typeSettingsProperties;
649
650 super.setTypeSettings(_typeSettingsProperties.toString());
651 }
652
653 private LayoutTypePortlet _getLayoutTypePortletClone(
654 HttpServletRequest request)
655 throws IOException {
656
657 LayoutTypePortlet layoutTypePortlet = null;
658
659 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
660
661 if (layoutClone != null) {
662 String typeSettings = layoutClone.get(request, getPlid());
663
664 if (typeSettings != null) {
665 UnicodeProperties typeSettingsProperties =
666 new UnicodeProperties(true);
667
668 typeSettingsProperties.load(typeSettings);
669
670 String stateMax = typeSettingsProperties.getProperty(
671 LayoutTypePortletConstants.STATE_MAX);
672 String stateMin = typeSettingsProperties.getProperty(
673 LayoutTypePortletConstants.STATE_MIN);
674
675 Layout layout = (Layout)this.clone();
676
677 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
678
679 layoutTypePortlet.setStateMax(stateMax);
680 layoutTypePortlet.setStateMin(stateMin);
681 }
682 }
683
684 if (layoutTypePortlet == null) {
685 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
686 }
687
688 return layoutTypePortlet;
689 }
690
691 private String _getURL(
692 HttpServletRequest request, boolean resetMaxState,
693 boolean resetRenderParameters)
694 throws PortalException, SystemException {
695
696 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
697 WebKeys.THEME_DISPLAY);
698
699 if (resetMaxState) {
700 Layout layout = themeDisplay.getLayout();
701
702 LayoutTypePortlet layoutTypePortlet = null;
703
704 if (layout.equals(this)) {
705 layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
706 }
707 else {
708 try {
709 layoutTypePortlet = _getLayoutTypePortletClone(request);
710 }
711 catch (IOException ioe) {
712 _log.error("Unable to clone layout settings", ioe);
713
714 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
715 }
716 }
717
718 if (layoutTypePortlet.hasStateMax()) {
719 String portletId =
720 StringUtil.split(layoutTypePortlet.getStateMax())[0];
721
722 PortletURLImpl portletURLImpl = new PortletURLImpl(
723 request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
724
725 try {
726 portletURLImpl.setWindowState(WindowState.NORMAL);
727 portletURLImpl.setPortletMode(PortletMode.VIEW);
728 }
729 catch (PortletException pe) {
730 throw new SystemException(pe);
731 }
732
733 portletURLImpl.setAnchor(false);
734
735 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
736 !resetRenderParameters) {
737
738 portletURLImpl.setParameter("p_l_reset", "0");
739 }
740 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
741 resetRenderParameters) {
742
743 portletURLImpl.setParameter("p_l_reset", "1");
744 }
745
746 return portletURLImpl.toString();
747 }
748 }
749
750 String portalURL = PortalUtil.getPortalURL(request);
751
752 String url = PortalUtil.getLayoutURL(this, themeDisplay);
753
754 if (!CookieKeys.hasSessionId(request) &&
755 (url.startsWith(portalURL) || url.startsWith(StringPool.SLASH))) {
756
757 url = PortalUtil.getURLWithSessionId(
758 url, request.getSession().getId());
759 }
760
761 if (!resetMaxState) {
762 return url;
763 }
764
765 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
766 url = HttpUtil.addParameter(url, "p_l_reset", 0);
767 }
768 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
769 resetRenderParameters) {
770
771 url = HttpUtil.addParameter(url, "p_l_reset", 1);
772 }
773
774 return url;
775 }
776
777 private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
778
779 private LayoutSet _layoutSet;
780 private LayoutType _layoutType;
781 private UnicodeProperties _typeSettingsProperties;
782
783 }