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