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