1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.model.impl;
24  
25  import com.liferay.portal.SystemException;
26  import com.liferay.portal.kernel.configuration.Filter;
27  import com.liferay.portal.kernel.portlet.PortletLayoutListener;
28  import com.liferay.portal.kernel.util.ArrayUtil;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.ListUtil;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.StringUtil;
33  import com.liferay.portal.kernel.util.UnicodeProperties;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.model.Group;
36  import com.liferay.portal.model.Layout;
37  import com.liferay.portal.model.LayoutTemplate;
38  import com.liferay.portal.model.LayoutTypePortlet;
39  import com.liferay.portal.model.Plugin;
40  import com.liferay.portal.model.Portlet;
41  import com.liferay.portal.model.PortletConstants;
42  import com.liferay.portal.model.PortletPreferences;
43  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
44  import com.liferay.portal.service.PluginSettingLocalServiceUtil;
45  import com.liferay.portal.service.PortletLocalServiceUtil;
46  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
47  import com.liferay.portal.util.PortletKeys;
48  import com.liferay.portal.util.PropsKeys;
49  import com.liferay.portal.util.PropsUtil;
50  import com.liferay.portal.util.PropsValues;
51  import com.liferay.util.PwdGenerator;
52  
53  import java.util.ArrayList;
54  import java.util.Iterator;
55  import java.util.List;
56  
57  import org.apache.commons.logging.Log;
58  import org.apache.commons.logging.LogFactory;
59  
60  /**
61   * <a href="LayoutTypePortletImpl.java.html"><b><i>View Source</i></b></a>
62   *
63   * @author Brian Wing Shun Chan
64   * @author Berentey Zsolt
65   * @author Jorge Ferrer
66   *
67   */
68  public class LayoutTypePortletImpl
69      extends LayoutTypeImpl implements LayoutTypePortlet {
70  
71      public static final String LAYOUT_TEMPLATE_ID = "layout-template-id";
72  
73      public static final String NESTED_COLUMN_IDS = "nested-column-ids";
74  
75      public static final String STATE_MAX = "state-max";
76  
77      public static final String STATE_MIN = "state-min";
78  
79      public static final String MODE_ABOUT = "mode-about";
80  
81      public static final String MODE_CONFIG = "mode-config";
82  
83      public static final String MODE_EDIT = "mode-edit";
84  
85      public static final String MODE_EDIT_DEFAULTS = "mode-edit-defaults";
86  
87      public static final String MODE_EDIT_GUEST = "mode-edit-guest";
88  
89      public static final String MODE_HELP = "mode-help";
90  
91      public static final String MODE_PREVIEW = "mode-preview";
92  
93      public static final String MODE_PRINT = "mode-print";
94  
95      public static final String STATIC_PORTLET_COMMUNITY_SELECTOR = "community";
96  
97      public static final String STATIC_PORTLET_ORGANIZATION_SELECTOR =
98          "organization";
99  
100     public static final String STATIC_PORTLET_USER_SELECTOR = "user";
101 
102     public static String getFullInstanceSeparator() {
103         String instanceId = PwdGenerator.getPassword(
104             PwdGenerator.KEY1 + PwdGenerator.KEY2 + PwdGenerator.KEY3, 4);
105 
106         return PortletConstants.INSTANCE_SEPARATOR + instanceId;
107     }
108 
109     public LayoutTypePortletImpl(LayoutImpl layout) {
110         super(layout);
111     }
112 
113     public LayoutTemplate getLayoutTemplate() {
114         LayoutTemplate layoutTemplate =
115             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
116                 getLayoutTemplateId(), false, null);
117 
118         if (layoutTemplate == null) {
119             layoutTemplate = new LayoutTemplateImpl(
120                 StringPool.BLANK, StringPool.BLANK);
121 
122             List<String> columns = new ArrayList<String>();
123 
124             for (int i = 1; i <= 10; i++) {
125                 columns.add("column-" + i);
126             }
127 
128             layoutTemplate.setColumns(columns);
129         }
130 
131         return layoutTemplate;
132     }
133 
134     public String getLayoutTemplateId() {
135         String layoutTemplateId =
136             getTypeSettingsProperties().getProperty(LAYOUT_TEMPLATE_ID);
137 
138         if (Validator.isNull(layoutTemplateId)) {
139             layoutTemplateId = StringPool.BLANK;
140         }
141 
142         return layoutTemplateId;
143     }
144 
145     public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
146         setLayoutTemplateId(userId, newLayoutTemplateId, true);
147     }
148 
149     public void setLayoutTemplateId(
150         long userId, String newLayoutTemplateId, boolean checkPermission) {
151 
152         if (checkPermission &&
153             !PluginSettingLocalServiceUtil.hasPermission(
154                 userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
155 
156             return;
157         }
158 
159         String oldLayoutTemplateId = getLayoutTemplateId();
160 
161         if (Validator.isNull(oldLayoutTemplateId)) {
162             oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
163         }
164 
165         getTypeSettingsProperties().setProperty(
166             LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
167 
168         String themeId = null;
169 
170         try {
171             themeId = getLayout().getTheme().getThemeId();
172         }
173         catch (Exception e) {
174             _log.error(e);
175         }
176 
177         LayoutTemplate oldLayoutTemplate =
178             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
179                 oldLayoutTemplateId, false, themeId);
180 
181         if (oldLayoutTemplate == null) {
182             return;
183         }
184 
185         LayoutTemplate newLayoutTemplate =
186             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
187                 newLayoutTemplateId, false, themeId);
188 
189         List<String> oldColumns = oldLayoutTemplate.getColumns();
190         List<String> newColumns = newLayoutTemplate.getColumns();
191 
192         reorganizePortlets(newColumns, oldColumns);
193     }
194 
195     public int getNumOfColumns() {
196         return getLayoutTemplate().getColumns().size();
197     }
198 
199     public List<Portlet> getAllPortlets() throws SystemException {
200         List<Portlet> portlets = new ArrayList<Portlet>();
201 
202         List<String> columns = getColumns();
203 
204         for (int i = 0; i < columns.size(); i++) {
205             String columnId = columns.get(i);
206 
207             portlets.addAll(getAllPortlets(columnId));
208 
209         }
210 
211         return portlets;
212     }
213 
214     public List<Portlet> getAllPortlets(String columnId)
215         throws SystemException {
216 
217         String columnValue =
218             getTypeSettingsProperties().getProperty(columnId);
219 
220         String[] portletIds = StringUtil.split(columnValue);
221 
222         List<Portlet> portlets = new ArrayList<Portlet>(portletIds.length);
223 
224         for (int i = 0; i < portletIds.length; i++) {
225             Portlet portlet = PortletLocalServiceUtil.getPortletById(
226                 getLayout().getCompanyId(), portletIds[i]);
227 
228             if (portlet != null) {
229                 portlets.add(portlet);
230             }
231         }
232 
233         List<Portlet> startPortlets = getStaticPortlets(
234             PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
235 
236         List<Portlet> endPortlets = getStaticPortlets(
237             PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
238 
239         return addStaticPortlets(portlets, startPortlets, endPortlets);
240     }
241 
242     public List<Portlet> addStaticPortlets(
243         List<Portlet> portlets, List<Portlet> startPortlets,
244         List<Portlet> endPortlets) {
245 
246         // Return the original array of portlets if no static portlets are
247         // specified
248 
249         if (startPortlets == null) {
250             startPortlets = new ArrayList<Portlet>();
251         }
252 
253         if (endPortlets == null) {
254             endPortlets = new ArrayList<Portlet>();
255         }
256 
257         if ((startPortlets.isEmpty()) && (endPortlets.isEmpty())) {
258             return portlets;
259         }
260 
261         // New array of portlets that contain the static portlets
262 
263         List<Portlet> list = new ArrayList<Portlet>(
264             portlets.size() + startPortlets.size() + endPortlets.size());
265 
266         if (startPortlets != null) {
267             list.addAll(startPortlets);
268         }
269 
270         for (int i = 0; i < portlets.size(); i++) {
271             Portlet portlet = portlets.get(i);
272 
273             // Add the portlet if and only if it is not also a static portlet
274 
275             if (!startPortlets.contains(portlet) &&
276                 !endPortlets.contains(portlet)) {
277 
278                 list.add(portlet);
279             }
280         }
281 
282         if (endPortlets != null) {
283             list.addAll(endPortlets);
284         }
285 
286         return list;
287     }
288 
289     // Modify portlets
290 
291     public String addPortletId(long userId, String portletId) {
292         return addPortletId(userId, portletId, true);
293     }
294 
295     public String addPortletId(
296         long userId, String portletId, boolean checkPermission) {
297 
298         return addPortletId(userId, portletId, null, -1, checkPermission);
299     }
300 
301     public String addPortletId(
302         long userId, String portletId, String columnId, int columnPos) {
303 
304         return addPortletId(userId, portletId, columnId, columnPos, true);
305     }
306 
307     public String addPortletId(
308         long userId, String portletId, String columnId, int columnPos,
309         boolean checkPermission) {
310 
311         Layout layout = getLayout();
312 
313         Portlet portlet = null;
314 
315         try {
316             portlet = PortletLocalServiceUtil.getPortletById(
317                 layout.getCompanyId(), portletId);
318 
319             if (portlet == null) {
320                 _log.error(
321                     "Portlet " + portletId +
322                         " cannot be added because it is not registered");
323             }
324 
325             if (checkPermission && !portlet.hasAddPortletPermission(userId)) {
326                 return null;
327             }
328         }
329         catch (Exception e) {
330             _log.error(e);
331         }
332 
333         if (portlet != null) {
334             if (portlet.isSystem()) {
335                 return null;
336             }
337 
338             if ((portlet.isInstanceable()) &&
339                 (PortletConstants.getInstanceId(
340                     portlet.getPortletId()) == null)) {
341 
342                 portletId = portletId + getFullInstanceSeparator();
343             }
344 
345             if (hasPortletId(portletId)) {
346                 return null;
347             }
348 
349             if (columnId == null) {
350                 LayoutTemplate layoutTemplate = getLayoutTemplate();
351 
352                 List<String> columns = layoutTemplate.getColumns();
353 
354                 if (columns.size() > 0) {
355                     columnId = columns.get(0);
356                 }
357             }
358 
359             if (columnId != null) {
360                 String columnValue =
361                     getTypeSettingsProperties().getProperty(columnId);
362 
363                 if ((columnValue == null) &&
364                     (columnId.startsWith(PortletKeys.NESTED_PORTLETS))) {
365 
366                     addNestedColumn(columnId);
367                 }
368 
369                 if (columnPos >= 0) {
370                     List<String> portletIds =
371                         ListUtil.fromArray(StringUtil.split(columnValue));
372 
373                     if (columnPos <= portletIds.size()) {
374                         portletIds.add(columnPos, portletId);
375                     }
376                     else {
377                         portletIds.add(portletId);
378                     }
379 
380                     columnValue = StringUtil.merge(portletIds);
381                 }
382                 else {
383                     columnValue = StringUtil.add(columnValue, portletId);
384                 }
385 
386                 getTypeSettingsProperties().setProperty(columnId, columnValue);
387             }
388 
389             try {
390                 PortletLayoutListener portletLayoutListener =
391                     portlet.getPortletLayoutListener();
392 
393                 if (_enablePortletLayoutListener &&
394                     (portletLayoutListener != null)) {
395 
396                     portletLayoutListener.onAddToLayout(
397                         portletId, layout.getPlid());
398                 }
399             }
400             catch (Exception e) {
401                 _log.error("Unable to fire portlet layout listener event", e);
402             }
403 
404             return portletId;
405         }
406         else {
407             return null;
408         }
409     }
410 
411     public void addPortletIds(
412         long userId, String[] portletIds, boolean checkPermission) {
413 
414         for (int i = 0; i < portletIds.length; i++) {
415             String portletId = portletIds[i];
416 
417             addPortletId(userId, portletId, checkPermission);
418         }
419     }
420 
421     public void addPortletIds(
422         long userId, String[] portletIds, String columnId,
423         boolean checkPermission) {
424 
425         for (int i = 0; i < portletIds.length; i++) {
426             String portletId = portletIds[i];
427 
428             addPortletId(userId, portletId, columnId, -1, checkPermission);
429         }
430     }
431 
432     public List<Portlet> getPortlets() throws SystemException {
433         List<String> portletIds = getPortletIds();
434 
435         List<Portlet> portlets = new ArrayList<Portlet>(portletIds.size());
436 
437         for (int i = 0; i < portletIds.size(); i++) {
438             String portletId = portletIds.get(i);
439 
440             Portlet portlet = PortletLocalServiceUtil.getPortletById(
441                 getLayout().getCompanyId(), portletId);
442 
443             if (portlet != null) {
444                 portlets.add(portlet);
445             }
446         }
447 
448         return portlets;
449     }
450 
451     public List<String> getPortletIds() {
452         List<String> portletIds = new ArrayList<String>();
453 
454         List<String> columns = getColumns();
455 
456         for (int i = 0; i < columns.size(); i++) {
457             String columnId = columns.get(i);
458 
459             String columnValue =
460                 getTypeSettingsProperties().getProperty(columnId);
461 
462             portletIds.addAll(
463                 ListUtil.fromArray(StringUtil.split(columnValue)));
464 
465         }
466 
467         return portletIds;
468     }
469 
470     public boolean hasPortletId(String portletId) {
471         List<String> columns = getColumns();
472 
473         for (int i = 0; i < columns.size(); i++) {
474             String columnId = columns.get(i);
475 
476             if (hasNonstaticPortletId(columnId, portletId)) {
477                 return true;
478             }
479 
480             if (hasStaticPortletId(columnId, portletId)) {
481                 return true;
482             }
483         }
484 
485         return false;
486     }
487 
488     public void movePortletId(
489         long userId, String portletId, String columnId, int columnPos) {
490 
491         _enablePortletLayoutListener = false;
492 
493         try {
494             removePortletId(portletId, false);
495             addPortletId(userId, portletId, columnId, columnPos);
496         }
497         finally {
498             _enablePortletLayoutListener = true;
499         }
500 
501         Layout layout = getLayout();
502 
503         try {
504             Portlet portlet = PortletLocalServiceUtil.getPortletById(
505                 layout.getCompanyId(), portletId);
506 
507             if (portlet != null) {
508                 PortletLayoutListener portletLayoutListener =
509                     portlet.getPortletLayoutListener();
510 
511                 if (portletLayoutListener != null) {
512                     portletLayoutListener.onMoveInLayout(
513                         portletId, layout.getPlid());
514                 }
515             }
516         }
517         catch (Exception e) {
518             _log.error("Unable to fire portlet layout listener event", e);
519         }
520     }
521 
522     public void removePortletId(String portletId) {
523         removePortletId(portletId, true);
524     }
525 
526     public void removePortletId(String portletId, boolean cleanUp) {
527         List<String> columns = getColumns();
528 
529         for (int i = 0; i < columns.size(); i++) {
530             String columnId = columns.get(i);
531 
532             String columnValue =
533                 getTypeSettingsProperties().getProperty(columnId);
534 
535             columnValue = StringUtil.remove(columnValue, portletId);
536 
537             getTypeSettingsProperties().setProperty(columnId, columnValue);
538         }
539 
540         if (cleanUp) {
541             removeStatesPortletId(portletId);
542             removeModesPortletId(portletId);
543 
544             try {
545                 onRemoveFromLayout(portletId);
546             }
547             catch (Exception e) {
548                 _log.error("Unable to fire portlet layout listener event", e);
549             }
550         }
551     }
552 
553     public void setPortletIds(String columnId, String portletIds) {
554         getTypeSettingsProperties().setProperty(columnId, portletIds);
555     }
556 
557     public void reorganizePortlets(
558         List<String> newColumns, List<String> oldColumns) {
559 
560         String lastNewColumnId = newColumns.get(newColumns.size() - 1);
561         String lastNewColumnValue =
562             getTypeSettingsProperties().getProperty(lastNewColumnId);
563 
564         Iterator<String> itr = oldColumns.iterator();
565 
566         while (itr.hasNext()) {
567             String oldColumnId = itr.next();
568 
569             if (!newColumns.contains(oldColumnId)) {
570                 String oldColumnValue = getTypeSettingsProperties().remove(
571                     oldColumnId);
572 
573                 String[] portletIds = StringUtil.split(oldColumnValue);
574 
575                 for (int i = 0; i < portletIds.length; i++) {
576                     lastNewColumnValue =
577                         StringUtil.add(lastNewColumnValue, portletIds[i]);
578                 }
579             }
580         }
581 
582         getTypeSettingsProperties().setProperty(
583             lastNewColumnId, lastNewColumnValue);
584     }
585 
586     // Maximized state
587 
588     public String getStateMax() {
589         return getTypeSettingsProperties().getProperty(STATE_MAX);
590     }
591 
592     public void setStateMax(String stateMax) {
593         getTypeSettingsProperties().setProperty(STATE_MAX, stateMax);
594     }
595 
596     public boolean hasStateMax() {
597         String[] stateMax = StringUtil.split(getStateMax());
598 
599         if (stateMax.length > 0) {
600             return true;
601         }
602         else {
603             return false;
604         }
605     }
606 
607     public void addStateMaxPortletId(String portletId) {
608         removeStatesPortletId(portletId);
609         //setStateMax(StringUtil.add(getStateMax(), portletId));
610         setStateMax(StringUtil.add(StringPool.BLANK, portletId));
611     }
612 
613     public String getStateMaxPortletId() {
614         String[] stateMax = StringUtil.split(getStateMax());
615 
616         if (stateMax.length > 0) {
617             return stateMax[0];
618         }
619         else {
620             return StringPool.BLANK;
621         }
622     }
623 
624     public boolean hasStateMaxPortletId(String portletId) {
625         if (StringUtil.contains(getStateMax(), portletId)) {
626             return true;
627         }
628         else {
629             return false;
630         }
631     }
632 
633     public void removeStateMaxPortletId(String portletId) {
634         setStateMax(StringUtil.remove(getStateMax(), portletId));
635     }
636 
637     // Minimized state
638 
639     public String getStateMin() {
640         return getTypeSettingsProperties().getProperty(STATE_MIN);
641     }
642 
643     public void setStateMin(String stateMin) {
644         getTypeSettingsProperties().setProperty(STATE_MIN, stateMin);
645     }
646 
647     public boolean hasStateMin() {
648         String[] stateMin = StringUtil.split(getStateMin());
649 
650         if (stateMin.length > 0) {
651             return true;
652         }
653         else {
654             return false;
655         }
656     }
657 
658     public void addStateMinPortletId(String portletId) {
659         removeStateMaxPortletId(portletId);
660         setStateMin(StringUtil.add(getStateMin(), portletId));
661     }
662 
663     public boolean hasStateMinPortletId(String portletId) {
664         if (StringUtil.contains(getStateMin(), portletId)) {
665             return true;
666         }
667         else {
668             return false;
669         }
670     }
671 
672     public void removeStateMinPortletId(String portletId) {
673         setStateMin(StringUtil.remove(getStateMin(), portletId));
674     }
675 
676     // Normal state
677 
678     public boolean hasStateNormalPortletId(String portletId) {
679         if (hasStateMaxPortletId(portletId) ||
680             hasStateMinPortletId(portletId)) {
681 
682             return false;
683         }
684         else {
685             return true;
686         }
687     }
688 
689     // All states
690 
691     public void resetStates() {
692         setStateMax(StringPool.BLANK);
693         setStateMin(StringPool.BLANK);
694     }
695 
696     public void removeStatesPortletId(String portletId) {
697         removeStateMaxPortletId(portletId);
698         removeStateMinPortletId(portletId);
699     }
700 
701     // About mode
702 
703     public String getModeAbout() {
704         return getTypeSettingsProperties().getProperty(MODE_ABOUT);
705     }
706 
707     public void setModeAbout(String modeAbout) {
708         getTypeSettingsProperties().setProperty(MODE_ABOUT, modeAbout);
709     }
710 
711     public void addModeAboutPortletId(String portletId) {
712         removeModesPortletId(portletId);
713         setModeAbout(StringUtil.add(getModeAbout(), portletId));
714     }
715 
716     public boolean hasModeAboutPortletId(String portletId) {
717         return StringUtil.contains(getModeAbout(), portletId);
718     }
719 
720     public void removeModeAboutPortletId(String portletId) {
721         setModeAbout(StringUtil.remove(getModeAbout(), portletId));
722     }
723 
724     // Config mode
725 
726     public String getModeConfig() {
727         return getTypeSettingsProperties().getProperty(MODE_CONFIG);
728     }
729 
730     public void setModeConfig(String modeConfig) {
731         getTypeSettingsProperties().setProperty(MODE_CONFIG, modeConfig);
732     }
733 
734     public void addModeConfigPortletId(String portletId) {
735         removeModesPortletId(portletId);
736         setModeConfig(StringUtil.add(getModeConfig(), portletId));
737     }
738 
739     public boolean hasModeConfigPortletId(String portletId) {
740         return StringUtil.contains(getModeConfig(), portletId);
741     }
742 
743     public void removeModeConfigPortletId(String portletId) {
744         setModeConfig(StringUtil.remove(getModeConfig(), portletId));
745     }
746 
747     // Edit mode
748 
749     public String getModeEdit() {
750         return getTypeSettingsProperties().getProperty(MODE_EDIT);
751     }
752 
753     public void setModeEdit(String modeEdit) {
754         getTypeSettingsProperties().setProperty(MODE_EDIT, modeEdit);
755     }
756 
757     public void addModeEditPortletId(String portletId) {
758         removeModesPortletId(portletId);
759         setModeEdit(StringUtil.add(getModeEdit(), portletId));
760     }
761 
762     public boolean hasModeEditPortletId(String portletId) {
763         return StringUtil.contains(getModeEdit(), portletId);
764     }
765 
766     public void removeModeEditPortletId(String portletId) {
767         setModeEdit(StringUtil.remove(getModeEdit(), portletId));
768     }
769 
770     // Edit defaults mode
771 
772     public String getModeEditDefaults() {
773         return getTypeSettingsProperties().getProperty(MODE_EDIT_DEFAULTS);
774     }
775 
776     public void setModeEditDefaults(String modeEditDefaults) {
777         getTypeSettingsProperties().setProperty(
778             MODE_EDIT_DEFAULTS, modeEditDefaults);
779     }
780 
781     public void addModeEditDefaultsPortletId(String portletId) {
782         removeModesPortletId(portletId);
783         setModeEditDefaults(StringUtil.add(getModeEditDefaults(), portletId));
784     }
785 
786     public boolean hasModeEditDefaultsPortletId(String portletId) {
787         return StringUtil.contains(getModeEditDefaults(), portletId);
788     }
789 
790     public void removeModeEditDefaultsPortletId(String portletId) {
791         setModeEditDefaults(
792             StringUtil.remove(getModeEditDefaults(), portletId));
793     }
794 
795     // Edit guest mode
796 
797     public String getModeEditGuest() {
798         return getTypeSettingsProperties().getProperty(MODE_EDIT_GUEST);
799     }
800 
801     public void setModeEditGuest(String modeEditGuest) {
802         getTypeSettingsProperties().setProperty(MODE_EDIT_GUEST, modeEditGuest);
803     }
804 
805     public void addModeEditGuestPortletId(String portletId) {
806         removeModesPortletId(portletId);
807         setModeEditGuest(StringUtil.add(getModeEditGuest(), portletId));
808     }
809 
810     public boolean hasModeEditGuestPortletId(String portletId) {
811         return StringUtil.contains(getModeEditGuest(), portletId);
812     }
813 
814     public void removeModeEditGuestPortletId(String portletId) {
815         setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
816     }
817 
818     // Help mode
819 
820     public String getModeHelp() {
821         return getTypeSettingsProperties().getProperty(MODE_HELP);
822     }
823 
824     public void setModeHelp(String modeHelp) {
825         getTypeSettingsProperties().setProperty(MODE_HELP, modeHelp);
826     }
827 
828     public void addModeHelpPortletId(String portletId) {
829         removeModesPortletId(portletId);
830         setModeHelp(StringUtil.add(getModeHelp(), portletId));
831     }
832 
833     public boolean hasModeHelpPortletId(String portletId) {
834         return StringUtil.contains(getModeHelp(), portletId);
835     }
836 
837     public void removeModeHelpPortletId(String portletId) {
838         setModeHelp(StringUtil.remove(getModeHelp(), portletId));
839     }
840 
841     // Preview mode
842 
843     public String getModePreview() {
844         return getTypeSettingsProperties().getProperty(MODE_PREVIEW);
845     }
846 
847     public void setModePreview(String modePreview) {
848         getTypeSettingsProperties().setProperty(MODE_PREVIEW, modePreview);
849     }
850 
851     public void addModePreviewPortletId(String portletId) {
852         removeModesPortletId(portletId);
853         setModePreview(StringUtil.add(getModePreview(), portletId));
854     }
855 
856     public boolean hasModePreviewPortletId(String portletId) {
857         return StringUtil.contains(getModePreview(), portletId);
858     }
859 
860     public void removeModePreviewPortletId(String portletId) {
861         setModePreview(StringUtil.remove(getModePreview(), portletId));
862     }
863 
864     // Print mode
865 
866     public String getModePrint() {
867         return getTypeSettingsProperties().getProperty(MODE_PRINT);
868     }
869 
870     public void setModePrint(String modePrint) {
871         getTypeSettingsProperties().setProperty(MODE_PRINT, modePrint);
872     }
873 
874     public void addModePrintPortletId(String portletId) {
875         removeModesPortletId(portletId);
876         setModePrint(StringUtil.add(getModePrint(), portletId));
877     }
878 
879     public boolean hasModePrintPortletId(String portletId) {
880         return StringUtil.contains(getModePrint(), portletId);
881     }
882 
883     public void removeModePrintPortletId(String portletId) {
884         setModePrint(StringUtil.remove(getModePrint(), portletId));
885     }
886 
887     // View mode
888 
889     public boolean hasModeViewPortletId(String portletId) {
890         if (hasModeAboutPortletId(portletId) ||
891             hasModeConfigPortletId(portletId) ||
892             hasModeEditPortletId(portletId) ||
893             hasModeEditDefaultsPortletId(portletId) ||
894             hasModeEditGuestPortletId(portletId) ||
895             hasModeHelpPortletId(portletId) ||
896             hasModePreviewPortletId(portletId) ||
897             hasModePrintPortletId(portletId)) {
898 
899             return false;
900         }
901         else {
902             return true;
903         }
904     }
905 
906     // All modes
907 
908     public void resetModes() {
909         setModeAbout(StringPool.BLANK);
910         setModeConfig(StringPool.BLANK);
911         setModeEdit(StringPool.BLANK);
912         setModeEditDefaults(StringPool.BLANK);
913         setModeEditGuest(StringPool.BLANK);
914         setModeHelp(StringPool.BLANK);
915         setModePreview(StringPool.BLANK);
916         setModePrint(StringPool.BLANK);
917     }
918 
919     public void removeModesPortletId(String portletId) {
920         removeModeAboutPortletId(portletId);
921         removeModeConfigPortletId(portletId);
922         removeModeEditPortletId(portletId);
923         removeModeEditDefaultsPortletId(portletId);
924         removeModeEditGuestPortletId(portletId);
925         removeModeHelpPortletId(portletId);
926         removeModePreviewPortletId(portletId);
927         removeModePrintPortletId(portletId);
928     }
929 
930     public void removeNestedColumns(String portletId) {
931         UnicodeProperties props = getTypeSettingsProperties();
932 
933         UnicodeProperties newProps = new UnicodeProperties();
934 
935         for (String key : props.keySet()) {
936             if (!key.startsWith(portletId)) {
937                 newProps.setProperty(key, props.getProperty(key));
938             }
939         }
940 
941         getLayout().setTypeSettingsProperties(newProps);
942 
943         String nestedColumnIds = GetterUtil.getString(
944             getTypeSettingsProperties().getProperty(NESTED_COLUMN_IDS));
945 
946         String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
947             StringUtil.split(nestedColumnIds), portletId);
948 
949         getTypeSettingsProperties().setProperty(
950             NESTED_COLUMN_IDS, StringUtil.merge(nestedColumnIdsArray));
951     }
952 
953     protected void addNestedColumn(String columnId) {
954         String nestedColumnIds = getTypeSettingsProperties().getProperty(
955             NESTED_COLUMN_IDS, StringPool.BLANK);
956 
957         if (nestedColumnIds.indexOf(columnId) == -1) {
958             nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
959 
960             getTypeSettingsProperties().setProperty(
961                 NESTED_COLUMN_IDS, nestedColumnIds);
962         }
963     }
964 
965     protected List<String> getColumns() {
966         LayoutTemplate layoutTemplate = getLayoutTemplate();
967 
968         List<String> columns = new ArrayList<String>();
969 
970         columns.addAll(layoutTemplate.getColumns());
971         columns.addAll(getNestedColumns());
972 
973         return columns;
974     }
975 
976     protected List<String> getNestedColumns() {
977         String nestedColumnIds = getTypeSettingsProperties().getProperty(
978             NESTED_COLUMN_IDS);
979 
980         return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
981     }
982 
983     protected String[] getStaticPortletIds(String position) {
984         Layout layout = getLayout();
985 
986         String selector1 = StringPool.BLANK;
987 
988         Group group = layout.getGroup();
989 
990         if (group.isUser()) {
991             selector1 = STATIC_PORTLET_USER_SELECTOR;
992         }
993         else if (group.isCommunity()) {
994             selector1 = STATIC_PORTLET_COMMUNITY_SELECTOR;
995         }
996         else if (group.isOrganization()) {
997             selector1 = STATIC_PORTLET_ORGANIZATION_SELECTOR;
998         }
999 
1000        String selector2 = layout.getFriendlyURL();
1001
1002        return PropsUtil.getArray(position, new Filter(selector1, selector2));
1003    }
1004
1005    protected List<Portlet> getStaticPortlets(String position)
1006        throws SystemException {
1007
1008        String[] portletIds = getStaticPortletIds(position);
1009
1010        List<Portlet> portlets = new ArrayList<Portlet>();
1011
1012        for (int i = 0; i < portletIds.length; i++) {
1013            String portletId = portletIds[i];
1014
1015            if (hasNonstaticPortletId(portletId)) {
1016                continue;
1017            }
1018
1019            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1020                getLayout().getCompanyId(), portletId);
1021
1022            if (portlet != null) {
1023                Portlet staticPortlet = portlet;
1024
1025                if (portlet.isInstanceable()) {
1026
1027                    // Instanceable portlets do not need to be cloned because
1028                    // they are already cloned. See the method getPortletById in
1029                    // the class PortletLocalServiceImpl and how it references
1030                    // the method getClonedInstance in the class PortletImpl.
1031
1032                }
1033                else {
1034                    staticPortlet = (Portlet)staticPortlet.clone();
1035                }
1036
1037                staticPortlet.setStatic(true);
1038
1039                if (position.startsWith("layout.static.portlets.start")) {
1040                    staticPortlet.setStaticStart(true);
1041                }
1042
1043                portlets.add(staticPortlet);
1044            }
1045        }
1046
1047        return portlets;
1048    }
1049
1050    protected boolean hasNonstaticPortletId(String portletId) {
1051        LayoutTemplate layoutTemplate = getLayoutTemplate();
1052
1053        List<String> columns = layoutTemplate.getColumns();
1054
1055        for (int i = 0; i < columns.size(); i++) {
1056            String columnId = columns.get(i);
1057
1058            if (hasNonstaticPortletId(columnId, portletId)) {
1059                return true;
1060            }
1061        }
1062
1063        return false;
1064    }
1065
1066    protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1067        String columnValue = getTypeSettingsProperties().getProperty(columnId);
1068
1069        if (StringUtil.contains(columnValue, portletId)) {
1070            return true;
1071        }
1072        else {
1073            return false;
1074        }
1075    }
1076
1077    /*protected boolean hasStaticPortletId(String portletId) {
1078        LayoutTemplate layoutTemplate = getLayoutTemplate();
1079
1080        List columns = layoutTemplate.getColumns();
1081
1082        for (int i = 0; i < columns.size(); i++) {
1083            String columnId = (String)columns.get(i);
1084
1085            if (hasStaticPortletId(columnId, portletId)) {
1086                return true;
1087            }
1088        }
1089
1090        return false;
1091    }*/
1092
1093    protected boolean hasStaticPortletId(String columnId, String portletId) {
1094        String[] staticPortletIdsStart = getStaticPortletIds(
1095            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1096
1097        String[] staticPortletIdsEnd = getStaticPortletIds(
1098            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1099
1100        String[] staticPortletIds = ArrayUtil.append(
1101            staticPortletIdsStart, staticPortletIdsEnd);
1102
1103        for (int i = 0; i < staticPortletIds.length; i++) {
1104            String staticPortletId = staticPortletIds[i];
1105
1106            if (staticPortletId.equals(portletId)) {
1107                return true;
1108            }
1109        }
1110
1111        return false;
1112    }
1113
1114    protected void onRemoveFromLayout(String portletId) throws SystemException {
1115        Portlet portlet = PortletLocalServiceUtil.getPortletById(
1116            getLayout().getCompanyId(), portletId);
1117
1118        if (portlet == null) {
1119            return;
1120        }
1121
1122        if (portlet.getRootPortletId().equals(PortletKeys.NESTED_PORTLETS)) {
1123            UnicodeProperties props = getTypeSettingsProperties();
1124
1125            for (String key : props.keySet()) {
1126                if (key.startsWith(portlet.getPortletId())) {
1127                    String portletIds = props.getProperty(key);
1128
1129                    String[] portletIdsArray = StringUtil.split(portletIds);
1130
1131                    for (int i = 0; i < portletIdsArray.length; i++) {
1132                        onRemoveFromLayout(portletIdsArray[i]);
1133                    }
1134                }
1135            }
1136
1137            removeNestedColumns(portletId);
1138        }
1139
1140        if (_enablePortletLayoutListener) {
1141            PortletLayoutListener portletLayoutListener =
1142                portlet.getPortletLayoutListener();
1143
1144            long plid = getLayout().getPlid();
1145
1146            if ((portletLayoutListener != null)) {
1147                portletLayoutListener.onRemoveFromLayout(portletId, plid);
1148            }
1149        }
1150
1151        deletePortletSetup(portletId);
1152    }
1153
1154    protected void deletePortletSetup(String portletId) {
1155        try {
1156            List<PortletPreferences> list =
1157                PortletPreferencesLocalServiceUtil.getPortletPreferences(
1158                    getLayout().getPlid(), portletId);
1159
1160            for (int i = 0; i < list.size(); i++) {
1161                PortletPreferences portletPreferences = list.get(i);
1162
1163                PortletPreferencesLocalServiceUtil.deletePortletPreferences(
1164                    portletPreferences.getPortletPreferencesId());
1165            }
1166        }
1167        catch (Exception e) {
1168            _log.error(e, e);
1169        }
1170    }
1171
1172    private static Log _log = LogFactory.getLog(LayoutTypePortletImpl.class);
1173
1174    private boolean _enablePortletLayoutListener = true;
1175
1176}