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