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 hasModeAboutPortletId(String portletId) {
503         return StringUtil.contains(getModeAbout(), portletId);
504     }
505 
506     public boolean hasModeConfigPortletId(String portletId) {
507         return StringUtil.contains(getModeConfig(), portletId);
508     }
509 
510     public boolean hasModeEditDefaultsPortletId(String portletId) {
511         return StringUtil.contains(getModeEditDefaults(), portletId);
512     }
513 
514     public boolean hasModeEditGuestPortletId(String portletId) {
515         return StringUtil.contains(getModeEditGuest(), portletId);
516     }
517 
518     public boolean hasModeEditPortletId(String portletId) {
519         return StringUtil.contains(getModeEdit(), portletId);
520     }
521 
522     public boolean hasModeHelpPortletId(String portletId) {
523         return StringUtil.contains(getModeHelp(), portletId);
524     }
525 
526     public boolean hasModePreviewPortletId(String portletId) {
527         return StringUtil.contains(getModePreview(), portletId);
528     }
529 
530     public boolean hasModePrintPortletId(String portletId) {
531         return StringUtil.contains(getModePrint(), portletId);
532     }
533 
534     public boolean hasModeViewPortletId(String portletId) {
535         if (hasModeAboutPortletId(portletId) ||
536             hasModeConfigPortletId(portletId) ||
537             hasModeEditPortletId(portletId) ||
538             hasModeEditDefaultsPortletId(portletId) ||
539             hasModeEditGuestPortletId(portletId) ||
540             hasModeHelpPortletId(portletId) ||
541             hasModePreviewPortletId(portletId) ||
542             hasModePrintPortletId(portletId)) {
543 
544             return false;
545         }
546         else {
547             return true;
548         }
549     }
550 
551     public boolean hasPortletId(String portletId)
552         throws PortalException, SystemException {
553 
554         List<String> columns = getColumns();
555 
556         for (int i = 0; i < columns.size(); i++) {
557             String columnId = columns.get(i);
558 
559             if (hasNonstaticPortletId(columnId, portletId)) {
560                 return true;
561             }
562 
563             if (hasStaticPortletId(columnId, portletId)) {
564                 return true;
565             }
566         }
567 
568         if (getLayout().isTypeControlPanel() &&
569             hasStateMaxPortletId(portletId)) {
570 
571             return true;
572         }
573 
574         return false;
575     }
576 
577     public boolean hasStateMax() {
578         String[] stateMax = StringUtil.split(getStateMax());
579 
580         if (stateMax.length > 0) {
581             return true;
582         }
583         else {
584             return false;
585         }
586     }
587 
588     public boolean hasStateMaxPortletId(String portletId) {
589         if (StringUtil.contains(getStateMax(), portletId)) {
590             return true;
591         }
592         else {
593             return false;
594         }
595     }
596 
597     public boolean hasStateMin() {
598         String[] stateMin = StringUtil.split(getStateMin());
599 
600         if (stateMin.length > 0) {
601             return true;
602         }
603         else {
604             return false;
605         }
606     }
607 
608     public boolean hasStateMinPortletId(String portletId) {
609         if (StringUtil.contains(getStateMin(), portletId)) {
610             return true;
611         }
612         else {
613             return false;
614         }
615     }
616 
617     public boolean hasStateNormalPortletId(String portletId) {
618         if (hasStateMaxPortletId(portletId) ||
619             hasStateMinPortletId(portletId)) {
620 
621             return false;
622         }
623         else {
624             return true;
625         }
626     }
627 
628     public void movePortletId(
629             long userId, String portletId, String columnId, int columnPos)
630         throws PortalException, SystemException {
631 
632         _enablePortletLayoutListener = false;
633 
634         try {
635             removePortletId(userId, portletId, false);
636             addPortletId(userId, portletId, columnId, columnPos);
637         }
638         finally {
639             _enablePortletLayoutListener = true;
640         }
641 
642         Layout layout = getLayout();
643 
644         try {
645             Portlet portlet = PortletLocalServiceUtil.getPortletById(
646                 layout.getCompanyId(), portletId);
647 
648             if (portlet != null) {
649                 PortletLayoutListener portletLayoutListener =
650                     portlet.getPortletLayoutListenerInstance();
651 
652                 if (portletLayoutListener != null) {
653                     portletLayoutListener.onMoveInLayout(
654                         portletId, layout.getPlid());
655                 }
656             }
657         }
658         catch (Exception e) {
659             _log.error("Unable to fire portlet layout listener event", e);
660         }
661     }
662 
663     public void removeModeAboutPortletId(String portletId) {
664         setModeAbout(StringUtil.remove(getModeAbout(), portletId));
665     }
666 
667     public void removeModeConfigPortletId(String portletId) {
668         setModeConfig(StringUtil.remove(getModeConfig(), portletId));
669     }
670 
671     public void removeModeEditDefaultsPortletId(String portletId) {
672         setModeEditDefaults(
673             StringUtil.remove(getModeEditDefaults(), portletId));
674     }
675 
676     public void removeModeEditGuestPortletId(String portletId) {
677         setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
678     }
679 
680     public void removeModeEditPortletId(String portletId) {
681         setModeEdit(StringUtil.remove(getModeEdit(), portletId));
682     }
683 
684     public void removeModeHelpPortletId(String portletId) {
685         setModeHelp(StringUtil.remove(getModeHelp(), portletId));
686     }
687 
688     public void removeModePreviewPortletId(String portletId) {
689         setModePreview(StringUtil.remove(getModePreview(), portletId));
690     }
691 
692     public void removeModePrintPortletId(String portletId) {
693         setModePrint(StringUtil.remove(getModePrint(), portletId));
694     }
695 
696     public void removeModesPortletId(String portletId) {
697         removeModeAboutPortletId(portletId);
698         removeModeConfigPortletId(portletId);
699         removeModeEditPortletId(portletId);
700         removeModeEditDefaultsPortletId(portletId);
701         removeModeEditGuestPortletId(portletId);
702         removeModeHelpPortletId(portletId);
703         removeModePreviewPortletId(portletId);
704         removeModePrintPortletId(portletId);
705     }
706 
707     public void removeNestedColumns(String portletId) {
708         UnicodeProperties props = getTypeSettingsProperties();
709 
710         UnicodeProperties newProps = new UnicodeProperties();
711 
712         for (String key : props.keySet()) {
713             if (!key.startsWith(portletId)) {
714                 newProps.setProperty(key, props.getProperty(key));
715             }
716         }
717 
718         getLayout().setTypeSettingsProperties(newProps);
719 
720         String nestedColumnIds = GetterUtil.getString(
721             getTypeSettingsProperties().getProperty(
722                 LayoutTypePortletConstants.NESTED_COLUMN_IDS));
723 
724         String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
725             StringUtil.split(nestedColumnIds), portletId);
726 
727         getTypeSettingsProperties().setProperty(
728             LayoutTypePortletConstants.NESTED_COLUMN_IDS,
729             StringUtil.merge(nestedColumnIdsArray));
730     }
731 
732     public void removePortletId(long userId, String portletId) {
733         removePortletId(userId, portletId, true);
734     }
735 
736     public void removePortletId (
737         long userId, String portletId, boolean cleanUp) {
738 
739         try {
740             Layout layout = getLayout();
741 
742             Portlet portlet = PortletLocalServiceUtil.getPortletById(
743                 layout.getCompanyId(), portletId);
744 
745             if (portlet == null) {
746                 _log.error(
747                     "Portlet " + portletId +
748                         " cannot be removed because it is not registered");
749 
750                 return;
751             }
752 
753             if (!portlet.hasAddPortletPermission(userId)) {
754                 return;
755             }
756         }
757         catch (Exception e) {
758             _log.error(e, e);
759         }
760 
761         List<String> columns = getColumns();
762 
763         for (int i = 0; i < columns.size(); i++) {
764             String columnId = columns.get(i);
765 
766             String columnValue =
767                 getTypeSettingsProperties().getProperty(columnId);
768 
769             columnValue = StringUtil.remove(columnValue, portletId);
770 
771             getTypeSettingsProperties().setProperty(columnId, columnValue);
772         }
773 
774         if (cleanUp) {
775             removeStatesPortletId(portletId);
776             removeModesPortletId(portletId);
777 
778             try {
779                 onRemoveFromLayout(portletId);
780             }
781             catch (Exception e) {
782                 _log.error("Unable to fire portlet layout listener event", e);
783             }
784         }
785     }
786 
787     public void removeStateMaxPortletId(String portletId) {
788         setStateMax(StringUtil.remove(getStateMax(), portletId));
789     }
790 
791     public void removeStateMinPortletId(String portletId) {
792         setStateMin(StringUtil.remove(getStateMin(), portletId));
793     }
794 
795     public void removeStatesPortletId(String portletId) {
796         removeStateMaxPortletId(portletId);
797         removeStateMinPortletId(portletId);
798     }
799 
800     public void reorganizePortlets(
801         List<String> newColumns, List<String> oldColumns) {
802 
803         String lastNewColumnId = newColumns.get(newColumns.size() - 1);
804         String lastNewColumnValue =
805             getTypeSettingsProperties().getProperty(lastNewColumnId);
806 
807         Iterator<String> itr = oldColumns.iterator();
808 
809         while (itr.hasNext()) {
810             String oldColumnId = itr.next();
811 
812             if (!newColumns.contains(oldColumnId)) {
813                 String oldColumnValue = getTypeSettingsProperties().remove(
814                     oldColumnId);
815 
816                 String[] portletIds = StringUtil.split(oldColumnValue);
817 
818                 for (String portletId : portletIds) {
819                     lastNewColumnValue = StringUtil.add(
820                         lastNewColumnValue, portletId);
821                 }
822             }
823         }
824 
825         getTypeSettingsProperties().setProperty(
826             lastNewColumnId, lastNewColumnValue);
827     }
828 
829     public void resetModes() {
830         setModeAbout(StringPool.BLANK);
831         setModeConfig(StringPool.BLANK);
832         setModeEdit(StringPool.BLANK);
833         setModeEditDefaults(StringPool.BLANK);
834         setModeEditGuest(StringPool.BLANK);
835         setModeHelp(StringPool.BLANK);
836         setModePreview(StringPool.BLANK);
837         setModePrint(StringPool.BLANK);
838     }
839 
840     public void resetStates() {
841         setStateMax(StringPool.BLANK);
842         setStateMin(StringPool.BLANK);
843     }
844 
845     public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
846         setLayoutTemplateId(userId, newLayoutTemplateId, true);
847     }
848 
849     public void setLayoutTemplateId(
850         long userId, String newLayoutTemplateId, boolean checkPermission) {
851 
852         if (checkPermission &&
853             !PluginSettingLocalServiceUtil.hasPermission(
854                 userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
855 
856             return;
857         }
858 
859         String oldLayoutTemplateId = getLayoutTemplateId();
860 
861         if (Validator.isNull(oldLayoutTemplateId)) {
862             oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
863         }
864 
865         getTypeSettingsProperties().setProperty(
866             LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
867 
868         String themeId = null;
869 
870         try {
871             Layout layout = getLayout();
872 
873             Theme theme = layout.getTheme();
874 
875             if (theme != null) {
876                 themeId = theme.getThemeId();
877             }
878             else {
879                 themeId = layout.getThemeId();
880             }
881         }
882         catch (Exception e) {
883             _log.error(e, e);
884         }
885 
886         LayoutTemplate oldLayoutTemplate =
887             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
888                 oldLayoutTemplateId, false, themeId);
889 
890         if (oldLayoutTemplate == null) {
891             return;
892         }
893 
894         LayoutTemplate newLayoutTemplate =
895             LayoutTemplateLocalServiceUtil.getLayoutTemplate(
896                 newLayoutTemplateId, false, themeId);
897 
898         List<String> oldColumns = oldLayoutTemplate.getColumns();
899         List<String> newColumns = newLayoutTemplate.getColumns();
900 
901         reorganizePortlets(newColumns, oldColumns);
902     }
903 
904     public void setModeAbout(String modeAbout) {
905         getTypeSettingsProperties().setProperty(
906             LayoutTypePortletConstants.MODE_ABOUT, modeAbout);
907     }
908 
909     public void setModeConfig(String modeConfig) {
910         getTypeSettingsProperties().setProperty(
911             LayoutTypePortletConstants.MODE_CONFIG, modeConfig);
912     }
913 
914     public void setModeEdit(String modeEdit) {
915         getTypeSettingsProperties().setProperty(
916             LayoutTypePortletConstants.MODE_EDIT, modeEdit);
917     }
918 
919     public void setModeEditDefaults(String modeEditDefaults) {
920         getTypeSettingsProperties().setProperty(
921             LayoutTypePortletConstants.MODE_EDIT_DEFAULTS, modeEditDefaults);
922     }
923 
924     public void setModeEditGuest(String modeEditGuest) {
925         getTypeSettingsProperties().setProperty(
926             LayoutTypePortletConstants.MODE_EDIT_GUEST, modeEditGuest);
927     }
928 
929     public void setModeHelp(String modeHelp) {
930         getTypeSettingsProperties().setProperty(
931             LayoutTypePortletConstants.MODE_HELP, modeHelp);
932     }
933 
934     public void setModePreview(String modePreview) {
935         getTypeSettingsProperties().setProperty(
936             LayoutTypePortletConstants.MODE_PREVIEW, modePreview);
937     }
938 
939     public void setModePrint(String modePrint) {
940         getTypeSettingsProperties().setProperty(
941             LayoutTypePortletConstants.MODE_PRINT, modePrint);
942     }
943 
944     public void setPortletIds(String columnId, String portletIds) {
945         getTypeSettingsProperties().setProperty(columnId, portletIds);
946     }
947 
948     public void setStateMax(String stateMax) {
949         getTypeSettingsProperties().setProperty(
950             LayoutTypePortletConstants.STATE_MAX, stateMax);
951     }
952 
953     public void setStateMin(String stateMin) {
954         getTypeSettingsProperties().setProperty(
955             LayoutTypePortletConstants.STATE_MIN, stateMin);
956     }
957 
958     protected void addNestedColumn(String columnId) {
959         String nestedColumnIds = getTypeSettingsProperties().getProperty(
960             LayoutTypePortletConstants.NESTED_COLUMN_IDS, StringPool.BLANK);
961 
962         if (nestedColumnIds.indexOf(columnId) == -1) {
963             nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
964 
965             getTypeSettingsProperties().setProperty(
966                 LayoutTypePortletConstants.NESTED_COLUMN_IDS, nestedColumnIds);
967         }
968     }
969 
970     protected void deletePortletSetup(String portletId) {
971         try {
972             List<PortletPreferences> list =
973                 PortletPreferencesLocalServiceUtil.getPortletPreferences(
974                     getLayout().getPlid(), portletId);
975 
976             for (int i = 0; i < list.size(); i++) {
977                 PortletPreferences portletPreferences = list.get(i);
978 
979                 PortletPreferencesLocalServiceUtil.deletePortletPreferences(
980                     portletPreferences.getPortletPreferencesId());
981             }
982         }
983         catch (Exception e) {
984             _log.error(e, e);
985         }
986     }
987 
988     protected List<String> getColumns() {
989         LayoutTemplate layoutTemplate = getLayoutTemplate();
990 
991         List<String> columns = new ArrayList<String>();
992 
993         columns.addAll(layoutTemplate.getColumns());
994         columns.addAll(getNestedColumns());
995 
996         return columns;
997     }
998 
999     protected List<String> getNestedColumns() {
1000        String nestedColumnIds = getTypeSettingsProperties().getProperty(
1001            LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1002
1003        return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
1004    }
1005
1006    /*protected boolean hasStaticPortletId(String portletId) {
1007        LayoutTemplate layoutTemplate = getLayoutTemplate();
1008
1009        List columns = layoutTemplate.getColumns();
1010
1011        for (int i = 0; i < columns.size(); i++) {
1012            String columnId = (String)columns.get(i);
1013
1014            if (hasStaticPortletId(columnId, portletId)) {
1015                return true;
1016            }
1017        }
1018
1019        return false;
1020    }*/
1021
1022    protected String[] getStaticPortletIds(String position)
1023        throws PortalException, SystemException {
1024
1025        Layout layout = getLayout();
1026
1027        String selector1 = StringPool.BLANK;
1028
1029        Group group = layout.getGroup();
1030
1031        if (group.isUser()) {
1032            selector1 = LayoutTypePortletConstants.STATIC_PORTLET_USER_SELECTOR;
1033        }
1034        else if (group.isCommunity()) {
1035            selector1 =
1036                LayoutTypePortletConstants.STATIC_PORTLET_COMMUNITY_SELECTOR;
1037        }
1038        else if (group.isOrganization()) {
1039            selector1 =
1040                LayoutTypePortletConstants.STATIC_PORTLET_ORGANIZATION_SELECTOR;
1041        }
1042
1043        String selector2 = layout.getFriendlyURL();
1044
1045        String[] portletIds = PropsUtil.getArray(
1046            position, new Filter(selector1, selector2));
1047
1048        for (int i = 0; i < portletIds.length; i++) {
1049            portletIds[i] = JS.getSafeName(portletIds[i]);
1050        }
1051
1052        return portletIds;
1053    }
1054
1055    protected List<Portlet> getStaticPortlets(String position)
1056        throws PortalException, SystemException {
1057
1058        String[] portletIds = getStaticPortletIds(position);
1059
1060        List<Portlet> portlets = new ArrayList<Portlet>();
1061
1062        for (int i = 0; i < portletIds.length; i++) {
1063            String portletId = portletIds[i];
1064
1065            if (Validator.isNull(portletId) ||
1066                hasNonstaticPortletId(portletId)) {
1067
1068                continue;
1069            }
1070
1071            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1072                getLayout().getCompanyId(), portletId);
1073
1074            if (portlet != null) {
1075                Portlet staticPortlet = portlet;
1076
1077                if (portlet.isInstanceable()) {
1078
1079                    // Instanceable portlets do not need to be cloned because
1080                    // they are already cloned. See the method getPortletById in
1081                    // the class PortletLocalServiceImpl and how it references
1082                    // the method getClonedInstance in the class PortletImpl.
1083
1084                }
1085                else {
1086                    staticPortlet = (Portlet)staticPortlet.clone();
1087                }
1088
1089                staticPortlet.setStatic(true);
1090
1091                if (position.startsWith("layout.static.portlets.start")) {
1092                    staticPortlet.setStaticStart(true);
1093                }
1094
1095                portlets.add(staticPortlet);
1096            }
1097        }
1098
1099        return portlets;
1100    }
1101
1102    protected boolean hasNonstaticPortletId(String portletId) {
1103        LayoutTemplate layoutTemplate = getLayoutTemplate();
1104
1105        List<String> columns = layoutTemplate.getColumns();
1106
1107        for (int i = 0; i < columns.size(); i++) {
1108            String columnId = columns.get(i);
1109
1110            if (hasNonstaticPortletId(columnId, portletId)) {
1111                return true;
1112            }
1113        }
1114
1115        return false;
1116    }
1117
1118    protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1119        String columnValue = getTypeSettingsProperties().getProperty(columnId);
1120
1121        if (StringUtil.contains(columnValue, portletId)) {
1122            return true;
1123        }
1124        else {
1125            return false;
1126        }
1127    }
1128
1129    protected boolean hasStaticPortletId(String columnId, String portletId)
1130        throws PortalException, SystemException {
1131
1132        String[] staticPortletIdsStart = getStaticPortletIds(
1133            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1134
1135        String[] staticPortletIdsEnd = getStaticPortletIds(
1136            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1137
1138        String[] staticPortletIds = ArrayUtil.append(
1139            staticPortletIdsStart, staticPortletIdsEnd);
1140
1141        for (int i = 0; i < staticPortletIds.length; i++) {
1142            String staticPortletId = staticPortletIds[i];
1143
1144            if (staticPortletId.equals(portletId)) {
1145                return true;
1146            }
1147        }
1148
1149        return false;
1150    }
1151
1152    protected void onRemoveFromLayout(String portletId) throws SystemException {
1153        Portlet portlet = PortletLocalServiceUtil.getPortletById(
1154            getLayout().getCompanyId(), portletId);
1155
1156        if (portlet == null) {
1157            return;
1158        }
1159
1160        if (portlet.getRootPortletId().equals(PortletKeys.NESTED_PORTLETS)) {
1161            UnicodeProperties props = getTypeSettingsProperties();
1162
1163            for (String key : props.keySet()) {
1164                if (key.startsWith(portlet.getPortletId())) {
1165                    String portletIds = props.getProperty(key);
1166
1167                    String[] portletIdsArray = StringUtil.split(portletIds);
1168
1169                    for (int i = 0; i < portletIdsArray.length; i++) {
1170                        onRemoveFromLayout(portletIdsArray[i]);
1171                    }
1172                }
1173            }
1174
1175            removeNestedColumns(portletId);
1176        }
1177
1178        if (_enablePortletLayoutListener) {
1179            PortletLayoutListener portletLayoutListener =
1180                portlet.getPortletLayoutListenerInstance();
1181
1182            long plid = getLayout().getPlid();
1183
1184            if ((portletLayoutListener != null)) {
1185                portletLayoutListener.onRemoveFromLayout(portletId, plid);
1186            }
1187        }
1188
1189        deletePortletSetup(portletId);
1190    }
1191
1192    private static final String _NESTED_PORTLETS_NAMESPACE =
1193        PortalUtil.getPortletNamespace(PortletKeys.NESTED_PORTLETS);
1194
1195    private static Log _log = LogFactoryUtil.getLog(
1196        LayoutTypePortletImpl.class);
1197
1198    private boolean _enablePortletLayoutListener = true;
1199
1200}