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