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.portlet.exportimport.backgroundtask;
016    
017    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_PUBLICATION_LAYOUT_LOCAL_FAILED;
018    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_PUBLICATION_LAYOUT_LOCAL_STARTED;
019    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.EVENT_PUBLICATION_LAYOUT_LOCAL_SUCCEEDED;
020    import static com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleConstants.PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS;
021    
022    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.MapUtil;
029    import com.liferay.portal.kernel.util.UnicodeProperties;
030    import com.liferay.portal.model.BackgroundTask;
031    import com.liferay.portal.model.Group;
032    import com.liferay.portal.service.GroupLocalServiceUtil;
033    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.spring.transaction.TransactionHandlerUtil;
036    import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
037    import com.liferay.portlet.exportimport.lar.MissingReferences;
038    import com.liferay.portlet.exportimport.lifecycle.ExportImportLifecycleManager;
039    import com.liferay.portlet.exportimport.model.ExportImportConfiguration;
040    import com.liferay.portlet.exportimport.service.ExportImportLocalServiceUtil;
041    import com.liferay.portlet.exportimport.service.StagingLocalServiceUtil;
042    
043    import java.io.File;
044    import java.io.Serializable;
045    
046    import java.util.Map;
047    import java.util.concurrent.Callable;
048    
049    /**
050     * @author Julio Camarero
051     */
052    public class LayoutStagingBackgroundTaskExecutor
053            extends BaseStagingBackgroundTaskExecutor {
054    
055            public LayoutStagingBackgroundTaskExecutor() {
056                    setBackgroundTaskStatusMessageTranslator(
057                            new LayoutStagingBackgroundTaskStatusMessageTranslator());
058            }
059    
060            @Override
061            public BackgroundTaskResult execute(BackgroundTask backgroundTask)
062                    throws PortalException {
063    
064                    ExportImportConfiguration exportImportConfiguration =
065                            getExportImportConfiguration(backgroundTask);
066    
067                    Map<String, Serializable> settingsMap =
068                            exportImportConfiguration.getSettingsMap();
069    
070                    long userId = MapUtil.getLong(settingsMap, "userId");
071                    long targetGroupId = MapUtil.getLong(settingsMap, "targetGroupId");
072                    long sourceGroupId = MapUtil.getLong(settingsMap, "sourceGroupId");
073    
074                    clearBackgroundTaskStatus(backgroundTask);
075    
076                    File file = null;
077                    MissingReferences missingReferences = null;
078    
079                    try {
080                            ExportImportThreadLocal.setLayoutStagingInProcess(true);
081    
082                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
083                                    EVENT_PUBLICATION_LAYOUT_LOCAL_STARTED,
084                                    PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS,
085                                    exportImportConfiguration);
086    
087                            boolean privateLayout = MapUtil.getBoolean(
088                                    settingsMap, "privateLayout");
089    
090                            initThreadLocals(sourceGroupId, privateLayout);
091    
092                            file = ExportImportLocalServiceUtil.exportLayoutsAsFile(
093                                    exportImportConfiguration);
094    
095                            markBackgroundTask(
096                                    backgroundTask.getBackgroundTaskId(), "exported");
097    
098                            missingReferences = TransactionHandlerUtil.invoke(
099                                    transactionAttribute,
100                                    new LayoutStagingImportCallable(
101                                            backgroundTask.getBackgroundTaskId(),
102                                            exportImportConfiguration, file, sourceGroupId,
103                                            targetGroupId, userId));
104    
105                            ExportImportThreadLocal.setLayoutStagingInProcess(false);
106    
107                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
108                                    EVENT_PUBLICATION_LAYOUT_LOCAL_SUCCEEDED,
109                                    PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS,
110                                    exportImportConfiguration);
111                    }
112                    catch (Throwable t) {
113                            ExportImportThreadLocal.setLayoutStagingInProcess(false);
114    
115                            ExportImportLifecycleManager.fireExportImportLifecycleEvent(
116                                    EVENT_PUBLICATION_LAYOUT_LOCAL_FAILED,
117                                    PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS,
118                                    exportImportConfiguration, t);
119    
120                            if (_log.isDebugEnabled()) {
121                                    _log.debug(t, t);
122                            }
123                            else if (_log.isWarnEnabled()) {
124                                    _log.warn("Unable to publish layout: " + t.getMessage());
125                            }
126    
127                            Group sourceGroup = GroupLocalServiceUtil.getGroup(sourceGroupId);
128    
129                            if (sourceGroup.hasStagingGroup()) {
130                                    ServiceContext serviceContext = new ServiceContext();
131    
132                                    serviceContext.setUserId(userId);
133    
134                                    StagingLocalServiceUtil.disableStaging(
135                                            sourceGroup, serviceContext);
136                            }
137    
138                            deleteTempLarOnFailure(file);
139    
140                            throw new SystemException(t);
141                    }
142    
143                    deleteTempLarOnSuccess(file);
144    
145                    return processMissingReferences(
146                            backgroundTask.getBackgroundTaskId(), missingReferences);
147            }
148    
149            protected void initLayoutSetBranches(
150                            long userId, long sourceGroupId, long targetGroupId)
151                    throws PortalException {
152    
153                    Group sourceGroup = GroupLocalServiceUtil.getGroup(sourceGroupId);
154    
155                    if (!sourceGroup.hasStagingGroup()) {
156                            return;
157                    }
158    
159                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
160                            targetGroupId, false, true);
161                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
162                            targetGroupId, true, true);
163    
164                    UnicodeProperties typeSettingsProperties =
165                            sourceGroup.getTypeSettingsProperties();
166    
167                    boolean branchingPrivate = GetterUtil.getBoolean(
168                            typeSettingsProperties.getProperty("branchingPrivate"));
169                    boolean branchingPublic = GetterUtil.getBoolean(
170                            typeSettingsProperties.getProperty("branchingPublic"));
171    
172                    ServiceContext serviceContext = new ServiceContext();
173    
174                    serviceContext.setUserId(userId);
175    
176                    StagingLocalServiceUtil.checkDefaultLayoutSetBranches(
177                            userId, sourceGroup, branchingPublic, branchingPrivate, false,
178                            serviceContext);
179            }
180    
181            private static final Log _log = LogFactoryUtil.getLog(
182                    LayoutStagingBackgroundTaskExecutor.class);
183    
184            private class LayoutStagingImportCallable
185                    implements Callable<MissingReferences> {
186    
187                    public LayoutStagingImportCallable(
188                            long backgroundTaskId,
189                            ExportImportConfiguration exportImportConfiguration, File file,
190                            long sourceGroupId, long targetGroupId, long userId) {
191    
192                            _backgroundTaskId = backgroundTaskId;
193                            _exportImportConfiguration = exportImportConfiguration;
194                            _file = file;
195                            _sourceGroupId = sourceGroupId;
196                            _targetGroupId = targetGroupId;
197                            _userId = userId;
198                    }
199    
200                    @Override
201                    public MissingReferences call() throws PortalException {
202                            ExportImportLocalServiceUtil.importLayoutsDataDeletions(
203                                    _exportImportConfiguration, _file);
204    
205                            MissingReferences missingReferences =
206                                    ExportImportLocalServiceUtil.validateImportLayoutsFile(
207                                            _exportImportConfiguration, _file);
208    
209                            markBackgroundTask(_backgroundTaskId, "validated");
210    
211                            ExportImportLocalServiceUtil.importLayouts(
212                                    _exportImportConfiguration, _file);
213    
214                            initLayoutSetBranches(_userId, _sourceGroupId, _targetGroupId);
215    
216                            return missingReferences;
217                    }
218    
219                    private final long _backgroundTaskId;
220                    private final ExportImportConfiguration _exportImportConfiguration;
221                    private final File _file;
222                    private final long _sourceGroupId;
223                    private final long _targetGroupId;
224                    private final long _userId;
225    
226            }
227    
228    }