001
014
015 package com.liferay.portal.lar.backgroundtask;
016
017 import com.liferay.portal.NoSuchLayoutException;
018 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.lar.ExportImportDateUtil;
022 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
023 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
024 import com.liferay.portal.kernel.lar.MissingReferences;
025 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
026 import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleConstants;
027 import com.liferay.portal.kernel.lar.lifecycle.ExportImportLifecycleManager;
028 import com.liferay.portal.kernel.log.Log;
029 import com.liferay.portal.kernel.log.LogFactoryUtil;
030 import com.liferay.portal.kernel.util.DateRange;
031 import com.liferay.portal.kernel.util.FileUtil;
032 import com.liferay.portal.kernel.util.GetterUtil;
033 import com.liferay.portal.kernel.util.MapUtil;
034 import com.liferay.portal.kernel.util.StreamUtil;
035 import com.liferay.portal.model.BackgroundTask;
036 import com.liferay.portal.model.ExportImportConfiguration;
037 import com.liferay.portal.model.Layout;
038 import com.liferay.portal.security.auth.HttpPrincipal;
039 import com.liferay.portal.service.ExportImportConfigurationLocalServiceUtil;
040 import com.liferay.portal.service.LayoutLocalServiceUtil;
041 import com.liferay.portal.service.http.LayoutServiceHttp;
042 import com.liferay.portal.service.http.StagingServiceHttp;
043 import com.liferay.portal.util.PropsValues;
044
045 import java.io.File;
046 import java.io.FileInputStream;
047 import java.io.Serializable;
048
049 import java.util.ArrayList;
050 import java.util.Date;
051 import java.util.List;
052 import java.util.Map;
053
054
057 public class LayoutRemoteStagingBackgroundTaskExecutor
058 extends BaseStagingBackgroundTaskExecutor {
059
060 public LayoutRemoteStagingBackgroundTaskExecutor() {
061 setBackgroundTaskStatusMessageTranslator(
062 new LayoutStagingBackgroundTaskStatusMessageTranslator());
063 }
064
065 @Override
066 public BackgroundTaskResult execute(BackgroundTask backgroundTask)
067 throws PortalException {
068
069 Map<String, Serializable> taskContextMap =
070 backgroundTask.getTaskContextMap();
071
072 long exportImportConfigurationId = MapUtil.getLong(
073 taskContextMap, "exportImportConfigurationId");
074
075 ExportImportConfiguration exportImportConfiguration =
076 ExportImportConfigurationLocalServiceUtil.
077 getExportImportConfiguration(exportImportConfigurationId);
078
079 Map<String, Serializable> settingsMap =
080 exportImportConfiguration.getSettingsMap();
081
082 long sourceGroupId = MapUtil.getLong(settingsMap, "sourceGroupId");
083 boolean privateLayout = MapUtil.getBoolean(
084 settingsMap, "privateLayout");
085
086 initThreadLocals(sourceGroupId, privateLayout);
087
088 Map<Long, Boolean> layoutIdMap = (Map<Long, Boolean>)settingsMap.get(
089 "layoutIdMap");
090 Map<String, String[]> parameterMap =
091 (Map<String, String[]>)settingsMap.get("parameterMap");
092 long remoteGroupId = MapUtil.getLong(settingsMap, "remoteGroupId");
093 DateRange dateRange = ExportImportDateUtil.getDateRange(
094 exportImportConfiguration,
095 ExportImportDateUtil.RANGE_FROM_LAST_PUBLISH_DATE);
096 HttpPrincipal httpPrincipal = (HttpPrincipal)taskContextMap.get(
097 "httpPrincipal");
098
099 clearBackgroundTaskStatus(backgroundTask);
100
101 long stagingRequestId = 0;
102
103 File file = null;
104 FileInputStream fileInputStream = null;
105 MissingReferences missingReferences = null;
106
107 try {
108 ExportImportThreadLocal.setLayoutStagingInProcess(true);
109
110 ExportImportLifecycleManager.fireExportImportLifecycleEvent(
111 ExportImportLifecycleConstants.
112 EVENT_PUBLICATION_LAYOUT_REMOTE_STARTED,
113 exportImportConfiguration);
114
115 file = exportLayoutsAsFile(
116 sourceGroupId, privateLayout, layoutIdMap, parameterMap,
117 remoteGroupId, dateRange.getStartDate(), dateRange.getEndDate(),
118 httpPrincipal);
119
120 String checksum = FileUtil.getMD5Checksum(file);
121
122 fileInputStream = new FileInputStream(file);
123
124 stagingRequestId = StagingServiceHttp.createStagingRequest(
125 httpPrincipal, remoteGroupId, checksum);
126
127 byte[] bytes =
128 new byte[PropsValues.STAGING_REMOTE_TRANSFER_BUFFER_SIZE];
129
130 int i = 0;
131 int j = 0;
132
133 String numberFormat = String.format(
134 "%%0%dd",
135 String.valueOf(
136 (int)(file.length() / bytes.length)).length() + 1);
137
138 while ((i = fileInputStream.read(bytes)) >= 0) {
139 String fileName =
140 file.getName() + String.format(numberFormat, j++);
141
142 if (i < PropsValues.STAGING_REMOTE_TRANSFER_BUFFER_SIZE) {
143 byte[] tempBytes = new byte[i];
144
145 System.arraycopy(bytes, 0, tempBytes, 0, i);
146
147 StagingServiceHttp.updateStagingRequest(
148 httpPrincipal, stagingRequestId, fileName, tempBytes);
149 }
150 else {
151 StagingServiceHttp.updateStagingRequest(
152 httpPrincipal, stagingRequestId, fileName, bytes);
153 }
154
155 bytes =
156 new byte[PropsValues.STAGING_REMOTE_TRANSFER_BUFFER_SIZE];
157 }
158
159 markBackgroundTask(
160 backgroundTask.getBackgroundTaskId(), "exported");
161
162 missingReferences = StagingServiceHttp.validateStagingRequest(
163 httpPrincipal, stagingRequestId, privateLayout, parameterMap);
164
165 markBackgroundTask(
166 backgroundTask.getBackgroundTaskId(), "validated");
167
168 StagingServiceHttp.publishStagingRequest(
169 httpPrincipal, stagingRequestId, privateLayout, parameterMap);
170
171 boolean updateLastPublishDate = MapUtil.getBoolean(
172 parameterMap, PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
173
174 if (updateLastPublishDate) {
175 ExportImportDateUtil.updateLastPublishDate(
176 sourceGroupId, privateLayout, dateRange,
177 dateRange.getEndDate());
178 }
179
180 ExportImportLifecycleManager.fireExportImportLifecycleEvent(
181 ExportImportLifecycleConstants.
182 EVENT_PUBLICATION_LAYOUT_REMOTE_SUCCEEDED,
183 exportImportConfiguration);
184 }
185 catch (Throwable t) {
186 ExportImportLifecycleManager.fireExportImportLifecycleEvent(
187 ExportImportLifecycleConstants.
188 EVENT_PUBLICATION_LAYOUT_REMOTE_FAILED,
189 exportImportConfiguration);
190
191 if (_log.isDebugEnabled()) {
192 _log.debug(t, t);
193 }
194 else if (_log.isWarnEnabled()) {
195 _log.warn("Unable to publish layout: " + t.getMessage());
196 }
197
198 throw new SystemException(t);
199 }
200 finally {
201 ExportImportThreadLocal.setLayoutStagingInProcess(false);
202
203 StreamUtil.cleanUp(fileInputStream);
204
205 FileUtil.delete(file);
206
207 if (stagingRequestId > 0) {
208 StagingServiceHttp.cleanUpStagingRequest(
209 httpPrincipal, stagingRequestId);
210 }
211 }
212
213 return processMissingReferences(
214 backgroundTask.getBackgroundTaskId(), missingReferences);
215 }
216
217 protected File exportLayoutsAsFile(
218 long sourceGroupId, boolean privateLayout,
219 Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
220 long remoteGroupId, Date startDate, Date endDate,
221 HttpPrincipal httpPrincipal)
222 throws PortalException {
223
224 List<Layout> layouts = new ArrayList<Layout>();
225
226 if (layoutIdMap != null) {
227 for (Map.Entry<Long, Boolean> entry : layoutIdMap.entrySet()) {
228 long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
229 boolean includeChildren = entry.getValue();
230
231 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
232
233 if (!layouts.contains(layout)) {
234 layouts.add(layout);
235 }
236
237 List<Layout> parentLayouts = getMissingRemoteParentLayouts(
238 httpPrincipal, layout, remoteGroupId);
239
240 for (Layout parentLayout : parentLayouts) {
241 if (!layouts.contains(parentLayout)) {
242 layouts.add(parentLayout);
243 }
244 }
245
246 if (includeChildren) {
247 for (Layout childLayout : layout.getAllChildren()) {
248 if (!layouts.contains(childLayout)) {
249 layouts.add(childLayout);
250 }
251 }
252 }
253 }
254 }
255
256 long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layouts);
257
258 return LayoutLocalServiceUtil.exportLayoutsAsFile(
259 sourceGroupId, privateLayout, layoutIds, parameterMap, startDate,
260 endDate);
261 }
262
263
267 protected List<Layout> getMissingRemoteParentLayouts(
268 HttpPrincipal httpPrincipal, Layout layout, long remoteGroupId)
269 throws PortalException {
270
271 List<Layout> missingRemoteParentLayouts = new ArrayList<Layout>();
272
273 long parentLayoutId = layout.getParentLayoutId();
274
275 while (parentLayoutId > 0) {
276 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
277 layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
278
279 try {
280 LayoutServiceHttp.getLayoutByUuidAndGroupId(
281 httpPrincipal, parentLayout.getUuid(), remoteGroupId,
282 parentLayout.getPrivateLayout());
283
284
285
286 break;
287 }
288 catch (NoSuchLayoutException nsle) {
289 missingRemoteParentLayouts.add(parentLayout);
290
291 parentLayoutId = parentLayout.getParentLayoutId();
292 }
293 }
294
295 return missingRemoteParentLayouts;
296 }
297
298 private static Log _log = LogFactoryUtil.getLog(
299 LayoutRemoteStagingBackgroundTaskExecutor.class);
300
301 }