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