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