001    /**
002     * Copyright (c) 2000-2011 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.DateFormatFactoryUtil;
025    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.ListUtil;
028    import com.liferay.portal.kernel.util.PropsKeys;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.StringUtil;
031    import com.liferay.portal.kernel.util.UnicodeProperties;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.model.CustomizedPages;
034    import com.liferay.portal.model.Group;
035    import com.liferay.portal.model.Layout;
036    import com.liferay.portal.model.LayoutPrototype;
037    import com.liferay.portal.model.LayoutSet;
038    import com.liferay.portal.model.LayoutSetPrototype;
039    import com.liferay.portal.model.LayoutTemplate;
040    import com.liferay.portal.model.LayoutTypePortlet;
041    import com.liferay.portal.model.LayoutTypePortletConstants;
042    import com.liferay.portal.model.Plugin;
043    import com.liferay.portal.model.Portlet;
044    import com.liferay.portal.model.PortletConstants;
045    import com.liferay.portal.model.PortletPreferences;
046    import com.liferay.portal.model.PortletPreferencesIds;
047    import com.liferay.portal.model.ResourceConstants;
048    import com.liferay.portal.model.Theme;
049    import com.liferay.portal.security.permission.ActionKeys;
050    import com.liferay.portal.security.permission.PermissionChecker;
051    import com.liferay.portal.security.permission.PermissionThreadLocal;
052    import com.liferay.portal.service.LayoutLocalServiceUtil;
053    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
054    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
055    import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
056    import com.liferay.portal.service.PluginSettingLocalServiceUtil;
057    import com.liferay.portal.service.PortletLocalServiceUtil;
058    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
059    import com.liferay.portal.service.ResourceLocalServiceUtil;
060    import com.liferay.portal.service.permission.LayoutPermissionUtil;
061    import com.liferay.portal.service.permission.PortletPermissionUtil;
062    import com.liferay.portal.util.PortalUtil;
063    import com.liferay.portal.util.PortletKeys;
064    import com.liferay.portal.util.PropsUtil;
065    import com.liferay.portal.util.PropsValues;
066    import com.liferay.portlet.PortalPreferences;
067    import com.liferay.portlet.PortletPreferencesFactoryUtil;
068    import com.liferay.util.JS;
069    import com.liferay.util.PwdGenerator;
070    
071    import java.text.DateFormat;
072    import java.text.Format;
073    
074    import java.util.ArrayList;
075    import java.util.Date;
076    import java.util.Iterator;
077    import java.util.List;
078    import java.util.Map;
079    
080    /**
081     * @author Brian Wing Shun Chan
082     * @author Berentey Zsolt
083     * @author Jorge Ferrer
084     * @author Raymond Augé
085     */
086    public class LayoutTypePortletImpl
087            extends LayoutTypeImpl implements LayoutTypePortlet {
088    
089            public static String getFullInstanceSeparator() {
090                    String instanceId = PwdGenerator.getPassword(
091                            PwdGenerator.KEY1 + PwdGenerator.KEY2 + PwdGenerator.KEY3, 12);
092    
093                    return PortletConstants.INSTANCE_SEPARATOR + instanceId;
094            }
095    
096            public static Layout getSourcePrototypeLayout(Layout layout) {
097                    if (Validator.isNull(layout.getUuid())) {
098                            return null;
099                    }
100    
101                    try {
102                            Group group = null;
103    
104                            if (Validator.isNotNull(layout.getLayoutPrototypeUuid())) {
105                                    LayoutPrototype layoutPrototype =
106                                            LayoutPrototypeLocalServiceUtil.getLayoutPrototypeByUuid(
107                                                    layout.getLayoutPrototypeUuid());
108    
109                                    group = layoutPrototype.getGroup();
110                            }
111                            else {
112                                    LayoutSet layoutSet = layout.getLayoutSet();
113    
114                                    if (Validator.isNull(layoutSet.getLayoutSetPrototypeUuid())) {
115                                            return null;
116                                    }
117    
118                                    LayoutSetPrototype layoutSetPrototype =
119                                            LayoutSetPrototypeLocalServiceUtil.
120                                                    getLayoutSetPrototypeByUuid(
121                                                            layoutSet.getLayoutSetPrototypeUuid());
122    
123                                    group = layoutSetPrototype.getGroup();
124                            }
125    
126                            return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
127                                    layout.getSourcePrototypeLayoutUuid(), group.getGroupId());
128                    }
129                    catch (Exception e) {
130                            _log.error(e, e);
131                    }
132    
133                    return null;
134            }
135    
136            public LayoutTypePortletImpl(Layout layout) {
137                    super(layout);
138    
139                    if (_nestedPortletsNamespace == null) {
140                            _nestedPortletsNamespace = PortalUtil.getPortletNamespace(
141                                    PortletKeys.NESTED_PORTLETS);
142                    }
143    
144                    _sourcePrototypeLayout = getSourcePrototypeLayout(layout);
145            }
146    
147            public void addModeAboutPortletId(String portletId) {
148                    removeModesPortletId(portletId);
149                    setModeAbout(StringUtil.add(getModeAbout(), portletId));
150            }
151    
152            public void addModeConfigPortletId(String portletId) {
153                    removeModesPortletId(portletId);
154                    setModeConfig(StringUtil.add(getModeConfig(), portletId));
155            }
156    
157            public void addModeEditDefaultsPortletId(String portletId) {
158                    removeModesPortletId(portletId);
159                    setModeEditDefaults(StringUtil.add(getModeEditDefaults(), portletId));
160            }
161    
162            public void addModeEditGuestPortletId(String portletId) {
163                    removeModesPortletId(portletId);
164                    setModeEditGuest(StringUtil.add(getModeEditGuest(), portletId));
165            }
166    
167            public void addModeEditPortletId(String portletId) {
168                    removeModesPortletId(portletId);
169                    setModeEdit(StringUtil.add(getModeEdit(), portletId));
170            }
171    
172            public void addModeHelpPortletId(String portletId) {
173                    removeModesPortletId(portletId);
174                    setModeHelp(StringUtil.add(getModeHelp(), portletId));
175            }
176    
177            public void addModePreviewPortletId(String portletId) {
178                    removeModesPortletId(portletId);
179                    setModePreview(StringUtil.add(getModePreview(), portletId));
180            }
181    
182            public void addModePrintPortletId(String portletId) {
183                    removeModesPortletId(portletId);
184                    setModePrint(StringUtil.add(getModePrint(), portletId));
185            }
186    
187            public String addPortletId(long userId, String portletId)
188                    throws PortalException, SystemException {
189    
190                    return addPortletId(userId, portletId, true);
191            }
192    
193            public String addPortletId(
194                            long userId, String portletId, boolean checkPermission)
195                    throws PortalException, SystemException {
196    
197                    return addPortletId(userId, portletId, null, -1, checkPermission);
198            }
199    
200            public String addPortletId(
201                            long userId, String portletId, String columnId, int columnPos)
202                    throws PortalException, SystemException {
203    
204                    return addPortletId(userId, portletId, columnId, columnPos, true);
205            }
206    
207            public String addPortletId(
208                            long userId, String portletId, String columnId, int columnPos,
209                            boolean checkPermission)
210                    throws PortalException, SystemException {
211    
212                    portletId = JS.getSafeName(portletId);
213    
214                    Layout layout = getLayout();
215    
216                    Portlet portlet = null;
217    
218                    try {
219                            portlet = PortletLocalServiceUtil.getPortletById(
220                                    layout.getCompanyId(), portletId);
221    
222                            if (portlet == null) {
223                                    if (_log.isWarnEnabled()) {
224                                            _log.warn(
225                                                    "Portlet " + portletId +
226                                                            " cannot be added because it is not registered");
227                                    }
228    
229                                    return null;
230                            }
231    
232                            PermissionChecker permissionChecker =
233                                    PermissionThreadLocal.getPermissionChecker();
234    
235                            if (checkPermission &&
236                                    !PortletPermissionUtil.contains(
237                                            permissionChecker, layout, portlet,
238                                            ActionKeys.ADD_TO_PAGE)) {
239    
240                                    return null;
241                            }
242                    }
243                    catch (Exception e) {
244                            _log.error(e, e);
245                    }
246    
247                    if (portlet.isSystem()) {
248                            return null;
249                    }
250    
251                    if ((portlet.isInstanceable()) &&
252                            (PortletConstants.getInstanceId(portlet.getPortletId()) == null)) {
253    
254                            portletId = portletId + getFullInstanceSeparator();
255                    }
256    
257                    if (hasPortletId(portletId)) {
258                            return null;
259                    }
260    
261                    if (columnId == null) {
262                            LayoutTemplate layoutTemplate = getLayoutTemplate();
263    
264                            List<String> columns = layoutTemplate.getColumns();
265    
266                            if (columns.size() > 0) {
267                                    columnId = columns.get(0);
268                            }
269                    }
270    
271                    if (columnId != null) {
272                            if (isCustomizable() && isColumnDisabled(columnId)) {
273                                    return null;
274                            }
275    
276                            String columnValue = StringPool.BLANK;
277    
278                            if (hasUserPreferences()) {
279                                    columnValue = getUserPreference(columnId);
280                            }
281                            else {
282                                    columnValue = getTypeSettingsProperties().getProperty(columnId);
283                            }
284    
285                            if ((columnValue == null) &&
286                                    (columnId.startsWith(_nestedPortletsNamespace))) {
287    
288                                    addNestedColumn(columnId);
289                            }
290    
291                            if (columnPos >= 0) {
292                                    List<String> portletIds = ListUtil.fromArray(
293                                            StringUtil.split(columnValue));
294    
295                                    if (columnPos <= portletIds.size()) {
296                                            portletIds.add(columnPos, portletId);
297                                    }
298                                    else {
299                                            portletIds.add(portletId);
300                                    }
301    
302                                    columnValue = StringUtil.merge(portletIds);
303                            }
304                            else {
305                                    columnValue = StringUtil.add(columnValue, portletId);
306                            }
307    
308                            if (hasUserPreferences()) {
309                                    setUserPreference(columnId, columnValue);
310                            }
311                            else {
312                                    getTypeSettingsProperties().setProperty(columnId, columnValue);
313                            }
314                    }
315    
316                    try {
317                            PortletLayoutListener portletLayoutListener =
318                                    portlet.getPortletLayoutListenerInstance();
319    
320                            if (_enablePortletLayoutListener &&
321                                    (portletLayoutListener != null)) {
322    
323                                    portletLayoutListener.onAddToLayout(
324                                            portletId, layout.getPlid());
325                            }
326                    }
327                    catch (Exception e) {
328                            _log.error("Unable to fire portlet layout listener event", e);
329                    }
330    
331                    return portletId;
332            }
333    
334            public void addPortletIds(
335                            long userId, String[] portletIds, boolean checkPermission)
336                    throws PortalException, SystemException {
337    
338                    for (String portletId : portletIds) {
339                            addPortletId(userId, portletId, checkPermission);
340                    }
341            }
342    
343            public void addPortletIds(
344                            long userId, String[] portletIds, String columnId,
345                            boolean checkPermission)
346                    throws PortalException, SystemException {
347    
348                    for (String portletId : portletIds) {
349                            addPortletId(userId, portletId, columnId, -1, checkPermission);
350                    }
351            }
352    
353            public void addStateMaxPortletId(String portletId) {
354                    removeStatesPortletId(portletId);
355                    //setStateMax(StringUtil.add(getStateMax(), portletId));
356                    setStateMax(StringUtil.add(StringPool.BLANK, portletId));
357            }
358    
359            public void addStateMinPortletId(String portletId) {
360                    removeStateMaxPortletId(portletId);
361                    setStateMin(StringUtil.add(getStateMin(), portletId));
362            }
363    
364            public List<Portlet> addStaticPortlets(
365                    List<Portlet> portlets, List<Portlet> startPortlets,
366                    List<Portlet> endPortlets) {
367    
368                    // Return the original array of portlets if no static portlets are
369                    // specified
370    
371                    if (startPortlets == null) {
372                            startPortlets = new ArrayList<Portlet>();
373                    }
374    
375                    if (endPortlets == null) {
376                            endPortlets = new ArrayList<Portlet>();
377                    }
378    
379                    if ((startPortlets.isEmpty()) && (endPortlets.isEmpty())) {
380                            return portlets;
381                    }
382    
383                    // New array of portlets that contain the static portlets
384    
385                    List<Portlet> list = new ArrayList<Portlet>(
386                            portlets.size() + startPortlets.size() + endPortlets.size());
387    
388                    if (!startPortlets.isEmpty()) {
389                            list.addAll(startPortlets);
390                    }
391    
392                    for (int i = 0; i < portlets.size(); i++) {
393                            Portlet portlet = portlets.get(i);
394    
395                            // Add the portlet if and only if it is not also a static portlet
396    
397                            if (!startPortlets.contains(portlet) &&
398                                    !endPortlets.contains(portlet)) {
399    
400                                    list.add(portlet);
401                            }
402                    }
403    
404                    if (!endPortlets.isEmpty()) {
405                            list.addAll(endPortlets);
406                    }
407    
408                    return list;
409            }
410    
411            public List<Portlet> getAllPortlets()
412                    throws PortalException, SystemException {
413    
414                    List<Portlet> portlets = new ArrayList<Portlet>();
415    
416                    List<String> columns = getColumns();
417    
418                    for (int i = 0; i < columns.size(); i++) {
419                            String columnId = columns.get(i);
420    
421                            portlets.addAll(getAllPortlets(columnId));
422                    }
423    
424                    List<Portlet> staticPortlets = getStaticPortlets(
425                            PropsKeys.LAYOUT_STATIC_PORTLETS_ALL);
426    
427                    return addStaticPortlets(portlets, staticPortlets, null);
428            }
429    
430            public List<Portlet> getAllPortlets(String columnId)
431                    throws PortalException, SystemException {
432    
433                    String columnValue = getColumnValue(columnId);
434    
435                    String[] portletIds = StringUtil.split(columnValue);
436    
437                    List<Portlet> portlets = new ArrayList<Portlet>(portletIds.length);
438    
439                    for (String portletId : portletIds) {
440                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
441                                    getCompanyId(), portletId);
442    
443                            if (portlet != null) {
444                                    portlets.add(portlet);
445                            }
446                    }
447    
448                    List<Portlet> startPortlets = getStaticPortlets(
449                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
450    
451                    List<Portlet> endPortlets = getStaticPortlets(
452                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
453    
454                    return addStaticPortlets(portlets, startPortlets, endPortlets);
455            }
456    
457            public LayoutTemplate getLayoutTemplate() {
458                    String themeId = getThemeId();
459    
460                    LayoutTemplate layoutTemplate =
461                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
462                                    getLayoutTemplateId(), false, themeId);
463    
464                    if (layoutTemplate == null) {
465                            layoutTemplate = new LayoutTemplateImpl(
466                                    StringPool.BLANK, StringPool.BLANK);
467    
468                            List<String> columns = new ArrayList<String>();
469    
470                            for (int i = 1; i <= 10; i++) {
471                                    columns.add("column-" + i);
472                            }
473    
474                            layoutTemplate.setColumns(columns);
475                    }
476    
477                    return layoutTemplate;
478            }
479    
480            public String getLayoutTemplateId() {
481                    String layoutTemplateId = StringPool.BLANK;
482    
483                    if (hasSourcePrototypeLayout()) {
484                            layoutTemplateId = getSourcePrototypeLayoutProperty(
485                                    LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
486                    }
487                    else {
488                            layoutTemplateId =
489                                    getTypeSettingsProperties().getProperty(
490                                            LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
491                    }
492    
493                    if (Validator.isNull(layoutTemplateId)) {
494                            layoutTemplateId = StringPool.BLANK;
495                    }
496    
497                    return layoutTemplateId;
498            }
499    
500            public String getModeAbout() {
501                    return getTypeSettingsProperties().getProperty(
502                            LayoutTypePortletConstants.MODE_ABOUT);
503            }
504    
505            public String getModeConfig() {
506                    return getTypeSettingsProperties().getProperty(
507                            LayoutTypePortletConstants.MODE_CONFIG);
508            }
509    
510            public String getModeEdit() {
511                    return getTypeSettingsProperties().getProperty(
512                            LayoutTypePortletConstants.MODE_EDIT);
513            }
514    
515            public String getModeEditDefaults() {
516                    return getTypeSettingsProperties().getProperty(
517                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS);
518            }
519    
520            public String getModeEditGuest() {
521                    return getTypeSettingsProperties().getProperty(
522                            LayoutTypePortletConstants.MODE_EDIT_GUEST);
523            }
524    
525            public String getModeHelp() {
526                    return getTypeSettingsProperties().getProperty(
527                            LayoutTypePortletConstants.MODE_HELP);
528            }
529    
530            public String getModePreview() {
531                    return getTypeSettingsProperties().getProperty(
532                            LayoutTypePortletConstants.MODE_PREVIEW);
533            }
534    
535            public String getModePrint() {
536                    return getTypeSettingsProperties().getProperty(
537                            LayoutTypePortletConstants.MODE_PRINT);
538            }
539    
540            public int getNumOfColumns() {
541                    return getLayoutTemplate().getColumns().size();
542            }
543    
544            public PortalPreferences getPortalPreferences() {
545                    return _portalPreferences;
546            }
547    
548            public List<String> getPortletIds() {
549                    List<String> portletIds = new ArrayList<String>();
550    
551                    List<String> columns = getColumns();
552    
553                    for (int i = 0; i < columns.size(); i++) {
554                            String columnId = columns.get(i);
555    
556                            String columnValue = getColumnValue(columnId);
557    
558                            portletIds.addAll(
559                                    ListUtil.fromArray(StringUtil.split(columnValue)));
560                    }
561    
562                    return portletIds;
563            }
564    
565            public List<Portlet> getPortlets() throws SystemException {
566                    List<String> portletIds = getPortletIds();
567    
568                    List<Portlet> portlets = new ArrayList<Portlet>(portletIds.size());
569    
570                    for (int i = 0; i < portletIds.size(); i++) {
571                            String portletId = portletIds.get(i);
572    
573                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
574                                    getCompanyId(), portletId);
575    
576                            if (portlet != null) {
577                                    portlets.add(portlet);
578                            }
579                    }
580    
581                    return portlets;
582            }
583    
584            public Layout getSourcePrototypeLayout() {
585                    return _sourcePrototypeLayout;
586            }
587    
588            public String getSourcePrototypeLayoutProperty(String key) {
589                    if (_sourcePrototypeLayout == null) {
590                            return StringPool.BLANK;
591                    }
592    
593                    UnicodeProperties typeSettingsProperties =
594                            _sourcePrototypeLayout.getTypeSettingsProperties();
595    
596                    return typeSettingsProperties.getProperty(key);
597            }
598    
599            public String getStateMax() {
600                    return getTypeSettingsProperties().getProperty(
601                            LayoutTypePortletConstants.STATE_MAX);
602            }
603    
604            public String getStateMaxPortletId() {
605                    String[] stateMax = StringUtil.split(getStateMax());
606    
607                    if (stateMax.length > 0) {
608                            return stateMax[0];
609                    }
610                    else {
611                            return StringPool.BLANK;
612                    }
613            }
614    
615            public String getStateMin() {
616                    return getTypeSettingsProperties().getProperty(
617                            LayoutTypePortletConstants.STATE_MIN);
618            }
619    
620            public boolean hasDefaultScopePortletId(long groupId, String portletId)
621                    throws PortalException, SystemException {
622    
623                    if (hasPortletId(portletId)) {
624                            long scopeGroupId = PortalUtil.getScopeGroupId(
625                                    getLayout(), portletId);
626    
627                            if (groupId == scopeGroupId) {
628                                    return true;
629                            }
630                    }
631    
632                    return false;
633            }
634    
635            public boolean hasModeAboutPortletId(String portletId) {
636                    return StringUtil.contains(getModeAbout(), portletId);
637            }
638    
639            public boolean hasModeConfigPortletId(String portletId) {
640                    return StringUtil.contains(getModeConfig(), portletId);
641            }
642    
643            public boolean hasModeEditDefaultsPortletId(String portletId) {
644                    return StringUtil.contains(getModeEditDefaults(), portletId);
645            }
646    
647            public boolean hasModeEditGuestPortletId(String portletId) {
648                    return StringUtil.contains(getModeEditGuest(), portletId);
649            }
650    
651            public boolean hasModeEditPortletId(String portletId) {
652                    return StringUtil.contains(getModeEdit(), portletId);
653            }
654    
655            public boolean hasModeHelpPortletId(String portletId) {
656                    return StringUtil.contains(getModeHelp(), portletId);
657            }
658    
659            public boolean hasModePreviewPortletId(String portletId) {
660                    return StringUtil.contains(getModePreview(), portletId);
661            }
662    
663            public boolean hasModePrintPortletId(String portletId) {
664                    return StringUtil.contains(getModePrint(), portletId);
665            }
666    
667            public boolean hasModeViewPortletId(String portletId) {
668                    if (hasModeAboutPortletId(portletId) ||
669                            hasModeConfigPortletId(portletId) ||
670                            hasModeEditPortletId(portletId) ||
671                            hasModeEditDefaultsPortletId(portletId) ||
672                            hasModeEditGuestPortletId(portletId) ||
673                            hasModeHelpPortletId(portletId) ||
674                            hasModePreviewPortletId(portletId) ||
675                            hasModePrintPortletId(portletId)) {
676    
677                            return false;
678                    }
679                    else {
680                            return true;
681                    }
682            }
683    
684            public boolean hasPortletId(String portletId)
685                    throws PortalException, SystemException {
686    
687                    List<String> columns = getColumns();
688    
689                    for (String columnId : columns) {
690                            if (hasNonstaticPortletId(columnId, portletId)) {
691                                    return true;
692                            }
693    
694                            if (hasStaticPortletId(columnId, portletId)) {
695                                    return true;
696                            }
697                    }
698    
699                    Layout layout = getLayout();
700    
701                    if (layout.isTypeControlPanel() || layout.isTypePanel()) {
702                            return true;
703                    }
704    
705                    return false;
706            }
707    
708            public boolean hasSourcePrototypeLayout() {
709                    if (_sourcePrototypeLayout != null) {
710                            return true;
711                    }
712    
713                    return false;
714            }
715    
716            public boolean hasStateMax() {
717                    String[] stateMax = StringUtil.split(getStateMax());
718    
719                    if (stateMax.length > 0) {
720                            return true;
721                    }
722                    else {
723                            return false;
724                    }
725            }
726    
727            public boolean hasStateMaxPortletId(String portletId) {
728                    if (StringUtil.contains(getStateMax(), portletId)) {
729                            return true;
730                    }
731                    else {
732                            return false;
733                    }
734            }
735    
736            public boolean hasStateMin() {
737                    String[] stateMin = StringUtil.split(getStateMin());
738    
739                    if (stateMin.length > 0) {
740                            return true;
741                    }
742                    else {
743                            return false;
744                    }
745            }
746    
747            public boolean hasStateMinPortletId(String portletId) {
748                    if (StringUtil.contains(getStateMin(), portletId)) {
749                            return true;
750                    }
751                    else {
752                            return false;
753                    }
754            }
755    
756            public boolean hasStateNormalPortletId(String portletId) {
757                    if (hasStateMaxPortletId(portletId) ||
758                            hasStateMinPortletId(portletId)) {
759    
760                            return false;
761                    }
762                    else {
763                            return true;
764                    }
765            }
766    
767            public boolean hasUpdatePermission() {
768                    return _updatePermission;
769            }
770    
771            public boolean isColumnCustomizable(String columnId) {
772                    if (!isLayoutSetPrototype() && isTemplateCustomizable(columnId)) {
773                            String customizableString =
774                                    getTypeSettingsProperties().getProperty(
775                                            CustomizedPages.namespaceColumnId(columnId));
776    
777                            boolean customizable = GetterUtil.getBoolean(customizableString);
778    
779                            if (!customizable && hasUserPreferences()) {
780                                    String columnValue = _portalPreferences.getValue(
781                                            CustomizedPages.namespacePlid(getPlid()), columnId,
782                                            StringPool.NULL);
783    
784                                    if (!Validator.equals(columnValue, StringPool.NULL)) {
785                                            setUserPreference(columnId, null);
786                                    }
787                            }
788    
789                            return customizable;
790                    }
791    
792                    return false;
793            }
794    
795            public boolean isColumnDisabled(String columnId) {
796                    if (!isTemplateCustomizable(columnId) ||
797                            (isCustomizedView() && !isColumnCustomizable(columnId)) ||
798                            (!isCustomizedView() && !hasUpdatePermission())) {
799    
800                            return true;
801                    }
802    
803                    return false;
804            }
805    
806            public boolean isCustomizable() {
807                    for (String columnId : getColumns()) {
808                            if (isColumnCustomizable(columnId)) {
809                                    return true;
810                            }
811                    }
812    
813                    return false;
814            }
815    
816            public boolean isCustomizedView() {
817                    return _customizedView;
818            }
819    
820            public boolean isDefaultUpdated() {
821                    if (!isCustomizedView() || !hasUserPreferences()) {
822                            return false;
823                    }
824    
825                    String preferencesModifiedDateString = _portalPreferences.getValue(
826                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
827                            _NULL_DATE);
828    
829                    DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
830                            PropsValues.INDEX_DATE_FORMAT_PATTERN);
831    
832                    try {
833                            Date preferencesModifiedDate = dateFormat.parse(
834                                    preferencesModifiedDateString);
835    
836                            if (hasSourcePrototypeLayout()) {
837                                    String propertiesModifiedDateString =
838                                            _sourcePrototypeLayout.getTypeSettingsProperties().
839                                                    getProperty(_MODIFIED_DATE, _NULL_DATE);
840    
841                                    Date propertiesModifiedDate = dateFormat.parse(
842                                            propertiesModifiedDateString);
843    
844                                    return propertiesModifiedDate.after(preferencesModifiedDate);
845                            }
846                            else {
847                                    Layout layout = getLayout();
848    
849                                    String propertiesModifiedDateString =
850                                            layout.getTypeSettingsProperties().getProperty(
851                                                    _MODIFIED_DATE, _NULL_DATE);
852    
853                                    Date propertiesModifiedDate = dateFormat.parse(
854                                            propertiesModifiedDateString);
855    
856                                    return propertiesModifiedDate.after(preferencesModifiedDate);
857                            }
858                    }
859                    catch (Exception e) {
860                            _log.error(e, e);
861                    }
862    
863                    return false;
864            }
865    
866            public boolean isPortletCustomizable(String portletId) {
867                    return isColumnCustomizable(getColumn(portletId));
868            }
869    
870            public boolean isTemplateCustomizable(String columnId) {
871                    if (!hasSourcePrototypeLayout()) {
872                            return true;
873                    }
874    
875                    String customizable = getSourcePrototypeLayoutProperty(
876                            CustomizedPages.namespaceColumnId(columnId));
877    
878                    return GetterUtil.getBoolean(customizable, false);
879            }
880    
881            public void movePortletId(
882                            long userId, String portletId, String columnId, int columnPos)
883                    throws PortalException, SystemException {
884    
885                    _enablePortletLayoutListener = false;
886    
887                    try {
888                            removePortletId(userId, portletId, false);
889                            addPortletId(userId, portletId, columnId, columnPos, false);
890                    }
891                    finally {
892                            _enablePortletLayoutListener = true;
893                    }
894    
895                    Layout layout = getLayout();
896    
897                    try {
898                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
899                                    layout.getCompanyId(), portletId);
900    
901                            if (portlet != null) {
902                                    PortletLayoutListener portletLayoutListener =
903                                            portlet.getPortletLayoutListenerInstance();
904    
905                                    if (portletLayoutListener != null) {
906                                            portletLayoutListener.onMoveInLayout(
907                                                    portletId, layout.getPlid());
908                                    }
909                            }
910                    }
911                    catch (Exception e) {
912                            _log.error("Unable to fire portlet layout listener event", e);
913                    }
914            }
915    
916            public void removeModeAboutPortletId(String portletId) {
917                    setModeAbout(StringUtil.remove(getModeAbout(), portletId));
918            }
919    
920            public void removeModeConfigPortletId(String portletId) {
921                    setModeConfig(StringUtil.remove(getModeConfig(), portletId));
922            }
923    
924            public void removeModeEditDefaultsPortletId(String portletId) {
925                    setModeEditDefaults(
926                            StringUtil.remove(getModeEditDefaults(), portletId));
927            }
928    
929            public void removeModeEditGuestPortletId(String portletId) {
930                    setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
931            }
932    
933            public void removeModeEditPortletId(String portletId) {
934                    setModeEdit(StringUtil.remove(getModeEdit(), portletId));
935            }
936    
937            public void removeModeHelpPortletId(String portletId) {
938                    setModeHelp(StringUtil.remove(getModeHelp(), portletId));
939            }
940    
941            public void removeModePreviewPortletId(String portletId) {
942                    setModePreview(StringUtil.remove(getModePreview(), portletId));
943            }
944    
945            public void removeModePrintPortletId(String portletId) {
946                    setModePrint(StringUtil.remove(getModePrint(), portletId));
947            }
948    
949            public void removeModesPortletId(String portletId) {
950                    removeModeAboutPortletId(portletId);
951                    removeModeConfigPortletId(portletId);
952                    removeModeEditPortletId(portletId);
953                    removeModeEditDefaultsPortletId(portletId);
954                    removeModeEditGuestPortletId(portletId);
955                    removeModeHelpPortletId(portletId);
956                    removeModePreviewPortletId(portletId);
957                    removeModePrintPortletId(portletId);
958            }
959    
960            public void removeNestedColumns(String portletNamespace) {
961                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
962    
963                    UnicodeProperties newTypeSettingsProperties = new UnicodeProperties();
964    
965                    for (Map.Entry<String, String> entry :
966                                    typeSettingsProperties.entrySet()) {
967    
968                            String key = entry.getKey();
969    
970                            if (!key.startsWith(portletNamespace)) {
971                                    newTypeSettingsProperties.setProperty(key, entry.getValue());
972                            }
973                    }
974    
975                    Layout layout = getLayout();
976    
977                    layout.setTypeSettingsProperties(newTypeSettingsProperties);
978    
979                    String nestedColumnIds = GetterUtil.getString(
980                            getTypeSettingsProperties().getProperty(
981                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS));
982    
983                    String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
984                            StringUtil.split(nestedColumnIds), portletNamespace);
985    
986                    getTypeSettingsProperties().setProperty(
987                            LayoutTypePortletConstants.NESTED_COLUMN_IDS,
988                            StringUtil.merge(nestedColumnIdsArray));
989            }
990    
991            public void removePortletId(long userId, String portletId) {
992                    removePortletId(userId, portletId, true);
993            }
994    
995            public void removePortletId(
996                    long userId, String portletId, boolean cleanUp) {
997    
998                    try {
999                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1000                                    getCompanyId(), portletId);
1001    
1002                            if (portlet == null) {
1003                                    _log.error(
1004                                            "Portlet " + portletId +
1005                                                    " cannot be removed because it is not registered");
1006    
1007                                    return;
1008                            }
1009    
1010                            PermissionChecker permissionChecker =
1011                                    PermissionThreadLocal.getPermissionChecker();
1012    
1013                            if (!LayoutPermissionUtil.contains(
1014                                            permissionChecker, getLayout(), ActionKeys.UPDATE) &&
1015                                    !isCustomizable()) {
1016    
1017                                    return;
1018                            }
1019                    }
1020                    catch (Exception e) {
1021                            _log.error(e, e);
1022                    }
1023    
1024                    List<String> columns = getColumns();
1025    
1026                    for (int i = 0; i < columns.size(); i++) {
1027                            String columnId = columns.get(i);
1028    
1029                            if (isCustomizable() && isColumnDisabled(columnId)) {
1030                                    continue;
1031                            }
1032    
1033                            String columnValue = StringPool.BLANK;
1034    
1035                            if (hasUserPreferences()) {
1036                                    columnValue = getUserPreference(columnId);
1037                            }
1038                            else {
1039                                    columnValue = getTypeSettingsProperties().getProperty(columnId);
1040                            }
1041    
1042                            columnValue = StringUtil.remove(columnValue, portletId);
1043    
1044                            if (hasUserPreferences()) {
1045                                    setUserPreference(columnId, columnValue);
1046    
1047                                    try {
1048                                            String rootPortletId = PortletConstants.getRootPortletId(
1049                                                    portletId);
1050    
1051                                            ResourceLocalServiceUtil.deleteResource(
1052                                                    getCompanyId(), rootPortletId,
1053                                                    ResourceConstants.SCOPE_INDIVIDUAL,
1054                                                    PortletPermissionUtil.getPrimaryKey(
1055                                                            getPlid(), portletId));
1056                                    }
1057                                    catch (Exception e) {
1058                                    }
1059                            }
1060                            else {
1061                                    getTypeSettingsProperties().setProperty(columnId, columnValue);
1062                            }
1063                    }
1064    
1065                    if (cleanUp) {
1066                            removeStatesPortletId(portletId);
1067                            removeModesPortletId(portletId);
1068    
1069                            try {
1070                                    onRemoveFromLayout(portletId);
1071                            }
1072                            catch (Exception e) {
1073                                    _log.error("Unable to fire portlet layout listener event", e);
1074                            }
1075                    }
1076            }
1077    
1078            public void removeStateMaxPortletId(String portletId) {
1079                    setStateMax(StringUtil.remove(getStateMax(), portletId));
1080            }
1081    
1082            public void removeStateMinPortletId(String portletId) {
1083                    setStateMin(StringUtil.remove(getStateMin(), portletId));
1084            }
1085    
1086            public void removeStatesPortletId(String portletId) {
1087                    removeStateMaxPortletId(portletId);
1088                    removeStateMinPortletId(portletId);
1089            }
1090    
1091            public void reorganizePortlets(
1092                    List<String> newColumns, List<String> oldColumns) {
1093    
1094                    String lastNewColumnId = newColumns.get(newColumns.size() - 1);
1095                    String lastNewColumnValue =
1096                            getTypeSettingsProperties().getProperty(lastNewColumnId);
1097    
1098                    Iterator<String> itr = oldColumns.iterator();
1099    
1100                    while (itr.hasNext()) {
1101                            String oldColumnId = itr.next();
1102    
1103                            if (!newColumns.contains(oldColumnId)) {
1104                                    String oldColumnValue = getTypeSettingsProperties().remove(
1105                                            oldColumnId);
1106    
1107                                    String[] portletIds = StringUtil.split(oldColumnValue);
1108    
1109                                    for (String portletId : portletIds) {
1110                                            lastNewColumnValue = StringUtil.add(
1111                                                    lastNewColumnValue, portletId);
1112                                    }
1113                            }
1114                    }
1115    
1116                    getTypeSettingsProperties().setProperty(
1117                            lastNewColumnId, lastNewColumnValue);
1118            }
1119    
1120            public void resetModes() {
1121                    setModeAbout(StringPool.BLANK);
1122                    setModeConfig(StringPool.BLANK);
1123                    setModeEdit(StringPool.BLANK);
1124                    setModeEditDefaults(StringPool.BLANK);
1125                    setModeEditGuest(StringPool.BLANK);
1126                    setModeHelp(StringPool.BLANK);
1127                    setModePreview(StringPool.BLANK);
1128                    setModePrint(StringPool.BLANK);
1129            }
1130    
1131            public void resetStates() {
1132                    setStateMax(StringPool.BLANK);
1133                    setStateMin(StringPool.BLANK);
1134            }
1135    
1136            public void resetUserPreferences() {
1137                    if (hasUserPreferences()) {
1138                            Layout layout = getLayout();
1139    
1140                            long plid = layout.getPlid();
1141    
1142                            _portalPreferences.resetValues(CustomizedPages.namespacePlid(plid));
1143    
1144                            _portalPreferences.setValue(
1145                                    CustomizedPages.namespacePlid(plid), _MODIFIED_DATE,
1146                                    _dateFormat.format(new Date()));
1147                    }
1148            }
1149    
1150            public void setCustomizedView(boolean customizedView) {
1151                    _customizedView = customizedView;
1152            }
1153    
1154            public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
1155                    setLayoutTemplateId(userId, newLayoutTemplateId, true);
1156            }
1157    
1158            public void setLayoutTemplateId(
1159                    long userId, String newLayoutTemplateId, boolean checkPermission) {
1160    
1161                    if (checkPermission &&
1162                            !PluginSettingLocalServiceUtil.hasPermission(
1163                                    userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
1164    
1165                            return;
1166                    }
1167    
1168                    String oldLayoutTemplateId = getLayoutTemplateId();
1169    
1170                    if (Validator.isNull(oldLayoutTemplateId)) {
1171                            oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
1172                    }
1173    
1174                    getTypeSettingsProperties().setProperty(
1175                            LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
1176    
1177                    String themeId = getThemeId();
1178    
1179                    LayoutTemplate oldLayoutTemplate =
1180                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1181                                    oldLayoutTemplateId, false, themeId);
1182    
1183                    if (oldLayoutTemplate == null) {
1184                            return;
1185                    }
1186    
1187                    LayoutTemplate newLayoutTemplate =
1188                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1189                                    newLayoutTemplateId, false, themeId);
1190    
1191                    List<String> oldColumns = oldLayoutTemplate.getColumns();
1192                    List<String> newColumns = newLayoutTemplate.getColumns();
1193    
1194                    reorganizePortlets(newColumns, oldColumns);
1195            }
1196    
1197            public void setModeAbout(String modeAbout) {
1198                    getTypeSettingsProperties().setProperty(
1199                            LayoutTypePortletConstants.MODE_ABOUT, modeAbout);
1200            }
1201    
1202            public void setModeConfig(String modeConfig) {
1203                    getTypeSettingsProperties().setProperty(
1204                            LayoutTypePortletConstants.MODE_CONFIG, modeConfig);
1205            }
1206    
1207            public void setModeEdit(String modeEdit) {
1208                    getTypeSettingsProperties().setProperty(
1209                            LayoutTypePortletConstants.MODE_EDIT, modeEdit);
1210            }
1211    
1212            public void setModeEditDefaults(String modeEditDefaults) {
1213                    getTypeSettingsProperties().setProperty(
1214                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS, modeEditDefaults);
1215            }
1216    
1217            public void setModeEditGuest(String modeEditGuest) {
1218                    getTypeSettingsProperties().setProperty(
1219                            LayoutTypePortletConstants.MODE_EDIT_GUEST, modeEditGuest);
1220            }
1221    
1222            public void setModeHelp(String modeHelp) {
1223                    getTypeSettingsProperties().setProperty(
1224                            LayoutTypePortletConstants.MODE_HELP, modeHelp);
1225            }
1226    
1227            public void setModePreview(String modePreview) {
1228                    getTypeSettingsProperties().setProperty(
1229                            LayoutTypePortletConstants.MODE_PREVIEW, modePreview);
1230            }
1231    
1232            public void setModePrint(String modePrint) {
1233                    getTypeSettingsProperties().setProperty(
1234                            LayoutTypePortletConstants.MODE_PRINT, modePrint);
1235            }
1236    
1237            public void setPortalPreferences(PortalPreferences portalPreferences) {
1238                    _portalPreferences = portalPreferences;
1239            }
1240    
1241            public void setPortletIds(String columnId, String portletIds) {
1242                    getTypeSettingsProperties().setProperty(columnId, portletIds);
1243            }
1244    
1245            public void setStateMax(String stateMax) {
1246                    getTypeSettingsProperties().setProperty(
1247                            LayoutTypePortletConstants.STATE_MAX, stateMax);
1248            }
1249    
1250            public void setStateMin(String stateMin) {
1251                    getTypeSettingsProperties().setProperty(
1252                            LayoutTypePortletConstants.STATE_MIN, stateMin);
1253            }
1254    
1255            public void setUpdatePermission(boolean updatePermission) {
1256                    _updatePermission = updatePermission;
1257            }
1258    
1259            protected void addNestedColumn(String columnId) {
1260                    String nestedColumnIds = getTypeSettingsProperties().getProperty(
1261                            LayoutTypePortletConstants.NESTED_COLUMN_IDS, StringPool.BLANK);
1262    
1263                    if (nestedColumnIds.indexOf(columnId) == -1) {
1264                            nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
1265    
1266                            getTypeSettingsProperties().setProperty(
1267                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS, nestedColumnIds);
1268                    }
1269            }
1270    
1271            protected void copyPreferences(
1272                    String sourcePortletId, String targetPortletId) {
1273    
1274                    Layout layout = getLayout();
1275    
1276                    PermissionChecker permissionChecker =
1277                            PermissionThreadLocal.getPermissionChecker();
1278    
1279                    try {
1280                            PortletPreferencesIds portletPreferencesIds =
1281                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1282                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1283                                            sourcePortletId, false);
1284    
1285                            javax.portlet.PortletPreferences sourcePortletPreferences =
1286                                    PortletPreferencesLocalServiceUtil.getPreferences(
1287                                            portletPreferencesIds);
1288    
1289                            portletPreferencesIds =
1290                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1291                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1292                                            targetPortletId, false);
1293    
1294                            PortletPreferencesLocalServiceUtil.updatePreferences(
1295                                    portletPreferencesIds.getOwnerId(),
1296                                    portletPreferencesIds.getOwnerType(),
1297                                    portletPreferencesIds.getPlid(),
1298                                    portletPreferencesIds.getPortletId(), sourcePortletPreferences);
1299                    }
1300                    catch (Exception e) {
1301                    }
1302            }
1303    
1304            protected void deletePortletSetup(String portletId) {
1305                    try {
1306                            List<PortletPreferences> portletPreferencesList =
1307                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
1308                                            getPlid(), portletId);
1309    
1310                            for (PortletPreferences portletPreferences :
1311                                            portletPreferencesList) {
1312    
1313                                    PortletPreferencesLocalServiceUtil.deletePortletPreferences(
1314                                            portletPreferences.getPortletPreferencesId());
1315                            }
1316                    }
1317                    catch (Exception e) {
1318                            _log.error(e, e);
1319                    }
1320            }
1321    
1322            protected String getColumn(String portletId) {
1323                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
1324    
1325                    List<String> columns = getColumns();
1326    
1327                    for (String columnId : columns) {
1328                            String columnValue = getColumnValue(columnId);
1329    
1330                            String[] portletIds = StringUtil.split(columnValue);
1331    
1332                            for (String columnPortletId : portletIds) {
1333                                    if (portletId.equals(columnPortletId) ||
1334                                            (portletId.equals(rootPortletId) &&
1335                                             columnPortletId.startsWith(rootPortletId))) {
1336    
1337                                            return columnId;
1338                                    }
1339                            }
1340                    }
1341    
1342                    return StringPool.BLANK;
1343            }
1344    
1345            protected List<String> getColumns() {
1346                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1347    
1348                    List<String> columns = new ArrayList<String>();
1349    
1350                    columns.addAll(layoutTemplate.getColumns());
1351                    columns.addAll(getNestedColumns());
1352    
1353                    return columns;
1354            }
1355    
1356            protected String getColumnValue(String columnId) {
1357                    Boolean customizable = null;
1358                    Boolean columnDisabled = null;
1359    
1360                    if (hasSourcePrototypeLayout()) {
1361                            customizable = isCustomizable();
1362    
1363                            if (customizable) {
1364                                    columnDisabled = isColumnDisabled(columnId);
1365    
1366                                    if (columnDisabled) {
1367                                            return getSourcePrototypeLayoutProperty(columnId);
1368                                    }
1369                            }
1370                    }
1371    
1372                    if (hasUserPreferences() &&
1373                            ((customizable == null) ? isCustomizable() : customizable) &&
1374                            ((columnDisabled == null) ?
1375                                    !isColumnDisabled(columnId) : !columnDisabled)) {
1376    
1377                            return getUserPreference(columnId);
1378                    }
1379    
1380                    return getTypeSettingsProperties().getProperty(columnId);
1381            }
1382    
1383            protected long getCompanyId() {
1384                    Layout layout = getLayout();
1385    
1386                    return layout.getCompanyId();
1387            }
1388    
1389            protected List<String> getNestedColumns() {
1390                    String nestedColumnIds = getTypeSettingsProperties().getProperty(
1391                            LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1392    
1393                    return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
1394            }
1395    
1396            protected long getPlid() {
1397                    Layout layout = getLayout();
1398    
1399                    return layout.getPlid();
1400            }
1401    
1402            protected String[] getStaticPortletIds(String position)
1403                    throws PortalException, SystemException {
1404    
1405                    Layout layout = getLayout();
1406    
1407                    if (hasSourcePrototypeLayout()) {
1408                            layout = _sourcePrototypeLayout;
1409                    }
1410    
1411                    String selector1 = StringPool.BLANK;
1412    
1413                    Group group = layout.getGroup();
1414    
1415                    if (group.isUser()) {
1416                            selector1 = LayoutTypePortletConstants.STATIC_PORTLET_USER_SELECTOR;
1417                    }
1418                    else if (group.isOrganization()) {
1419                            selector1 =
1420                                    LayoutTypePortletConstants.STATIC_PORTLET_ORGANIZATION_SELECTOR;
1421                    }
1422                    else if (group.isRegularSite()) {
1423                            selector1 =
1424                                    LayoutTypePortletConstants.STATIC_PORTLET_REGULAR_SITE_SELECTOR;
1425                    }
1426    
1427                    String selector2 = layout.getFriendlyURL();
1428    
1429                    String[] portletIds = PropsUtil.getArray(
1430                            position, new Filter(selector1, selector2));
1431    
1432                    for (int i = 0; i < portletIds.length; i++) {
1433                            portletIds[i] = JS.getSafeName(portletIds[i]);
1434                    }
1435    
1436                    return portletIds;
1437            }
1438    
1439            protected List<Portlet> getStaticPortlets(String position)
1440                    throws PortalException, SystemException {
1441    
1442                    String[] portletIds = getStaticPortletIds(position);
1443    
1444                    List<Portlet> portlets = new ArrayList<Portlet>();
1445    
1446                    for (String portletId : portletIds) {
1447                            if (Validator.isNull(portletId) ||
1448                                    hasNonstaticPortletId(portletId)) {
1449    
1450                                    continue;
1451                            }
1452    
1453                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1454                                    getCompanyId(), portletId);
1455    
1456                            if (portlet != null) {
1457                                    Portlet staticPortlet = portlet;
1458    
1459                                    if (portlet.isInstanceable()) {
1460    
1461                                            // Instanceable portlets do not need to be cloned because
1462                                            // they are already cloned. See the method getPortletById in
1463                                            // the class PortletLocalServiceImpl and how it references
1464                                            // the method getClonedInstance in the class PortletImpl.
1465    
1466                                    }
1467                                    else {
1468                                            staticPortlet = (Portlet)staticPortlet.clone();
1469                                    }
1470    
1471                                    staticPortlet.setStatic(true);
1472    
1473                                    if (position.startsWith("layout.static.portlets.start")) {
1474                                            staticPortlet.setStaticStart(true);
1475                                    }
1476    
1477                                    portlets.add(staticPortlet);
1478                            }
1479                    }
1480    
1481                    return portlets;
1482            }
1483    
1484            protected String getThemeId() {
1485                    String themeId = null;
1486    
1487                    try {
1488                            Layout layout = getLayout();
1489    
1490                            Theme theme = layout.getTheme();
1491    
1492                            if (theme != null) {
1493                                    themeId = theme.getThemeId();
1494                            }
1495                            else {
1496                                    themeId = layout.getThemeId();
1497                            }
1498                    }
1499                    catch (Exception e) {
1500                            _log.error(e, e);
1501                    }
1502    
1503                    return themeId;
1504            }
1505    
1506            protected String getUserPreference(String key) {
1507                    String value = StringPool.BLANK;
1508    
1509                    if (!hasUserPreferences()) {
1510                            return value;
1511                    }
1512    
1513                    value = _portalPreferences.getValue(
1514                            CustomizedPages.namespacePlid(getPlid()), key, StringPool.NULL);
1515    
1516                    if (!value.equals(StringPool.NULL)) {
1517                            return value;
1518                    }
1519    
1520                    if (hasSourcePrototypeLayout()) {
1521                            value = getSourcePrototypeLayoutProperty(key);
1522                    }
1523                    else {
1524                            value = getTypeSettingsProperties().getProperty(key);
1525                    }
1526    
1527                    if (Validator.isNull(value)) {
1528                            return value;
1529                    }
1530    
1531                    String[] portletIds = StringUtil.split(value);
1532    
1533                    String[] newPortletIds = new String[portletIds.length];
1534    
1535                    for (int i = 0; i < portletIds.length; i++) {
1536                            if (portletIds[i].contains(PortletConstants.INSTANCE_SEPARATOR)) {
1537                                    String rootPortletId = PortletConstants.getRootPortletId(
1538                                            portletIds[i]);
1539    
1540                                    newPortletIds[i] = rootPortletId + getFullInstanceSeparator();
1541    
1542                                    copyPreferences(portletIds[i], newPortletIds[i]);
1543                            }
1544                            else {
1545                                    newPortletIds[i] = portletIds[i];
1546                            }
1547                    }
1548    
1549                    value = StringUtil.merge(newPortletIds);
1550    
1551                    setUserPreference(key, value);
1552    
1553                    return value;
1554            }
1555    
1556            protected boolean hasNonstaticPortletId(String portletId) {
1557                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1558    
1559                    List<String> columns = layoutTemplate.getColumns();
1560    
1561                    for (int i = 0; i < columns.size(); i++) {
1562                            String columnId = columns.get(i);
1563    
1564                            if (hasNonstaticPortletId(columnId, portletId)) {
1565                                    return true;
1566                            }
1567                    }
1568    
1569                    return false;
1570            }
1571    
1572            protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1573                    String columnValue = getColumnValue(columnId);
1574    
1575                    String[] columnValues = StringUtil.split(columnValue);
1576    
1577                    for (String nonstaticPortletId : columnValues) {
1578                            if (nonstaticPortletId.equals(portletId) ||
1579                                    nonstaticPortletId.startsWith(
1580                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1581    
1582                                    return true;
1583                            }
1584                    }
1585    
1586                    return false;
1587            }
1588    
1589            protected boolean hasStaticPortletId(String columnId, String portletId)
1590                    throws PortalException, SystemException {
1591    
1592                    String[] staticPortletIdsStart = getStaticPortletIds(
1593                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1594    
1595                    String[] staticPortletIdsEnd = getStaticPortletIds(
1596                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1597    
1598                    for (String staticPortletId : staticPortletIdsStart) {
1599                            if (staticPortletId.equals(portletId) ||
1600                                    staticPortletId.startsWith(
1601                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1602    
1603                                    return true;
1604                            }
1605                    }
1606    
1607                    for (String staticPortletId : staticPortletIdsEnd) {
1608                            if (staticPortletId.equals(portletId) ||
1609                                    staticPortletId.startsWith(
1610                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1611    
1612                                    return true;
1613                            }
1614                    }
1615    
1616                    return false;
1617            }
1618    
1619            protected boolean hasUserPreferences() {
1620                    if (_portalPreferences != null) {
1621                            return true;
1622                    }
1623    
1624                    return false;
1625            }
1626    
1627            protected boolean isLayoutSetPrototype() {
1628                    try {
1629                            Layout layout = getLayout();
1630    
1631                            LayoutSet layoutSet = layout.getLayoutSet();
1632    
1633                            Group group = layoutSet.getGroup();
1634    
1635                            return group.isLayoutSetPrototype();
1636                    }
1637                    catch (Exception e) {
1638                            _log.error(e, e);
1639                    }
1640    
1641                    return false;
1642            }
1643    
1644            protected void onRemoveFromLayout(String portletId) throws SystemException {
1645                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1646                            getCompanyId(), portletId);
1647    
1648                    if (portlet == null) {
1649                            return;
1650                    }
1651    
1652                    if (portlet.getRootPortletId().equals(PortletKeys.NESTED_PORTLETS)) {
1653                            String portletNamespace = PortalUtil.getPortletNamespace(portletId);
1654    
1655                            UnicodeProperties typeSettingsProperties =
1656                                    getTypeSettingsProperties();
1657    
1658                            for (Map.Entry<String, String> entry :
1659                                            typeSettingsProperties.entrySet()) {
1660    
1661                                    String key = entry.getKey();
1662    
1663                                    if (key.startsWith(portletNamespace)) {
1664                                            String portletIds = entry.getValue();
1665    
1666                                            String[] portletIdsArray = StringUtil.split(portletIds);
1667    
1668                                            for (String curPortletId : portletIdsArray) {
1669                                                    onRemoveFromLayout(curPortletId);
1670                                            }
1671                                    }
1672                            }
1673    
1674                            removeNestedColumns(portletNamespace);
1675                    }
1676    
1677                    if (_enablePortletLayoutListener) {
1678                            PortletLayoutListener portletLayoutListener =
1679                                    portlet.getPortletLayoutListenerInstance();
1680    
1681                            if ((portletLayoutListener != null)) {
1682                                    portletLayoutListener.onRemoveFromLayout(portletId, getPlid());
1683                            }
1684                    }
1685    
1686                    deletePortletSetup(portletId);
1687            }
1688    
1689            protected void setUserPreference(String key, String value) {
1690                    if (!hasUserPreferences()) {
1691                            return;
1692                    }
1693    
1694                    _portalPreferences.setValue(
1695                            CustomizedPages.namespacePlid(getPlid()), key, value);
1696    
1697                    _portalPreferences.setValue(
1698                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
1699                            _dateFormat.format(new Date()));
1700            }
1701    
1702            private static final String _MODIFIED_DATE = "modifiedDate";
1703    
1704            private static final String _NULL_DATE = "00000000000000";
1705    
1706            private static Log _log = LogFactoryUtil.getLog(
1707                    LayoutTypePortletImpl.class);
1708    
1709            private static String _nestedPortletsNamespace;
1710    
1711            private boolean _customizedView;
1712            private Format _dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
1713                    PropsValues.INDEX_DATE_FORMAT_PATTERN);
1714            private boolean _enablePortletLayoutListener = true;
1715            private PortalPreferences _portalPreferences;
1716            private Layout _sourcePrototypeLayout;
1717            private boolean _updatePermission;
1718    
1719    }