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.kernel.configuration.Filter;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
023    import com.liferay.portal.kernel.util.ArrayUtil;
024    import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
025    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.ListUtil;
028    import com.liferay.portal.kernel.util.PropsKeys;
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.UniqueList;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.model.CustomizedPages;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.Layout;
037    import com.liferay.portal.model.LayoutSet;
038    import com.liferay.portal.model.LayoutTemplate;
039    import com.liferay.portal.model.LayoutTypePortlet;
040    import com.liferay.portal.model.LayoutTypePortletConstants;
041    import com.liferay.portal.model.Plugin;
042    import com.liferay.portal.model.Portlet;
043    import com.liferay.portal.model.PortletConstants;
044    import com.liferay.portal.model.PortletPreferencesIds;
045    import com.liferay.portal.model.Theme;
046    import com.liferay.portal.security.permission.ActionKeys;
047    import com.liferay.portal.security.permission.PermissionChecker;
048    import com.liferay.portal.security.permission.PermissionThreadLocal;
049    import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
050    import com.liferay.portal.service.PluginSettingLocalServiceUtil;
051    import com.liferay.portal.service.PortletLocalServiceUtil;
052    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
053    import com.liferay.portal.service.permission.LayoutPermissionUtil;
054    import com.liferay.portal.service.permission.PortletPermissionUtil;
055    import com.liferay.portal.util.PortalUtil;
056    import com.liferay.portal.util.PortletKeys;
057    import com.liferay.portal.util.PropsUtil;
058    import com.liferay.portal.util.PropsValues;
059    import com.liferay.portlet.PortalPreferences;
060    import com.liferay.portlet.PortletPreferencesFactoryUtil;
061    import com.liferay.portlet.sites.util.SitesUtil;
062    import com.liferay.util.JS;
063    import com.liferay.util.PwdGenerator;
064    
065    import java.text.DateFormat;
066    import java.text.Format;
067    
068    import java.util.ArrayList;
069    import java.util.Date;
070    import java.util.Iterator;
071    import java.util.List;
072    import java.util.Map;
073    
074    /**
075     * @author Brian Wing Shun Chan
076     * @author Berentey Zsolt
077     * @author Jorge Ferrer
078     * @author Raymond Aug??
079     */
080    public class LayoutTypePortletImpl
081            extends LayoutTypeImpl implements LayoutTypePortlet {
082    
083            public static String getFullInstanceSeparator() {
084                    String instanceId = PwdGenerator.getPassword(
085                            PwdGenerator.KEY1 + PwdGenerator.KEY2 + PwdGenerator.KEY3, 12);
086    
087                    return PortletConstants.INSTANCE_SEPARATOR + instanceId;
088            }
089    
090            public LayoutTypePortletImpl(Layout layout) {
091                    super(layout);
092    
093                    if (_nestedPortletsNamespace == null) {
094                            _nestedPortletsNamespace = PortalUtil.getPortletNamespace(
095                                    PortletKeys.NESTED_PORTLETS);
096                    }
097    
098                    _layoutSetPrototypeLayout = SitesUtil.getLayoutSetPrototypeLayout(
099                            layout);
100            }
101    
102            @Override
103            public void addModeAboutPortletId(String portletId) {
104                    removeModesPortletId(portletId);
105                    setModeAbout(StringUtil.add(getModeAbout(), portletId));
106            }
107    
108            @Override
109            public void addModeConfigPortletId(String portletId) {
110                    removeModesPortletId(portletId);
111                    setModeConfig(StringUtil.add(getModeConfig(), portletId));
112            }
113    
114            @Override
115            public void addModeEditDefaultsPortletId(String portletId) {
116                    removeModesPortletId(portletId);
117                    setModeEditDefaults(StringUtil.add(getModeEditDefaults(), portletId));
118            }
119    
120            @Override
121            public void addModeEditGuestPortletId(String portletId) {
122                    removeModesPortletId(portletId);
123                    setModeEditGuest(StringUtil.add(getModeEditGuest(), portletId));
124            }
125    
126            @Override
127            public void addModeEditPortletId(String portletId) {
128                    removeModesPortletId(portletId);
129                    setModeEdit(StringUtil.add(getModeEdit(), portletId));
130            }
131    
132            @Override
133            public void addModeHelpPortletId(String portletId) {
134                    removeModesPortletId(portletId);
135                    setModeHelp(StringUtil.add(getModeHelp(), portletId));
136            }
137    
138            @Override
139            public void addModePreviewPortletId(String portletId) {
140                    removeModesPortletId(portletId);
141                    setModePreview(StringUtil.add(getModePreview(), portletId));
142            }
143    
144            @Override
145            public void addModePrintPortletId(String portletId) {
146                    removeModesPortletId(portletId);
147                    setModePrint(StringUtil.add(getModePrint(), portletId));
148            }
149    
150            @Override
151            public String addPortletId(long userId, String portletId)
152                    throws PortalException, SystemException {
153    
154                    return addPortletId(userId, portletId, true);
155            }
156    
157            @Override
158            public String addPortletId(
159                            long userId, String portletId, boolean checkPermission)
160                    throws PortalException, SystemException {
161    
162                    return addPortletId(userId, portletId, null, -1, checkPermission);
163            }
164    
165            @Override
166            public String addPortletId(
167                            long userId, String portletId, String columnId, int columnPos)
168                    throws PortalException, SystemException {
169    
170                    return addPortletId(userId, portletId, columnId, columnPos, true);
171            }
172    
173            @Override
174            public String addPortletId(
175                            long userId, String portletId, String columnId, int columnPos,
176                            boolean checkPermission)
177                    throws PortalException, SystemException {
178    
179                    portletId = JS.getSafeName(portletId);
180    
181                    Layout layout = getLayout();
182    
183                    Portlet portlet = null;
184    
185                    try {
186                            portlet = PortletLocalServiceUtil.getPortletById(
187                                    layout.getCompanyId(), portletId);
188    
189                            if (portlet == null) {
190                                    if (_log.isWarnEnabled()) {
191                                            _log.warn(
192                                                    "Portlet " + portletId +
193                                                            " cannot be added because it is not registered");
194                                    }
195    
196                                    return null;
197                            }
198    
199                            PermissionChecker permissionChecker =
200                                    PermissionThreadLocal.getPermissionChecker();
201    
202                            if (checkPermission &&
203                                    !PortletPermissionUtil.contains(
204                                            permissionChecker, layout, portlet,
205                                            ActionKeys.ADD_TO_PAGE)) {
206    
207                                    return null;
208                            }
209                    }
210                    catch (Exception e) {
211                            _log.error(e, e);
212                    }
213    
214                    if (portlet.isSystem()) {
215                            return null;
216                    }
217    
218                    if (portlet.isInstanceable() &&
219                            !PortletConstants.hasInstanceId(portletId)) {
220    
221                            portletId = portletId + getFullInstanceSeparator();
222                    }
223    
224                    if (hasPortletId(portletId)) {
225                            return null;
226                    }
227    
228                    if (columnId == null) {
229                            LayoutTemplate layoutTemplate = getLayoutTemplate();
230    
231                            List<String> columns = layoutTemplate.getColumns();
232    
233                            if (columns.size() > 0) {
234                                    columnId = columns.get(0);
235                            }
236                    }
237    
238                    if (columnId != null) {
239                            if (isCustomizable() && isColumnDisabled(columnId)) {
240                                    return null;
241                            }
242    
243                            String columnValue = StringPool.BLANK;
244    
245                            if (hasUserPreferences()) {
246                                    columnValue = getUserPreference(columnId);
247                            }
248                            else {
249                                    columnValue = getTypeSettingsProperty(columnId);
250                            }
251    
252                            if ((columnValue == null) &&
253                                    columnId.startsWith(_nestedPortletsNamespace)) {
254    
255                                    addNestedColumn(columnId);
256                            }
257    
258                            if (columnPos >= 0) {
259                                    List<String> portletIds = ListUtil.fromArray(
260                                            StringUtil.split(columnValue));
261    
262                                    if (columnPos <= portletIds.size()) {
263                                            portletIds.add(columnPos, portletId);
264                                    }
265                                    else {
266                                            portletIds.add(portletId);
267                                    }
268    
269                                    columnValue = StringUtil.merge(portletIds);
270                            }
271                            else {
272                                    columnValue = StringUtil.add(columnValue, portletId);
273                            }
274    
275                            if (hasUserPreferences()) {
276                                    setUserPreference(columnId, columnValue);
277                            }
278                            else {
279                                    setTypeSettingsProperty(columnId, columnValue);
280                            }
281                    }
282    
283                    try {
284                            PortletLayoutListener portletLayoutListener =
285                                    portlet.getPortletLayoutListenerInstance();
286    
287                            if (_enablePortletLayoutListener &&
288                                    (portletLayoutListener != null)) {
289    
290                                    portletLayoutListener.onAddToLayout(
291                                            portletId, layout.getPlid());
292                            }
293                    }
294                    catch (Exception e) {
295                            _log.error("Unable to fire portlet layout listener event", e);
296                    }
297    
298                    return portletId;
299            }
300    
301            @Override
302            public void addPortletIds(
303                            long userId, String[] portletIds, boolean checkPermission)
304                    throws PortalException, SystemException {
305    
306                    for (String portletId : portletIds) {
307                            addPortletId(userId, portletId, checkPermission);
308                    }
309            }
310    
311            @Override
312            public void addPortletIds(
313                            long userId, String[] portletIds, String columnId,
314                            boolean checkPermission)
315                    throws PortalException, SystemException {
316    
317                    for (String portletId : portletIds) {
318                            addPortletId(userId, portletId, columnId, -1, checkPermission);
319                    }
320            }
321    
322            @Override
323            public void addStateMaxPortletId(String portletId) {
324                    removeStatesPortletId(portletId);
325                    //setStateMax(StringUtil.add(getStateMax(), portletId));
326                    setStateMax(StringUtil.add(StringPool.BLANK, portletId));
327            }
328    
329            @Override
330            public void addStateMinPortletId(String portletId) {
331                    removeStateMaxPortletId(portletId);
332                    setStateMin(StringUtil.add(getStateMin(), portletId));
333            }
334    
335            @Override
336            public List<Portlet> addStaticPortlets(
337                    List<Portlet> portlets, List<Portlet> startPortlets,
338                    List<Portlet> endPortlets) {
339    
340                    // Return the original array of portlets if no static portlets are
341                    // specified
342    
343                    if (startPortlets == null) {
344                            startPortlets = new ArrayList<Portlet>();
345                    }
346    
347                    if (endPortlets == null) {
348                            endPortlets = new ArrayList<Portlet>();
349                    }
350    
351                    if (startPortlets.isEmpty() && endPortlets.isEmpty()) {
352                            return portlets;
353                    }
354    
355                    // New array of portlets that contain the static portlets
356    
357                    List<Portlet> list = new ArrayList<Portlet>(
358                            portlets.size() + startPortlets.size() + endPortlets.size());
359    
360                    if (!startPortlets.isEmpty()) {
361                            list.addAll(startPortlets);
362                    }
363    
364                    for (int i = 0; i < portlets.size(); i++) {
365                            Portlet portlet = portlets.get(i);
366    
367                            // Add the portlet if and only if it is not also a static portlet
368    
369                            if (!startPortlets.contains(portlet) &&
370                                    !endPortlets.contains(portlet)) {
371    
372                                    list.add(portlet);
373                            }
374                    }
375    
376                    if (!endPortlets.isEmpty()) {
377                            list.addAll(endPortlets);
378                    }
379    
380                    return list;
381            }
382    
383            @Override
384            public List<Portlet> getAllPortlets()
385                    throws PortalException, SystemException {
386    
387                    List<Portlet> portlets = new ArrayList<Portlet>();
388    
389                    List<String> columns = getColumns();
390    
391                    for (int i = 0; i < columns.size(); i++) {
392                            String columnId = columns.get(i);
393    
394                            portlets.addAll(getAllPortlets(columnId));
395                    }
396    
397                    List<Portlet> staticPortlets = getStaticPortlets(
398                            PropsKeys.LAYOUT_STATIC_PORTLETS_ALL);
399    
400                    return addStaticPortlets(portlets, staticPortlets, null);
401            }
402    
403            @Override
404            public List<Portlet> getAllPortlets(String columnId)
405                    throws PortalException, SystemException {
406    
407                    String columnValue = getColumnValue(columnId);
408    
409                    String[] portletIds = StringUtil.split(columnValue);
410    
411                    List<Portlet> portlets = new ArrayList<Portlet>(portletIds.length);
412    
413                    for (String portletId : portletIds) {
414                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
415                                    getCompanyId(), portletId);
416    
417                            if (portlet != null) {
418                                    portlets.add(portlet);
419                            }
420                    }
421    
422                    List<Portlet> startPortlets = getStaticPortlets(
423                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
424    
425                    List<Portlet> endPortlets = getStaticPortlets(
426                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
427    
428                    return addStaticPortlets(portlets, startPortlets, endPortlets);
429            }
430    
431            @Override
432            public Layout getLayoutSetPrototypeLayout() {
433                    return _layoutSetPrototypeLayout;
434            }
435    
436            @Override
437            public String getLayoutSetPrototypeLayoutProperty(String key) {
438                    if (_layoutSetPrototypeLayout== null) {
439                            return StringPool.BLANK;
440                    }
441    
442                    UnicodeProperties typeSettingsProperties =
443                            _layoutSetPrototypeLayout.getTypeSettingsProperties();
444    
445                    return typeSettingsProperties.getProperty(key);
446            }
447    
448            @Override
449            public LayoutTemplate getLayoutTemplate() {
450                    String themeId = getThemeId();
451    
452                    LayoutTemplate layoutTemplate =
453                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
454                                    getLayoutTemplateId(), false, themeId);
455    
456                    if (layoutTemplate == null) {
457                            layoutTemplate = new LayoutTemplateImpl(
458                                    StringPool.BLANK, StringPool.BLANK);
459    
460                            List<String> columns = new ArrayList<String>();
461    
462                            for (int i = 1; i <= 10; i++) {
463                                    columns.add(LayoutTypePortletConstants.COLUMN_PREFIX + i);
464                            }
465    
466                            layoutTemplate.setColumns(columns);
467                    }
468    
469                    return layoutTemplate;
470            }
471    
472            @Override
473            public String getLayoutTemplateId() {
474                    return GetterUtil.getString(
475                            getTypeSettingsProperty(
476                                    LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID));
477            }
478    
479            @Override
480            public String getModeAbout() {
481                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_ABOUT);
482            }
483    
484            @Override
485            public String getModeConfig() {
486                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_CONFIG);
487            }
488    
489            @Override
490            public String getModeEdit() {
491                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_EDIT);
492            }
493    
494            @Override
495            public String getModeEditDefaults() {
496                    return getTypeSettingsProperty(
497                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS);
498            }
499    
500            @Override
501            public String getModeEditGuest() {
502                    return getTypeSettingsProperty(
503                            LayoutTypePortletConstants.MODE_EDIT_GUEST);
504            }
505    
506            @Override
507            public String getModeHelp() {
508                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_HELP);
509            }
510    
511            @Override
512            public String getModePreview() {
513                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_PREVIEW);
514            }
515    
516            @Override
517            public String getModePrint() {
518                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_PRINT);
519            }
520    
521            @Override
522            public int getNumOfColumns() {
523                    return getLayoutTemplate().getColumns().size();
524            }
525    
526            @Override
527            public PortalPreferences getPortalPreferences() {
528                    return _portalPreferences;
529            }
530    
531            @Override
532            public List<String> getPortletIds() {
533                    List<String> portletIds = new ArrayList<String>();
534    
535                    List<String> columns = getColumns();
536    
537                    for (int i = 0; i < columns.size(); i++) {
538                            String columnId = columns.get(i);
539    
540                            String columnValue = getColumnValue(columnId);
541    
542                            portletIds.addAll(
543                                    ListUtil.fromArray(StringUtil.split(columnValue)));
544                    }
545    
546                    return portletIds;
547            }
548    
549            @Override
550            public List<Portlet> getPortlets() throws SystemException {
551                    List<String> portletIds = getPortletIds();
552    
553                    List<Portlet> portlets = new ArrayList<Portlet>(portletIds.size());
554    
555                    for (int i = 0; i < portletIds.size(); i++) {
556                            String portletId = portletIds.get(i);
557    
558                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
559                                    getCompanyId(), portletId);
560    
561                            if (portlet != null) {
562                                    portlets.add(portlet);
563                            }
564                    }
565    
566                    return portlets;
567            }
568    
569            @Override
570            public String getStateMax() {
571                    return getTypeSettingsProperty(LayoutTypePortletConstants.STATE_MAX);
572            }
573    
574            @Override
575            public String getStateMaxPortletId() {
576                    String[] stateMax = StringUtil.split(getStateMax());
577    
578                    if (stateMax.length > 0) {
579                            return stateMax[0];
580                    }
581                    else {
582                            return StringPool.BLANK;
583                    }
584            }
585    
586            @Override
587            public String getStateMin() {
588                    return getTypeSettingsProperty(LayoutTypePortletConstants.STATE_MIN);
589            }
590    
591            @Override
592            public boolean hasDefaultScopePortletId(long groupId, String portletId)
593                    throws PortalException, SystemException {
594    
595                    if (hasPortletId(portletId)) {
596                            long scopeGroupId = PortalUtil.getScopeGroupId(
597                                    getLayout(), portletId);
598    
599                            if (groupId == scopeGroupId) {
600                                    return true;
601                            }
602                    }
603    
604                    return false;
605            }
606    
607            @Override
608            public boolean hasLayoutSetPrototypeLayout() {
609                    if (_layoutSetPrototypeLayout != null) {
610                            return true;
611                    }
612    
613                    return false;
614            }
615    
616            @Override
617            public boolean hasModeAboutPortletId(String portletId) {
618                    return StringUtil.contains(getModeAbout(), portletId);
619            }
620    
621            @Override
622            public boolean hasModeConfigPortletId(String portletId) {
623                    return StringUtil.contains(getModeConfig(), portletId);
624            }
625    
626            @Override
627            public boolean hasModeEditDefaultsPortletId(String portletId) {
628                    return StringUtil.contains(getModeEditDefaults(), portletId);
629            }
630    
631            @Override
632            public boolean hasModeEditGuestPortletId(String portletId) {
633                    return StringUtil.contains(getModeEditGuest(), portletId);
634            }
635    
636            @Override
637            public boolean hasModeEditPortletId(String portletId) {
638                    return StringUtil.contains(getModeEdit(), portletId);
639            }
640    
641            @Override
642            public boolean hasModeHelpPortletId(String portletId) {
643                    return StringUtil.contains(getModeHelp(), portletId);
644            }
645    
646            @Override
647            public boolean hasModePreviewPortletId(String portletId) {
648                    return StringUtil.contains(getModePreview(), portletId);
649            }
650    
651            @Override
652            public boolean hasModePrintPortletId(String portletId) {
653                    return StringUtil.contains(getModePrint(), portletId);
654            }
655    
656            @Override
657            public boolean hasModeViewPortletId(String portletId) {
658                    if (hasModeAboutPortletId(portletId) ||
659                            hasModeConfigPortletId(portletId) ||
660                            hasModeEditPortletId(portletId) ||
661                            hasModeEditDefaultsPortletId(portletId) ||
662                            hasModeEditGuestPortletId(portletId) ||
663                            hasModeHelpPortletId(portletId) ||
664                            hasModePreviewPortletId(portletId) ||
665                            hasModePrintPortletId(portletId)) {
666    
667                            return false;
668                    }
669                    else {
670                            return true;
671                    }
672            }
673    
674            @Override
675            public boolean hasPortletId(String portletId)
676                    throws PortalException, SystemException {
677    
678                    List<String> columns = getColumns();
679    
680                    for (String columnId : columns) {
681                            if (hasNonstaticPortletId(columnId, portletId)) {
682                                    return true;
683                            }
684    
685                            if (hasStaticPortletId(columnId, portletId)) {
686                                    return true;
687                            }
688                    }
689    
690                    Layout layout = getLayout();
691    
692                    if (layout.isTypeControlPanel() || layout.isTypePanel()) {
693                            return true;
694                    }
695    
696                    return false;
697            }
698    
699            @Override
700            public boolean hasStateMax() {
701                    String[] stateMax = StringUtil.split(getStateMax());
702    
703                    if (stateMax.length > 0) {
704                            return true;
705                    }
706                    else {
707                            return false;
708                    }
709            }
710    
711            @Override
712            public boolean hasStateMaxPortletId(String portletId) {
713                    if (StringUtil.contains(getStateMax(), portletId)) {
714                            return true;
715                    }
716                    else {
717                            return false;
718                    }
719            }
720    
721            @Override
722            public boolean hasStateMin() {
723                    String[] stateMin = StringUtil.split(getStateMin());
724    
725                    if (stateMin.length > 0) {
726                            return true;
727                    }
728                    else {
729                            return false;
730                    }
731            }
732    
733            @Override
734            public boolean hasStateMinPortletId(String portletId) {
735                    if (StringUtil.contains(getStateMin(), portletId)) {
736                            return true;
737                    }
738                    else {
739                            return false;
740                    }
741            }
742    
743            @Override
744            public boolean hasStateNormalPortletId(String portletId) {
745                    if (hasStateMaxPortletId(portletId) ||
746                            hasStateMinPortletId(portletId)) {
747    
748                            return false;
749                    }
750                    else {
751                            return true;
752                    }
753            }
754    
755            @Override
756            public boolean hasUpdatePermission() {
757                    return _updatePermission;
758            }
759    
760            @Override
761            public boolean isColumnCustomizable(String columnId) {
762                    if (!isLayoutSetPrototype()) {
763                            String customizableString = getTypeSettingsProperty(
764                                    CustomizedPages.namespaceColumnId(columnId));
765    
766                            boolean customizable = GetterUtil.getBoolean(customizableString);
767    
768                            if (!customizable && hasUserPreferences()) {
769                                    String columnValue = _portalPreferences.getValue(
770                                            CustomizedPages.namespacePlid(getPlid()), columnId,
771                                            StringPool.NULL);
772    
773                                    if (!Validator.equals(columnValue, StringPool.NULL)) {
774                                            setUserPreference(columnId, null);
775                                    }
776                            }
777    
778                            return customizable;
779                    }
780    
781                    return false;
782            }
783    
784            @Override
785            public boolean isColumnDisabled(String columnId) {
786                    if ((isCustomizedView() && !isColumnCustomizable(columnId)) ||
787                            (!isCustomizedView() && !hasUpdatePermission())) {
788    
789                            return true;
790                    }
791    
792                    return false;
793            }
794    
795            @Override
796            public boolean isCustomizable() {
797                    for (String columnId : getColumns()) {
798                            if (isColumnCustomizable(columnId)) {
799                                    return true;
800                            }
801                    }
802    
803                    return false;
804            }
805    
806            @Override
807            public boolean isCustomizedView() {
808                    return _customizedView;
809            }
810    
811            @Override
812            public boolean isDefaultUpdated() {
813                    if (!isCustomizedView() || !hasUserPreferences()) {
814                            return false;
815                    }
816    
817                    String preferencesModifiedDateString = _portalPreferences.getValue(
818                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
819                            _NULL_DATE);
820    
821                    DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
822                            PropsValues.INDEX_DATE_FORMAT_PATTERN);
823    
824                    try {
825                            Date preferencesModifiedDate = dateFormat.parse(
826                                    preferencesModifiedDateString);
827    
828                            Layout layout = getLayout();
829    
830                            String propertiesModifiedDateString =
831                                    layout.getTypeSettingsProperty(_MODIFIED_DATE, _NULL_DATE);
832    
833                            Date propertiesModifiedDate = dateFormat.parse(
834                                    propertiesModifiedDateString);
835    
836                            return propertiesModifiedDate.after(preferencesModifiedDate);
837                    }
838                    catch (Exception e) {
839                            _log.error(e, e);
840                    }
841    
842                    return false;
843            }
844    
845            @Override
846            public boolean isPortletCustomizable(String portletId) {
847                    return isColumnCustomizable(getColumn(portletId));
848            }
849    
850            @Override
851            public void movePortletId(
852                            long userId, String portletId, String columnId, int columnPos)
853                    throws PortalException, SystemException {
854    
855                    _enablePortletLayoutListener = false;
856    
857                    try {
858                            removePortletId(userId, portletId, false);
859                            addPortletId(userId, portletId, columnId, columnPos, false);
860                    }
861                    finally {
862                            _enablePortletLayoutListener = true;
863                    }
864    
865                    Layout layout = getLayout();
866    
867                    try {
868                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
869                                    layout.getCompanyId(), portletId);
870    
871                            if (portlet != null) {
872                                    PortletLayoutListener portletLayoutListener =
873                                            portlet.getPortletLayoutListenerInstance();
874    
875                                    if (portletLayoutListener != null) {
876                                            portletLayoutListener.onMoveInLayout(
877                                                    portletId, layout.getPlid());
878                                    }
879                            }
880                    }
881                    catch (Exception e) {
882                            _log.error("Unable to fire portlet layout listener event", e);
883                    }
884            }
885    
886            @Override
887            public void removeModeAboutPortletId(String portletId) {
888                    setModeAbout(StringUtil.remove(getModeAbout(), portletId));
889            }
890    
891            @Override
892            public void removeModeConfigPortletId(String portletId) {
893                    setModeConfig(StringUtil.remove(getModeConfig(), portletId));
894            }
895    
896            @Override
897            public void removeModeEditDefaultsPortletId(String portletId) {
898                    setModeEditDefaults(
899                            StringUtil.remove(getModeEditDefaults(), portletId));
900            }
901    
902            @Override
903            public void removeModeEditGuestPortletId(String portletId) {
904                    setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
905            }
906    
907            @Override
908            public void removeModeEditPortletId(String portletId) {
909                    setModeEdit(StringUtil.remove(getModeEdit(), portletId));
910            }
911    
912            @Override
913            public void removeModeHelpPortletId(String portletId) {
914                    setModeHelp(StringUtil.remove(getModeHelp(), portletId));
915            }
916    
917            @Override
918            public void removeModePreviewPortletId(String portletId) {
919                    setModePreview(StringUtil.remove(getModePreview(), portletId));
920            }
921    
922            @Override
923            public void removeModePrintPortletId(String portletId) {
924                    setModePrint(StringUtil.remove(getModePrint(), portletId));
925            }
926    
927            @Override
928            public void removeModesPortletId(String portletId) {
929                    removeModeAboutPortletId(portletId);
930                    removeModeConfigPortletId(portletId);
931                    removeModeEditPortletId(portletId);
932                    removeModeEditDefaultsPortletId(portletId);
933                    removeModeEditGuestPortletId(portletId);
934                    removeModeHelpPortletId(portletId);
935                    removeModePreviewPortletId(portletId);
936                    removeModePrintPortletId(portletId);
937            }
938    
939            @Override
940            public void removeNestedColumns(String portletNamespace) {
941                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
942    
943                    UnicodeProperties newTypeSettingsProperties = new UnicodeProperties();
944    
945                    for (Map.Entry<String, String> entry :
946                                    typeSettingsProperties.entrySet()) {
947    
948                            String key = entry.getKey();
949    
950                            if (!key.startsWith(portletNamespace)) {
951                                    newTypeSettingsProperties.setProperty(key, entry.getValue());
952                            }
953                    }
954    
955                    Layout layout = getLayout();
956    
957                    layout.setTypeSettingsProperties(newTypeSettingsProperties);
958    
959                    String nestedColumnIds = GetterUtil.getString(
960                            getTypeSettingsProperty(
961                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS));
962    
963                    String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
964                            StringUtil.split(nestedColumnIds), portletNamespace);
965    
966                    setTypeSettingsProperty(
967                            LayoutTypePortletConstants.NESTED_COLUMN_IDS,
968                            StringUtil.merge(nestedColumnIdsArray));
969            }
970    
971            @Override
972            public void removePortletId(long userId, String portletId) {
973                    removePortletId(userId, portletId, true);
974            }
975    
976            @Override
977            public void removePortletId(
978                    long userId, String portletId, boolean cleanUp) {
979    
980                    try {
981                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
982                                    getCompanyId(), portletId);
983    
984                            if (portlet == null) {
985                                    _log.error(
986                                            "Portlet " + portletId +
987                                                    " cannot be removed because it is not registered");
988    
989                                    return;
990                            }
991    
992                            PermissionChecker permissionChecker =
993                                    PermissionThreadLocal.getPermissionChecker();
994    
995                            if (!LayoutPermissionUtil.contains(
996                                            permissionChecker, getLayout(), ActionKeys.UPDATE) &&
997                                    !isCustomizable()) {
998    
999                                    return;
1000                            }
1001                    }
1002                    catch (Exception e) {
1003                            _log.error(e, e);
1004    
1005                            return;
1006                    }
1007    
1008                    List<String> columns = getColumns();
1009    
1010                    for (int i = 0; i < columns.size(); i++) {
1011                            String columnId = columns.get(i);
1012    
1013                            if (isCustomizable() && isColumnDisabled(columnId)) {
1014                                    continue;
1015                            }
1016    
1017                            String columnValue = StringPool.BLANK;
1018    
1019                            if (hasUserPreferences()) {
1020                                    columnValue = getUserPreference(columnId);
1021                            }
1022                            else {
1023                                    columnValue = getTypeSettingsProperty(columnId);
1024                            }
1025    
1026                            columnValue = StringUtil.remove(columnValue, portletId);
1027    
1028                            if (hasUserPreferences()) {
1029                                    setUserPreference(columnId, columnValue);
1030                            }
1031                            else {
1032                                    setTypeSettingsProperty(columnId, columnValue);
1033                            }
1034                    }
1035    
1036                    if (cleanUp) {
1037                            try {
1038                                    onRemoveFromLayout(new String[] {portletId});
1039                            }
1040                            catch (Exception e) {
1041                                    _log.error(e, e);
1042                            }
1043                    }
1044            }
1045    
1046            @Override
1047            public void removeStateMaxPortletId(String portletId) {
1048                    setStateMax(StringUtil.remove(getStateMax(), portletId));
1049            }
1050    
1051            @Override
1052            public void removeStateMinPortletId(String portletId) {
1053                    setStateMin(StringUtil.remove(getStateMin(), portletId));
1054            }
1055    
1056            @Override
1057            public void removeStatesPortletId(String portletId) {
1058                    removeStateMaxPortletId(portletId);
1059                    removeStateMinPortletId(portletId);
1060            }
1061    
1062            @Override
1063            public void reorganizePortlets(
1064                    List<String> newColumns, List<String> oldColumns) {
1065    
1066                    String lastNewColumnId = newColumns.get(newColumns.size() - 1);
1067                    String lastNewColumnValue = getTypeSettingsProperty(lastNewColumnId);
1068    
1069                    Iterator<String> itr = oldColumns.iterator();
1070    
1071                    while (itr.hasNext()) {
1072                            String oldColumnId = itr.next();
1073    
1074                            if (!newColumns.contains(oldColumnId)) {
1075                                    String oldColumnValue = getTypeSettingsProperties().remove(
1076                                            oldColumnId);
1077    
1078                                    String[] portletIds = StringUtil.split(oldColumnValue);
1079    
1080                                    for (String portletId : portletIds) {
1081                                            lastNewColumnValue = StringUtil.add(
1082                                                    lastNewColumnValue, portletId);
1083                                    }
1084                            }
1085                    }
1086    
1087                    setTypeSettingsProperty(lastNewColumnId, lastNewColumnValue);
1088            }
1089    
1090            @Override
1091            public void resetModes() {
1092                    setModeAbout(StringPool.BLANK);
1093                    setModeConfig(StringPool.BLANK);
1094                    setModeEdit(StringPool.BLANK);
1095                    setModeEditDefaults(StringPool.BLANK);
1096                    setModeEditGuest(StringPool.BLANK);
1097                    setModeHelp(StringPool.BLANK);
1098                    setModePreview(StringPool.BLANK);
1099                    setModePrint(StringPool.BLANK);
1100            }
1101    
1102            @Override
1103            public void resetStates() {
1104                    setStateMax(StringPool.BLANK);
1105                    setStateMin(StringPool.BLANK);
1106            }
1107    
1108            @Override
1109            public void resetUserPreferences() {
1110                    if (!hasUserPreferences()) {
1111                            return;
1112                    }
1113    
1114                    long plid = getPlid();
1115    
1116                    List<String> customPortletIds = new UniqueList<String>();
1117    
1118                    for (String columnId : getColumns()) {
1119                            String value = _portalPreferences.getValue(
1120                                    CustomizedPages.namespacePlid(plid), columnId);
1121    
1122                            for (String customPortletId : StringUtil.split(value)) {
1123                                    customPortletIds.add(customPortletId);
1124                            }
1125                    }
1126    
1127                    try {
1128                            onRemoveFromLayout(
1129                                    customPortletIds.toArray(new String[customPortletIds.size()]));
1130                    }
1131                    catch (Exception e) {
1132                            _log.error(e, e);
1133                    }
1134    
1135                    _portalPreferences.resetValues(CustomizedPages.namespacePlid(plid));
1136    
1137                    _portalPreferences.setValue(
1138                            CustomizedPages.namespacePlid(plid), _MODIFIED_DATE,
1139                            _dateFormat.format(new Date()));
1140            }
1141    
1142            @Override
1143            public void setCustomizedView(boolean customizedView) {
1144                    _customizedView = customizedView;
1145            }
1146    
1147            @Override
1148            public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
1149                    setLayoutTemplateId(userId, newLayoutTemplateId, true);
1150            }
1151    
1152            @Override
1153            public void setLayoutTemplateId(
1154                    long userId, String newLayoutTemplateId, boolean checkPermission) {
1155    
1156                    if (checkPermission &&
1157                            !PluginSettingLocalServiceUtil.hasPermission(
1158                                    userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
1159    
1160                            return;
1161                    }
1162    
1163                    String oldLayoutTemplateId = getLayoutTemplateId();
1164    
1165                    if (Validator.isNull(oldLayoutTemplateId)) {
1166                            oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
1167                    }
1168    
1169                    String themeId = getThemeId();
1170    
1171                    LayoutTemplate oldLayoutTemplate =
1172                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1173                                    oldLayoutTemplateId, false, themeId);
1174    
1175                    if (oldLayoutTemplate == null) {
1176                            if (_log.isWarnEnabled()) {
1177                                    _log.warn(
1178                                            "Unable to find layout template " + oldLayoutTemplateId);
1179                            }
1180    
1181                            return;
1182                    }
1183    
1184                    LayoutTemplate newLayoutTemplate =
1185                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1186                                    newLayoutTemplateId, false, themeId);
1187    
1188                    if (newLayoutTemplate == null) {
1189                            if (_log.isWarnEnabled()) {
1190                                    _log.warn(
1191                                            "Unable to find layout template " + newLayoutTemplateId);
1192                            }
1193    
1194                            return;
1195                    }
1196    
1197                    setTypeSettingsProperty(
1198                            LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
1199    
1200                    List<String> oldColumns = oldLayoutTemplate.getColumns();
1201                    List<String> newColumns = newLayoutTemplate.getColumns();
1202    
1203                    reorganizePortlets(newColumns, oldColumns);
1204            }
1205    
1206            @Override
1207            public void setModeAbout(String modeAbout) {
1208                    setTypeSettingsProperty(
1209                            LayoutTypePortletConstants.MODE_ABOUT, modeAbout);
1210            }
1211    
1212            @Override
1213            public void setModeConfig(String modeConfig) {
1214                    setTypeSettingsProperty(
1215                            LayoutTypePortletConstants.MODE_CONFIG, modeConfig);
1216            }
1217    
1218            @Override
1219            public void setModeEdit(String modeEdit) {
1220                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_EDIT, modeEdit);
1221            }
1222    
1223            @Override
1224            public void setModeEditDefaults(String modeEditDefaults) {
1225                    setTypeSettingsProperty(
1226                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS, modeEditDefaults);
1227            }
1228    
1229            @Override
1230            public void setModeEditGuest(String modeEditGuest) {
1231                    setTypeSettingsProperty(
1232                            LayoutTypePortletConstants.MODE_EDIT_GUEST, modeEditGuest);
1233            }
1234    
1235            @Override
1236            public void setModeHelp(String modeHelp) {
1237                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_HELP, modeHelp);
1238            }
1239    
1240            @Override
1241            public void setModePreview(String modePreview) {
1242                    setTypeSettingsProperty(
1243                            LayoutTypePortletConstants.MODE_PREVIEW, modePreview);
1244            }
1245    
1246            @Override
1247            public void setModePrint(String modePrint) {
1248                    setTypeSettingsProperty(
1249                            LayoutTypePortletConstants.MODE_PRINT, modePrint);
1250            }
1251    
1252            @Override
1253            public void setPortalPreferences(PortalPreferences portalPreferences) {
1254                    _portalPreferences = portalPreferences;
1255            }
1256    
1257            @Override
1258            public void setPortletIds(String columnId, String portletIds) {
1259                    setTypeSettingsProperty(columnId, portletIds);
1260    
1261                    if (!columnId.startsWith(
1262                                    LayoutTypePortletConstants.RUNTIME_COLUMN_PREFIX)) {
1263    
1264                            return;
1265                    }
1266    
1267                    String runtimeColumnIds = getTypeSettingsProperty(
1268                            LayoutTypePortletConstants.RUNTIME_COLUMN_IDS, StringPool.BLANK);
1269    
1270                    int pos = runtimeColumnIds.indexOf(columnId);
1271    
1272                    if ((pos == -1) && Validator.isNotNull(portletIds)) {
1273                            runtimeColumnIds = StringUtil.add(runtimeColumnIds, columnId);
1274    
1275                            setTypeSettingsProperty(
1276                                    LayoutTypePortletConstants.RUNTIME_COLUMN_IDS,
1277                                    runtimeColumnIds);
1278                    }
1279                    else if ((pos != -1) && Validator.isNull(portletIds)) {
1280                            runtimeColumnIds = StringUtil.remove(runtimeColumnIds, columnId);
1281    
1282                            setTypeSettingsProperty(
1283                                    LayoutTypePortletConstants.RUNTIME_COLUMN_IDS,
1284                                    runtimeColumnIds);
1285                    }
1286            }
1287    
1288            @Override
1289            public void setStateMax(String stateMax) {
1290                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MAX, stateMax);
1291            }
1292    
1293            @Override
1294            public void setStateMin(String stateMin) {
1295                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MIN, stateMin);
1296            }
1297    
1298            @Override
1299            public void setUpdatePermission(boolean updatePermission) {
1300                    _updatePermission = updatePermission;
1301            }
1302    
1303            protected void addNestedColumn(String columnId) {
1304                    String nestedColumnIds = getTypeSettingsProperty(
1305                            LayoutTypePortletConstants.NESTED_COLUMN_IDS, StringPool.BLANK);
1306    
1307                    if (!nestedColumnIds.contains(columnId)) {
1308                            nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
1309    
1310                            setTypeSettingsProperty(
1311                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS, nestedColumnIds);
1312                    }
1313            }
1314    
1315            protected void copyPreferences(
1316                    String sourcePortletId, String targetPortletId) {
1317    
1318                    Layout layout = getLayout();
1319    
1320                    PermissionChecker permissionChecker =
1321                            PermissionThreadLocal.getPermissionChecker();
1322    
1323                    try {
1324                            PortletPreferencesIds portletPreferencesIds =
1325                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1326                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1327                                            sourcePortletId, false);
1328    
1329                            javax.portlet.PortletPreferences sourcePortletPreferences =
1330                                    PortletPreferencesLocalServiceUtil.getPreferences(
1331                                            portletPreferencesIds);
1332    
1333                            portletPreferencesIds =
1334                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1335                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1336                                            targetPortletId, false);
1337    
1338                            PortletPreferencesLocalServiceUtil.updatePreferences(
1339                                    portletPreferencesIds.getOwnerId(),
1340                                    portletPreferencesIds.getOwnerType(),
1341                                    portletPreferencesIds.getPlid(),
1342                                    portletPreferencesIds.getPortletId(), sourcePortletPreferences);
1343                    }
1344                    catch (Exception e) {
1345                    }
1346            }
1347    
1348            protected String getColumn(String portletId) {
1349                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
1350    
1351                    List<String> columns = getColumns();
1352    
1353                    for (String columnId : columns) {
1354                            String columnValue = getColumnValue(columnId);
1355    
1356                            String[] portletIds = StringUtil.split(columnValue);
1357    
1358                            for (String columnPortletId : portletIds) {
1359                                    if (portletId.equals(columnPortletId) ||
1360                                            (portletId.equals(rootPortletId) &&
1361                                             columnPortletId.startsWith(rootPortletId))) {
1362    
1363                                            return columnId;
1364                                    }
1365                            }
1366                    }
1367    
1368                    return StringPool.BLANK;
1369            }
1370    
1371            protected List<String> getColumns() {
1372                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1373    
1374                    List<String> columns = new ArrayList<String>();
1375    
1376                    columns.addAll(layoutTemplate.getColumns());
1377                    columns.addAll(getNestedColumns());
1378                    columns.addAll(getRuntimeColumns());
1379    
1380                    return columns;
1381            }
1382    
1383            protected String getColumnValue(String columnId) {
1384                    if (hasUserPreferences() && isCustomizable() &&
1385                            !isColumnDisabled(columnId)) {
1386    
1387                            return getUserPreference(columnId);
1388                    }
1389    
1390                    return getTypeSettingsProperty(columnId);
1391            }
1392    
1393            protected long getCompanyId() {
1394                    Layout layout = getLayout();
1395    
1396                    return layout.getCompanyId();
1397            }
1398    
1399            protected List<String> getNestedColumns() {
1400                    String nestedColumnIds = getTypeSettingsProperty(
1401                            LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1402    
1403                    return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
1404            }
1405    
1406            protected long getPlid() {
1407                    Layout layout = getLayout();
1408    
1409                    return layout.getPlid();
1410            }
1411    
1412            protected List<String> getRuntimeColumns() {
1413                    String runtimePortletIds = getTypeSettingsProperty(
1414                            LayoutTypePortletConstants.RUNTIME_COLUMN_IDS);
1415    
1416                    return ListUtil.fromArray(StringUtil.split(runtimePortletIds));
1417            }
1418    
1419            protected String[] getStaticPortletIds(String position)
1420                    throws PortalException, SystemException {
1421    
1422                    Layout layout = getLayout();
1423    
1424                    String selector1 = StringPool.BLANK;
1425    
1426                    Group group = layout.getGroup();
1427    
1428                    if (group.isUser()) {
1429                            selector1 = LayoutTypePortletConstants.STATIC_PORTLET_USER_SELECTOR;
1430                    }
1431                    else if (group.isOrganization()) {
1432                            selector1 =
1433                                    LayoutTypePortletConstants.STATIC_PORTLET_ORGANIZATION_SELECTOR;
1434                    }
1435                    else if (group.isRegularSite()) {
1436                            selector1 =
1437                                    LayoutTypePortletConstants.STATIC_PORTLET_REGULAR_SITE_SELECTOR;
1438                    }
1439    
1440                    String selector2 = layout.getFriendlyURL();
1441    
1442                    String[] portletIds = PropsUtil.getArray(
1443                            position, new Filter(selector1, selector2));
1444    
1445                    for (int i = 0; i < portletIds.length; i++) {
1446                            portletIds[i] = JS.getSafeName(portletIds[i]);
1447                    }
1448    
1449                    return portletIds;
1450            }
1451    
1452            protected List<Portlet> getStaticPortlets(String position)
1453                    throws PortalException, SystemException {
1454    
1455                    String[] portletIds = getStaticPortletIds(position);
1456    
1457                    List<Portlet> portlets = new ArrayList<Portlet>();
1458    
1459                    for (String portletId : portletIds) {
1460                            if (Validator.isNull(portletId) ||
1461                                    hasNonstaticPortletId(portletId)) {
1462    
1463                                    continue;
1464                            }
1465    
1466                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1467                                    getCompanyId(), portletId);
1468    
1469                            if (portlet != null) {
1470                                    Portlet staticPortlet = portlet;
1471    
1472                                    if (portlet.isInstanceable()) {
1473    
1474                                            // Instanceable portlets do not need to be cloned because
1475                                            // they are already cloned. See the method getPortletById in
1476                                            // the class PortletLocalServiceImpl and how it references
1477                                            // the method getClonedInstance in the class PortletImpl.
1478    
1479                                    }
1480                                    else {
1481                                            staticPortlet = (Portlet)staticPortlet.clone();
1482                                    }
1483    
1484                                    staticPortlet.setStatic(true);
1485    
1486                                    if (position.startsWith("layout.static.portlets.start")) {
1487                                            staticPortlet.setStaticStart(true);
1488                                    }
1489    
1490                                    portlets.add(staticPortlet);
1491                            }
1492                    }
1493    
1494                    return portlets;
1495            }
1496    
1497            protected String getThemeId() {
1498                    String themeId = null;
1499    
1500                    try {
1501                            Layout layout = getLayout();
1502    
1503                            Theme theme = layout.getTheme();
1504    
1505                            if (theme != null) {
1506                                    themeId = theme.getThemeId();
1507                            }
1508                            else {
1509                                    themeId = layout.getThemeId();
1510                            }
1511                    }
1512                    catch (Exception e) {
1513                            _log.error(e, e);
1514                    }
1515    
1516                    return themeId;
1517            }
1518    
1519            protected String getUserPreference(String key) {
1520                    String value = StringPool.BLANK;
1521    
1522                    if (!hasUserPreferences()) {
1523                            return value;
1524                    }
1525    
1526                    value = _portalPreferences.getValue(
1527                            CustomizedPages.namespacePlid(getPlid()), key, StringPool.NULL);
1528    
1529                    if (!value.equals(StringPool.NULL)) {
1530                            return value;
1531                    }
1532    
1533                    value = getTypeSettingsProperty(key);
1534    
1535                    if (Validator.isNull(value)) {
1536                            return value;
1537                    }
1538    
1539                    String[] portletIds = StringUtil.split(value);
1540    
1541                    String[] newPortletIds = new String[portletIds.length];
1542    
1543                    for (int i = 0; i < portletIds.length; i++) {
1544                            if (portletIds[i].contains(PortletConstants.INSTANCE_SEPARATOR)) {
1545                                    String rootPortletId = PortletConstants.getRootPortletId(
1546                                            portletIds[i]);
1547    
1548                                    newPortletIds[i] = rootPortletId + getFullInstanceSeparator();
1549    
1550                                    copyPreferences(portletIds[i], newPortletIds[i]);
1551                            }
1552                            else {
1553                                    newPortletIds[i] = portletIds[i];
1554                            }
1555                    }
1556    
1557                    value = StringUtil.merge(newPortletIds);
1558    
1559                    setUserPreference(key, value);
1560    
1561                    return value;
1562            }
1563    
1564            protected boolean hasNonstaticPortletId(String portletId) {
1565                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1566    
1567                    List<String> columns = layoutTemplate.getColumns();
1568    
1569                    for (int i = 0; i < columns.size(); i++) {
1570                            String columnId = columns.get(i);
1571    
1572                            if (hasNonstaticPortletId(columnId, portletId)) {
1573                                    return true;
1574                            }
1575                    }
1576    
1577                    return false;
1578            }
1579    
1580            protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1581                    String columnValue = getColumnValue(columnId);
1582    
1583                    String[] columnValues = StringUtil.split(columnValue);
1584    
1585                    for (String nonstaticPortletId : columnValues) {
1586                            if (nonstaticPortletId.equals(portletId) ||
1587                                    nonstaticPortletId.startsWith(
1588                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1589    
1590                                    return true;
1591                            }
1592                    }
1593    
1594                    return false;
1595            }
1596    
1597            protected boolean hasStaticPortletId(String columnId, String portletId)
1598                    throws PortalException, SystemException {
1599    
1600                    String[] staticPortletIdsStart = getStaticPortletIds(
1601                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1602    
1603                    String[] staticPortletIdsEnd = getStaticPortletIds(
1604                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1605    
1606                    for (String staticPortletId : staticPortletIdsStart) {
1607                            if (staticPortletId.equals(portletId) ||
1608                                    staticPortletId.startsWith(
1609                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1610    
1611                                    return true;
1612                            }
1613                    }
1614    
1615                    for (String staticPortletId : staticPortletIdsEnd) {
1616                            if (staticPortletId.equals(portletId) ||
1617                                    staticPortletId.startsWith(
1618                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1619    
1620                                    return true;
1621                            }
1622                    }
1623    
1624                    return false;
1625            }
1626    
1627            protected boolean hasUserPreferences() {
1628                    if (_portalPreferences != null) {
1629                            return true;
1630                    }
1631    
1632                    return false;
1633            }
1634    
1635            protected boolean isLayoutSetPrototype() {
1636                    try {
1637                            Layout layout = getLayout();
1638    
1639                            LayoutSet layoutSet = layout.getLayoutSet();
1640    
1641                            Group group = layoutSet.getGroup();
1642    
1643                            return group.isLayoutSetPrototype();
1644                    }
1645                    catch (Exception e) {
1646                            _log.error(e, e);
1647                    }
1648    
1649                    return false;
1650            }
1651    
1652            protected void onRemoveFromLayout(String[] portletIds)
1653                    throws SystemException {
1654    
1655                    List<String> portletIdList = new UniqueList<String>();
1656    
1657                    for (String portletId : portletIds) {
1658                            removeModesPortletId(portletId);
1659                            removeStatesPortletId(portletId);
1660    
1661                            String rootPortletId = PortletConstants.getRootPortletId(portletId);
1662    
1663                            portletIdList.add(portletId);
1664    
1665                            if (rootPortletId.equals(PortletKeys.NESTED_PORTLETS)) {
1666                                    String portletNamespace = PortalUtil.getPortletNamespace(
1667                                            portletId);
1668    
1669                                    UnicodeProperties typeSettingsProperties =
1670                                            getTypeSettingsProperties();
1671    
1672                                    for (Map.Entry<String, String> entry :
1673                                                    typeSettingsProperties.entrySet()) {
1674    
1675                                            String key = entry.getKey();
1676    
1677                                            if (!key.startsWith(portletNamespace)) {
1678                                                    continue;
1679                                            }
1680    
1681                                            String nestedPortletIds = entry.getValue();
1682    
1683                                            for (String nestedPortletId :
1684                                                            StringUtil.split(nestedPortletIds)) {
1685    
1686                                                    removeModesPortletId(nestedPortletId);
1687                                                    removeStatesPortletId(nestedPortletId);
1688    
1689                                                    portletIdList.add(nestedPortletId);
1690                                            }
1691                                    }
1692    
1693                                    removeNestedColumns(portletNamespace);
1694                            }
1695                    }
1696    
1697                    try {
1698                            PortletLocalServiceUtil.deletePortlets(
1699                                    getCompanyId(),
1700                                    portletIdList.toArray(new String[portletIdList.size()]),
1701                                    getPlid());
1702                    }
1703                    catch (PortalException pe) {
1704                            _log.error(pe, pe);
1705                    }
1706            }
1707    
1708            protected void setUserPreference(String key, String value) {
1709                    if (!hasUserPreferences()) {
1710                            return;
1711                    }
1712    
1713                    _portalPreferences.setValue(
1714                            CustomizedPages.namespacePlid(getPlid()), key, value);
1715    
1716                    _portalPreferences.setValue(
1717                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
1718                            _dateFormat.format(new Date()));
1719            }
1720    
1721            private static final String _MODIFIED_DATE = "modifiedDate";
1722    
1723            private static final String _NULL_DATE = "00000000000000";
1724    
1725            private static Log _log = LogFactoryUtil.getLog(
1726                    LayoutTypePortletImpl.class);
1727    
1728            private static String _nestedPortletsNamespace;
1729    
1730            private boolean _customizedView;
1731            private Format _dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
1732                    PropsValues.INDEX_DATE_FORMAT_PATTERN);
1733            private boolean _enablePortletLayoutListener = true;
1734            private Layout _layoutSetPrototypeLayout;
1735            private PortalPreferences _portalPreferences;
1736            private boolean _updatePermission;
1737    
1738    }