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