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