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