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.LocalizationUtil;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.UnicodeProperties;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.model.ColorScheme;
034 import com.liferay.portal.model.Group;
035 import com.liferay.portal.model.Layout;
036 import com.liferay.portal.model.LayoutConstants;
037 import com.liferay.portal.model.LayoutSet;
038 import com.liferay.portal.model.LayoutType;
039 import com.liferay.portal.model.LayoutTypePortlet;
040 import com.liferay.portal.model.LayoutTypePortletConstants;
041 import com.liferay.portal.model.Theme;
042 import com.liferay.portal.security.permission.ActionKeys;
043 import com.liferay.portal.security.permission.PermissionChecker;
044 import com.liferay.portal.service.GroupLocalServiceUtil;
045 import com.liferay.portal.service.LayoutLocalServiceUtil;
046 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
047 import com.liferay.portal.service.ThemeLocalServiceUtil;
048 import com.liferay.portal.service.permission.LayoutPermissionUtil;
049 import com.liferay.portal.theme.ThemeDisplay;
050 import com.liferay.portal.util.CookieKeys;
051 import com.liferay.portal.util.LayoutClone;
052 import com.liferay.portal.util.LayoutCloneFactory;
053 import com.liferay.portal.util.PortalUtil;
054 import com.liferay.portal.util.PropsUtil;
055 import com.liferay.portal.util.PropsValues;
056 import com.liferay.portal.util.WebKeys;
057 import com.liferay.portlet.PortletURLImpl;
058
059 import java.io.IOException;
060
061 import java.util.ArrayList;
062 import java.util.Iterator;
063 import java.util.List;
064 import java.util.Locale;
065
066 import javax.portlet.PortletException;
067 import javax.portlet.PortletMode;
068 import javax.portlet.PortletRequest;
069 import javax.portlet.WindowState;
070
071 import javax.servlet.http.HttpServletRequest;
072
073
076 public class LayoutImpl extends LayoutModelImpl implements Layout {
077
078 public static int validateFriendlyURL(String friendlyURL) {
079 if (friendlyURL.length() < 2) {
080 return LayoutFriendlyURLException.TOO_SHORT;
081 }
082
083 if (!friendlyURL.startsWith(StringPool.SLASH)) {
084 return LayoutFriendlyURLException.DOES_NOT_START_WITH_SLASH;
085 }
086
087 if (friendlyURL.endsWith(StringPool.SLASH)) {
088 return LayoutFriendlyURLException.ENDS_WITH_SLASH;
089 }
090
091 if (friendlyURL.indexOf(StringPool.DOUBLE_SLASH) != -1) {
092 return LayoutFriendlyURLException.ADJACENT_SLASHES;
093 }
094
095 for (char c : friendlyURL.toCharArray()) {
096 if ((!Validator.isChar(c)) && (!Validator.isDigit(c)) &&
097 (c != CharPool.DASH) && (c != CharPool.PERCENT) &&
098 (c != CharPool.PERIOD) && (c != CharPool.PLUS) &&
099 (c != CharPool.SLASH) && (c != CharPool.STAR) &&
100 (c != CharPool.UNDERLINE)) {
101
102 return LayoutFriendlyURLException.INVALID_CHARACTERS;
103 }
104 }
105
106 return -1;
107 }
108
109 public static void validateFriendlyURLKeyword(String friendlyURL)
110 throws LayoutFriendlyURLException {
111
112 String[] keywords = PropsUtil.getArray(
113 PropsKeys.LAYOUT_FRIENDLY_URL_KEYWORDS);
114
115 for (int i = 0; i < keywords.length; i++) {
116 String keyword = keywords[i];
117
118 if ((friendlyURL.indexOf(
119 StringPool.SLASH + keyword + StringPool.SLASH) != -1) ||
120 (friendlyURL.endsWith(StringPool.SLASH + keyword))) {
121
122 LayoutFriendlyURLException lfurle =
123 new LayoutFriendlyURLException(
124 LayoutFriendlyURLException.KEYWORD_CONFLICT);
125
126 lfurle.setKeywordConflict(keyword);
127
128 throw lfurle;
129 }
130 }
131 }
132
133 public LayoutImpl() {
134 }
135
136 public List<Layout> getAllChildren() throws SystemException {
137 List<Layout> layouts = new ArrayList<Layout>();
138
139 Iterator<Layout> itr = getChildren().iterator();
140
141 while (itr.hasNext()) {
142 Layout layout = itr.next();
143
144 layouts.add(layout);
145 layouts.addAll(layout.getChildren());
146 }
147
148 return layouts;
149 }
150
151 public long getAncestorLayoutId() throws PortalException, SystemException {
152 long layoutId = 0;
153
154 Layout layout = this;
155
156 while (true) {
157 if (!layout.isRootLayout()) {
158 layout = LayoutLocalServiceUtil.getLayout(
159 layout.getGroupId(), layout.isPrivateLayout(),
160 layout.getParentLayoutId());
161 }
162 else {
163 layoutId = layout.getLayoutId();
164
165 break;
166 }
167 }
168
169 return layoutId;
170 }
171
172 public long getAncestorPlid() throws PortalException, SystemException {
173 long plid = 0;
174
175 Layout layout = this;
176
177 while (true) {
178 if (!layout.isRootLayout()) {
179 layout = LayoutLocalServiceUtil.getLayout(
180 layout.getGroupId(), layout.isPrivateLayout(),
181 layout.getParentLayoutId());
182 }
183 else {
184 plid = layout.getPlid();
185
186 break;
187 }
188 }
189
190 return plid;
191 }
192
193 public List<Layout> getAncestors() throws PortalException, SystemException {
194 List<Layout> layouts = new ArrayList<Layout>();
195
196 Layout layout = this;
197
198 while (true) {
199 if (!layout.isRootLayout()) {
200 layout = LayoutLocalServiceUtil.getLayout(
201 layout.getGroupId(), layout.isPrivateLayout(),
202 layout.getParentLayoutId());
203
204 layouts.add(layout);
205 }
206 else {
207 break;
208 }
209 }
210
211 return layouts;
212 }
213
214 public List<Layout> getChildren() throws SystemException {
215 return LayoutLocalServiceUtil.getLayouts(
216 getGroupId(), isPrivateLayout(), getLayoutId());
217 }
218
219 public List<Layout> getChildren(PermissionChecker permissionChecker)
220 throws PortalException, SystemException {
221
222 List<Layout> layouts = ListUtil.copy(getChildren());
223
224 Iterator<Layout> itr = layouts.iterator();
225
226 while (itr.hasNext()) {
227 Layout layout = itr.next();
228
229 if (layout.isHidden() ||
230 !LayoutPermissionUtil.contains(
231 permissionChecker, layout, ActionKeys.VIEW)) {
232
233 itr.remove();
234 }
235 }
236
237 return layouts;
238 }
239
240 public ColorScheme getColorScheme()
241 throws PortalException, SystemException {
242
243 if (isInheritLookAndFeel()) {
244 return getLayoutSet().getColorScheme();
245 }
246 else {
247 return ThemeLocalServiceUtil.getColorScheme(
248 getCompanyId(), getTheme().getThemeId(), getColorSchemeId(),
249 false);
250 }
251 }
252
253 public String getCssText() throws PortalException, SystemException {
254 if (isInheritLookAndFeel()) {
255 return getLayoutSet().getCss();
256 }
257 else {
258 return getCss();
259 }
260 }
261
262 public Group getGroup() throws PortalException, SystemException {
263 return GroupLocalServiceUtil.getGroup(getGroupId());
264 }
265
266 public String getHTMLTitle(Locale locale) {
267 String localeLanguageId = LocaleUtil.toLanguageId(locale);
268
269 return getHTMLTitle(localeLanguageId);
270 }
271
272 public String getHTMLTitle(String localeLanguageId) {
273 String htmlTitle = getTitle(localeLanguageId);
274
275 if (Validator.isNull(htmlTitle)) {
276 htmlTitle = getName(localeLanguageId);
277 }
278
279 return htmlTitle;
280 }
281
282 public LayoutSet getLayoutSet() throws PortalException, SystemException {
283 return LayoutSetLocalServiceUtil.getLayoutSet(
284 getGroupId(), isPrivateLayout());
285 }
286
287 public LayoutType getLayoutType() {
288 return new LayoutTypePortletImpl(this);
289 }
290
291 public String getName(Locale locale) {
292 String localeLanguageId = LocaleUtil.toLanguageId(locale);
293
294 return getName(localeLanguageId);
295 }
296
297 public String getName(Locale locale, boolean useDefault) {
298 String localeLanguageId = LocaleUtil.toLanguageId(locale);
299
300 return getName(localeLanguageId, useDefault);
301 }
302
303 public String getName(String localeLanguageId) {
304 return LocalizationUtil.getLocalization(getName(), localeLanguageId);
305 }
306
307 public String getName(String localeLanguageId, boolean useDefault) {
308 return LocalizationUtil.getLocalization(
309 getName(), localeLanguageId, useDefault);
310 }
311
312 public long getParentPlid() throws PortalException, SystemException {
313 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
314 return 0;
315 }
316
317 Layout layout = LayoutLocalServiceUtil.getLayout(
318 getGroupId(), isPrivateLayout(), getParentLayoutId());
319
320 return layout.getPlid();
321 }
322
323 public String getRegularURL(HttpServletRequest request)
324 throws PortalException, SystemException {
325
326 return _getURL(request, false, false);
327 }
328
329 public String getResetLayoutURL(HttpServletRequest request)
330 throws PortalException, SystemException {
331
332 return _getURL(request, true, true);
333 }
334
335 public String getResetMaxStateURL(HttpServletRequest request)
336 throws PortalException, SystemException {
337
338 return _getURL(request, true, false);
339 }
340
341 public Group getScopeGroup() throws PortalException, SystemException {
342 Group group = null;
343
344 try {
345 group = GroupLocalServiceUtil.getLayoutGroup(
346 getCompanyId(), getPlid());
347 }
348 catch (NoSuchGroupException nsge) {
349 }
350
351 return group;
352 }
353
354 public String getTarget() {
355 return PortalUtil.getLayoutTarget(this);
356 }
357
358 public Theme getTheme() throws PortalException, SystemException {
359 if (isInheritLookAndFeel()) {
360 return getLayoutSet().getTheme();
361 }
362 else {
363 return ThemeLocalServiceUtil.getTheme(
364 getCompanyId(), getThemeId(), false);
365 }
366 }
367
368 public String getTitle(Locale locale) {
369 String localeLanguageId = LocaleUtil.toLanguageId(locale);
370
371 return getTitle(localeLanguageId);
372 }
373
374 public String getTitle(Locale locale, boolean useDefault) {
375 String localeLanguageId = LocaleUtil.toLanguageId(locale);
376
377 return getTitle(localeLanguageId, useDefault);
378 }
379
380 public String getTitle(String localeLanguageId) {
381 return LocalizationUtil.getLocalization(getTitle(), localeLanguageId);
382 }
383
384 public String getTitle(String localeLanguageId, boolean useDefault) {
385 return LocalizationUtil.getLocalization(
386 getTitle(), localeLanguageId, useDefault);
387 }
388
389 public String getTypeSettings() {
390 if (_typeSettingsProperties == null) {
391 return super.getTypeSettings();
392 }
393 else {
394 return _typeSettingsProperties.toString();
395 }
396 }
397
398 public UnicodeProperties getTypeSettingsProperties() {
399 if (_typeSettingsProperties == null) {
400 _typeSettingsProperties = new UnicodeProperties(true);
401
402 _typeSettingsProperties.fastLoad(super.getTypeSettings());
403 }
404
405 return _typeSettingsProperties;
406 }
407
408 public ColorScheme getWapColorScheme()
409 throws PortalException, SystemException {
410
411 if (isInheritLookAndFeel()) {
412 return getLayoutSet().getWapColorScheme();
413 }
414 else {
415 return ThemeLocalServiceUtil.getColorScheme(
416 getCompanyId(), getWapTheme().getThemeId(),
417 getWapColorSchemeId(), true);
418 }
419 }
420
421 public Theme getWapTheme() throws PortalException, SystemException {
422 if (isInheritWapLookAndFeel()) {
423 return getLayoutSet().getWapTheme();
424 }
425 else {
426 return ThemeLocalServiceUtil.getTheme(
427 getCompanyId(), getWapThemeId(), true);
428 }
429 }
430
431 public boolean hasAncestor(long layoutId)
432 throws PortalException, SystemException {
433
434 long parentLayoutId = getParentLayoutId();
435
436 while (isRootLayout()) {
437 if (parentLayoutId == layoutId) {
438 return true;
439 }
440 else {
441 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
442 getGroupId(), isPrivateLayout(), parentLayoutId);
443
444 parentLayoutId = parentLayout.getParentLayoutId();
445 }
446 }
447
448 return false;
449 }
450
451 public boolean hasChildren() throws SystemException {
452 return LayoutLocalServiceUtil.hasLayouts(
453 getGroupId(), isPrivateLayout(), getLayoutId());
454 }
455
456 public boolean hasScopeGroup() throws PortalException, SystemException {
457 Group group = getScopeGroup();
458
459 if (group != null) {
460 return true;
461 }
462 else {
463 return false;
464 }
465 }
466
467 public boolean isChildSelected(boolean selectable, Layout layout)
468 throws PortalException, SystemException {
469
470 if (selectable) {
471 long plid = getPlid();
472
473 List<Layout> ancestors = layout.getAncestors();
474
475 for (Layout curLayout : ancestors) {
476 if (plid == curLayout.getPlid()) {
477 return true;
478 }
479 }
480 }
481
482 return false;
483 }
484
485 public boolean isFirstChild() {
486 if (getPriority() == 0) {
487 return true;
488 }
489 else {
490 return false;
491 }
492 }
493
494 public boolean isFirstParent() {
495 if (isFirstChild() && isRootLayout()) {
496 return true;
497 }
498 else {
499 return false;
500 }
501 }
502
503 public boolean isInheritLookAndFeel() {
504 if (Validator.isNull(getThemeId()) ||
505 Validator.isNull(getColorSchemeId())) {
506
507 return true;
508 }
509 else {
510 return false;
511 }
512 }
513
514 public boolean isInheritWapLookAndFeel() {
515 if (Validator.isNull(getWapThemeId()) ||
516 Validator.isNull(getWapColorSchemeId())) {
517
518 return true;
519 }
520 else {
521 return false;
522 }
523 }
524
525 public boolean isPublicLayout() {
526 return !isPrivateLayout();
527 }
528
529 public boolean isRootLayout() {
530 if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
531 return true;
532 }
533 else {
534 return false;
535 }
536 }
537
538 public boolean isSelected(
539 boolean selectable, Layout layout, long ancestorPlid) {
540
541 if (selectable) {
542 long plid = getPlid();
543
544 if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
545 return true;
546 }
547 }
548
549 return false;
550 }
551
552 public boolean isTypeArticle() {
553 if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
554 return true;
555 }
556 else {
557 return false;
558 }
559 }
560
561 public boolean isTypeControlPanel() {
562 if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
563 return true;
564 }
565 else {
566 return false;
567 }
568 }
569
570 public boolean isTypeEmbedded() {
571 if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
572 return true;
573 }
574 else {
575 return false;
576 }
577 }
578
579 public boolean isTypeLinkToLayout() {
580 if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
581 return true;
582 }
583 else {
584 return false;
585 }
586 }
587
588 public boolean isTypePanel() {
589 if (getType().equals(LayoutConstants.TYPE_PANEL)) {
590 return true;
591 }
592 else {
593 return false;
594 }
595 }
596
597 public boolean isTypePortlet() {
598 if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
599 return true;
600 }
601 else {
602 return false;
603 }
604 }
605
606 public boolean isTypeURL() {
607 if (getType().equals(LayoutConstants.TYPE_URL)) {
608 return true;
609 }
610 else {
611 return false;
612 }
613 }
614
615 public void setName(String name, Locale locale) {
616 String localeLanguageId = LocaleUtil.toLanguageId(locale);
617
618 if (Validator.isNotNull(name)) {
619 setName(
620 LocalizationUtil.updateLocalization(
621 getName(), "name", name, localeLanguageId));
622 }
623 else {
624 setName(
625 LocalizationUtil.removeLocalization(
626 getName(), "name", localeLanguageId));
627 }
628 }
629
630 public void setTitle(String title, Locale locale) {
631 String localeLanguageId = LocaleUtil.toLanguageId(locale);
632
633 if (Validator.isNotNull(title)) {
634 setTitle(
635 LocalizationUtil.updateLocalization(
636 getTitle(), "title", title, localeLanguageId));
637 }
638 else {
639 setTitle(
640 LocalizationUtil.removeLocalization(
641 getTitle(), "title", localeLanguageId));
642 }
643 }
644
645 public void setTypeSettings(String typeSettings) {
646 _typeSettingsProperties = null;
647
648 super.setTypeSettings(typeSettings);
649 }
650
651 public void setTypeSettingsProperties(
652 UnicodeProperties typeSettingsProperties) {
653
654 _typeSettingsProperties = typeSettingsProperties;
655
656 super.setTypeSettings(_typeSettingsProperties.toString());
657 }
658
659 private LayoutTypePortlet _getLayoutTypePortletClone(
660 HttpServletRequest request)
661 throws IOException {
662
663 LayoutTypePortlet layoutTypePortlet = null;
664
665 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
666
667 if (layoutClone != null) {
668 String typeSettings = layoutClone.get(request, getPlid());
669
670 if (typeSettings != null) {
671 UnicodeProperties props = new UnicodeProperties(true);
672
673 props.load(typeSettings);
674
675 String stateMax = props.getProperty(
676 LayoutTypePortletConstants.STATE_MAX);
677 String stateMin = props.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 UnicodeProperties _typeSettingsProperties;
781
782 }