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.PropsKeys;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.util.UnicodeProperties;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.model.ColorScheme;
033 import com.liferay.portal.model.Group;
034 import com.liferay.portal.model.Layout;
035 import com.liferay.portal.model.LayoutConstants;
036 import com.liferay.portal.model.LayoutSet;
037 import com.liferay.portal.model.LayoutType;
038 import com.liferay.portal.model.LayoutTypePortlet;
039 import com.liferay.portal.model.LayoutTypePortletConstants;
040 import com.liferay.portal.model.Theme;
041 import com.liferay.portal.security.permission.ActionKeys;
042 import com.liferay.portal.security.permission.PermissionChecker;
043 import com.liferay.portal.service.GroupLocalServiceUtil;
044 import com.liferay.portal.service.LayoutLocalServiceUtil;
045 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
046 import com.liferay.portal.service.ThemeLocalServiceUtil;
047 import com.liferay.portal.service.permission.LayoutPermissionUtil;
048 import com.liferay.portal.theme.ThemeDisplay;
049 import com.liferay.portal.util.CookieKeys;
050 import com.liferay.portal.util.LayoutClone;
051 import com.liferay.portal.util.LayoutCloneFactory;
052 import com.liferay.portal.util.PortalUtil;
053 import com.liferay.portal.util.PropsUtil;
054 import com.liferay.portal.util.PropsValues;
055 import com.liferay.portal.util.WebKeys;
056 import com.liferay.portlet.PortletURLImpl;
057
058 import java.io.IOException;
059
060 import java.util.ArrayList;
061 import java.util.Iterator;
062 import java.util.List;
063 import java.util.Locale;
064
065 import javax.portlet.PortletException;
066 import javax.portlet.PortletMode;
067 import javax.portlet.PortletRequest;
068 import javax.portlet.WindowState;
069
070 import javax.servlet.http.HttpServletRequest;
071
072
075 public class LayoutImpl extends LayoutBaseImpl {
076
077 public static int validateFriendlyURL(String friendlyURL) {
078 if (friendlyURL.length() < 2) {
079 return LayoutFriendlyURLException.TOO_SHORT;
080 }
081
082 if (friendlyURL.length() > LayoutConstants.FRIENDLY_URL_MAX_LENGTH) {
083 return LayoutFriendlyURLException.TOO_LONG;
084 }
085
086 if (!friendlyURL.startsWith(StringPool.SLASH)) {
087 return LayoutFriendlyURLException.DOES_NOT_START_WITH_SLASH;
088 }
089
090 if (friendlyURL.endsWith(StringPool.SLASH)) {
091 return LayoutFriendlyURLException.ENDS_WITH_SLASH;
092 }
093
094 if (friendlyURL.indexOf(StringPool.DOUBLE_SLASH) != -1) {
095 return LayoutFriendlyURLException.ADJACENT_SLASHES;
096 }
097
098 for (char c : friendlyURL.toCharArray()) {
099 if ((!Validator.isChar(c)) && (!Validator.isDigit(c)) &&
100 (c != CharPool.DASH) && (c != CharPool.PERCENT) &&
101 (c != CharPool.PERIOD) && (c != CharPool.PLUS) &&
102 (c != CharPool.SLASH) && (c != CharPool.STAR) &&
103 (c != CharPool.UNDERLINE)) {
104
105 return LayoutFriendlyURLException.INVALID_CHARACTERS;
106 }
107 }
108
109 return -1;
110 }
111
112 public static void validateFriendlyURLKeyword(String friendlyURL)
113 throws LayoutFriendlyURLException {
114
115 String[] keywords = PropsUtil.getArray(
116 PropsKeys.LAYOUT_FRIENDLY_URL_KEYWORDS);
117
118 for (String keyword : keywords) {
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 if (_layoutSet == null) {
285 _layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
286 getGroupId(), isPrivateLayout());
287 }
288
289 return _layoutSet;
290 }
291
292 public LayoutType getLayoutType() {
293 if (_layoutType == null) {
294 _layoutType = new LayoutTypePortletImpl(this);
295 }
296
297 return _layoutType;
298 }
299
300 public long getParentPlid() throws PortalException, SystemException {
301 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
302 return 0;
303 }
304
305 Layout layout = LayoutLocalServiceUtil.getLayout(
306 getGroupId(), isPrivateLayout(), getParentLayoutId());
307
308 return layout.getPlid();
309 }
310
311 public String getRegularURL(HttpServletRequest request)
312 throws PortalException, SystemException {
313
314 return _getURL(request, false, false);
315 }
316
317 public String getResetLayoutURL(HttpServletRequest request)
318 throws PortalException, SystemException {
319
320 return _getURL(request, true, true);
321 }
322
323 public String getResetMaxStateURL(HttpServletRequest request)
324 throws PortalException, SystemException {
325
326 return _getURL(request, true, false);
327 }
328
329 public Group getScopeGroup() throws PortalException, SystemException {
330 Group group = null;
331
332 try {
333 group = GroupLocalServiceUtil.getLayoutGroup(
334 getCompanyId(), getPlid());
335 }
336 catch (NoSuchGroupException nsge) {
337 }
338
339 return group;
340 }
341
342 public String getTarget() {
343 return PortalUtil.getLayoutTarget(this);
344 }
345
346 public Theme getTheme() throws PortalException, SystemException {
347 if (isInheritLookAndFeel()) {
348 return getLayoutSet().getTheme();
349 }
350 else {
351 return ThemeLocalServiceUtil.getTheme(
352 getCompanyId(), getThemeId(), false);
353 }
354 }
355
356 public String getThemeSetting(String key, String device) {
357 UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
358
359 String value = typeSettingsProperties.getProperty(
360 ThemeSettingImpl.namespaceProperty(device, key));
361
362 if (value != null) {
363 return value;
364 }
365
366 try {
367 LayoutSet layoutSet = getLayoutSet();
368
369 value = layoutSet.getThemeSetting(key, device);
370 }
371 catch (Exception e) {
372 }
373
374 return value;
375 }
376
377 @Override
378 public String getTypeSettings() {
379 if (_typeSettingsProperties == null) {
380 return super.getTypeSettings();
381 }
382 else {
383 return _typeSettingsProperties.toString();
384 }
385 }
386
387 public UnicodeProperties getTypeSettingsProperties() {
388 if (_typeSettingsProperties == null) {
389 _typeSettingsProperties = new UnicodeProperties(true);
390
391 _typeSettingsProperties.fastLoad(super.getTypeSettings());
392 }
393
394 return _typeSettingsProperties;
395 }
396
397 public String getTypeSettingsProperty(String key) {
398 UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
399
400 return typeSettingsProperties.getProperty(key);
401 }
402
403 public ColorScheme getWapColorScheme()
404 throws PortalException, SystemException {
405
406 if (isInheritLookAndFeel()) {
407 return getLayoutSet().getWapColorScheme();
408 }
409 else {
410 return ThemeLocalServiceUtil.getColorScheme(
411 getCompanyId(), getWapTheme().getThemeId(),
412 getWapColorSchemeId(), true);
413 }
414 }
415
416 public Theme getWapTheme() throws PortalException, SystemException {
417 if (isInheritWapLookAndFeel()) {
418 return getLayoutSet().getWapTheme();
419 }
420 else {
421 return ThemeLocalServiceUtil.getTheme(
422 getCompanyId(), getWapThemeId(), true);
423 }
424 }
425
426 public boolean hasAncestor(long layoutId)
427 throws PortalException, SystemException {
428
429 long parentLayoutId = getParentLayoutId();
430
431 while (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
432 if (parentLayoutId == layoutId) {
433 return true;
434 }
435 else {
436 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
437 getGroupId(), isPrivateLayout(), parentLayoutId);
438
439 parentLayoutId = parentLayout.getParentLayoutId();
440 }
441 }
442
443 return false;
444 }
445
446 public boolean hasChildren() throws SystemException {
447 return LayoutLocalServiceUtil.hasLayouts(
448 getGroupId(), isPrivateLayout(), getLayoutId());
449 }
450
451 public boolean hasScopeGroup() throws PortalException, SystemException {
452 Group group = getScopeGroup();
453
454 if (group != null) {
455 return true;
456 }
457 else {
458 return false;
459 }
460 }
461
462 public boolean isChildSelected(boolean selectable, Layout layout)
463 throws PortalException, SystemException {
464
465 if (selectable) {
466 long plid = getPlid();
467
468 List<Layout> ancestors = layout.getAncestors();
469
470 for (Layout curLayout : ancestors) {
471 if (plid == curLayout.getPlid()) {
472 return true;
473 }
474 }
475 }
476
477 return false;
478 }
479
480 public boolean isContentDisplayPage() {
481 UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
482
483 String defaultAssetPublisherPortletId =
484 typeSettingsProperties.getProperty(
485 LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID);
486
487 if (Validator.isNotNull(defaultAssetPublisherPortletId)) {
488 return true;
489 }
490 else {
491 return false;
492 }
493 }
494
495 public boolean isFirstChild() {
496 if (getPriority() == 0) {
497 return true;
498 }
499 else {
500 return false;
501 }
502 }
503
504 public boolean isFirstParent() {
505 if (isFirstChild() && isRootLayout()) {
506 return true;
507 }
508 else {
509 return false;
510 }
511 }
512
513 public boolean isInheritLookAndFeel() {
514 if (Validator.isNull(getThemeId()) ||
515 Validator.isNull(getColorSchemeId())) {
516
517 return true;
518 }
519 else {
520 return 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 boolean isPublicLayout() {
536 return !isPrivateLayout();
537 }
538
539 public boolean isRootLayout() {
540 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
541 return true;
542 }
543 else {
544 return false;
545 }
546 }
547
548 public boolean isSelected(
549 boolean selectable, Layout layout, long ancestorPlid) {
550
551 if (selectable) {
552 long plid = getPlid();
553
554 if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
555 return true;
556 }
557 }
558
559 return false;
560 }
561
562 public boolean isTypeArticle() {
563 if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
564 return true;
565 }
566 else {
567 return false;
568 }
569 }
570
571 public boolean isTypeControlPanel() {
572 if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
573 return true;
574 }
575 else {
576 return false;
577 }
578 }
579
580 public boolean isTypeEmbedded() {
581 if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
582 return true;
583 }
584 else {
585 return false;
586 }
587 }
588
589 public boolean isTypeLinkToLayout() {
590 if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
591 return true;
592 }
593 else {
594 return false;
595 }
596 }
597
598 public boolean isTypePanel() {
599 if (getType().equals(LayoutConstants.TYPE_PANEL)) {
600 return true;
601 }
602 else {
603 return false;
604 }
605 }
606
607 public boolean isTypePortlet() {
608 if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
609 return true;
610 }
611 else {
612 return false;
613 }
614 }
615
616 public boolean isTypeURL() {
617 if (getType().equals(LayoutConstants.TYPE_URL)) {
618 return true;
619 }
620 else {
621 return false;
622 }
623 }
624
625 @Override
626 public void setGroupId(long groupId) {
627 super.setGroupId(groupId);
628
629 _layoutSet = null;
630 }
631
632 public void setLayoutSet(LayoutSet layoutSet) {
633 _layoutSet = layoutSet;
634 }
635
636 @Override
637 public void setPrivateLayout(boolean privateLayout) {
638 super.setPrivateLayout(privateLayout);
639
640 _layoutSet = null;
641 }
642
643 @Override
644 public void setTypeSettings(String typeSettings) {
645 _typeSettingsProperties = null;
646
647 super.setTypeSettings(typeSettings);
648 }
649
650 public void setTypeSettingsProperties(
651 UnicodeProperties typeSettingsProperties) {
652
653 _typeSettingsProperties = typeSettingsProperties;
654
655 super.setTypeSettings(_typeSettingsProperties.toString());
656 }
657
658 private LayoutTypePortlet _getLayoutTypePortletClone(
659 HttpServletRequest request)
660 throws IOException {
661
662 LayoutTypePortlet layoutTypePortlet = null;
663
664 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
665
666 if (layoutClone != null) {
667 String typeSettings = layoutClone.get(request, getPlid());
668
669 if (typeSettings != null) {
670 UnicodeProperties typeSettingsProperties =
671 new UnicodeProperties(true);
672
673 typeSettingsProperties.load(typeSettings);
674
675 String stateMax = typeSettingsProperties.getProperty(
676 LayoutTypePortletConstants.STATE_MAX);
677 String stateMin = typeSettingsProperties.getProperty(
678 LayoutTypePortletConstants.STATE_MIN);
679
680 Layout layout = (Layout)this.clone();
681
682 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
683
684 layoutTypePortlet.setStateMax(stateMax);
685 layoutTypePortlet.setStateMin(stateMin);
686 }
687 }
688
689 if (layoutTypePortlet == null) {
690 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
691 }
692
693 return layoutTypePortlet;
694 }
695
696 private String _getURL(
697 HttpServletRequest request, boolean resetMaxState,
698 boolean resetRenderParameters)
699 throws PortalException, SystemException {
700
701 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
702 WebKeys.THEME_DISPLAY);
703
704 if (resetMaxState) {
705 Layout layout = themeDisplay.getLayout();
706
707 LayoutTypePortlet layoutTypePortlet = null;
708
709 if (layout.equals(this)) {
710 layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
711 }
712 else {
713 try {
714 layoutTypePortlet = _getLayoutTypePortletClone(request);
715 }
716 catch (IOException ioe) {
717 _log.error("Unable to clone layout settings", ioe);
718
719 layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
720 }
721 }
722
723 if (layoutTypePortlet.hasStateMax()) {
724 String portletId =
725 StringUtil.split(layoutTypePortlet.getStateMax())[0];
726
727 PortletURLImpl portletURLImpl = new PortletURLImpl(
728 request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
729
730 try {
731 portletURLImpl.setWindowState(WindowState.NORMAL);
732 portletURLImpl.setPortletMode(PortletMode.VIEW);
733 }
734 catch (PortletException pe) {
735 throw new SystemException(pe);
736 }
737
738 portletURLImpl.setAnchor(false);
739
740 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
741 !resetRenderParameters) {
742
743 portletURLImpl.setParameter("p_l_reset", "0");
744 }
745 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
746 resetRenderParameters) {
747
748 portletURLImpl.setParameter("p_l_reset", "1");
749 }
750
751 return portletURLImpl.toString();
752 }
753 }
754
755 String url = PortalUtil.getLayoutURL(this, themeDisplay);
756
757 if (!CookieKeys.hasSessionId(request)) {
758 url = PortalUtil.getURLWithSessionId(
759 url, request.getSession().getId());
760 }
761
762 if (!resetMaxState) {
763 return url;
764 }
765
766 if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
767 url = HttpUtil.addParameter(url, "p_l_reset", 0);
768 }
769 else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
770 resetRenderParameters) {
771
772 url = HttpUtil.addParameter(url, "p_l_reset", 1);
773 }
774
775 return url;
776 }
777
778 private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
779
780 private LayoutSet _layoutSet;
781 private LayoutType _layoutType;
782 private UnicodeProperties _typeSettingsProperties;
783
784 }