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