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