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