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