1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.model.impl;
24  
25  import com.liferay.portal.SystemException;
26  import com.liferay.portal.kernel.configuration.Filter;
27  import com.liferay.portal.kernel.portlet.PortletLayoutListener;
28  import com.liferay.portal.kernel.util.ArrayUtil;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.ListUtil;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.StringUtil;
33  import com.liferay.portal.kernel.util.UnicodeProperties;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.model.Group;
36  import com.liferay.portal.model.Layout;
37  import com.liferay.portal.model.LayoutTemplate;
38  import com.liferay.portal.model.LayoutTypePortlet;
39  import com.liferay.portal.model.Plugin;
40  import com.liferay.portal.model.Portlet;
41  import com.liferay.portal.model.PortletConstants;
42  import com.liferay.portal.model.PortletPreferences;
43  import com.liferay.portal.model.Theme;
44  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
45  import com.liferay.portal.service.PluginSettingLocalServiceUtil;
46  import com.liferay.portal.service.PortletLocalServiceUtil;
47  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
48  import com.liferay.portal.util.PortletKeys;
49  import com.liferay.portal.util.PropsKeys;
50  import com.liferay.portal.util.PropsUtil;
51  import com.liferay.portal.util.PropsValues;
52  import com.liferay.util.JS;
53  import com.liferay.util.PwdGenerator;
54  
55  import java.util.ArrayList;
56  import java.util.Iterator;
57  import java.util.List;
58  
59  import org.apache.commons.logging.Log;
60  import org.apache.commons.logging.LogFactory;
61  
62  /**
63   * <a href="LayoutTypePortletImpl.java.html"><b><i>View Source</i></b></a>
64   *
65   * @author Brian Wing Shun Chan
66   * @author Berentey Zsolt
67   * @author Jorge Ferrer
68   *
69   */
70  public class LayoutTypePortletImpl
71      extends LayoutTypeImpl implements LayoutTypePortlet {
72  
73      public static final String LAYOUT_TEMPLATE_ID = "layout-template-id";
74  
75      public static final String NESTED_COLUMN_IDS = "nested-column-ids";
76  
77      public static final String STATE_MAX = "state-max";
78  
79      public static final String STATE_MIN = "state-min";
80  
81      public static final String MODE_ABOUT = "mode-about";
82  
83      public static final String MODE_CONFIG = "mode-config";
84  
85      public static final String MODE_EDIT = "mode-edit";
86  
87      public static final String MODE_EDIT_DEFAULTS = "mode-edit-defaults";
88  
89      public static final String MODE_EDIT_GUEST = "mode-edit-guest";
90  
91      public static final String MODE_HELP = "mode-help";
92  
93      public static final String MODE_PREVIEW = "mode-preview";
94  
95      public static final String MODE_PRINT = "mode-print";
96  
97      public static final String STATIC_PORTLET_COMMUNITY_SELECTOR = "community";
98  
99      public static final String STATIC_PORTLET_ORGANIZATION_SELECTOR =
100         "organization";
101 
102     public static final String STATIC_PORTLET_USER_SELECTOR = "user";
103 
104     public static String getFullInstanceSeparator() {
105         String instanceId = PwdGenerator.getPassword(
106             PwdGenerator.KEY1 + PwdGenerator.KEY2 + PwdGenerator.KEY3, 4);
107 
108         return PortletConstants.INSTANCE_SEPARATOR + instanceId;
109     }
110 
111     public LayoutTypePortletImpl(LayoutImpl layout) {
112         super(layout);
113     }
114 
115     public LayoutTemplate getLayoutTemplate() {
116         LayoutTemplate layoutTemplate =
117             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
118                 getLayoutTemplateId(), false, null);
119 
120         if (layoutTemplate == null) {
121             layoutTemplate = new LayoutTemplateImpl(
122                 StringPool.BLANK, StringPool.BLANK);
123 
124             List<String> columns = new ArrayList<String>();
125 
126             for (int i = 1; i <= 10; i++) {
127                 columns.add("column-" + i);
128             }
129 
130             layoutTemplate.setColumns(columns);
131         }
132 
133         return layoutTemplate;
134     }
135 
136     public String getLayoutTemplateId() {
137         String layoutTemplateId =
138             getTypeSettingsProperties().getProperty(LAYOUT_TEMPLATE_ID);
139 
140         if (Validator.isNull(layoutTemplateId)) {
141             layoutTemplateId = StringPool.BLANK;
142         }
143 
144         return layoutTemplateId;
145     }
146 
147     public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
148         setLayoutTemplateId(userId, newLayoutTemplateId, true);
149     }
150 
151     public void setLayoutTemplateId(
152         long userId, String newLayoutTemplateId, boolean checkPermission) {
153 
154         if (checkPermission &&
155             !PluginSettingLocalServiceUtil.hasPermission(
156                 userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
157 
158             return;
159         }
160 
161         String oldLayoutTemplateId = getLayoutTemplateId();
162 
163         if (Validator.isNull(oldLayoutTemplateId)) {
164             oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
165         }
166 
167         getTypeSettingsProperties().setProperty(
168             LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
169 
170         String themeId = null;
171 
172         try {
173             Layout layout = getLayout();
174 
175             Theme theme = layout.getTheme();
176 
177             if (theme != null) {
178                 themeId = theme.getThemeId();
179             }
180             else {
181                 themeId = layout.getThemeId();
182             }
183         }
184         catch (Exception e) {
185             _log.error(e);
186         }
187 
188         LayoutTemplate oldLayoutTemplate =
189             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
190                 oldLayoutTemplateId, false, themeId);
191 
192         if (oldLayoutTemplate == null) {
193             return;
194         }
195 
196         LayoutTemplate newLayoutTemplate =
197             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
198                 newLayoutTemplateId, false, themeId);
199 
200         List<String> oldColumns = oldLayoutTemplate.getColumns();
201         List<String> newColumns = newLayoutTemplate.getColumns();
202 
203         reorganizePortlets(newColumns, oldColumns);
204     }
205 
206     public int getNumOfColumns() {
207         return getLayoutTemplate().getColumns().size();
208     }
209 
210     public List<Portlet> getAllPortlets() throws SystemException {
211         List<Portlet> portlets = new ArrayList<Portlet>();
212 
213         List<String> columns = getColumns();
214 
215         for (int i = 0; i < columns.size(); i++) {
216             String columnId = columns.get(i);
217 
218             portlets.addAll(getAllPortlets(columnId));
219 
220         }
221 
222         return portlets;
223     }
224 
225     public List<Portlet> getAllPortlets(String columnId)
226         throws SystemException {
227 
228         String columnValue =
229             getTypeSettingsProperties().getProperty(columnId);
230 
231         String[] portletIds = StringUtil.split(columnValue);
232 
233         List<Portlet> portlets = new ArrayList<Portlet>(portletIds.length);
234 
235         for (int i = 0; i < portletIds.length; i++) {
236             Portlet portlet = PortletLocalServiceUtil.getPortletById(
237                 getLayout().getCompanyId(), portletIds[i]);
238 
239             if (portlet != null) {
240                 portlets.add(portlet);
241             }
242         }
243 
244         List<Portlet> startPortlets = getStaticPortlets(
245             PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
246 
247         List<Portlet> endPortlets = getStaticPortlets(
248             PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
249 
250         return addStaticPortlets(portlets, startPortlets, endPortlets);
251     }
252 
253     public List<Portlet> addStaticPortlets(
254         List<Portlet> portlets, List<Portlet> startPortlets,
255         List<Portlet> endPortlets) {
256 
257         // Return the original array of portlets if no static portlets are
258         // specified
259 
260         if (startPortlets == null) {
261             startPortlets = new ArrayList<Portlet>();
262         }
263 
264         if (endPortlets == null) {
265             endPortlets = new ArrayList<Portlet>();
266         }
267 
268         if ((startPortlets.isEmpty()) && (endPortlets.isEmpty())) {
269             return portlets;
270         }
271 
272         // New array of portlets that contain the static portlets
273 
274         List<Portlet> list = new ArrayList<Portlet>(
275             portlets.size() + startPortlets.size() + endPortlets.size());
276 
277         if (startPortlets != null) {
278             list.addAll(startPortlets);
279         }
280 
281         for (int i = 0; i < portlets.size(); i++) {
282             Portlet portlet = portlets.get(i);
283 
284             // Add the portlet if and only if it is not also a static portlet
285 
286             if (!startPortlets.contains(portlet) &&
287                 !endPortlets.contains(portlet)) {
288 
289                 list.add(portlet);
290             }
291         }
292 
293         if (endPortlets != null) {
294             list.addAll(endPortlets);
295         }
296 
297         return list;
298     }
299 
300     // Modify portlets
301 
302     public String addPortletId(long userId, String portletId) {
303         return addPortletId(userId, portletId, true);
304     }
305 
306     public String addPortletId(
307         long userId, String portletId, boolean checkPermission) {
308 
309         return addPortletId(userId, portletId, null, -1, checkPermission);
310     }
311 
312     public String addPortletId(
313         long userId, String portletId, String columnId, int columnPos) {
314 
315         return addPortletId(userId, portletId, columnId, columnPos, true);
316     }
317 
318     public String addPortletId(
319         long userId, String portletId, String columnId, int columnPos,
320         boolean checkPermission) {
321 
322         portletId = JS.getSafeName(portletId);
323 
324         Layout layout = getLayout();
325 
326         Portlet portlet = null;
327 
328         try {
329             portlet = PortletLocalServiceUtil.getPortletById(
330                 layout.getCompanyId(), portletId);
331 
332             if (portlet == null) {
333                 _log.error(
334                     "Portlet " + portletId +
335                         " cannot be added because it is not registered");
336             }
337 
338             if (checkPermission && !portlet.hasAddPortletPermission(userId)) {
339                 return null;
340             }
341         }
342         catch (Exception e) {
343             _log.error(e);
344         }
345 
346         if (portlet != null) {
347             if (portlet.isSystem()) {
348                 return null;
349             }
350 
351             if ((portlet.isInstanceable()) &&
352                 (PortletConstants.getInstanceId(
353                     portlet.getPortletId()) == null)) {
354 
355                 portletId = portletId + getFullInstanceSeparator();
356             }
357 
358             if (hasPortletId(portletId)) {
359                 return null;
360             }
361 
362             if (columnId == null) {
363                 LayoutTemplate layoutTemplate = getLayoutTemplate();
364 
365                 List<String> columns = layoutTemplate.getColumns();
366 
367                 if (columns.size() > 0) {
368                     columnId = columns.get(0);
369                 }
370             }
371 
372             if (columnId != null) {
373                 String columnValue =
374                     getTypeSettingsProperties().getProperty(columnId);
375 
376                 if ((columnValue == null) &&
377                     (columnId.startsWith(PortletKeys.NESTED_PORTLETS))) {
378 
379                     addNestedColumn(columnId);
380                 }
381 
382                 if (columnPos >= 0) {
383                     List<String> portletIds =
384                         ListUtil.fromArray(StringUtil.split(columnValue));
385 
386                     if (columnPos <= portletIds.size()) {
387                         portletIds.add(columnPos, portletId);
388                     }
389                     else {
390                         portletIds.add(portletId);
391                     }
392 
393                     columnValue = StringUtil.merge(portletIds);
394                 }
395                 else {
396                     columnValue = StringUtil.add(columnValue, portletId);
397                 }
398 
399                 getTypeSettingsProperties().setProperty(columnId, columnValue);
400             }
401 
402             try {
403                 PortletLayoutListener portletLayoutListener =
404                     portlet.getPortletLayoutListener();
405 
406                 if (_enablePortletLayoutListener &&
407                     (portletLayoutListener != null)) {
408 
409                     portletLayoutListener.onAddToLayout(
410                         portletId, layout.getPlid());
411                 }
412             }
413             catch (Exception e) {
414                 _log.error("Unable to fire portlet layout listener event", e);
415             }
416 
417             return portletId;
418         }
419         else {
420             return null;
421         }
422     }
423 
424     public void addPortletIds(
425         long userId, String[] portletIds, boolean checkPermission) {
426 
427         for (int i = 0; i < portletIds.length; i++) {
428             String portletId = portletIds[i];
429 
430             addPortletId(userId, portletId, checkPermission);
431         }
432     }
433 
434     public void addPortletIds(
435         long userId, String[] portletIds, String columnId,
436         boolean checkPermission) {
437 
438         for (int i = 0; i < portletIds.length; i++) {
439             String portletId = portletIds[i];
440 
441             addPortletId(userId, portletId, columnId, -1, checkPermission);
442         }
443     }
444 
445     public List<Portlet> getPortlets() throws SystemException {
446         List<String> portletIds = getPortletIds();
447 
448         List<Portlet> portlets = new ArrayList<Portlet>(portletIds.size());
449 
450         for (int i = 0; i < portletIds.size(); i++) {
451             String portletId = portletIds.get(i);
452 
453             Portlet portlet = PortletLocalServiceUtil.getPortletById(
454                 getLayout().getCompanyId(), portletId);
455 
456             if (portlet != null) {
457                 portlets.add(portlet);
458             }
459         }
460 
461         return portlets;
462     }
463 
464     public List<String> getPortletIds() {
465         List<String> portletIds = new ArrayList<String>();
466 
467         List<String> columns = getColumns();
468 
469         for (int i = 0; i < columns.size(); i++) {
470             String columnId = columns.get(i);
471 
472             String columnValue =
473                 getTypeSettingsProperties().getProperty(columnId);
474 
475             portletIds.addAll(
476                 ListUtil.fromArray(StringUtil.split(columnValue)));
477 
478         }
479 
480         return portletIds;
481     }
482 
483     public boolean hasPortletId(String portletId) {
484         List<String> columns = getColumns();
485 
486         for (int i = 0; i < columns.size(); i++) {
487             String columnId = columns.get(i);
488 
489             if (hasNonstaticPortletId(columnId, portletId)) {
490                 return true;
491             }
492 
493             if (hasStaticPortletId(columnId, portletId)) {
494                 return true;
495             }
496         }
497 
498         return false;
499     }
500 
501     public void movePortletId(
502         long userId, String portletId, String columnId, int columnPos) {
503 
504         _enablePortletLayoutListener = false;
505 
506         try {
507             removePortletId(portletId, false);
508             addPortletId(userId, portletId, columnId, columnPos);
509         }
510         finally {
511             _enablePortletLayoutListener = true;
512         }
513 
514         Layout layout = getLayout();
515 
516         try {
517             Portlet portlet = PortletLocalServiceUtil.getPortletById(
518                 layout.getCompanyId(), portletId);
519 
520             if (portlet != null) {
521                 PortletLayoutListener portletLayoutListener =
522                     portlet.getPortletLayoutListener();
523 
524                 if (portletLayoutListener != null) {
525                     portletLayoutListener.onMoveInLayout(
526                         portletId, layout.getPlid());
527                 }
528             }
529         }
530         catch (Exception e) {
531             _log.error("Unable to fire portlet layout listener event", e);
532         }
533     }
534 
535     public void removePortletId(String portletId) {
536         removePortletId(portletId, true);
537     }
538 
539     public void removePortletId(String portletId, boolean cleanUp) {
540         List<String> columns = getColumns();
541 
542         for (int i = 0; i < columns.size(); i++) {
543             String columnId = columns.get(i);
544 
545             String columnValue =
546                 getTypeSettingsProperties().getProperty(columnId);
547 
548             columnValue = StringUtil.remove(columnValue, portletId);
549 
550             getTypeSettingsProperties().setProperty(columnId, columnValue);
551         }
552 
553         if (cleanUp) {
554             removeStatesPortletId(portletId);
555             removeModesPortletId(portletId);
556 
557             try {
558                 onRemoveFromLayout(portletId);
559             }
560             catch (Exception e) {
561                 _log.error("Unable to fire portlet layout listener event", e);
562             }
563         }
564     }
565 
566     public void setPortletIds(String columnId, String portletIds) {
567         getTypeSettingsProperties().setProperty(columnId, portletIds);
568     }
569 
570     public void reorganizePortlets(
571         List<String> newColumns, List<String> oldColumns) {
572 
573         String lastNewColumnId = newColumns.get(newColumns.size() - 1);
574         String lastNewColumnValue =
575             getTypeSettingsProperties().getProperty(lastNewColumnId);
576 
577         Iterator<String> itr = oldColumns.iterator();
578 
579         while (itr.hasNext()) {
580             String oldColumnId = itr.next();
581 
582             if (!newColumns.contains(oldColumnId)) {
583                 String oldColumnValue = getTypeSettingsProperties().remove(
584                     oldColumnId);
585 
586                 String[] portletIds = StringUtil.split(oldColumnValue);
587 
588                 for (int i = 0; i < portletIds.length; i++) {
589                     lastNewColumnValue =
590                         StringUtil.add(lastNewColumnValue, portletIds[i]);
591                 }
592             }
593         }
594 
595         getTypeSettingsProperties().setProperty(
596             lastNewColumnId, lastNewColumnValue);
597     }
598 
599     // Maximized state
600 
601     public String getStateMax() {
602         return getTypeSettingsProperties().getProperty(STATE_MAX);
603     }
604 
605     public void setStateMax(String stateMax) {
606         getTypeSettingsProperties().setProperty(STATE_MAX, stateMax);
607     }
608 
609     public boolean hasStateMax() {
610         String[] stateMax = StringUtil.split(getStateMax());
611 
612         if (stateMax.length > 0) {
613             return true;
614         }
615         else {
616             return false;
617         }
618     }
619 
620     public void addStateMaxPortletId(String portletId) {
621         removeStatesPortletId(portletId);
622         //setStateMax(StringUtil.add(getStateMax(), portletId));
623         setStateMax(StringUtil.add(StringPool.BLANK, portletId));
624     }
625 
626     public String getStateMaxPortletId() {
627         String[] stateMax = StringUtil.split(getStateMax());
628 
629         if (stateMax.length > 0) {
630             return stateMax[0];
631         }
632         else {
633             return StringPool.BLANK;
634         }
635     }
636 
637     public boolean hasStateMaxPortletId(String portletId) {
638         if (StringUtil.contains(getStateMax(), portletId)) {
639             return true;
640         }
641         else {
642             return false;
643         }
644     }
645 
646     public void removeStateMaxPortletId(String portletId) {
647         setStateMax(StringUtil.remove(getStateMax(), portletId));
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         UnicodeProperties props = getTypeSettingsProperties();
945 
946         UnicodeProperties newProps = new UnicodeProperties();
947 
948         for (String key : props.keySet()) {
949             if (!key.startsWith(portletId)) {
950                 newProps.setProperty(key, props.getProperty(key));
951             }
952         }
953 
954         getLayout().setTypeSettingsProperties(newProps);
955 
956         String nestedColumnIds = GetterUtil.getString(
957             getTypeSettingsProperties().getProperty(NESTED_COLUMN_IDS));
958 
959         String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
960             StringUtil.split(nestedColumnIds), portletId);
961 
962         getTypeSettingsProperties().setProperty(
963             NESTED_COLUMN_IDS, StringUtil.merge(nestedColumnIdsArray));
964     }
965 
966     protected void addNestedColumn(String columnId) {
967         String nestedColumnIds = getTypeSettingsProperties().getProperty(
968             NESTED_COLUMN_IDS, StringPool.BLANK);
969 
970         if (nestedColumnIds.indexOf(columnId) == -1) {
971             nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
972 
973             getTypeSettingsProperties().setProperty(
974                 NESTED_COLUMN_IDS, nestedColumnIds);
975         }
976     }
977 
978     protected List<String> getColumns() {
979         LayoutTemplate layoutTemplate = getLayoutTemplate();
980 
981         List<String> columns = new ArrayList<String>();
982 
983         columns.addAll(layoutTemplate.getColumns());
984         columns.addAll(getNestedColumns());
985 
986         return columns;
987     }
988 
989     protected List<String> getNestedColumns() {
990         String nestedColumnIds = getTypeSettingsProperties().getProperty(
991             NESTED_COLUMN_IDS);
992 
993         return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
994     }
995 
996     protected String[] getStaticPortletIds(String position) {
997         Layout layout = getLayout();
998 
999         String selector1 = StringPool.BLANK;
1000
1001        Group group = layout.getGroup();
1002
1003        if (group.isUser()) {
1004            selector1 = STATIC_PORTLET_USER_SELECTOR;
1005        }
1006        else if (group.isCommunity()) {
1007            selector1 = STATIC_PORTLET_COMMUNITY_SELECTOR;
1008        }
1009        else if (group.isOrganization()) {
1010            selector1 = STATIC_PORTLET_ORGANIZATION_SELECTOR;
1011        }
1012
1013        String selector2 = layout.getFriendlyURL();
1014
1015        String[] portletIds = PropsUtil.getArray(
1016            position, new Filter(selector1, selector2));
1017
1018        for (int i = 0; i < portletIds.length; i++) {
1019            portletIds[i] = JS.getSafeName(portletIds[i]);
1020        }
1021
1022        return portletIds;
1023    }
1024
1025    protected List<Portlet> getStaticPortlets(String position)
1026        throws SystemException {
1027
1028        String[] portletIds = getStaticPortletIds(position);
1029
1030        List<Portlet> portlets = new ArrayList<Portlet>();
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<String> columns = layoutTemplate.getColumns();
1074
1075        for (int i = 0; i < columns.size(); i++) {
1076            String columnId = 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            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1116
1117        String[] staticPortletIdsEnd = getStaticPortletIds(
1118            PropsKeys.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            UnicodeProperties props = getTypeSettingsProperties();
1144
1145            for (String key : props.keySet()) {
1146                if (key.startsWith(portlet.getPortletId())) {
1147                    String portletIds = props.getProperty(key);
1148
1149                    String[] portletIdsArray = StringUtil.split(portletIds);
1150
1151                    for (int i = 0; i < portletIdsArray.length; i++) {
1152                        onRemoveFromLayout(portletIdsArray[i]);
1153                    }
1154                }
1155            }
1156
1157            removeNestedColumns(portletId);
1158        }
1159
1160        if (_enablePortletLayoutListener) {
1161            PortletLayoutListener portletLayoutListener =
1162                portlet.getPortletLayoutListener();
1163
1164            long plid = getLayout().getPlid();
1165
1166            if ((portletLayoutListener != null)) {
1167                portletLayoutListener.onRemoveFromLayout(portletId, plid);
1168            }
1169        }
1170
1171        deletePortletSetup(portletId);
1172    }
1173
1174    protected void deletePortletSetup(String portletId) {
1175        try {
1176            List<PortletPreferences> list =
1177                PortletPreferencesLocalServiceUtil.getPortletPreferences(
1178                    getLayout().getPlid(), portletId);
1179
1180            for (int i = 0; i < list.size(); i++) {
1181                PortletPreferences portletPreferences = list.get(i);
1182
1183                PortletPreferencesLocalServiceUtil.deletePortletPreferences(
1184                    portletPreferences.getPortletPreferencesId());
1185            }
1186        }
1187        catch (Exception e) {
1188            _log.error(e, e);
1189        }
1190    }
1191
1192    private static Log _log = LogFactory.getLog(LayoutTypePortletImpl.class);
1193
1194    private boolean _enablePortletLayoutListener = true;
1195
1196}