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