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