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                            else {
528                                    Layout parentLayout = LayoutLocalServiceUtil.getLayout(
529                                            getGroupId(), isPrivateLayout(), parentLayoutId);
530    
531                                    parentLayoutId = parentLayout.getParentLayoutId();
532                            }
533                    }
534    
535                    return false;
536            }
537    
538            @Override
539            public boolean hasChildren() throws SystemException {
540                    return LayoutLocalServiceUtil.hasLayouts(
541                            getGroupId(), isPrivateLayout(), getLayoutId());
542            }
543    
544            @Override
545            public boolean hasScopeGroup() throws PortalException, SystemException {
546                    Group group = getScopeGroup();
547    
548                    if (group != null) {
549                            return true;
550                    }
551                    else {
552                            return false;
553                    }
554            }
555    
556            @Override
557            public boolean isChildSelected(boolean selectable, Layout layout)
558                    throws PortalException, SystemException {
559    
560                    if (selectable) {
561                            long plid = getPlid();
562    
563                            List<Layout> ancestors = layout.getAncestors();
564    
565                            for (Layout curLayout : ancestors) {
566                                    if (plid == curLayout.getPlid()) {
567                                            return true;
568                                    }
569                            }
570                    }
571    
572                    return false;
573            }
574    
575            @Override
576            public boolean isContentDisplayPage() {
577                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
578    
579                    String defaultAssetPublisherPortletId =
580                            typeSettingsProperties.getProperty(
581                                    LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID);
582    
583                    if (Validator.isNotNull(defaultAssetPublisherPortletId)) {
584                            return true;
585                    }
586    
587                    return false;
588            }
589    
590            @Override
591            public boolean isFirstChild() {
592                    if (getPriority() == 0) {
593                            return true;
594                    }
595    
596                    return false;
597            }
598    
599            @Override
600            public boolean isFirstParent() {
601                    if (isFirstChild() && isRootLayout()) {
602                            return true;
603                    }
604    
605                    return false;
606            }
607    
608            @Override
609            public boolean isInheritLookAndFeel() {
610                    if (Validator.isNull(getThemeId()) ||
611                            Validator.isNull(getColorSchemeId())) {
612    
613                            return true;
614                    }
615    
616                    return false;
617            }
618    
619            @Override
620            public boolean isInheritWapLookAndFeel() {
621                    if (Validator.isNull(getWapThemeId()) ||
622                            Validator.isNull(getWapColorSchemeId())) {
623    
624                            return true;
625                    }
626    
627                    return false;
628            }
629    
630            @Override
631            public boolean isLayoutPrototypeLinkActive() {
632                    if (isLayoutPrototypeLinkEnabled() &&
633                            Validator.isNotNull(getLayoutPrototypeUuid())) {
634    
635                            return true;
636                    }
637    
638                    return false;
639            }
640    
641            @Override
642            public boolean isPublicLayout() {
643                    return !isPrivateLayout();
644            }
645    
646            @Override
647            public boolean isRootLayout() {
648                    if (getParentLayoutId() == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
649                            return true;
650                    }
651    
652                    return false;
653            }
654    
655            @Override
656            public boolean isSelected(
657                    boolean selectable, Layout layout, long ancestorPlid) {
658    
659                    if (selectable) {
660                            long plid = getPlid();
661    
662                            if ((plid == layout.getPlid()) || (plid == ancestorPlid)) {
663                                    return true;
664                            }
665                    }
666    
667                    return false;
668            }
669    
670            @Override
671            public boolean isSupportsEmbeddedPortlets() {
672                    if (isTypeArticle() || isTypeEmbedded() || isTypePanel() ||
673                            isTypePortlet()) {
674    
675                            return true;
676                    }
677    
678                    return false;
679            }
680    
681            @Override
682            public boolean isTypeArticle() {
683                    if (getType().equals(LayoutConstants.TYPE_ARTICLE)) {
684                            return true;
685                    }
686    
687                    return false;
688            }
689    
690            @Override
691            public boolean isTypeControlPanel() {
692                    if (getType().equals(LayoutConstants.TYPE_CONTROL_PANEL)) {
693                            return true;
694                    }
695    
696                    return false;
697            }
698    
699            @Override
700            public boolean isTypeEmbedded() {
701                    if (getType().equals(LayoutConstants.TYPE_EMBEDDED)) {
702                            return true;
703                    }
704    
705                    return false;
706            }
707    
708            @Override
709            public boolean isTypeLinkToLayout() {
710                    if (getType().equals(LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
711                            return true;
712                    }
713    
714                    return false;
715            }
716    
717            @Override
718            public boolean isTypePanel() {
719                    if (getType().equals(LayoutConstants.TYPE_PANEL)) {
720                            return true;
721                    }
722    
723                    return false;
724            }
725    
726            @Override
727            public boolean isTypePortlet() {
728                    if (getType().equals(LayoutConstants.TYPE_PORTLET)) {
729                            return true;
730                    }
731    
732                    return false;
733            }
734    
735            @Override
736            public boolean isTypeURL() {
737                    if (getType().equals(LayoutConstants.TYPE_URL)) {
738                            return true;
739                    }
740    
741                    return false;
742            }
743    
744            @Override
745            public void setGroupId(long groupId) {
746                    super.setGroupId(groupId);
747    
748                    _layoutSet = null;
749            }
750    
751            @Override
752            public void setLayoutSet(LayoutSet layoutSet) {
753                    _layoutSet = layoutSet;
754            }
755    
756            @Override
757            public void setPrivateLayout(boolean privateLayout) {
758                    super.setPrivateLayout(privateLayout);
759    
760                    _layoutSet = null;
761            }
762    
763            @Override
764            public void setTypeSettings(String typeSettings) {
765                    _typeSettingsProperties = null;
766    
767                    super.setTypeSettings(typeSettings);
768            }
769    
770            @Override
771            public void setTypeSettingsProperties(
772                    UnicodeProperties typeSettingsProperties) {
773    
774                    _typeSettingsProperties = typeSettingsProperties;
775    
776                    super.setTypeSettings(_typeSettingsProperties.toString());
777            }
778    
779            private static String _getFriendlyURLKeyword(String friendlyURL) {
780                    friendlyURL = friendlyURL.toLowerCase();
781    
782                    for (String keyword : _friendlyURLKeywords) {
783                            if (friendlyURL.startsWith(keyword)) {
784                                    return keyword;
785                            }
786    
787                            if (keyword.equals(friendlyURL + StringPool.SLASH)) {
788                                    return friendlyURL;
789                            }
790                    }
791    
792                    return null;
793            }
794    
795            private static void _initFriendlyURLKeywords() {
796                    _friendlyURLKeywords =
797                            new String[PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS.length];
798    
799                    for (int i = 0; i < PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS.length;
800                                    i++) {
801    
802                            String keyword = PropsValues.LAYOUT_FRIENDLY_URL_KEYWORDS[i];
803    
804                            keyword = StringPool.SLASH + keyword;
805    
806                            if (!keyword.contains(StringPool.PERIOD)) {
807                                    if (keyword.endsWith(StringPool.STAR)) {
808                                            keyword = keyword.substring(0, keyword.length() - 1);
809                                    }
810                                    else {
811                                            keyword = keyword + StringPool.SLASH;
812                                    }
813                            }
814    
815                            _friendlyURLKeywords[i] = keyword.toLowerCase();
816                    }
817            }
818    
819            private LayoutTypePortlet _getLayoutTypePortletClone(
820                            HttpServletRequest request)
821                    throws IOException {
822    
823                    LayoutTypePortlet layoutTypePortlet = null;
824    
825                    LayoutClone layoutClone = LayoutCloneFactory.getInstance();
826    
827                    if (layoutClone != null) {
828                            String typeSettings = layoutClone.get(request, getPlid());
829    
830                            if (typeSettings != null) {
831                                    UnicodeProperties typeSettingsProperties =
832                                            new UnicodeProperties(true);
833    
834                                    typeSettingsProperties.load(typeSettings);
835    
836                                    String stateMax = typeSettingsProperties.getProperty(
837                                            LayoutTypePortletConstants.STATE_MAX);
838                                    String stateMin = typeSettingsProperties.getProperty(
839                                            LayoutTypePortletConstants.STATE_MIN);
840    
841                                    Layout layout = (Layout)this.clone();
842    
843                                    layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
844    
845                                    layoutTypePortlet.setStateMax(stateMax);
846                                    layoutTypePortlet.setStateMin(stateMin);
847                            }
848                    }
849    
850                    if (layoutTypePortlet == null) {
851                            layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
852                    }
853    
854                    return layoutTypePortlet;
855            }
856    
857            private Theme _getTheme(String device)
858                    throws PortalException, SystemException {
859    
860                    if (device.equals("regular")) {
861                            return getTheme();
862                    }
863                    else {
864                            return getWapTheme();
865                    }
866            }
867    
868            private String _getURL(
869                            HttpServletRequest request, boolean resetMaxState,
870                            boolean resetRenderParameters)
871                    throws PortalException, SystemException {
872    
873                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
874                            WebKeys.THEME_DISPLAY);
875    
876                    if (resetMaxState) {
877                            Layout layout = themeDisplay.getLayout();
878    
879                            LayoutTypePortlet layoutTypePortlet = null;
880    
881                            if (layout.equals(this)) {
882                                    layoutTypePortlet = themeDisplay.getLayoutTypePortlet();
883                            }
884                            else {
885                                    try {
886                                            layoutTypePortlet = _getLayoutTypePortletClone(request);
887                                    }
888                                    catch (IOException ioe) {
889                                            _log.error("Unable to clone layout settings", ioe);
890    
891                                            layoutTypePortlet = (LayoutTypePortlet)getLayoutType();
892                                    }
893                            }
894    
895                            if (layoutTypePortlet.hasStateMax()) {
896                                    String portletId = StringUtil.split(
897                                            layoutTypePortlet.getStateMax())[0];
898    
899                                    PortletURLImpl portletURLImpl = new PortletURLImpl(
900                                            request, portletId, getPlid(), PortletRequest.ACTION_PHASE);
901    
902                                    try {
903                                            portletURLImpl.setWindowState(WindowState.NORMAL);
904                                            portletURLImpl.setPortletMode(PortletMode.VIEW);
905                                    }
906                                    catch (PortletException pe) {
907                                            throw new SystemException(pe);
908                                    }
909    
910                                    portletURLImpl.setAnchor(false);
911    
912                                    if (PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
913                                            !resetRenderParameters) {
914    
915                                            portletURLImpl.setParameter("p_l_reset", "0");
916                                    }
917                                    else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
918                                                     resetRenderParameters) {
919    
920                                            portletURLImpl.setParameter("p_l_reset", "1");
921                                    }
922    
923                                    return portletURLImpl.toString();
924                            }
925                    }
926    
927                    String portalURL = PortalUtil.getPortalURL(request);
928    
929                    String url = PortalUtil.getLayoutURL(this, themeDisplay);
930    
931                    if (!CookieKeys.hasSessionId(request) &&
932                            (url.startsWith(portalURL) || url.startsWith(StringPool.SLASH))) {
933    
934                            url = PortalUtil.getURLWithSessionId(
935                                    url, request.getSession().getId());
936                    }
937    
938                    if (!resetMaxState) {
939                            return url;
940                    }
941    
942                    if (PropsValues.LAYOUT_DEFAULT_P_L_RESET && !resetRenderParameters) {
943                            url = HttpUtil.addParameter(url, "p_l_reset", 0);
944                    }
945                    else if (!PropsValues.LAYOUT_DEFAULT_P_L_RESET &&
946                                     resetRenderParameters) {
947    
948                            url = HttpUtil.addParameter(url, "p_l_reset", 1);
949                    }
950    
951                    return url;
952            }
953    
954            private static Log _log = LogFactoryUtil.getLog(LayoutImpl.class);
955    
956            private static String[] _friendlyURLKeywords;
957    
958            private LayoutSet _layoutSet;
959            private LayoutType _layoutType;
960            private UnicodeProperties _typeSettingsProperties;
961    
962            static {
963                    _initFriendlyURLKeywords();
964            }
965    
966    }