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