001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.CookieKeys;
025    import com.liferay.portal.kernel.util.HttpUtil;
026    import com.liferay.portal.kernel.util.ListUtil;
027    import com.liferay.portal.kernel.util.LocaleUtil;
028    import com.liferay.portal.kernel.util.LocalizationUtil;
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.LayoutFriendlyURL;
038    import com.liferay.portal.model.LayoutSet;
039    import com.liferay.portal.model.LayoutType;
040    import com.liferay.portal.model.LayoutTypePortlet;
041    import com.liferay.portal.model.LayoutTypePortletConstants;
042    import com.liferay.portal.model.Theme;
043    import com.liferay.portal.security.permission.ActionKeys;
044    import com.liferay.portal.security.permission.PermissionChecker;
045    import com.liferay.portal.service.GroupLocalServiceUtil;
046    import com.liferay.portal.service.LayoutFriendlyURLLocalServiceUtil;
047    import com.liferay.portal.service.LayoutLocalServiceUtil;
048    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
049    import com.liferay.portal.service.ThemeLocalServiceUtil;
050    import com.liferay.portal.service.permission.LayoutPermissionUtil;
051    import com.liferay.portal.theme.ThemeDisplay;
052    import com.liferay.portal.util.LayoutClone;
053    import com.liferay.portal.util.LayoutCloneFactory;
054    import com.liferay.portal.util.PortalUtil;
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.HashMap;
063    import java.util.Iterator;
064    import java.util.List;
065    import java.util.Locale;
066    import java.util.Map;
067    
068    import javax.portlet.PortletException;
069    import javax.portlet.PortletMode;
070    import javax.portlet.PortletRequest;
071    import javax.portlet.WindowState;
072    
073    import javax.servlet.http.HttpServletRequest;
074    
075    /**
076     * @author Brian Wing Shun Chan
077     */
078    public class LayoutImpl extends LayoutBaseImpl {
079    
080            public static boolean hasFriendlyURLKeyword(String friendlyURL) {
081                    String keyword = _getFriendlyURLKeyword(friendlyURL);
082    
083                    if (Validator.isNotNull(keyword)) {
084                            return true;
085                    }
086    
087                    return false;
088            }
089    
090            public static int validateFriendlyURL(String friendlyURL) {
091                    return validateFriendlyURL(friendlyURL, true);
092            }
093    
094            public static int validateFriendlyURL(
095                    String friendlyURL, boolean checkMaxLength) {
096    
097                    if (friendlyURL.length() < 2) {
098                            return LayoutFriendlyURLException.TOO_SHORT;
099                    }
100    
101                    if (checkMaxLength &&
102                            (friendlyURL.length() > LayoutConstants.FRIENDLY_URL_MAX_LENGTH)) {
103    
104                            return LayoutFriendlyURLException.TOO_LONG;
105                    }
106    
107                    if (!friendlyURL.startsWith(StringPool.SLASH)) {
108                            return LayoutFriendlyURLException.DOES_NOT_START_WITH_SLASH;
109                    }
110    
111                    if (friendlyURL.endsWith(StringPool.SLASH)) {
112                            return LayoutFriendlyURLException.ENDS_WITH_SLASH;
113                    }
114    
115                    if (friendlyURL.contains(StringPool.DOUBLE_SLASH)) {
116                            return LayoutFriendlyURLException.ADJACENT_SLASHES;
117                    }
118    
119                    for (char c : friendlyURL.toCharArray()) {
120                            if (!Validator.isChar(c) && !Validator.isDigit(c) &&
121                                    (c != CharPool.DASH) && (c != CharPool.PERCENT) &&
122                                    (c != CharPool.PERIOD) && (c != CharPool.PLUS) &&
123                                    (c != CharPool.SLASH) && (c != CharPool.STAR) &&
124                                    (c != CharPool.UNDERLINE)) {
125    
126                                    return LayoutFriendlyURLException.INVALID_CHARACTERS;
127                            }
128                    }
129    
130                    return -1;
131            }
132    
133            public static void validateFriendlyURLKeyword(String friendlyURL)
134                    throws LayoutFriendlyURLException {
135    
136                    String keyword = _getFriendlyURLKeyword(friendlyURL);
137    
138                    if (Validator.isNotNull(keyword)) {
139                            LayoutFriendlyURLException lfurle = new LayoutFriendlyURLException(
140                                    LayoutFriendlyURLException.KEYWORD_CONFLICT);
141    
142                            lfurle.setKeywordConflict(keyword);
143    
144                            throw lfurle;
145                    }
146            }
147    
148            public LayoutImpl() {
149            }
150    
151            @Override
152            public List<Layout> getAllChildren() throws SystemException {
153                    List<Layout> layouts = new ArrayList<Layout>();
154    
155                    for (Layout layout : getChildren()) {
156                            layouts.add(layout);
157                            layouts.addAll(layout.getAllChildren());
158                    }
159    
160                    return layouts;
161            }
162    
163            @Override
164            public long getAncestorLayoutId() throws PortalException, SystemException {
165                    long layoutId = 0;
166    
167                    Layout layout = this;
168    
169                    while (true) {
170                            if (!layout.isRootLayout()) {
171                                    layout = LayoutLocalServiceUtil.getLayout(
172                                            layout.getGroupId(), layout.isPrivateLayout(),
173                                            layout.getParentLayoutId());
174                            }
175                            else {
176                                    layoutId = layout.getLayoutId();
177    
178                                    break;
179                            }
180                    }
181    
182                    return layoutId;
183            }
184    
185            @Override
186            public long getAncestorPlid() throws PortalException, SystemException {
187                    long plid = 0;
188    
189                    Layout layout = this;
190    
191                    while (true) {
192                            if (!layout.isRootLayout()) {
193                                    layout = LayoutLocalServiceUtil.getLayout(
194                                            layout.getGroupId(), layout.isPrivateLayout(),
195                                            layout.getParentLayoutId());
196                            }
197                            else {
198                                    plid = layout.getPlid();
199    
200                                    break;
201                            }
202                    }
203    
204                    return plid;
205            }
206    
207            @Override
208            public List<Layout> getAncestors() throws PortalException, SystemException {
209                    List<Layout> layouts = new ArrayList<Layout>();
210    
211                    Layout layout = this;
212    
213                    while (!layout.isRootLayout()) {
214                            layout = LayoutLocalServiceUtil.getLayout(
215                                    layout.getGroupId(), layout.isPrivateLayout(),
216                                    layout.getParentLayoutId());
217    
218                            layouts.add(layout);
219                    }
220    
221                    return layouts;
222            }
223    
224            @Override
225            public List<Layout> getChildren() throws SystemException {
226                    return LayoutLocalServiceUtil.getLayouts(
227                            getGroupId(), isPrivateLayout(), getLayoutId());
228            }
229    
230            @Override
231            public List<Layout> getChildren(PermissionChecker permissionChecker)
232                    throws PortalException, SystemException {
233    
234                    List<Layout> layouts = ListUtil.copy(getChildren());
235    
236                    Iterator<Layout> itr = layouts.iterator();
237    
238                    while (itr.hasNext()) {
239                            Layout layout = itr.next();
240    
241                            if (layout.isHidden() ||
242                                    !LayoutPermissionUtil.contains(
243                                            permissionChecker, layout, ActionKeys.VIEW)) {
244    
245                                    itr.remove();
246                            }
247                    }
248    
249                    return layouts;
250            }
251    
252            @Override
253            public ColorScheme getColorScheme()
254                    throws PortalException, SystemException {
255    
256                    if (isInheritLookAndFeel()) {
257                            return getLayoutSet().getColorScheme();
258                    }
259                    else {
260                            return ThemeLocalServiceUtil.getColorScheme(
261                                    getCompanyId(), getTheme().getThemeId(), getColorSchemeId(),
262                                    false);
263                    }
264            }
265    
266            @Override
267            public String getCssText() throws PortalException, SystemException {
268                    if (isInheritLookAndFeel()) {
269                            return getLayoutSet().getCss();
270                    }
271                    else {
272                            return getCss();
273                    }
274            }
275    
276            @Override
277            public String getFriendlyURL(Locale locale) {
278                    Layout layout = this;
279    
280                    String friendlyURL = layout.getFriendlyURL();
281    
282                    try {
283                            LayoutFriendlyURL layoutFriendlyURL =
284                                    LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURL(
285                                            layout.getPlid(), LocaleUtil.toLanguageId(locale));
286    
287                            friendlyURL = layoutFriendlyURL.getFriendlyURL();
288                    }
289                    catch (Exception e) {
290                    }
291    
292                    return friendlyURL;
293            }
294    
295            @Override
296            public Map<Locale, String> getFriendlyURLMap() throws SystemException {
297                    Map<Locale, String> friendlyURLMap = new HashMap<Locale, String>();
298    
299                    List<LayoutFriendlyURL> layoutFriendlyURLs =
300                            LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(getPlid());
301    
302                    for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
303                            friendlyURLMap.put(
304                                    LocaleUtil.fromLanguageId(layoutFriendlyURL.getLanguageId()),
305                                    layoutFriendlyURL.getFriendlyURL());
306                    }
307    
308                    return friendlyURLMap;
309            }
310    
311            @Override
312            public String getFriendlyURLsXML() throws SystemException {
313                    Map<Locale, String> friendlyURLMap = getFriendlyURLMap();
314    
315                    return LocalizationUtil.updateLocalization(
316                            friendlyURLMap, StringPool.BLANK, "FriendlyURL",
317                            LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
318            }
319    
320            @Override
321            public Group getGroup() throws PortalException, SystemException {
322                    return GroupLocalServiceUtil.getGroup(getGroupId());
323            }
324    
325            @Override
326            public String getHTMLTitle(Locale locale) {
327                    String localeLanguageId = LocaleUtil.toLanguageId(locale);
328    
329                    return getHTMLTitle(localeLanguageId);
330            }
331    
332            @Override
333            public String getHTMLTitle(String localeLanguageId) {
334                    String htmlTitle = getTitle(localeLanguageId);
335    
336                    if (Validator.isNull(htmlTitle)) {
337                            htmlTitle = getName(localeLanguageId);
338                    }
339    
340                    return htmlTitle;
341            }
342    
343            @Override
344            public LayoutSet getLayoutSet() throws PortalException, SystemException {
345                    if (_layoutSet == null) {
346                            _layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
347                                    getGroupId(), isPrivateLayout());
348                    }
349    
350                    return _layoutSet;
351            }
352    
353            @Override
354            public LayoutType getLayoutType() {
355                    if (_layoutType == null) {
356                            _layoutType = new LayoutTypePortletImpl(this);
357                    }
358    
359                    return _layoutType;
360            }
361    
362            @Override
363            public long getParentPlid() throws PortalException, SystemException {
364                    if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
365                            return 0;
366                    }
367    
368                    Layout layout = LayoutLocalServiceUtil.getLayout(
369                            getGroupId(), isPrivateLayout(), getParentLayoutId());
370    
371                    return layout.getPlid();
372            }
373    
374            @Override
375            public String getRegularURL(HttpServletRequest request)
376                    throws PortalException, SystemException {
377    
378                    return _getURL(request, false, false);
379            }
380    
381            @Override
382            public String getResetLayoutURL(HttpServletRequest request)
383                    throws PortalException, SystemException {
384    
385                    return _getURL(request, true, true);
386            }
387    
388            @Override
389            public String getResetMaxStateURL(HttpServletRequest request)
390                    throws PortalException, SystemException {
391    
392                    return _getURL(request, true, false);
393            }
394    
395            @Override
396            public Group getScopeGroup() throws PortalException, SystemException {
397                    Group group = null;
398    
399                    try {
400                            group = GroupLocalServiceUtil.getLayoutGroup(
401                                    getCompanyId(), getPlid());
402                    }
403                    catch (NoSuchGroupException nsge) {
404                    }
405    
406                    return group;
407            }
408    
409            @Override
410            public String getTarget() {
411                    return PortalUtil.getLayoutTarget(this);
412            }
413    
414            @Override
415            public Theme getTheme() throws PortalException, SystemException {
416                    if (isInheritLookAndFeel()) {
417                            return getLayoutSet().getTheme();
418                    }
419                    else {
420                            return ThemeLocalServiceUtil.getTheme(
421                                    getCompanyId(), getThemeId(), false);
422                    }
423            }
424    
425            @Override
426            public String getThemeSetting(String key, String device) {
427                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
428    
429                    String value = typeSettingsProperties.getProperty(
430                            ThemeSettingImpl.namespaceProperty(device, key));
431    
432                    if (value != null) {
433                            return value;
434                    }
435    
436                    if (!isInheritLookAndFeel()) {
437                            try {
438                                    Theme theme = getTheme(device);
439    
440                                    return theme.getSetting(key);
441                            }
442                            catch (Exception e) {
443                            }
444                    }
445    
446                    try {
447                            LayoutSet layoutSet = getLayoutSet();
448    
449                            value = layoutSet.getThemeSetting(key, device);
450                    }
451                    catch (Exception e) {
452                    }
453    
454                    return value;
455            }
456    
457            @Override
458            public String getTypeSettings() {
459                    if (_typeSettingsProperties == null) {
460                            return super.getTypeSettings();
461                    }
462                    else {
463                            return _typeSettingsProperties.toString();
464                    }
465            }
466    
467            @Override
468            public UnicodeProperties getTypeSettingsProperties() {
469                    if (_typeSettingsProperties == null) {
470                            _typeSettingsProperties = new UnicodeProperties(true);
471    
472                            _typeSettingsProperties.fastLoad(super.getTypeSettings());
473                    }
474    
475                    return _typeSettingsProperties;
476            }
477    
478            @Override
479            public String getTypeSettingsProperty(String key) {
480                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
481    
482                    return typeSettingsProperties.getProperty(key);
483            }
484    
485            @Override
486            public String getTypeSettingsProperty(String key, String defaultValue) {
487                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
488    
489                    return typeSettingsProperties.getProperty(key, defaultValue);
490            }
491    
492            @Override
493            public ColorScheme getWapColorScheme()
494                    throws PortalException, SystemException {
495    
496                    if (isInheritLookAndFeel()) {
497                            return getLayoutSet().getWapColorScheme();
498                    }
499                    else {
500                            return ThemeLocalServiceUtil.getColorScheme(
501                                    getCompanyId(), getWapTheme().getThemeId(),
502                                    getWapColorSchemeId(), true);
503                    }
504            }
505    
506            @Override
507            public Theme getWapTheme() throws PortalException, SystemException {
508                    if (isInheritWapLookAndFeel()) {
509                            return getLayoutSet().getWapTheme();
510                    }
511                    else {
512                            return ThemeLocalServiceUtil.getTheme(
513                                    getCompanyId(), getWapThemeId(), true);
514                    }
515            }
516    
517            @Override
518            public boolean hasAncestor(long layoutId)
519                    throws PortalException, SystemException {
520    
521                    long parentLayoutId = getParentLayoutId();
522    
523                    while (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
524                            if (parentLayoutId == layoutId) {
525                                    return true;
526                            }
527    
528                            Layout parentLayout = LayoutLocalServiceUtil.getLayout(
529                                    getGroupId(), isPrivateLayout(), parentLayoutId);
530    
531                            parentLayoutId = parentLayout.getParentLayoutId();
532                    }
533    
534                    return false;
535            }
536    
537            @Override
538            public boolean hasChildren() throws SystemException {
539                    return LayoutLocalServiceUtil.hasLayouts(
540                            getGroupId(), isPrivateLayout(), getLayoutId());
541            }
542    
543            @Override
544            public boolean hasScopeGroup() throws PortalException, SystemException {
545                    Group group = getScopeGroup();
546    
547                    if (group != null) {
548                            return true;
549                    }
550                    else {
551                            return false;
552                    }
553            }
554    
555            @Override
556            public boolean isChildSelected(boolean selectable, Layout layout)
557                    throws PortalException, SystemException {
558    
559                    if (selectable) {
560                            long plid = getPlid();
561    
562                            List<Layout> ancestors = layout.getAncestors();
563    
564                            for (Layout curLayout : ancestors) {
565                                    if (plid == curLayout.getPlid()) {
566                                            return true;
567                                    }
568                            }
569                    }
570    
571                    return false;
572            }
573    
574            @Override
575            public boolean isContentDisplayPage() {
576                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
577    
578                    String defaultAssetPublisherPortletId =
579                            typeSettingsProperties.getProperty(
580                                    LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID);
581    
582                    if (Validator.isNotNull(defaultAssetPublisherPortletId)) {
583                            return true;
584                    }
585    
586                    return false;
587            }
588    
589            @Override
590            public boolean isFirstChild() {
591                    if (getPriority() == 0) {
592                            return true;
593                    }
594    
595                    return false;
596            }
597    
598            @Override
599            public boolean isFirstParent() {
600                    if (isFirstChild() && isRootLayout()) {
601                            return true;
602                    }
603    
604                    return false;
605            }
606    
607            @Override
608            public boolean isInheritLookAndFeel() {
609                    if (Validator.isNull(getThemeId()) ||
610                            Validator.isNull(getColorSchemeId())) {
611    
612                            return true;
613                    }
614    
615                    return false;
616            }
617    
618            @Override
619            public boolean isInheritWapLookAndFeel() {
620                    if (Validator.isNull(getWapThemeId()) ||
621                            Validator.isNull(getWapColorSchemeId())) {
622    
623                            return true;
624                    }
625    
626                    return false;
627            }
628    
629            @Override
630            public boolean isLayoutPrototypeLinkActive() {
631                    if (isLayoutPrototypeLinkEnabled() &&
632                            Validator.isNotNull(getLayoutPrototypeUuid())) {
633    
634                            return true;
635                    }
636    
637                    return false;
638            }
639    
640            @Override
641            public boolean isPublicLayout() {
642                    return !isPrivateLayout();
643            }
644    
645            @Override
646            public boolean isRootLayout() {
647                    if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
648                            return true;
649                    }
650    
651                    return false;
652            }
653    
654            @Override
655            public boolean isSelected(
656                    boolean selectable, Layout layout, long ancestorPlid) {
657    
658                    if (selectable) {
659                            long plid = getPlid();
660    
661                            if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
662                                    return true;
663                            }
664                    }
665    
666                    return false;
667            }
668    
669            @Override
670            public boolean isSupportsEmbeddedPortlets() {
671                    if (isTypeArticle() || isTypeEmbedded() || isTypePanel() ||
672                            isTypePortlet()) {
673    
674                            return true;
675                    }
676    
677                    return false;
678            }
679    
680            @Override
681            public boolean isTypeArticle() {
682                    if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
683                            return true;
684                    }
685    
686                    return false;
687            }
688    
689            @Override
690            public boolean isTypeControlPanel() {
691                    if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
692                            return true;
693                    }
694    
695                    return false;
696            }
697    
698            @Override
699            public boolean isTypeEmbedded() {
700                    if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
701                            return true;
702                    }
703    
704                    return false;
705            }
706    
707            @Override
708            public boolean isTypeLinkToLayout() {
709                    if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
710                            return true;
711                    }
712    
713                    return false;
714            }
715    
716            @Override
717            public boolean isTypePanel() {
718                    if (getType().equals(LayoutConstants.TYPE_PANEL)) {
719                            return true;
720                    }
721    
722                    return false;
723            }
724    
725            @Override
726            public boolean isTypePortlet() {
727                    if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
728                            return true;
729                    }
730    
731                    return false;
732            }
733    
734            @Override
735            public boolean isTypeURL() {
736                    if (getType().equals(LayoutConstants.TYPE_URL)) {
737                            return true;
738                    }
739    
740                    return false;
741            }
742    
743            @Override
744            public void setGroupId(long groupId) {
745                    super.setGroupId(groupId);
746    
747                    _layoutSet = null;
748            }
749    
750            @Override
751            public void setLayoutSet(LayoutSet layoutSet) {
752                    _layoutSet = layoutSet;
753            }
754    
755            @Override
756            public void setPrivateLayout(boolean privateLayout) {
757                    super.setPrivateLayout(privateLayout);
758    
759                    _layoutSet = null;
760            }
761    
762            @Override
763            public void setTypeSettings(String typeSettings) {
764                    _typeSettingsProperties = null;
765    
766                    super.setTypeSettings(typeSettings);
767            }
768    
769            @Override
770            public void setTypeSettingsProperties(
771                    UnicodeProperties typeSettingsProperties) {
772    
773                    _typeSettingsProperties = typeSettingsProperties;
774    
775                    super.setTypeSettings(_typeSettingsProperties.toString());
776            }
777    
778            protected Theme getTheme(String device)
779                    throws PortalException, SystemException {
780    
781                    if (device.equals("regular")) {
782                            return getTheme();
783                    }
784                    else {
785                            return getWapTheme();
786                    }
787            }
788    
789            private static String _getFriendlyURLKeyword(String friendlyURL) {
790                    friendlyURL = StringUtil.toLowerCase(friendlyURL);
791    
792                    for (String keyword : _friendlyURLKeywords) {
793                            if (friendlyURL.startsWith(keyword)) {
794                                    return keyword;
795                            }
796    
797                            if (keyword.equals(friendlyURL + StringPool.SLASH)) {
798                                    return friendlyURL;
799                            }
800                    }
801    
802                    return null;
803            }
804    
805            private static void _initFriendlyURLKeywords() {
806                    _friendlyURLKeywords =
807                            new String[PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS.length];
808    
809                    for (int i = 0; i < PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS.length;
810                                    i++) {
811    
812                            String keyword = PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS[i];
813    
814                            keyword = StringPool.SLASH + keyword;
815    
816                            if (!keyword.contains(StringPool.PERIOD)) {
817                                    if (keyword.endsWith(StringPool.STAR)) {
818                                            keyword = keyword.substring(0, keyword.length() - 1);
819                                    }
820                                    else {
821                                            keyword = keyword + StringPool.SLASH;
822                                    }
823                            }
824    
825                            _friendlyURLKeywords[i] = StringUtil.toLowerCase(keyword);
826                    }
827            }
828    
829            private LayoutTypePortlet _getLayoutTypePortletClone(
830                            HttpServletRequest request)
831                    throws IOException {
832    
833                    LayoutTypePortlet layoutTypePortlet = null;
834    
835                    LayoutClone layoutClone = LayoutCloneFactory.getInstance();
836    
837                    if (layoutClone != null) {
838                            String typeSettings = layoutClone.get(request, getPlid());
839    
840                            if (typeSettings != null) {
841                                    UnicodeProperties typeSettingsProperties =
842                                            new UnicodeProperties(true);
843    
844                                    typeSettingsProperties.load(typeSettings);
845    
846                                    String stateMax = typeSettingsProperties.getProperty(
847                                            LayoutTypePortletConstants.STATE_MAX);
848                                    String stateMin = typeSettingsProperties.getProperty(
849                                            LayoutTypePortletConstants.STATE_MIN);
850    
851                                    Layout layout = (Layout)this.clone();
852    
853                                    layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
854    
855                                    layoutTypePortlet.setStateMax(stateMax);
856                                    layoutTypePortlet.setStateMin(stateMin);
857                            }
858                    }
859    
860                    if (layoutTypePortlet == null) {
861                            layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
862                    }
863    
864                    return layoutTypePortlet;
865            }
866    
867            private String _getURL(
868                            HttpServletRequest request, boolean resetMaxState,
869                            boolean resetRenderParameters)
870                    throws PortalException, SystemException {
871    
872                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
873                            WebKeys.THEME_DISPLAY);
874    
875                    if (resetMaxState) {
876                            Layout layout = themeDisplay.getLayout();
877    
878                            LayoutTypePortlet layoutTypePortlet = null;
879    
880                            if (layout.equals(this)) {
881                                    layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
882                            }
883                            else {
884                                    try {
885                                            layoutTypePortlet = _getLayoutTypePortletClone(request);
886                                    }
887                                    catch (IOException ioe) {
888                                            _log.error("Unable to clone layout settings", ioe);
889    
890                                            layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
891                                    }
892                            }
893    
894                            if (layoutTypePortlet.hasStateMax()) {
895                                    String portletId = StringUtil.split(
896                                            layoutTypePortlet.getStateMax())[0];
897    
898                                    PortletURLImpl portletURLImpl = new PortletURLImpl(
899                                            request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
900    
901                                    try {
902                                            portletURLImpl.setWindowState(WindowState.NORMAL);
903                                            portletURLImpl.setPortletMode(PortletMode.VIEW);
904                                    }
905                                    catch (PortletException pe) {
906                                            throw new SystemException(pe);
907                                    }
908    
909                                    portletURLImpl.setAnchor(false);
910    
911                                    if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
912                                            !resetRenderParameters) {
913    
914                                            portletURLImpl.setParameter("p_l_reset", "0");
915                                    }
916                                    else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
917                                                     resetRenderParameters) {
918    
919                                            portletURLImpl.setParameter("p_l_reset", "1");
920                                    }
921    
922                                    return portletURLImpl.toString();
923                            }
924                    }
925    
926                    String portalURL = PortalUtil.getPortalURL(request);
927    
928                    String url = PortalUtil.getLayoutURL(this, themeDisplay);
929    
930                    if (!CookieKeys.hasSessionId(request) &&
931                            (url.startsWith(portalURL) || url.startsWith(StringPool.SLASH))) {
932    
933                            url = PortalUtil.getURLWithSessionId(
934                                    url, request.getSession().getId());
935                    }
936    
937                    if (!resetMaxState) {
938                            return url;
939                    }
940    
941                    if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
942                            url = HttpUtil.addParameter(url, "p_l_reset", 0);
943                    }
944                    else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
945                                     resetRenderParameters) {
946    
947                            url = HttpUtil.addParameter(url, "p_l_reset", 1);
948                    }
949    
950                    return url;
951            }
952    
953            private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
954    
955            private static String[] _friendlyURLKeywords;
956    
957            private LayoutSet _layoutSet;
958            private LayoutType _layoutType;
959            private UnicodeProperties _typeSettingsProperties;
960    
961            static {
962                    _initFriendlyURLKeywords();
963            }
964    
965    }