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