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