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>();
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                    if (!isLayoutSetPrototype()) {
727                            String customizableString = getTypeSettingsProperty(
728                                    CustomizedPages.namespaceColumnId(columnId));
729    
730                            boolean customizable = GetterUtil.getBoolean(customizableString);
731    
732                            if (!customizable && hasUserPreferences()) {
733                                    String columnValue = _portalPreferences.getValue(
734                                            CustomizedPages.namespacePlid(getPlid()), columnId,
735                                            StringPool.NULL);
736    
737                                    if (!Validator.equals(columnValue, StringPool.NULL)) {
738                                            setUserPreference(columnId, null);
739                                    }
740                            }
741    
742                            return customizable;
743                    }
744    
745                    return false;
746            }
747    
748            @Override
749            public boolean isColumnDisabled(String columnId) {
750                    if ((isCustomizedView() && !isColumnCustomizable(columnId)) ||
751                            (!isCustomizedView() && !hasUpdatePermission())) {
752    
753                            return true;
754                    }
755    
756                    return false;
757            }
758    
759            @Override
760            public boolean isCustomizable() {
761                    for (String columnId : getColumns()) {
762                            if (isColumnCustomizable(columnId)) {
763                                    return true;
764                            }
765                    }
766    
767                    return false;
768            }
769    
770            @Override
771            public boolean isCustomizedView() {
772                    return _customizedView;
773            }
774    
775            @Override
776            public boolean isDefaultUpdated() {
777                    if (!isCustomizedView() || !hasUserPreferences()) {
778                            return false;
779                    }
780    
781                    String preferencesModifiedDateString = _portalPreferences.getValue(
782                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
783                            _NULL_DATE);
784    
785                    DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
786                            PropsValues.INDEX_DATE_FORMAT_PATTERN);
787    
788                    try {
789                            Date preferencesModifiedDate = dateFormat.parse(
790                                    preferencesModifiedDateString);
791    
792                            Layout layout = getLayout();
793    
794                            String propertiesModifiedDateString =
795                                    layout.getTypeSettingsProperty(_MODIFIED_DATE, _NULL_DATE);
796    
797                            Date propertiesModifiedDate = dateFormat.parse(
798                                    propertiesModifiedDateString);
799    
800                            return propertiesModifiedDate.after(preferencesModifiedDate);
801                    }
802                    catch (Exception e) {
803                            _log.error(e, e);
804                    }
805    
806                    return false;
807            }
808    
809            @Override
810            public boolean isPortletCustomizable(String portletId) {
811                    return isColumnCustomizable(getColumn(portletId));
812            }
813    
814            @Override
815            public void movePortletId(
816                            long userId, String portletId, String columnId, int columnPos)
817                    throws PortalException, SystemException {
818    
819                    if (!hasPortletId(portletId)) {
820                            return;
821                    }
822    
823                    _enablePortletLayoutListener = false;
824    
825                    try {
826                            removePortletId(userId, portletId, false);
827                            addPortletId(userId, portletId, columnId, columnPos, false, true);
828                    }
829                    finally {
830                            _enablePortletLayoutListener = true;
831                    }
832    
833                    Layout layout = getLayout();
834    
835                    try {
836                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
837                                    layout.getCompanyId(), portletId);
838    
839                            if (portlet != null) {
840                                    PortletLayoutListener portletLayoutListener =
841                                            portlet.getPortletLayoutListenerInstance();
842    
843                                    if (portletLayoutListener != null) {
844                                            portletLayoutListener.onMoveInLayout(
845                                                    portletId, layout.getPlid());
846                                    }
847                            }
848                    }
849                    catch (Exception e) {
850                            _log.error("Unable to fire portlet layout listener event", e);
851                    }
852            }
853    
854            @Override
855            public void removeModeAboutPortletId(String portletId) {
856                    setModeAbout(StringUtil.remove(getModeAbout(), portletId));
857            }
858    
859            @Override
860            public void removeModeConfigPortletId(String portletId) {
861                    setModeConfig(StringUtil.remove(getModeConfig(), portletId));
862            }
863    
864            @Override
865            public void removeModeEditDefaultsPortletId(String portletId) {
866                    setModeEditDefaults(
867                            StringUtil.remove(getModeEditDefaults(), portletId));
868            }
869    
870            @Override
871            public void removeModeEditGuestPortletId(String portletId) {
872                    setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
873            }
874    
875            @Override
876            public void removeModeEditPortletId(String portletId) {
877                    setModeEdit(StringUtil.remove(getModeEdit(), portletId));
878            }
879    
880            @Override
881            public void removeModeHelpPortletId(String portletId) {
882                    setModeHelp(StringUtil.remove(getModeHelp(), portletId));
883            }
884    
885            @Override
886            public void removeModePreviewPortletId(String portletId) {
887                    setModePreview(StringUtil.remove(getModePreview(), portletId));
888            }
889    
890            @Override
891            public void removeModePrintPortletId(String portletId) {
892                    setModePrint(StringUtil.remove(getModePrint(), portletId));
893            }
894    
895            @Override
896            public void removeModesPortletId(String portletId) {
897                    removeModeAboutPortletId(portletId);
898                    removeModeConfigPortletId(portletId);
899                    removeModeEditPortletId(portletId);
900                    removeModeEditDefaultsPortletId(portletId);
901                    removeModeEditGuestPortletId(portletId);
902                    removeModeHelpPortletId(portletId);
903                    removeModePreviewPortletId(portletId);
904                    removeModePrintPortletId(portletId);
905            }
906    
907            @Override
908            public void removeNestedColumns(String portletNamespace) {
909                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
910    
911                    UnicodeProperties newTypeSettingsProperties = new UnicodeProperties();
912    
913                    for (Map.Entry<String, String> entry :
914                                    typeSettingsProperties.entrySet()) {
915    
916                            String key = entry.getKey();
917    
918                            if (!key.startsWith(portletNamespace)) {
919                                    newTypeSettingsProperties.setProperty(key, entry.getValue());
920                            }
921                    }
922    
923                    Layout layout = getLayout();
924    
925                    layout.setTypeSettingsProperties(newTypeSettingsProperties);
926    
927                    String nestedColumnIds = GetterUtil.getString(
928                            getTypeSettingsProperty(
929                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS));
930    
931                    String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
932                            StringUtil.split(nestedColumnIds), portletNamespace);
933    
934                    setTypeSettingsProperty(
935                            LayoutTypePortletConstants.NESTED_COLUMN_IDS,
936                            StringUtil.merge(nestedColumnIdsArray));
937            }
938    
939            @Override
940            public void removePortletId(long userId, String portletId) {
941                    removePortletId(userId, portletId, true);
942            }
943    
944            @Override
945            public void removePortletId(
946                    long userId, String portletId, boolean cleanUp) {
947    
948                    try {
949                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
950                                    getCompanyId(), portletId);
951    
952                            if (portlet == null) {
953                                    _log.error(
954                                            "Portlet " + portletId +
955                                                    " cannot be removed because it is not registered");
956    
957                                    return;
958                            }
959    
960                            PermissionChecker permissionChecker =
961                                    PermissionThreadLocal.getPermissionChecker();
962    
963                            if (!LayoutPermissionUtil.contains(
964                                            permissionChecker, getLayout(), ActionKeys.UPDATE) &&
965                                    !isCustomizable()) {
966    
967                                    return;
968                            }
969                    }
970                    catch (Exception e) {
971                            _log.error(e, e);
972    
973                            return;
974                    }
975    
976                    List<String> columns = getColumns();
977    
978                    for (int i = 0; i < columns.size(); i++) {
979                            String columnId = columns.get(i);
980    
981                            if (isCustomizable() && isColumnDisabled(columnId)) {
982                                    continue;
983                            }
984    
985                            String columnValue = StringPool.BLANK;
986    
987                            if (hasUserPreferences()) {
988                                    columnValue = getUserPreference(columnId);
989                            }
990                            else {
991                                    columnValue = getTypeSettingsProperty(columnId);
992                            }
993    
994                            columnValue = StringUtil.remove(columnValue, portletId);
995    
996                            if (hasUserPreferences()) {
997                                    setUserPreference(columnId, columnValue);
998                            }
999                            else {
1000                                    setTypeSettingsProperty(columnId, columnValue);
1001                            }
1002                    }
1003    
1004                    if (cleanUp) {
1005                            try {
1006                                    onRemoveFromLayout(new String[] {portletId});
1007                            }
1008                            catch (Exception e) {
1009                                    _log.error(e, e);
1010                            }
1011                    }
1012            }
1013    
1014            @Override
1015            public void removeStateMaxPortletId(String portletId) {
1016                    setStateMax(StringUtil.remove(getStateMax(), portletId));
1017            }
1018    
1019            @Override
1020            public void removeStateMinPortletId(String portletId) {
1021                    setStateMin(StringUtil.remove(getStateMin(), portletId));
1022            }
1023    
1024            @Override
1025            public void removeStatesPortletId(String portletId) {
1026                    removeStateMaxPortletId(portletId);
1027                    removeStateMinPortletId(portletId);
1028            }
1029    
1030            @Override
1031            public void reorganizePortlets(
1032                    List<String> newColumns, List<String> oldColumns) {
1033    
1034                    String lastNewColumnId = newColumns.get(newColumns.size() - 1);
1035                    String lastNewColumnValue = getTypeSettingsProperty(lastNewColumnId);
1036    
1037                    for (String oldColumnId : oldColumns) {
1038                            if (!newColumns.contains(oldColumnId)) {
1039                                    String oldColumnValue = getTypeSettingsProperties().remove(
1040                                            oldColumnId);
1041    
1042                                    String[] portletIds = StringUtil.split(oldColumnValue);
1043    
1044                                    for (String portletId : portletIds) {
1045                                            lastNewColumnValue = StringUtil.add(
1046                                                    lastNewColumnValue, portletId);
1047                                    }
1048                            }
1049                    }
1050    
1051                    setTypeSettingsProperty(lastNewColumnId, lastNewColumnValue);
1052            }
1053    
1054            @Override
1055            public void resetModes() {
1056                    setModeAbout(StringPool.BLANK);
1057                    setModeConfig(StringPool.BLANK);
1058                    setModeEdit(StringPool.BLANK);
1059                    setModeEditDefaults(StringPool.BLANK);
1060                    setModeEditGuest(StringPool.BLANK);
1061                    setModeHelp(StringPool.BLANK);
1062                    setModePreview(StringPool.BLANK);
1063                    setModePrint(StringPool.BLANK);
1064            }
1065    
1066            @Override
1067            public void resetStates() {
1068                    setStateMax(StringPool.BLANK);
1069                    setStateMin(StringPool.BLANK);
1070            }
1071    
1072            @Override
1073            public void resetUserPreferences() {
1074                    if (!hasUserPreferences()) {
1075                            return;
1076                    }
1077    
1078                    long plid = getPlid();
1079    
1080                    List<String> customPortletIds = new UniqueList<String>();
1081    
1082                    for (String columnId : getColumns()) {
1083                            String value = _portalPreferences.getValue(
1084                                    CustomizedPages.namespacePlid(plid), columnId);
1085    
1086                            for (String customPortletId : StringUtil.split(value)) {
1087                                    customPortletIds.add(customPortletId);
1088                            }
1089                    }
1090    
1091                    try {
1092                            onRemoveFromLayout(
1093                                    customPortletIds.toArray(new String[customPortletIds.size()]));
1094                    }
1095                    catch (Exception e) {
1096                            _log.error(e, e);
1097                    }
1098    
1099                    _portalPreferences.resetValues(CustomizedPages.namespacePlid(plid));
1100    
1101                    _portalPreferences.setValue(
1102                            CustomizedPages.namespacePlid(plid), _MODIFIED_DATE,
1103                            _dateFormat.format(new Date()));
1104            }
1105    
1106            @Override
1107            public void setCustomizedView(boolean customizedView) {
1108                    _customizedView = customizedView;
1109            }
1110    
1111            @Override
1112            public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
1113                    setLayoutTemplateId(userId, newLayoutTemplateId, true);
1114            }
1115    
1116            @Override
1117            public void setLayoutTemplateId(
1118                    long userId, String newLayoutTemplateId, boolean checkPermission) {
1119    
1120                    if (checkPermission &&
1121                            !PluginSettingLocalServiceUtil.hasPermission(
1122                                    userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
1123    
1124                            return;
1125                    }
1126    
1127                    LayoutTemplate oldLayoutTemplate = getLayoutTemplate();
1128    
1129                    String themeId = getThemeId();
1130    
1131                    LayoutTemplate newLayoutTemplate =
1132                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1133                                    newLayoutTemplateId, false, themeId);
1134    
1135                    if (newLayoutTemplate == null) {
1136                            if (_log.isWarnEnabled()) {
1137                                    _log.warn(
1138                                            "Unable to find layout template " + newLayoutTemplateId);
1139                            }
1140    
1141                            return;
1142                    }
1143    
1144                    setTypeSettingsProperty(
1145                            LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
1146    
1147                    List<String> oldColumns = oldLayoutTemplate.getColumns();
1148                    List<String> newColumns = newLayoutTemplate.getColumns();
1149    
1150                    reorganizePortlets(newColumns, oldColumns);
1151            }
1152    
1153            @Override
1154            public void setModeAbout(String modeAbout) {
1155                    setTypeSettingsProperty(
1156                            LayoutTypePortletConstants.MODE_ABOUT, modeAbout);
1157            }
1158    
1159            @Override
1160            public void setModeConfig(String modeConfig) {
1161                    setTypeSettingsProperty(
1162                            LayoutTypePortletConstants.MODE_CONFIG, modeConfig);
1163            }
1164    
1165            @Override
1166            public void setModeEdit(String modeEdit) {
1167                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_EDIT, modeEdit);
1168            }
1169    
1170            @Override
1171            public void setModeEditDefaults(String modeEditDefaults) {
1172                    setTypeSettingsProperty(
1173                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS, modeEditDefaults);
1174            }
1175    
1176            @Override
1177            public void setModeEditGuest(String modeEditGuest) {
1178                    setTypeSettingsProperty(
1179                            LayoutTypePortletConstants.MODE_EDIT_GUEST, modeEditGuest);
1180            }
1181    
1182            @Override
1183            public void setModeHelp(String modeHelp) {
1184                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_HELP, modeHelp);
1185            }
1186    
1187            @Override
1188            public void setModePreview(String modePreview) {
1189                    setTypeSettingsProperty(
1190                            LayoutTypePortletConstants.MODE_PREVIEW, modePreview);
1191            }
1192    
1193            @Override
1194            public void setModePrint(String modePrint) {
1195                    setTypeSettingsProperty(
1196                            LayoutTypePortletConstants.MODE_PRINT, modePrint);
1197            }
1198    
1199            @Override
1200            public void setPortalPreferences(PortalPreferences portalPreferences) {
1201                    _portalPreferences = portalPreferences;
1202            }
1203    
1204            @Override
1205            public void setStateMax(String stateMax) {
1206                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MAX, stateMax);
1207            }
1208    
1209            @Override
1210            public void setStateMin(String stateMin) {
1211                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MIN, stateMin);
1212            }
1213    
1214            @Override
1215            public void setUpdatePermission(boolean updatePermission) {
1216                    _updatePermission = updatePermission;
1217            }
1218    
1219            protected void addNestedColumn(String columnId) {
1220                    String nestedColumnIds = getTypeSettingsProperty(
1221                            LayoutTypePortletConstants.NESTED_COLUMN_IDS, StringPool.BLANK);
1222    
1223                    if (!nestedColumnIds.contains(columnId)) {
1224                            nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
1225    
1226                            setTypeSettingsProperty(
1227                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS, nestedColumnIds);
1228                    }
1229            }
1230    
1231            protected String addPortletId(
1232                            long userId, String portletId, String columnId, int columnPos,
1233                            boolean checkPermission, boolean strictHasPortlet)
1234                    throws PortalException, SystemException {
1235    
1236                    portletId = JS.getSafeName(portletId);
1237    
1238                    Layout layout = getLayout();
1239    
1240                    Portlet portlet = null;
1241    
1242                    try {
1243                            portlet = PortletLocalServiceUtil.getPortletById(
1244                                    layout.getCompanyId(), portletId);
1245    
1246                            if (portlet == null) {
1247                                    if (_log.isWarnEnabled()) {
1248                                            _log.warn(
1249                                                    "Portlet " + portletId +
1250                                                            " cannot be added because it is not registered");
1251                                    }
1252    
1253                                    return null;
1254                            }
1255    
1256                            PermissionChecker permissionChecker =
1257                                    PermissionThreadLocal.getPermissionChecker();
1258    
1259                            if (checkPermission &&
1260                                    !PortletPermissionUtil.contains(
1261                                            permissionChecker, layout, portlet,
1262                                            ActionKeys.ADD_TO_PAGE)) {
1263    
1264                                    return null;
1265                            }
1266                    }
1267                    catch (Exception e) {
1268                            _log.error(e, e);
1269                    }
1270    
1271                    if (portlet.isSystem()) {
1272                            return null;
1273                    }
1274    
1275                    if (portlet.isInstanceable() &&
1276                            !PortletConstants.hasInstanceId(portletId)) {
1277    
1278                            portletId = PortletConstants.assemblePortletId(
1279                                    portletId, generateInstanceId());
1280                    }
1281    
1282                    if (hasPortletId(portletId, strictHasPortlet)) {
1283                            return null;
1284                    }
1285    
1286                    if (columnId == null) {
1287                            LayoutTemplate layoutTemplate = getLayoutTemplate();
1288    
1289                            List<String> columns = layoutTemplate.getColumns();
1290    
1291                            if (columns.size() > 0) {
1292                                    columnId = columns.get(0);
1293                            }
1294                    }
1295    
1296                    if (columnId == null) {
1297                            return null;
1298                    }
1299    
1300                    if (isCustomizable()) {
1301                            if (isColumnDisabled(columnId)) {
1302                                    return null;
1303                            }
1304    
1305                            if ((PortletConstants.hasInstanceId(portletId) ||
1306                                     portlet.isPreferencesUniquePerLayout()) &&
1307                                    hasUserPreferences()) {
1308    
1309                                    portletId = PortletConstants.assemblePortletId(
1310                                            portletId, userId);
1311                            }
1312                    }
1313    
1314                    String columnValue = StringPool.BLANK;
1315    
1316                    if (hasUserPreferences()) {
1317                            columnValue = getUserPreference(columnId);
1318                    }
1319                    else {
1320                            columnValue = getTypeSettingsProperty(columnId);
1321                    }
1322    
1323                    if ((columnValue == null) &&
1324                            columnId.startsWith(_nestedPortletsNamespace)) {
1325    
1326                            addNestedColumn(columnId);
1327                    }
1328    
1329                    if (columnPos >= 0) {
1330                            List<String> portletIds = ListUtil.fromArray(
1331                                    StringUtil.split(columnValue));
1332    
1333                            if (columnPos <= portletIds.size()) {
1334                                    portletIds.add(columnPos, portletId);
1335                            }
1336                            else {
1337                                    portletIds.add(portletId);
1338                            }
1339    
1340                            columnValue = StringUtil.merge(portletIds);
1341                    }
1342                    else {
1343                            columnValue = StringUtil.add(columnValue, portletId);
1344                    }
1345    
1346                    if (hasUserPreferences()) {
1347                            setUserPreference(columnId, columnValue);
1348                    }
1349                    else {
1350                            setTypeSettingsProperty(columnId, columnValue);
1351                    }
1352    
1353                    try {
1354                            if (_enablePortletLayoutListener) {
1355                                    PortletLayoutListener portletLayoutListener =
1356                                            portlet.getPortletLayoutListenerInstance();
1357    
1358                                    if (portletLayoutListener != null) {
1359                                            portletLayoutListener.onAddToLayout(
1360                                                    portletId, layout.getPlid());
1361                                    }
1362                            }
1363                    }
1364                    catch (Exception e) {
1365                            _log.error("Unable to fire portlet layout listener event", e);
1366                    }
1367    
1368                    return portletId;
1369            }
1370    
1371            protected void copyPreferences(
1372                    long userId, String sourcePortletId, String targetPortletId) {
1373    
1374                    Layout layout = getLayout();
1375    
1376                    try {
1377                            PortletPreferencesIds portletPreferencesIds =
1378                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1379                                            layout.getGroupId(), 0, layout, sourcePortletId, false);
1380    
1381                            javax.portlet.PortletPreferences sourcePortletPreferences =
1382                                    PortletPreferencesLocalServiceUtil.getStrictPreferences(
1383                                            portletPreferencesIds);
1384    
1385                            portletPreferencesIds =
1386                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1387                                            layout.getGroupId(), userId, layout, targetPortletId,
1388                                            false);
1389    
1390                            PortletPreferencesLocalServiceUtil.updatePreferences(
1391                                    portletPreferencesIds.getOwnerId(),
1392                                    portletPreferencesIds.getOwnerType(),
1393                                    portletPreferencesIds.getPlid(),
1394                                    portletPreferencesIds.getPortletId(), sourcePortletPreferences);
1395                    }
1396                    catch (Exception e) {
1397                    }
1398            }
1399    
1400            protected void copyResourcePermissions(
1401                            String sourcePortletId, String targetPortletId)
1402                    throws SystemException {
1403    
1404                    Layout layout = getLayout();
1405    
1406                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1407                            getCompanyId(), sourcePortletId);
1408    
1409                    String sourcePortletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
1410                            layout.getPlid(), sourcePortletId);
1411    
1412                    List<ResourcePermission> resourcePermissions =
1413                            ResourcePermissionLocalServiceUtil.getResourcePermissions(
1414                                    portlet.getCompanyId(), portlet.getPortletName(),
1415                                    PortletKeys.PREFS_OWNER_TYPE_USER, sourcePortletPrimaryKey);
1416    
1417                    for (ResourcePermission resourcePermission : resourcePermissions) {
1418                            String targetPortletPrimaryKey =
1419                                    PortletPermissionUtil.getPrimaryKey(
1420                                            layout.getPlid(), targetPortletId);
1421    
1422                            resourcePermission.setResourcePermissionId(
1423                                    CounterLocalServiceUtil.increment());
1424                            resourcePermission.setPrimKey(targetPortletPrimaryKey);
1425    
1426                            ResourcePermissionLocalServiceUtil.addResourcePermission(
1427                                    resourcePermission);
1428                    }
1429            }
1430    
1431            protected String getColumn(String portletId) {
1432                    String portletIdColumnId = StringPool.BLANK;
1433    
1434                    List<String> columnIds = getColumns();
1435    
1436                    for (String columnId : columnIds) {
1437                            String columnValue = getColumnValue(columnId);
1438    
1439                            String[] portletIds = StringUtil.split(columnValue);
1440    
1441                            for (String columnPortletId : portletIds) {
1442                                    if (columnPortletId.equals(portletId)) {
1443                                            return columnId;
1444                                    }
1445    
1446                                    if (Validator.isNull(portletIdColumnId) &&
1447                                            PortletConstants.hasIdenticalRootPortletId(
1448                                                    columnPortletId, portletId)) {
1449    
1450                                            portletIdColumnId = columnId;
1451                                    }
1452                            }
1453                    }
1454    
1455                    return portletIdColumnId;
1456            }
1457    
1458            protected List<String> getColumns() {
1459                    List<String> columns = new ArrayList<String>();
1460    
1461                    Layout layout = getLayout();
1462    
1463                    if (layout.isTypePortlet()) {
1464                            LayoutTemplate layoutTemplate = getLayoutTemplate();
1465    
1466                            columns.addAll(layoutTemplate.getColumns());
1467    
1468                            columns.addAll(getNestedColumns());
1469                    }
1470                    else if (layout.isTypePanel()) {
1471                            columns.add("panelSelectedPortlets");
1472                    }
1473    
1474                    return columns;
1475            }
1476    
1477            protected String getColumnValue(String columnId) {
1478                    if (hasUserPreferences() && isCustomizable() &&
1479                            !isColumnDisabled(columnId)) {
1480    
1481                            return getUserPreference(columnId);
1482                    }
1483    
1484                    return getTypeSettingsProperty(columnId);
1485            }
1486    
1487            protected long getCompanyId() {
1488                    Layout layout = getLayout();
1489    
1490                    return layout.getCompanyId();
1491            }
1492    
1493            protected LayoutTypePortletImpl getDefaultLayoutTypePortletImpl() {
1494                    if (!isCustomizedView()) {
1495                            return this;
1496                    }
1497    
1498                    LayoutTypePortletImpl defaultLayoutTypePortletImpl =
1499                            new LayoutTypePortletImpl(getLayout());
1500    
1501                    defaultLayoutTypePortletImpl._embeddedPortlets = _embeddedPortlets;
1502                    defaultLayoutTypePortletImpl._layoutSetPrototypeLayout =
1503                            _layoutSetPrototypeLayout;
1504                    defaultLayoutTypePortletImpl._updatePermission = _updatePermission;
1505    
1506                    return defaultLayoutTypePortletImpl;
1507            }
1508    
1509            protected List<Portlet> getEmbeddedPortlets(
1510                            List<Portlet> columnPortlets, List<Portlet> staticPortlets)
1511                    throws SystemException {
1512    
1513                    if (_embeddedPortlets != null) {
1514                            return _embeddedPortlets;
1515                    }
1516    
1517                    List<Portlet> portlets = new ArrayList<Portlet>();
1518    
1519                    Layout layout = getLayout();
1520    
1521                    List<PortletPreferences> portletPreferences =
1522                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1523                                    PortletKeys.PREFS_OWNER_ID_DEFAULT,
1524                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid());
1525    
1526                    if (isCustomizable() && hasUserPreferences()) {
1527                            portletPreferences = ListUtil.copy(portletPreferences);
1528    
1529                            portletPreferences.addAll(
1530                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
1531                                            _portalPreferences.getUserId(),
1532                                            PortletKeys.PREFS_OWNER_TYPE_USER, layout.getPlid()));
1533                    }
1534    
1535                    for (PortletPreferences portletPreference : portletPreferences) {
1536                            String portletId = portletPreference.getPortletId();
1537    
1538                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1539                                    getCompanyId(), portletId);
1540    
1541                            if ((portlet == null) || columnPortlets.contains(portlet) ||
1542                                    staticPortlets.contains(portlet) || !portlet.isReady() ||
1543                                    portlet.isUndeployedPortlet() || !portlet.isActive()) {
1544    
1545                                    continue;
1546                            }
1547    
1548                            Portlet embeddedPortlet = portlet;
1549    
1550                            if (portlet.isInstanceable()) {
1551    
1552                                    // Instanceable portlets do not need to be cloned because they
1553                                    // are already cloned. See the method getPortletById in the
1554                                    // class PortletLocalServiceImpl and how it references the
1555                                    // method getClonedInstance in the class PortletImpl.
1556    
1557                            }
1558                            else {
1559                                    embeddedPortlet = (Portlet)embeddedPortlet.clone();
1560                            }
1561    
1562                            // We set embedded portlets as static on order to avoid adding the
1563                            // close and/or move icons.
1564    
1565                            embeddedPortlet.setStatic(true);
1566    
1567                            portlets.add(embeddedPortlet);
1568                    }
1569    
1570                    _embeddedPortlets = portlets;
1571    
1572                    return _embeddedPortlets;
1573            }
1574    
1575            protected List<String> getNestedColumns() {
1576                    String nestedColumnIds = getTypeSettingsProperty(
1577                            LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1578    
1579                    return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
1580            }
1581    
1582            protected long getPlid() {
1583                    Layout layout = getLayout();
1584    
1585                    return layout.getPlid();
1586            }
1587    
1588            protected String[] getStaticPortletIds(String position)
1589                    throws PortalException, SystemException {
1590    
1591                    Layout layout = getLayout();
1592    
1593                    String selector1 = StringPool.BLANK;
1594    
1595                    Group group = layout.getGroup();
1596    
1597                    if (group.isUser()) {
1598                            selector1 = LayoutTypePortletConstants.STATIC_PORTLET_USER_SELECTOR;
1599                    }
1600                    else if (group.isOrganization()) {
1601                            selector1 =
1602                                    LayoutTypePortletConstants.STATIC_PORTLET_ORGANIZATION_SELECTOR;
1603                    }
1604                    else if (group.isRegularSite()) {
1605                            selector1 =
1606                                    LayoutTypePortletConstants.STATIC_PORTLET_REGULAR_SITE_SELECTOR;
1607                    }
1608    
1609                    String selector2 = layout.getFriendlyURL();
1610    
1611                    String[] portletIds = PropsUtil.getArray(
1612                            position, new Filter(selector1, selector2));
1613    
1614                    for (int i = 0; i < portletIds.length; i++) {
1615                            portletIds[i] = JS.getSafeName(portletIds[i]);
1616                    }
1617    
1618                    return portletIds;
1619            }
1620    
1621            protected List<Portlet> getStaticPortlets(String position)
1622                    throws PortalException, SystemException {
1623    
1624                    String[] portletIds = getStaticPortletIds(position);
1625    
1626                    List<Portlet> portlets = new ArrayList<Portlet>();
1627    
1628                    for (String portletId : portletIds) {
1629                            if (Validator.isNull(portletId) ||
1630                                    hasNonstaticPortletId(portletId)) {
1631    
1632                                    continue;
1633                            }
1634    
1635                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1636                                    getCompanyId(), portletId);
1637    
1638                            if (portlet != null) {
1639                                    Portlet staticPortlet = portlet;
1640    
1641                                    if (portlet.isInstanceable()) {
1642    
1643                                            // Instanceable portlets do not need to be cloned because
1644                                            // they are already cloned. See the method getPortletById in
1645                                            // the class PortletLocalServiceImpl and how it references
1646                                            // the method getClonedInstance in the class PortletImpl.
1647    
1648                                    }
1649                                    else {
1650                                            staticPortlet = (Portlet)staticPortlet.clone();
1651                                    }
1652    
1653                                    staticPortlet.setStatic(true);
1654    
1655                                    if (position.startsWith("layout.static.portlets.start")) {
1656                                            staticPortlet.setStaticStart(true);
1657                                    }
1658    
1659                                    portlets.add(staticPortlet);
1660                            }
1661                    }
1662    
1663                    return portlets;
1664            }
1665    
1666            protected String getThemeId() {
1667                    String themeId = null;
1668    
1669                    try {
1670                            Layout layout = getLayout();
1671    
1672                            Theme theme = layout.getTheme();
1673    
1674                            if (theme != null) {
1675                                    themeId = theme.getThemeId();
1676                            }
1677                            else {
1678                                    themeId = layout.getThemeId();
1679                            }
1680                    }
1681                    catch (Exception e) {
1682                            _log.error(e, e);
1683                    }
1684    
1685                    return themeId;
1686            }
1687    
1688            protected String getUserPreference(String key) {
1689                    String value = StringPool.BLANK;
1690    
1691                    if (!hasUserPreferences()) {
1692                            return value;
1693                    }
1694    
1695                    value = _portalPreferences.getValue(
1696                            CustomizedPages.namespacePlid(getPlid()), key, StringPool.NULL);
1697    
1698                    if (!value.equals(StringPool.NULL)) {
1699                            return value;
1700                    }
1701    
1702                    value = getTypeSettingsProperty(key);
1703    
1704                    if (Validator.isNull(value)) {
1705                            return value;
1706                    }
1707    
1708                    List<String> newPortletIds = new ArrayList<String>();
1709    
1710                    PermissionChecker permissionChecker =
1711                            PermissionThreadLocal.getPermissionChecker();
1712    
1713                    String[] portletIds = StringUtil.split(value);
1714    
1715                    for (String portletId : portletIds) {
1716                            try {
1717                                    if (!PortletPermissionUtil.contains(
1718                                                    permissionChecker, getLayout(), portletId,
1719                                                    ActionKeys.VIEW, true)) {
1720    
1721                                            continue;
1722                                    }
1723    
1724                                    String rootPortletId = PortletConstants.getRootPortletId(
1725                                            portletId);
1726    
1727                                    if (!PortletPermissionUtil.contains(
1728                                                    permissionChecker, rootPortletId,
1729                                                    ActionKeys.ADD_TO_PAGE)) {
1730    
1731                                            continue;
1732                                    }
1733                            }
1734                            catch (Exception e) {
1735                                    _log.error(e, e);
1736                            }
1737    
1738                            String newPortletId = null;
1739    
1740                            boolean preferencesUniquePerLayout = false;
1741    
1742                            try {
1743                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1744                                            getCompanyId(), portletId);
1745    
1746                                    preferencesUniquePerLayout =
1747                                            portlet.isPreferencesUniquePerLayout();
1748                            }
1749                            catch (SystemException se) {
1750                                    _log.error(se, se);
1751                            }
1752    
1753                            if (PortletConstants.hasInstanceId(portletId) ||
1754                                    preferencesUniquePerLayout) {
1755    
1756                                    String instanceId = null;
1757    
1758                                    if (PortletConstants.hasInstanceId(portletId)) {
1759                                            instanceId = generateInstanceId();
1760                                    }
1761    
1762                                    newPortletId = PortletConstants.assemblePortletId(
1763                                            portletId, _portalPreferences.getUserId(), instanceId);
1764    
1765                                    copyPreferences(
1766                                            _portalPreferences.getUserId(), portletId, newPortletId);
1767    
1768                                    try {
1769                                            copyResourcePermissions(portletId, newPortletId);
1770                                    }
1771                                    catch (SystemException se) {
1772                                            _log.error(se, se);
1773                                    }
1774                            }
1775                            else {
1776                                    newPortletId = portletId;
1777                            }
1778    
1779                            newPortletIds.add(newPortletId);
1780                    }
1781    
1782                    value = StringUtil.merge(newPortletIds);
1783    
1784                    setUserPreference(key, value);
1785    
1786                    return value;
1787            }
1788    
1789            protected boolean hasNonstaticPortletId(String portletId) {
1790                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1791    
1792                    List<String> columns = layoutTemplate.getColumns();
1793    
1794                    for (int i = 0; i < columns.size(); i++) {
1795                            String columnId = columns.get(i);
1796    
1797                            if (hasNonstaticPortletId(columnId, portletId)) {
1798                                    return true;
1799                            }
1800                    }
1801    
1802                    return false;
1803            }
1804    
1805            protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1806                    String columnValue = getColumnValue(columnId);
1807    
1808                    String[] columnValues = StringUtil.split(columnValue);
1809    
1810                    for (String nonstaticPortletId : columnValues) {
1811                            if (nonstaticPortletId.equals(portletId) ||
1812                                    PortletConstants.getRootPortletId(
1813                                            nonstaticPortletId).equals(portletId)) {
1814    
1815                                    return true;
1816                            }
1817                    }
1818    
1819                    return false;
1820            }
1821    
1822            protected boolean hasStaticPortletId(String columnId, String portletId)
1823                    throws PortalException, SystemException {
1824    
1825                    String[] staticPortletIdsStart = getStaticPortletIds(
1826                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1827    
1828                    String[] staticPortletIdsEnd = getStaticPortletIds(
1829                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1830    
1831                    for (String staticPortletId : staticPortletIdsStart) {
1832                            if (staticPortletId.equals(portletId) ||
1833                                    PortletConstants.getRootPortletId(
1834                                            staticPortletId).equals(portletId)) {
1835    
1836                                    return true;
1837                            }
1838                    }
1839    
1840                    for (String staticPortletId : staticPortletIdsEnd) {
1841                            if (staticPortletId.equals(portletId) ||
1842                                    PortletConstants.getRootPortletId(
1843                                            staticPortletId).equals(portletId)) {
1844    
1845                                    return true;
1846                            }
1847                    }
1848    
1849                    return false;
1850            }
1851    
1852            protected boolean hasUserPreferences() {
1853                    if (_portalPreferences != null) {
1854                            return true;
1855                    }
1856    
1857                    return false;
1858            }
1859    
1860            protected boolean isLayoutSetPrototype() {
1861                    try {
1862                            Layout layout = getLayout();
1863    
1864                            LayoutSet layoutSet = layout.getLayoutSet();
1865    
1866                            Group group = layoutSet.getGroup();
1867    
1868                            return group.isLayoutSetPrototype();
1869                    }
1870                    catch (Exception e) {
1871                            _log.error(e, e);
1872                    }
1873    
1874                    return false;
1875            }
1876    
1877            protected void onRemoveFromLayout(String[] portletIds)
1878                    throws SystemException {
1879    
1880                    List<String> portletIdList = new UniqueList<String>();
1881    
1882                    for (String portletId : portletIds) {
1883                            removeModesPortletId(portletId);
1884                            removeStatesPortletId(portletId);
1885    
1886                            portletIdList.add(portletId);
1887    
1888                            String rootPortletId = PortletConstants.getRootPortletId(portletId);
1889    
1890                            if (rootPortletId.equals(PortletKeys.NESTED_PORTLETS)) {
1891                                    String portletNamespace = PortalUtil.getPortletNamespace(
1892                                            portletId);
1893    
1894                                    UnicodeProperties typeSettingsProperties =
1895                                            getTypeSettingsProperties();
1896    
1897                                    for (Map.Entry<String, String> entry :
1898                                                    typeSettingsProperties.entrySet()) {
1899    
1900                                            String key = entry.getKey();
1901    
1902                                            if (!key.startsWith(portletNamespace)) {
1903                                                    continue;
1904                                            }
1905    
1906                                            String nestedPortletIds = entry.getValue();
1907    
1908                                            for (String nestedPortletId :
1909                                                            StringUtil.split(nestedPortletIds)) {
1910    
1911                                                    removeModesPortletId(nestedPortletId);
1912                                                    removeStatesPortletId(nestedPortletId);
1913    
1914                                                    portletIdList.add(nestedPortletId);
1915                                            }
1916                                    }
1917    
1918                                    removeNestedColumns(portletNamespace);
1919                            }
1920                    }
1921    
1922                    try {
1923                            PortletLocalServiceUtil.deletePortlets(
1924                                    getCompanyId(),
1925                                    portletIdList.toArray(new String[portletIdList.size()]),
1926                                    getPlid());
1927                    }
1928                    catch (PortalException pe) {
1929                            _log.error(pe, pe);
1930                    }
1931            }
1932    
1933            protected void setUserPreference(String key, String value) {
1934                    if (!hasUserPreferences()) {
1935                            return;
1936                    }
1937    
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    }