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