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.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                                    file = LayoutLocalServiceUtil.exportLayoutsAsFile(
170                                            _sourceGroupId, privateLayout, layoutIds, parameterMap,
171                                            startDate, endDate);
172    
173                                    _backgroundTask = markBackgroundTask(
174                                            _backgroundTask, "exported");
175    
176                                    missingReferences =
177                                            LayoutLocalServiceUtil.validateImportLayoutsFile(
178                                                    _userId, _targetGroupId, privateLayout, parameterMap,
179                                                    file);
180    
181                                    _backgroundTask = markBackgroundTask(
182                                            _backgroundTask, "validated");
183    
184                                    LayoutLocalServiceUtil.importLayouts(
185                                            _userId, _targetGroupId, privateLayout, parameterMap, file);
186    
187                                    initLayoutSetBranches(_userId, _sourceGroupId, _targetGroupId);
188    
189                                    boolean updateLastPublishDate = MapUtil.getBoolean(
190                                            parameterMap,
191                                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
192    
193                                    if (updateLastPublishDate) {
194                                            Group sourceGroup = GroupLocalServiceUtil.getGroup(
195                                                    _sourceGroupId);
196    
197                                            if (!sourceGroup.hasStagingGroup()) {
198                                                    StagingUtil.updateLastPublishDate(
199                                                            _sourceGroupId, privateLayout, endDate);
200                                            }
201                                            else {
202                                                    StagingUtil.updateLastPublishDate(
203                                                            _targetGroupId, privateLayout, endDate);
204                                            }
205                                    }
206                            }
207                            finally {
208                                    FileUtil.delete(file);
209                            }
210    
211                            return missingReferences;
212                    }
213    
214                    private BackgroundTask _backgroundTask;
215                    private long _sourceGroupId;
216                    private long _targetGroupId;
217                    private Map<String, Serializable> _taskContextMap;
218                    private long _userId;
219    
220            }
221    
222    }