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