001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.lar.backgroundtask;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
019    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
022    import com.liferay.portal.kernel.lar.MissingReferences;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.staging.StagingUtil;
026    import com.liferay.portal.kernel.util.FileUtil;
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.BackgroundTaskLocalServiceUtil;
033    import com.liferay.portal.service.GroupLocalServiceUtil;
034    import com.liferay.portal.service.LayoutLocalServiceUtil;
035    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portal.service.StagingLocalServiceUtil;
038    import com.liferay.portal.spring.transaction.TransactionalCallableUtil;
039    import com.liferay.portal.util.PropsValues;
040    
041    import java.io.File;
042    import java.io.Serializable;
043    
044    import java.util.Date;
045    import java.util.List;
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 Exception {
063    
064                    Map<String, Serializable> taskContextMap =
065                            backgroundTask.getTaskContextMap();
066    
067                    long userId = MapUtil.getLong(taskContextMap, "userId");
068                    long targetGroupId = MapUtil.getLong(taskContextMap, "targetGroupId");
069    
070                    StagingUtil.lockGroup(userId, targetGroupId);
071    
072                    long sourceGroupId = MapUtil.getLong(taskContextMap, "sourceGroupId");
073    
074                    clearBackgroundTaskStatus(backgroundTask);
075    
076                    MissingReferences missingReferences = null;
077    
078                    try {
079                            ExportImportThreadLocal.setLayoutStagingInProcess(true);
080    
081                            Group targetGroup = GroupLocalServiceUtil.fetchGroup(targetGroupId);
082    
083                            if (targetGroup == null) {
084                                    throw new NoSuchGroupException(
085                                            "Target group does not exists with the primary key " +
086                                                    targetGroupId);
087                            }
088    
089                            missingReferences = TransactionalCallableUtil.call(
090                                    transactionAttribute,
091                                    new LayoutStagingCallable(
092                                            backgroundTask, sourceGroupId, targetGroupId,
093                                            taskContextMap, userId));
094                    }
095                    catch (Throwable t) {
096                            if (_log.isDebugEnabled()) {
097                                    _log.debug(t, t);
098                            }
099                            else if (_log.isWarnEnabled()) {
100                                    _log.warn("Unable to publish layout: " + t.getMessage());
101                            }
102    
103                            Group sourceGroup = GroupLocalServiceUtil.getGroup(sourceGroupId);
104    
105                            if (sourceGroup.hasStagingGroup()) {
106                                    ServiceContext serviceContext = new ServiceContext();
107    
108                                    serviceContext.setUserId(userId);
109    
110                                    StagingLocalServiceUtil.disableStaging(
111                                            sourceGroup, serviceContext);
112    
113                                    List<BackgroundTask> queuedBackgroundTasks =
114                                            BackgroundTaskLocalServiceUtil.getBackgroundTasks(
115                                                    sourceGroupId,
116                                                    LayoutStagingBackgroundTaskExecutor.class.getName(),
117                                                    BackgroundTaskConstants.STATUS_QUEUED);
118    
119                                    for (BackgroundTask queuedBackgroundTask :
120                                                    queuedBackgroundTasks) {
121    
122                                            BackgroundTaskLocalServiceUtil.amendBackgroundTask(
123                                                    queuedBackgroundTask.getBackgroundTaskId(), null,
124                                                    BackgroundTaskConstants.STATUS_CANCELLED,
125                                                    new ServiceContext());
126                                    }
127                            }
128    
129                            if (t instanceof Exception) {
130                                    throw (Exception)t;
131                            }
132                            else {
133                                    throw new SystemException(t);
134                            }
135                    }
136                    finally {
137                            ExportImportThreadLocal.setLayoutStagingInProcess(false);
138    
139                            StagingUtil.unlockGroup(targetGroupId);
140                    }
141    
142                    return processMissingReferences(backgroundTask, missingReferences);
143            }
144    
145            protected void initLayoutSetBranches(
146                            long userId, long sourceGroupId, long targetGroupId)
147                    throws Exception {
148    
149                    Group sourceGroup = GroupLocalServiceUtil.getGroup(sourceGroupId);
150    
151                    if (!sourceGroup.hasStagingGroup()) {
152                            return;
153                    }
154    
155                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
156                            targetGroupId, false, true);
157                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
158                            targetGroupId, true, true);
159    
160                    UnicodeProperties typeSettingsProperties =
161                            sourceGroup.getTypeSettingsProperties();
162    
163                    boolean branchingPrivate = GetterUtil.getBoolean(
164                            typeSettingsProperties.getProperty("branchingPrivate"));
165                    boolean branchingPublic = GetterUtil.getBoolean(
166                            typeSettingsProperties.getProperty("branchingPublic"));
167    
168                    ServiceContext serviceContext = new ServiceContext();
169    
170                    serviceContext.setUserId(userId);
171    
172                    StagingLocalServiceUtil.checkDefaultLayoutSetBranches(
173                            userId, sourceGroup, branchingPublic, branchingPrivate, false,
174                            serviceContext);
175            }
176    
177            private static Log _log = LogFactoryUtil.getLog(
178                    LayoutStagingBackgroundTaskExecutor.class);
179    
180            private class LayoutStagingCallable implements Callable<MissingReferences> {
181    
182                    public LayoutStagingCallable(
183                            BackgroundTask backgroundTask, long sourceGroupId,
184                            long targetGroupId, Map<String, Serializable> taskContextMap,
185                            long userId) {
186    
187                            _backgroundTask = backgroundTask;
188                            _sourceGroupId = sourceGroupId;
189                            _targetGroupId = targetGroupId;
190                            _taskContextMap = taskContextMap;
191                            _userId = userId;
192                    }
193    
194                    @Override
195                    public MissingReferences call() throws Exception {
196                            File file = null;
197                            MissingReferences missingReferences = null;
198    
199                            try {
200                                    boolean privateLayout = MapUtil.getBoolean(
201                                            _taskContextMap, "privateLayout");
202                                    long[] layoutIds = GetterUtil.getLongValues(
203                                            _taskContextMap.get("layoutIds"));
204                                    Map<String, String[]> parameterMap =
205                                            (Map<String, String[]>)_taskContextMap.get("parameterMap");
206                                    Date startDate = (Date)_taskContextMap.get("startDate");
207                                    Date endDate = (Date)_taskContextMap.get("endDate");
208    
209                                    file = LayoutLocalServiceUtil.exportLayoutsAsFile(
210                                            _sourceGroupId, privateLayout, layoutIds, parameterMap,
211                                            startDate, endDate);
212    
213                                    _backgroundTask = markBackgroundTask(
214                                            _backgroundTask, "exported");
215    
216                                    missingReferences =
217                                            LayoutLocalServiceUtil.validateImportLayoutsFile(
218                                                    _userId, _targetGroupId, privateLayout, parameterMap,
219                                                    file);
220    
221                                    _backgroundTask = markBackgroundTask(
222                                            _backgroundTask, "validated");
223    
224                                    LayoutLocalServiceUtil.importLayouts(
225                                            _userId, _targetGroupId, privateLayout, parameterMap, file);
226    
227                                    initLayoutSetBranches(_userId, _sourceGroupId, _targetGroupId);
228                            }
229                            catch (Exception e) {
230                                    if (PropsValues.STAGING_DELETE_TEMP_LAR_ON_FAILURE) {
231                                            FileUtil.delete(file);
232                                    }
233                                    else if ((file != null) && _log.isErrorEnabled()) {
234                                            _log.error(
235                                                    "Kept temporary LAR file " + file.getAbsolutePath());
236                                    }
237    
238                                    throw e;
239                            }
240    
241                            if (PropsValues.STAGING_DELETE_TEMP_LAR_ON_SUCCESS) {
242                                    FileUtil.delete(file);
243                            }
244                            else if ((file != null) && _log.isDebugEnabled()) {
245                                    _log.debug("Kept temporary LAR file " + file.getAbsolutePath());
246                            }
247    
248                            return missingReferences;
249                    }
250    
251                    private BackgroundTask _backgroundTask;
252                    private long _sourceGroupId;
253                    private long _targetGroupId;
254                    private Map<String, Serializable> _taskContextMap;
255                    private long _userId;
256    
257            }
258    
259    }