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