001    /**
002     * Copyright (c) 2000-2012 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 (layout.isLayoutPrototypeLinkActive()) {
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 (!layoutSet.isLayoutSetPrototypeLinkActive()) {
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 = getTypeSettingsProperty(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                                    setTypeSettingsProperty(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 = getTypeSettingsProperty(
489                                    LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
490                    }
491    
492                    if (Validator.isNull(layoutTemplateId)) {
493                            layoutTemplateId = StringPool.BLANK;
494                    }
495    
496                    return layoutTemplateId;
497            }
498    
499            public String getModeAbout() {
500                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_ABOUT);
501            }
502    
503            public String getModeConfig() {
504                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_CONFIG);
505            }
506    
507            public String getModeEdit() {
508                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_EDIT);
509            }
510    
511            public String getModeEditDefaults() {
512                    return getTypeSettingsProperty(
513                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS);
514            }
515    
516            public String getModeEditGuest() {
517                    return getTypeSettingsProperty(
518                            LayoutTypePortletConstants.MODE_EDIT_GUEST);
519            }
520    
521            public String getModeHelp() {
522                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_HELP);
523            }
524    
525            public String getModePreview() {
526                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_PREVIEW);
527            }
528    
529            public String getModePrint() {
530                    return getTypeSettingsProperty(LayoutTypePortletConstants.MODE_PRINT);
531            }
532    
533            public int getNumOfColumns() {
534                    return getLayoutTemplate().getColumns().size();
535            }
536    
537            public PortalPreferences getPortalPreferences() {
538                    return _portalPreferences;
539            }
540    
541            public List<String> getPortletIds() {
542                    List<String> portletIds = new ArrayList<String>();
543    
544                    List<String> columns = getColumns();
545    
546                    for (int i = 0; i < columns.size(); i++) {
547                            String columnId = columns.get(i);
548    
549                            String columnValue = getColumnValue(columnId);
550    
551                            portletIds.addAll(
552                                    ListUtil.fromArray(StringUtil.split(columnValue)));
553                    }
554    
555                    return portletIds;
556            }
557    
558            public List<Portlet> getPortlets() throws SystemException {
559                    List<String> portletIds = getPortletIds();
560    
561                    List<Portlet> portlets = new ArrayList<Portlet>(portletIds.size());
562    
563                    for (int i = 0; i < portletIds.size(); i++) {
564                            String portletId = portletIds.get(i);
565    
566                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
567                                    getCompanyId(), portletId);
568    
569                            if (portlet != null) {
570                                    portlets.add(portlet);
571                            }
572                    }
573    
574                    return portlets;
575            }
576    
577            public Layout getSourcePrototypeLayout() {
578                    return _sourcePrototypeLayout;
579            }
580    
581            public String getSourcePrototypeLayoutProperty(String key) {
582                    if (_sourcePrototypeLayout == null) {
583                            return StringPool.BLANK;
584                    }
585    
586                    UnicodeProperties typeSettingsProperties =
587                            _sourcePrototypeLayout.getTypeSettingsProperties();
588    
589                    return typeSettingsProperties.getProperty(key);
590            }
591    
592            public String getStateMax() {
593                    return getTypeSettingsProperty(LayoutTypePortletConstants.STATE_MAX);
594            }
595    
596            public String getStateMaxPortletId() {
597                    String[] stateMax = StringUtil.split(getStateMax());
598    
599                    if (stateMax.length > 0) {
600                            return stateMax[0];
601                    }
602                    else {
603                            return StringPool.BLANK;
604                    }
605            }
606    
607            public String getStateMin() {
608                    return getTypeSettingsProperty(LayoutTypePortletConstants.STATE_MIN);
609            }
610    
611            public boolean hasDefaultScopePortletId(long groupId, String portletId)
612                    throws PortalException, SystemException {
613    
614                    if (hasPortletId(portletId)) {
615                            long scopeGroupId = PortalUtil.getScopeGroupId(
616                                    getLayout(), portletId);
617    
618                            if (groupId == scopeGroupId) {
619                                    return true;
620                            }
621                    }
622    
623                    return false;
624            }
625    
626            public boolean hasModeAboutPortletId(String portletId) {
627                    return StringUtil.contains(getModeAbout(), portletId);
628            }
629    
630            public boolean hasModeConfigPortletId(String portletId) {
631                    return StringUtil.contains(getModeConfig(), portletId);
632            }
633    
634            public boolean hasModeEditDefaultsPortletId(String portletId) {
635                    return StringUtil.contains(getModeEditDefaults(), portletId);
636            }
637    
638            public boolean hasModeEditGuestPortletId(String portletId) {
639                    return StringUtil.contains(getModeEditGuest(), portletId);
640            }
641    
642            public boolean hasModeEditPortletId(String portletId) {
643                    return StringUtil.contains(getModeEdit(), portletId);
644            }
645    
646            public boolean hasModeHelpPortletId(String portletId) {
647                    return StringUtil.contains(getModeHelp(), portletId);
648            }
649    
650            public boolean hasModePreviewPortletId(String portletId) {
651                    return StringUtil.contains(getModePreview(), portletId);
652            }
653    
654            public boolean hasModePrintPortletId(String portletId) {
655                    return StringUtil.contains(getModePrint(), portletId);
656            }
657    
658            public boolean hasModeViewPortletId(String portletId) {
659                    if (hasModeAboutPortletId(portletId) ||
660                            hasModeConfigPortletId(portletId) ||
661                            hasModeEditPortletId(portletId) ||
662                            hasModeEditDefaultsPortletId(portletId) ||
663                            hasModeEditGuestPortletId(portletId) ||
664                            hasModeHelpPortletId(portletId) ||
665                            hasModePreviewPortletId(portletId) ||
666                            hasModePrintPortletId(portletId)) {
667    
668                            return false;
669                    }
670                    else {
671                            return true;
672                    }
673            }
674    
675            public boolean hasPortletId(String portletId)
676                    throws PortalException, SystemException {
677    
678                    List<String> columns = getColumns();
679    
680                    for (String columnId : columns) {
681                            if (hasNonstaticPortletId(columnId, portletId)) {
682                                    return true;
683                            }
684    
685                            if (hasStaticPortletId(columnId, portletId)) {
686                                    return true;
687                            }
688                    }
689    
690                    Layout layout = getLayout();
691    
692                    if (layout.isTypeControlPanel() || layout.isTypePanel()) {
693                            return true;
694                    }
695    
696                    return false;
697            }
698    
699            public boolean hasSourcePrototypeLayout() {
700                    if (_sourcePrototypeLayout != null) {
701                            return true;
702                    }
703    
704                    return false;
705            }
706    
707            public boolean hasStateMax() {
708                    String[] stateMax = StringUtil.split(getStateMax());
709    
710                    if (stateMax.length > 0) {
711                            return true;
712                    }
713                    else {
714                            return false;
715                    }
716            }
717    
718            public boolean hasStateMaxPortletId(String portletId) {
719                    if (StringUtil.contains(getStateMax(), portletId)) {
720                            return true;
721                    }
722                    else {
723                            return false;
724                    }
725            }
726    
727            public boolean hasStateMin() {
728                    String[] stateMin = StringUtil.split(getStateMin());
729    
730                    if (stateMin.length > 0) {
731                            return true;
732                    }
733                    else {
734                            return false;
735                    }
736            }
737    
738            public boolean hasStateMinPortletId(String portletId) {
739                    if (StringUtil.contains(getStateMin(), portletId)) {
740                            return true;
741                    }
742                    else {
743                            return false;
744                    }
745            }
746    
747            public boolean hasStateNormalPortletId(String portletId) {
748                    if (hasStateMaxPortletId(portletId) ||
749                            hasStateMinPortletId(portletId)) {
750    
751                            return false;
752                    }
753                    else {
754                            return true;
755                    }
756            }
757    
758            public boolean hasUpdatePermission() {
759                    return _updatePermission;
760            }
761    
762            public boolean isColumnCustomizable(String columnId) {
763                    if (!isLayoutSetPrototype() && isTemplateCustomizable(columnId)) {
764                            String customizableString = getTypeSettingsProperty(
765                                    CustomizedPages.namespaceColumnId(columnId));
766    
767                            boolean customizable = GetterUtil.getBoolean(customizableString);
768    
769                            if (!customizable && hasUserPreferences()) {
770                                    String columnValue = _portalPreferences.getValue(
771                                            CustomizedPages.namespacePlid(getPlid()), columnId,
772                                            StringPool.NULL);
773    
774                                    if (!Validator.equals(columnValue, StringPool.NULL)) {
775                                            setUserPreference(columnId, null);
776                                    }
777                            }
778    
779                            return customizable;
780                    }
781    
782                    return false;
783            }
784    
785            public boolean isColumnDisabled(String columnId) {
786                    if (!isTemplateCustomizable(columnId) ||
787                            (isCustomizedView() && !isColumnCustomizable(columnId)) ||
788                            (!isCustomizedView() && !hasUpdatePermission())) {
789    
790                            return true;
791                    }
792    
793                    return false;
794            }
795    
796            public boolean isCustomizable() {
797                    for (String columnId : getColumns()) {
798                            if (isColumnCustomizable(columnId)) {
799                                    return true;
800                            }
801                    }
802    
803                    return false;
804            }
805    
806            public boolean isCustomizedView() {
807                    return _customizedView;
808            }
809    
810            public boolean isDefaultUpdated() {
811                    if (!isCustomizedView() || !hasUserPreferences()) {
812                            return false;
813                    }
814    
815                    String preferencesModifiedDateString = _portalPreferences.getValue(
816                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
817                            _NULL_DATE);
818    
819                    DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
820                            PropsValues.INDEX_DATE_FORMAT_PATTERN);
821    
822                    try {
823                            Date preferencesModifiedDate = dateFormat.parse(
824                                    preferencesModifiedDateString);
825    
826                            if (hasSourcePrototypeLayout()) {
827                                    String propertiesModifiedDateString =
828                                            _sourcePrototypeLayout.getTypeSettingsProperty(
829                                                    _MODIFIED_DATE, _NULL_DATE);
830    
831                                    Date propertiesModifiedDate = dateFormat.parse(
832                                            propertiesModifiedDateString);
833    
834                                    return propertiesModifiedDate.after(preferencesModifiedDate);
835                            }
836                            else {
837                                    Layout layout = getLayout();
838    
839                                    String propertiesModifiedDateString =
840                                            layout.getTypeSettingsProperty(_MODIFIED_DATE, _NULL_DATE);
841    
842                                    Date propertiesModifiedDate = dateFormat.parse(
843                                            propertiesModifiedDateString);
844    
845                                    return propertiesModifiedDate.after(preferencesModifiedDate);
846                            }
847                    }
848                    catch (Exception e) {
849                            _log.error(e, e);
850                    }
851    
852                    return false;
853            }
854    
855            public boolean isPortletCustomizable(String portletId) {
856                    return isColumnCustomizable(getColumn(portletId));
857            }
858    
859            public boolean isTemplateCustomizable(String columnId) {
860                    if (!hasSourcePrototypeLayout()) {
861                            return true;
862                    }
863    
864                    String customizable = getSourcePrototypeLayoutProperty(
865                            CustomizedPages.namespaceColumnId(columnId));
866    
867                    return GetterUtil.getBoolean(customizable, false);
868            }
869    
870            public void movePortletId(
871                            long userId, String portletId, String columnId, int columnPos)
872                    throws PortalException, SystemException {
873    
874                    _enablePortletLayoutListener = false;
875    
876                    try {
877                            removePortletId(userId, portletId, false);
878                            addPortletId(userId, portletId, columnId, columnPos, false);
879                    }
880                    finally {
881                            _enablePortletLayoutListener = true;
882                    }
883    
884                    Layout layout = getLayout();
885    
886                    try {
887                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
888                                    layout.getCompanyId(), portletId);
889    
890                            if (portlet != null) {
891                                    PortletLayoutListener portletLayoutListener =
892                                            portlet.getPortletLayoutListenerInstance();
893    
894                                    if (portletLayoutListener != null) {
895                                            portletLayoutListener.onMoveInLayout(
896                                                    portletId, layout.getPlid());
897                                    }
898                            }
899                    }
900                    catch (Exception e) {
901                            _log.error("Unable to fire portlet layout listener event", e);
902                    }
903            }
904    
905            public void removeModeAboutPortletId(String portletId) {
906                    setModeAbout(StringUtil.remove(getModeAbout(), portletId));
907            }
908    
909            public void removeModeConfigPortletId(String portletId) {
910                    setModeConfig(StringUtil.remove(getModeConfig(), portletId));
911            }
912    
913            public void removeModeEditDefaultsPortletId(String portletId) {
914                    setModeEditDefaults(
915                            StringUtil.remove(getModeEditDefaults(), portletId));
916            }
917    
918            public void removeModeEditGuestPortletId(String portletId) {
919                    setModeEditGuest(StringUtil.remove(getModeEditGuest(), portletId));
920            }
921    
922            public void removeModeEditPortletId(String portletId) {
923                    setModeEdit(StringUtil.remove(getModeEdit(), portletId));
924            }
925    
926            public void removeModeHelpPortletId(String portletId) {
927                    setModeHelp(StringUtil.remove(getModeHelp(), portletId));
928            }
929    
930            public void removeModePreviewPortletId(String portletId) {
931                    setModePreview(StringUtil.remove(getModePreview(), portletId));
932            }
933    
934            public void removeModePrintPortletId(String portletId) {
935                    setModePrint(StringUtil.remove(getModePrint(), portletId));
936            }
937    
938            public void removeModesPortletId(String portletId) {
939                    removeModeAboutPortletId(portletId);
940                    removeModeConfigPortletId(portletId);
941                    removeModeEditPortletId(portletId);
942                    removeModeEditDefaultsPortletId(portletId);
943                    removeModeEditGuestPortletId(portletId);
944                    removeModeHelpPortletId(portletId);
945                    removeModePreviewPortletId(portletId);
946                    removeModePrintPortletId(portletId);
947            }
948    
949            public void removeNestedColumns(String portletNamespace) {
950                    UnicodeProperties typeSettingsProperties = getTypeSettingsProperties();
951    
952                    UnicodeProperties newTypeSettingsProperties = new UnicodeProperties();
953    
954                    for (Map.Entry<String, String> entry :
955                                    typeSettingsProperties.entrySet()) {
956    
957                            String key = entry.getKey();
958    
959                            if (!key.startsWith(portletNamespace)) {
960                                    newTypeSettingsProperties.setProperty(key, entry.getValue());
961                            }
962                    }
963    
964                    Layout layout = getLayout();
965    
966                    layout.setTypeSettingsProperties(newTypeSettingsProperties);
967    
968                    String nestedColumnIds = GetterUtil.getString(
969                            getTypeSettingsProperty(
970                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS));
971    
972                    String[] nestedColumnIdsArray = ArrayUtil.removeByPrefix(
973                            StringUtil.split(nestedColumnIds), portletNamespace);
974    
975                    setTypeSettingsProperty(
976                            LayoutTypePortletConstants.NESTED_COLUMN_IDS,
977                            StringUtil.merge(nestedColumnIdsArray));
978            }
979    
980            public void removePortletId(long userId, String portletId) {
981                    removePortletId(userId, portletId, true);
982            }
983    
984            public void removePortletId(
985                    long userId, String portletId, boolean cleanUp) {
986    
987                    try {
988                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
989                                    getCompanyId(), portletId);
990    
991                            if (portlet == null) {
992                                    _log.error(
993                                            "Portlet " + portletId +
994                                                    " cannot be removed because it is not registered");
995    
996                                    return;
997                            }
998    
999                            PermissionChecker permissionChecker =
1000                                    PermissionThreadLocal.getPermissionChecker();
1001    
1002                            if (!LayoutPermissionUtil.contains(
1003                                            permissionChecker, getLayout(), ActionKeys.UPDATE) &&
1004                                    !isCustomizable()) {
1005    
1006                                    return;
1007                            }
1008                    }
1009                    catch (Exception e) {
1010                            _log.error(e, e);
1011                    }
1012    
1013                    List<String> columns = getColumns();
1014    
1015                    for (int i = 0; i < columns.size(); i++) {
1016                            String columnId = columns.get(i);
1017    
1018                            if (isCustomizable() && isColumnDisabled(columnId)) {
1019                                    continue;
1020                            }
1021    
1022                            String columnValue = StringPool.BLANK;
1023    
1024                            if (hasUserPreferences()) {
1025                                    columnValue = getUserPreference(columnId);
1026                            }
1027                            else {
1028                                    columnValue = getTypeSettingsProperty(columnId);
1029                            }
1030    
1031                            columnValue = StringUtil.remove(columnValue, portletId);
1032    
1033                            if (hasUserPreferences()) {
1034                                    setUserPreference(columnId, columnValue);
1035    
1036                                    try {
1037                                            String rootPortletId = PortletConstants.getRootPortletId(
1038                                                    portletId);
1039    
1040                                            ResourceLocalServiceUtil.deleteResource(
1041                                                    getCompanyId(), rootPortletId,
1042                                                    ResourceConstants.SCOPE_INDIVIDUAL,
1043                                                    PortletPermissionUtil.getPrimaryKey(
1044                                                            getPlid(), portletId));
1045                                    }
1046                                    catch (Exception e) {
1047                                    }
1048                            }
1049                            else {
1050                                    setTypeSettingsProperty(columnId, columnValue);
1051                            }
1052                    }
1053    
1054                    if (cleanUp) {
1055                            removeStatesPortletId(portletId);
1056                            removeModesPortletId(portletId);
1057    
1058                            try {
1059                                    onRemoveFromLayout(portletId);
1060                            }
1061                            catch (Exception e) {
1062                                    _log.error("Unable to fire portlet layout listener event", e);
1063                            }
1064                    }
1065            }
1066    
1067            public void removeStateMaxPortletId(String portletId) {
1068                    setStateMax(StringUtil.remove(getStateMax(), portletId));
1069            }
1070    
1071            public void removeStateMinPortletId(String portletId) {
1072                    setStateMin(StringUtil.remove(getStateMin(), portletId));
1073            }
1074    
1075            public void removeStatesPortletId(String portletId) {
1076                    removeStateMaxPortletId(portletId);
1077                    removeStateMinPortletId(portletId);
1078            }
1079    
1080            public void reorganizePortlets(
1081                    List<String> newColumns, List<String> oldColumns) {
1082    
1083                    String lastNewColumnId = newColumns.get(newColumns.size() - 1);
1084                    String lastNewColumnValue = getTypeSettingsProperty(lastNewColumnId);
1085    
1086                    Iterator<String> itr = oldColumns.iterator();
1087    
1088                    while (itr.hasNext()) {
1089                            String oldColumnId = itr.next();
1090    
1091                            if (!newColumns.contains(oldColumnId)) {
1092                                    String oldColumnValue = getTypeSettingsProperties().remove(
1093                                            oldColumnId);
1094    
1095                                    String[] portletIds = StringUtil.split(oldColumnValue);
1096    
1097                                    for (String portletId : portletIds) {
1098                                            lastNewColumnValue = StringUtil.add(
1099                                                    lastNewColumnValue, portletId);
1100                                    }
1101                            }
1102                    }
1103    
1104                    setTypeSettingsProperty(lastNewColumnId, lastNewColumnValue);
1105            }
1106    
1107            public void resetModes() {
1108                    setModeAbout(StringPool.BLANK);
1109                    setModeConfig(StringPool.BLANK);
1110                    setModeEdit(StringPool.BLANK);
1111                    setModeEditDefaults(StringPool.BLANK);
1112                    setModeEditGuest(StringPool.BLANK);
1113                    setModeHelp(StringPool.BLANK);
1114                    setModePreview(StringPool.BLANK);
1115                    setModePrint(StringPool.BLANK);
1116            }
1117    
1118            public void resetStates() {
1119                    setStateMax(StringPool.BLANK);
1120                    setStateMin(StringPool.BLANK);
1121            }
1122    
1123            public void resetUserPreferences() {
1124                    if (hasUserPreferences()) {
1125                            Layout layout = getLayout();
1126    
1127                            long plid = layout.getPlid();
1128    
1129                            _portalPreferences.resetValues(CustomizedPages.namespacePlid(plid));
1130    
1131                            _portalPreferences.setValue(
1132                                    CustomizedPages.namespacePlid(plid), _MODIFIED_DATE,
1133                                    _dateFormat.format(new Date()));
1134                    }
1135            }
1136    
1137            public void setCustomizedView(boolean customizedView) {
1138                    _customizedView = customizedView;
1139            }
1140    
1141            public void setLayoutTemplateId(long userId, String newLayoutTemplateId) {
1142                    setLayoutTemplateId(userId, newLayoutTemplateId, true);
1143            }
1144    
1145            public void setLayoutTemplateId(
1146                    long userId, String newLayoutTemplateId, boolean checkPermission) {
1147    
1148                    if (checkPermission &&
1149                            !PluginSettingLocalServiceUtil.hasPermission(
1150                                    userId, newLayoutTemplateId, Plugin.TYPE_LAYOUT_TEMPLATE)) {
1151    
1152                            return;
1153                    }
1154    
1155                    String oldLayoutTemplateId = getLayoutTemplateId();
1156    
1157                    if (Validator.isNull(oldLayoutTemplateId)) {
1158                            oldLayoutTemplateId = PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID;
1159                    }
1160    
1161                    setTypeSettingsProperty(
1162                            LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID, newLayoutTemplateId);
1163    
1164                    String themeId = getThemeId();
1165    
1166                    LayoutTemplate oldLayoutTemplate =
1167                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1168                                    oldLayoutTemplateId, false, themeId);
1169    
1170                    if (oldLayoutTemplate == null) {
1171                            return;
1172                    }
1173    
1174                    LayoutTemplate newLayoutTemplate =
1175                            LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1176                                    newLayoutTemplateId, false, themeId);
1177    
1178                    List<String> oldColumns = oldLayoutTemplate.getColumns();
1179                    List<String> newColumns = newLayoutTemplate.getColumns();
1180    
1181                    reorganizePortlets(newColumns, oldColumns);
1182            }
1183    
1184            public void setModeAbout(String modeAbout) {
1185                    setTypeSettingsProperty(
1186                            LayoutTypePortletConstants.MODE_ABOUT, modeAbout);
1187            }
1188    
1189            public void setModeConfig(String modeConfig) {
1190                    setTypeSettingsProperty(
1191                            LayoutTypePortletConstants.MODE_CONFIG, modeConfig);
1192            }
1193    
1194            public void setModeEdit(String modeEdit) {
1195                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_EDIT, modeEdit);
1196            }
1197    
1198            public void setModeEditDefaults(String modeEditDefaults) {
1199                    setTypeSettingsProperty(
1200                            LayoutTypePortletConstants.MODE_EDIT_DEFAULTS, modeEditDefaults);
1201            }
1202    
1203            public void setModeEditGuest(String modeEditGuest) {
1204                    setTypeSettingsProperty(
1205                            LayoutTypePortletConstants.MODE_EDIT_GUEST, modeEditGuest);
1206            }
1207    
1208            public void setModeHelp(String modeHelp) {
1209                    setTypeSettingsProperty(LayoutTypePortletConstants.MODE_HELP, modeHelp);
1210            }
1211    
1212            public void setModePreview(String modePreview) {
1213                    setTypeSettingsProperty(
1214                            LayoutTypePortletConstants.MODE_PREVIEW, modePreview);
1215            }
1216    
1217            public void setModePrint(String modePrint) {
1218                    setTypeSettingsProperty(
1219                            LayoutTypePortletConstants.MODE_PRINT, modePrint);
1220            }
1221    
1222            public void setPortalPreferences(PortalPreferences portalPreferences) {
1223                    _portalPreferences = portalPreferences;
1224            }
1225    
1226            public void setPortletIds(String columnId, String portletIds) {
1227                    setTypeSettingsProperty(columnId, portletIds);
1228            }
1229    
1230            public void setStateMax(String stateMax) {
1231                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MAX, stateMax);
1232            }
1233    
1234            public void setStateMin(String stateMin) {
1235                    setTypeSettingsProperty(LayoutTypePortletConstants.STATE_MIN, stateMin);
1236            }
1237    
1238            public void setUpdatePermission(boolean updatePermission) {
1239                    _updatePermission = updatePermission;
1240            }
1241    
1242            protected void addNestedColumn(String columnId) {
1243                    String nestedColumnIds = getTypeSettingsProperty(
1244                            LayoutTypePortletConstants.NESTED_COLUMN_IDS, StringPool.BLANK);
1245    
1246                    if (nestedColumnIds.indexOf(columnId) == -1) {
1247                            nestedColumnIds = StringUtil.add(nestedColumnIds, columnId);
1248    
1249                            setTypeSettingsProperty(
1250                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS, nestedColumnIds);
1251                    }
1252            }
1253    
1254            protected void copyPreferences(
1255                    String sourcePortletId, String targetPortletId) {
1256    
1257                    Layout layout = getLayout();
1258    
1259                    PermissionChecker permissionChecker =
1260                            PermissionThreadLocal.getPermissionChecker();
1261    
1262                    try {
1263                            PortletPreferencesIds portletPreferencesIds =
1264                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1265                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1266                                            sourcePortletId, false);
1267    
1268                            javax.portlet.PortletPreferences sourcePortletPreferences =
1269                                    PortletPreferencesLocalServiceUtil.getPreferences(
1270                                            portletPreferencesIds);
1271    
1272                            portletPreferencesIds =
1273                                    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
1274                                            layout.getGroupId(), permissionChecker.getUserId(), layout,
1275                                            targetPortletId, false);
1276    
1277                            PortletPreferencesLocalServiceUtil.updatePreferences(
1278                                    portletPreferencesIds.getOwnerId(),
1279                                    portletPreferencesIds.getOwnerType(),
1280                                    portletPreferencesIds.getPlid(),
1281                                    portletPreferencesIds.getPortletId(), sourcePortletPreferences);
1282                    }
1283                    catch (Exception e) {
1284                    }
1285            }
1286    
1287            protected void deletePortletSetup(String portletId) {
1288                    try {
1289                            List<PortletPreferences> portletPreferencesList =
1290                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
1291                                            getPlid(), portletId);
1292    
1293                            for (PortletPreferences portletPreferences :
1294                                            portletPreferencesList) {
1295    
1296                                    PortletPreferencesLocalServiceUtil.deletePortletPreferences(
1297                                            portletPreferences.getPortletPreferencesId());
1298                            }
1299                    }
1300                    catch (Exception e) {
1301                            _log.error(e, e);
1302                    }
1303            }
1304    
1305            protected String getColumn(String portletId) {
1306                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
1307    
1308                    List<String> columns = getColumns();
1309    
1310                    for (String columnId : columns) {
1311                            String columnValue = getColumnValue(columnId);
1312    
1313                            String[] portletIds = StringUtil.split(columnValue);
1314    
1315                            for (String columnPortletId : portletIds) {
1316                                    if (portletId.equals(columnPortletId) ||
1317                                            (portletId.equals(rootPortletId) &&
1318                                             columnPortletId.startsWith(rootPortletId))) {
1319    
1320                                            return columnId;
1321                                    }
1322                            }
1323                    }
1324    
1325                    return StringPool.BLANK;
1326            }
1327    
1328            protected List<String> getColumns() {
1329                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1330    
1331                    List<String> columns = new ArrayList<String>();
1332    
1333                    columns.addAll(layoutTemplate.getColumns());
1334                    columns.addAll(getNestedColumns());
1335    
1336                    return columns;
1337            }
1338    
1339            protected String getColumnValue(String columnId) {
1340                    Boolean customizable = null;
1341                    Boolean columnDisabled = null;
1342    
1343                    if (hasSourcePrototypeLayout()) {
1344                            customizable = isCustomizable();
1345    
1346                            if (customizable) {
1347                                    columnDisabled = isColumnDisabled(columnId);
1348    
1349                                    if (columnDisabled) {
1350                                            return getSourcePrototypeLayoutProperty(columnId);
1351                                    }
1352                            }
1353                    }
1354    
1355                    if (hasUserPreferences() &&
1356                            ((customizable == null) ? isCustomizable() : customizable) &&
1357                            ((columnDisabled == null) ?
1358                                    !isColumnDisabled(columnId) : !columnDisabled)) {
1359    
1360                            return getUserPreference(columnId);
1361                    }
1362    
1363                    return getTypeSettingsProperty(columnId);
1364            }
1365    
1366            protected long getCompanyId() {
1367                    Layout layout = getLayout();
1368    
1369                    return layout.getCompanyId();
1370            }
1371    
1372            protected List<String> getNestedColumns() {
1373                    String nestedColumnIds = getTypeSettingsProperty(
1374                            LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1375    
1376                    return ListUtil.fromArray(StringUtil.split(nestedColumnIds));
1377            }
1378    
1379            protected long getPlid() {
1380                    Layout layout = getLayout();
1381    
1382                    return layout.getPlid();
1383            }
1384    
1385            protected String[] getStaticPortletIds(String position)
1386                    throws PortalException, SystemException {
1387    
1388                    Layout layout = getLayout();
1389    
1390                    if (hasSourcePrototypeLayout()) {
1391                            layout = _sourcePrototypeLayout;
1392                    }
1393    
1394                    String selector1 = StringPool.BLANK;
1395    
1396                    Group group = layout.getGroup();
1397    
1398                    if (group.isUser()) {
1399                            selector1 = LayoutTypePortletConstants.STATIC_PORTLET_USER_SELECTOR;
1400                    }
1401                    else if (group.isOrganization()) {
1402                            selector1 =
1403                                    LayoutTypePortletConstants.STATIC_PORTLET_ORGANIZATION_SELECTOR;
1404                    }
1405                    else if (group.isRegularSite()) {
1406                            selector1 =
1407                                    LayoutTypePortletConstants.STATIC_PORTLET_REGULAR_SITE_SELECTOR;
1408                    }
1409    
1410                    String selector2 = layout.getFriendlyURL();
1411    
1412                    String[] portletIds = PropsUtil.getArray(
1413                            position, new Filter(selector1, selector2));
1414    
1415                    for (int i = 0; i < portletIds.length; i++) {
1416                            portletIds[i] = JS.getSafeName(portletIds[i]);
1417                    }
1418    
1419                    return portletIds;
1420            }
1421    
1422            protected List<Portlet> getStaticPortlets(String position)
1423                    throws PortalException, SystemException {
1424    
1425                    String[] portletIds = getStaticPortletIds(position);
1426    
1427                    List<Portlet> portlets = new ArrayList<Portlet>();
1428    
1429                    for (String portletId : portletIds) {
1430                            if (Validator.isNull(portletId) ||
1431                                    hasNonstaticPortletId(portletId)) {
1432    
1433                                    continue;
1434                            }
1435    
1436                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
1437                                    getCompanyId(), portletId);
1438    
1439                            if (portlet != null) {
1440                                    Portlet staticPortlet = portlet;
1441    
1442                                    if (portlet.isInstanceable()) {
1443    
1444                                            // Instanceable portlets do not need to be cloned because
1445                                            // they are already cloned. See the method getPortletById in
1446                                            // the class PortletLocalServiceImpl and how it references
1447                                            // the method getClonedInstance in the class PortletImpl.
1448    
1449                                    }
1450                                    else {
1451                                            staticPortlet = (Portlet)staticPortlet.clone();
1452                                    }
1453    
1454                                    staticPortlet.setStatic(true);
1455    
1456                                    if (position.startsWith("layout.static.portlets.start")) {
1457                                            staticPortlet.setStaticStart(true);
1458                                    }
1459    
1460                                    portlets.add(staticPortlet);
1461                            }
1462                    }
1463    
1464                    return portlets;
1465            }
1466    
1467            protected String getThemeId() {
1468                    String themeId = null;
1469    
1470                    try {
1471                            Layout layout = getLayout();
1472    
1473                            Theme theme = layout.getTheme();
1474    
1475                            if (theme != null) {
1476                                    themeId = theme.getThemeId();
1477                            }
1478                            else {
1479                                    themeId = layout.getThemeId();
1480                            }
1481                    }
1482                    catch (Exception e) {
1483                            _log.error(e, e);
1484                    }
1485    
1486                    return themeId;
1487            }
1488    
1489            protected String getUserPreference(String key) {
1490                    String value = StringPool.BLANK;
1491    
1492                    if (!hasUserPreferences()) {
1493                            return value;
1494                    }
1495    
1496                    value = _portalPreferences.getValue(
1497                            CustomizedPages.namespacePlid(getPlid()), key, StringPool.NULL);
1498    
1499                    if (!value.equals(StringPool.NULL)) {
1500                            return value;
1501                    }
1502    
1503                    if (hasSourcePrototypeLayout()) {
1504                            value = getSourcePrototypeLayoutProperty(key);
1505                    }
1506                    else {
1507                            value = getTypeSettingsProperty(key);
1508                    }
1509    
1510                    if (Validator.isNull(value)) {
1511                            return value;
1512                    }
1513    
1514                    String[] portletIds = StringUtil.split(value);
1515    
1516                    String[] newPortletIds = new String[portletIds.length];
1517    
1518                    for (int i = 0; i < portletIds.length; i++) {
1519                            if (portletIds[i].contains(PortletConstants.INSTANCE_SEPARATOR)) {
1520                                    String rootPortletId = PortletConstants.getRootPortletId(
1521                                            portletIds[i]);
1522    
1523                                    newPortletIds[i] = rootPortletId + getFullInstanceSeparator();
1524    
1525                                    copyPreferences(portletIds[i], newPortletIds[i]);
1526                            }
1527                            else {
1528                                    newPortletIds[i] = portletIds[i];
1529                            }
1530                    }
1531    
1532                    value = StringUtil.merge(newPortletIds);
1533    
1534                    setUserPreference(key, value);
1535    
1536                    return value;
1537            }
1538    
1539            protected boolean hasNonstaticPortletId(String portletId) {
1540                    LayoutTemplate layoutTemplate = getLayoutTemplate();
1541    
1542                    List<String> columns = layoutTemplate.getColumns();
1543    
1544                    for (int i = 0; i < columns.size(); i++) {
1545                            String columnId = columns.get(i);
1546    
1547                            if (hasNonstaticPortletId(columnId, portletId)) {
1548                                    return true;
1549                            }
1550                    }
1551    
1552                    return false;
1553            }
1554    
1555            protected boolean hasNonstaticPortletId(String columnId, String portletId) {
1556                    String columnValue = getColumnValue(columnId);
1557    
1558                    String[] columnValues = StringUtil.split(columnValue);
1559    
1560                    for (String nonstaticPortletId : columnValues) {
1561                            if (nonstaticPortletId.equals(portletId) ||
1562                                    nonstaticPortletId.startsWith(
1563                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1564    
1565                                    return true;
1566                            }
1567                    }
1568    
1569                    return false;
1570            }
1571    
1572            protected boolean hasStaticPortletId(String columnId, String portletId)
1573                    throws PortalException, SystemException {
1574    
1575                    String[] staticPortletIdsStart = getStaticPortletIds(
1576                            PropsKeys.LAYOUT_STATIC_PORTLETS_START + columnId);
1577    
1578                    String[] staticPortletIdsEnd = getStaticPortletIds(
1579                            PropsKeys.LAYOUT_STATIC_PORTLETS_END + columnId);
1580    
1581                    for (String staticPortletId : staticPortletIdsStart) {
1582                            if (staticPortletId.equals(portletId) ||
1583                                    staticPortletId.startsWith(
1584                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1585    
1586                                    return true;
1587                            }
1588                    }
1589    
1590                    for (String staticPortletId : staticPortletIdsEnd) {
1591                            if (staticPortletId.equals(portletId) ||
1592                                    staticPortletId.startsWith(
1593                                            portletId.concat(PortletConstants.INSTANCE_SEPARATOR))) {
1594    
1595                                    return true;
1596                            }
1597                    }
1598    
1599                    return false;
1600            }
1601    
1602            protected boolean hasUserPreferences() {
1603                    if (_portalPreferences != null) {
1604                            return true;
1605                    }
1606    
1607                    return false;
1608            }
1609    
1610            protected boolean isLayoutSetPrototype() {
1611                    try {
1612                            Layout layout = getLayout();
1613    
1614                            LayoutSet layoutSet = layout.getLayoutSet();
1615    
1616                            Group group = layoutSet.getGroup();
1617    
1618                            return group.isLayoutSetPrototype();
1619                    }
1620                    catch (Exception e) {
1621                            _log.error(e, e);
1622                    }
1623    
1624                    return false;
1625            }
1626    
1627            protected void onRemoveFromLayout(String portletId) throws SystemException {
1628                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1629                            getCompanyId(), portletId);
1630    
1631                    if (portlet == null) {
1632                            return;
1633                    }
1634    
1635                    if (portlet.getRootPortletId().equals(PortletKeys.NESTED_PORTLETS)) {
1636                            String portletNamespace = PortalUtil.getPortletNamespace(portletId);
1637    
1638                            UnicodeProperties typeSettingsProperties =
1639                                    getTypeSettingsProperties();
1640    
1641                            for (Map.Entry<String, String> entry :
1642                                            typeSettingsProperties.entrySet()) {
1643    
1644                                    String key = entry.getKey();
1645    
1646                                    if (key.startsWith(portletNamespace)) {
1647                                            String portletIds = entry.getValue();
1648    
1649                                            String[] portletIdsArray = StringUtil.split(portletIds);
1650    
1651                                            for (String curPortletId : portletIdsArray) {
1652                                                    onRemoveFromLayout(curPortletId);
1653                                            }
1654                                    }
1655                            }
1656    
1657                            removeNestedColumns(portletNamespace);
1658                    }
1659    
1660                    if (_enablePortletLayoutListener) {
1661                            PortletLayoutListener portletLayoutListener =
1662                                    portlet.getPortletLayoutListenerInstance();
1663    
1664                            if ((portletLayoutListener != null)) {
1665                                    portletLayoutListener.onRemoveFromLayout(portletId, getPlid());
1666                            }
1667                    }
1668    
1669                    deletePortletSetup(portletId);
1670            }
1671    
1672            protected void setUserPreference(String key, String value) {
1673                    if (!hasUserPreferences()) {
1674                            return;
1675                    }
1676    
1677                    _portalPreferences.setValue(
1678                            CustomizedPages.namespacePlid(getPlid()), key, value);
1679    
1680                    _portalPreferences.setValue(
1681                            CustomizedPages.namespacePlid(getPlid()), _MODIFIED_DATE,
1682                            _dateFormat.format(new Date()));
1683            }
1684    
1685            private static final String _MODIFIED_DATE = "modifiedDate";
1686    
1687            private static final String _NULL_DATE = "00000000000000";
1688    
1689            private static Log _log = LogFactoryUtil.getLog(
1690                    LayoutTypePortletImpl.class);
1691    
1692            private static String _nestedPortletsNamespace;
1693    
1694            private boolean _customizedView;
1695            private Format _dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
1696                    PropsValues.INDEX_DATE_FORMAT_PATTERN);
1697            private boolean _enablePortletLayoutListener = true;
1698            private PortalPreferences _portalPreferences;
1699            private Layout _sourcePrototypeLayout;
1700            private boolean _updatePermission;
1701    
1702    }