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