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