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