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