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