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