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