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