001
014
015 package com.liferay.portlet.messageboards.lar;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.repository.model.FileEntry;
022 import com.liferay.portal.kernel.trash.TrashHandler;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.MapUtil;
025 import com.liferay.portal.kernel.util.ObjectValuePair;
026 import com.liferay.portal.kernel.util.StreamUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.service.ServiceContext;
030 import com.liferay.portlet.documentlibrary.lar.FileEntryUtil;
031 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
032 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
033 import com.liferay.portlet.exportimport.lar.BaseStagedModelDataHandler;
034 import com.liferay.portlet.exportimport.lar.ExportImportPathUtil;
035 import com.liferay.portlet.exportimport.lar.PortletDataContext;
036 import com.liferay.portlet.exportimport.lar.StagedModelDataHandlerUtil;
037 import com.liferay.portlet.exportimport.lar.StagedModelModifiedDateComparator;
038 import com.liferay.portlet.messageboards.model.MBCategory;
039 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
040 import com.liferay.portlet.messageboards.model.MBDiscussion;
041 import com.liferay.portlet.messageboards.model.MBMessage;
042 import com.liferay.portlet.messageboards.model.MBThread;
043 import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
044 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
045 import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
046 import com.liferay.portlet.ratings.model.RatingsEntry;
047 import com.liferay.portlet.ratings.service.RatingsEntryLocalServiceUtil;
048
049 import java.io.InputStream;
050
051 import java.util.ArrayList;
052 import java.util.Collections;
053 import java.util.List;
054 import java.util.Map;
055
056
059 public class MBMessageStagedModelDataHandler
060 extends BaseStagedModelDataHandler<MBMessage> {
061
062 public static final String[] CLASS_NAMES = {MBMessage.class.getName()};
063
064 @Override
065 public void deleteStagedModel(MBMessage message) throws PortalException {
066 MBMessageLocalServiceUtil.deleteMessage(message);
067 }
068
069 @Override
070 public void deleteStagedModel(
071 String uuid, long groupId, String className, String extraData)
072 throws PortalException {
073
074 MBMessage message = fetchStagedModelByUuidAndGroupId(uuid, groupId);
075
076 if (message != null) {
077 deleteStagedModel(message);
078 }
079 }
080
081 @Override
082 public MBMessage fetchStagedModelByUuidAndGroupId(
083 String uuid, long groupId) {
084
085 return MBMessageLocalServiceUtil.fetchMBMessageByUuidAndGroupId(
086 uuid, groupId);
087 }
088
089 @Override
090 public List<MBMessage> fetchStagedModelsByUuidAndCompanyId(
091 String uuid, long companyId) {
092
093 return MBMessageLocalServiceUtil.getMBMessagesByUuidAndCompanyId(
094 uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
095 new StagedModelModifiedDateComparator<MBMessage>());
096 }
097
098 @Override
099 public String[] getClassNames() {
100 return CLASS_NAMES;
101 }
102
103 @Override
104 public String getDisplayName(MBMessage message) {
105 return message.getSubject();
106 }
107
108 protected MBMessage addDiscussionMessage(
109 PortletDataContext portletDataContext, long userId, long threadId,
110 long parentMessageId, MBMessage message,
111 ServiceContext serviceContext)
112 throws PortalException {
113
114 MBDiscussion discussion =
115 MBDiscussionLocalServiceUtil.getThreadDiscussion(threadId);
116
117 MBMessage importedMessage = null;
118
119 if (!message.isRoot()) {
120 importedMessage = MBMessageLocalServiceUtil.addDiscussionMessage(
121 userId, message.getUserName(),
122 portletDataContext.getScopeGroupId(), discussion.getClassName(),
123 discussion.getClassPK(), threadId, parentMessageId,
124 message.getSubject(), message.getBody(), serviceContext);
125 }
126 else {
127 MBThread thread = MBThreadLocalServiceUtil.getThread(threadId);
128
129 importedMessage = MBMessageLocalServiceUtil.getMBMessage(
130 thread.getRootMessageId());
131 }
132
133 return importedMessage;
134 }
135
136 @Override
137 protected void doExportStagedModel(
138 PortletDataContext portletDataContext, MBMessage message)
139 throws Exception {
140
141 if (message.isDiscussion()) {
142 MBDiscussion discussion =
143 MBDiscussionLocalServiceUtil.getDiscussion(
144 message.getClassName(), message.getClassPK());
145
146 StagedModelDataHandlerUtil.exportReferenceStagedModel(
147 portletDataContext, message, discussion,
148 PortletDataContext.REFERENCE_TYPE_PARENT);
149
150
151
152
153 List<RatingsEntry> ratingsEntries =
154 RatingsEntryLocalServiceUtil.getEntries(
155 MBDiscussion.class.getName(), message.getMessageId());
156
157 for (RatingsEntry ratingsEntry : ratingsEntries) {
158 StagedModelDataHandlerUtil.exportReferenceStagedModel(
159 portletDataContext, message, ratingsEntry,
160 PortletDataContext.REFERENCE_TYPE_WEAK);
161 }
162 }
163 else if (message.getCategoryId() !=
164 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
165
166 StagedModelDataHandlerUtil.exportReferenceStagedModel(
167 portletDataContext, message, message.getCategory(),
168 PortletDataContext.REFERENCE_TYPE_PARENT);
169 }
170
171 if (!message.isRoot()) {
172 MBMessage parentMessage = MBMessageLocalServiceUtil.getMessage(
173 message.getParentMessageId());
174
175 StagedModelDataHandlerUtil.exportReferenceStagedModel(
176 portletDataContext, message, parentMessage,
177 PortletDataContext.REFERENCE_TYPE_PARENT);
178 }
179
180 message.setPriority(message.getPriority());
181
182 MBThread thread = message.getThread();
183
184 Element messageElement = portletDataContext.getExportDataElement(
185 message);
186
187 messageElement.addAttribute(
188 "question", String.valueOf(thread.isQuestion()));
189 messageElement.addAttribute("threadUuid", thread.getUuid());
190
191 boolean hasAttachmentsFileEntries =
192 message.getAttachmentsFileEntriesCount() > 0;
193
194 messageElement.addAttribute(
195 "hasAttachmentsFileEntries",
196 String.valueOf(hasAttachmentsFileEntries));
197
198 if (hasAttachmentsFileEntries) {
199 for (FileEntry fileEntry : message.getAttachmentsFileEntries()) {
200 StagedModelDataHandlerUtil.exportReferenceStagedModel(
201 portletDataContext, message, fileEntry,
202 PortletDataContext.REFERENCE_TYPE_WEAK);
203 }
204
205 long folderId = message.getAttachmentsFolderId();
206
207 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
208 message.setAttachmentsFolderId(folderId);
209 }
210 }
211
212 portletDataContext.addClassedModel(
213 messageElement, ExportImportPathUtil.getModelPath(message),
214 message);
215 }
216
217 @Override
218 protected void doImportStagedModel(
219 PortletDataContext portletDataContext, MBMessage message)
220 throws Exception {
221
222 if (!message.isRoot()) {
223 StagedModelDataHandlerUtil.importReferenceStagedModel(
224 portletDataContext, message, MBMessage.class,
225 message.getParentMessageId());
226 }
227
228 long userId = portletDataContext.getUserId(message.getUserUuid());
229
230 Map<Long, Long> categoryIds =
231 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
232 MBCategory.class);
233
234 long parentCategoryId = MapUtil.getLong(
235 categoryIds, message.getCategoryId(), message.getCategoryId());
236
237 Map<Long, Long> threadIds =
238 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
239 MBThread.class);
240
241 long threadId = MapUtil.getLong(threadIds, message.getThreadId(), 0);
242
243 Element messageElement =
244 portletDataContext.getImportDataStagedModelElement(message);
245
246 if (threadId == 0) {
247 String threadUuid = messageElement.attributeValue("threadUuid");
248
249 MBThread thread =
250 MBThreadLocalServiceUtil.fetchMBThreadByUuidAndGroupId(
251 threadUuid, portletDataContext.getScopeGroupId());
252
253 if (thread != null) {
254 threadId = thread.getThreadId();
255 }
256 }
257
258 Map<Long, Long> messageIds =
259 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
260 MBMessage.class);
261
262 long parentMessageId = MapUtil.getLong(
263 messageIds, message.getParentMessageId(),
264 message.getParentMessageId());
265
266 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
267 getAttachments(portletDataContext, messageElement, message);
268
269 try {
270 ServiceContext serviceContext =
271 portletDataContext.createServiceContext(message);
272
273 MBMessage importedMessage = null;
274
275 if (portletDataContext.isDataStrategyMirror()) {
276 MBMessage existingMessage = fetchStagedModelByUuidAndGroupId(
277 message.getUuid(), portletDataContext.getScopeGroupId());
278
279 if (existingMessage == null) {
280 serviceContext.setUuid(message.getUuid());
281
282 if (message.isDiscussion()) {
283 importedMessage = addDiscussionMessage(
284 portletDataContext, userId, threadId,
285 parentMessageId, message, serviceContext);
286 }
287 else {
288 importedMessage = MBMessageLocalServiceUtil.addMessage(
289 userId, message.getUserName(),
290 portletDataContext.getScopeGroupId(),
291 parentCategoryId, threadId, parentMessageId,
292 message.getSubject(), message.getBody(),
293 message.getFormat(), inputStreamOVPs,
294 message.getAnonymous(), message.getPriority(),
295 message.getAllowPingbacks(), serviceContext);
296 }
297 }
298 else {
299 if (!message.isRoot() && message.isDiscussion()) {
300 MBDiscussion discussion =
301 MBDiscussionLocalServiceUtil.getThreadDiscussion(
302 threadId);
303
304 importedMessage =
305 MBMessageLocalServiceUtil.updateDiscussionMessage(
306 userId, existingMessage.getMessageId(),
307 discussion.getClassName(),
308 discussion.getClassPK(), message.getSubject(),
309 message.getBody(), serviceContext);
310 }
311 else {
312 importedMessage =
313 MBMessageLocalServiceUtil.updateMessage(
314 userId, existingMessage.getMessageId(),
315 message.getSubject(), message.getBody(),
316 inputStreamOVPs, new ArrayList<String>(),
317 message.getPriority(),
318 message.getAllowPingbacks(), serviceContext);
319 }
320 }
321 }
322 else {
323 if (message.isDiscussion()) {
324 importedMessage = addDiscussionMessage(
325 portletDataContext, userId, threadId, parentMessageId,
326 message, serviceContext);
327 }
328 else {
329 importedMessage = MBMessageLocalServiceUtil.addMessage(
330 userId, message.getUserName(),
331 portletDataContext.getScopeGroupId(), parentCategoryId,
332 threadId, parentMessageId, message.getSubject(),
333 message.getBody(), message.getFormat(), inputStreamOVPs,
334 message.getAnonymous(), message.getPriority(),
335 message.getAllowPingbacks(), serviceContext);
336 }
337 }
338
339 MBMessageLocalServiceUtil.updateAnswer(
340 importedMessage, message.isAnswer(), false);
341
342 if (importedMessage.isRoot() && !importedMessage.isDiscussion()) {
343 MBThreadLocalServiceUtil.updateQuestion(
344 importedMessage.getThreadId(),
345 GetterUtil.getBoolean(
346 messageElement.attributeValue("question")));
347 }
348
349 if (message.isDiscussion()) {
350 Map<Long, Long> discussionIds =
351 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
352 MBDiscussion.class);
353
354 discussionIds.put(
355 message.getMessageId(), importedMessage.getMessageId());
356 }
357
358 threadIds.put(message.getThreadId(), importedMessage.getThreadId());
359
360
361
362 MBThread thread = importedMessage.getThread();
363
364 thread.setUuid(messageElement.attributeValue("threadUuid"));
365
366 MBThreadLocalServiceUtil.updateMBThread(thread);
367
368 portletDataContext.importClassedModel(message, importedMessage);
369 }
370 finally {
371 for (ObjectValuePair<String, InputStream> inputStreamOVP :
372 inputStreamOVPs) {
373
374 InputStream inputStream = inputStreamOVP.getValue();
375
376 StreamUtil.cleanUp(inputStream);
377 }
378 }
379 }
380
381 @Override
382 protected void doRestoreStagedModel(
383 PortletDataContext portletDataContext, MBMessage message)
384 throws Exception {
385
386 long userId = portletDataContext.getUserId(message.getUserUuid());
387
388 MBMessage existingMessage = fetchStagedModelByUuidAndGroupId(
389 message.getUuid(), portletDataContext.getScopeGroupId());
390
391 if (existingMessage == null) {
392 return;
393 }
394
395 if (existingMessage.isInTrash()) {
396 TrashHandler trashHandler = existingMessage.getTrashHandler();
397
398 if (trashHandler.isRestorable(existingMessage.getMessageId())) {
399 trashHandler.restoreTrashEntry(
400 userId, existingMessage.getMessageId());
401 }
402 }
403
404 if (existingMessage.isInTrashContainer()) {
405 MBThread existingThread = existingMessage.getThread();
406
407 TrashHandler trashHandler = existingThread.getTrashHandler();
408
409 if (trashHandler.isRestorable(existingThread.getThreadId())) {
410 trashHandler.restoreTrashEntry(
411 userId, existingThread.getThreadId());
412 }
413 }
414 }
415
416 protected List<ObjectValuePair<String, InputStream>> getAttachments(
417 PortletDataContext portletDataContext, Element messageElement,
418 MBMessage message) {
419
420 boolean hasAttachmentsFileEntries = GetterUtil.getBoolean(
421 messageElement.attributeValue("hasAttachmentsFileEntries"));
422
423 if (!hasAttachmentsFileEntries) {
424 return Collections.emptyList();
425 }
426
427 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
428 new ArrayList<>();
429
430 List<Element> attachmentElements =
431 portletDataContext.getReferenceDataElements(
432 messageElement, DLFileEntry.class,
433 PortletDataContext.REFERENCE_TYPE_WEAK);
434
435 for (Element attachmentElement : attachmentElements) {
436 String path = attachmentElement.attributeValue("path");
437
438 FileEntry fileEntry =
439 (FileEntry)portletDataContext.getZipEntryAsObject(path);
440
441 InputStream inputStream = null;
442
443 String binPath = attachmentElement.attributeValue("bin-path");
444
445 if (Validator.isNull(binPath) &&
446 portletDataContext.isPerformDirectBinaryImport()) {
447
448 try {
449 inputStream = FileEntryUtil.getContentStream(fileEntry);
450 }
451 catch (Exception e) {
452 }
453 }
454 else {
455 inputStream = portletDataContext.getZipEntryAsInputStream(
456 binPath);
457 }
458
459 if (inputStream == null) {
460 if (_log.isWarnEnabled()) {
461 _log.warn(
462 "Unable to import attachment for file entry " +
463 fileEntry.getFileEntryId());
464 }
465
466 continue;
467 }
468
469 ObjectValuePair<String, InputStream> inputStreamOVP =
470 new ObjectValuePair<>(fileEntry.getTitle(), inputStream);
471
472 inputStreamOVPs.add(inputStreamOVP);
473 }
474
475 if (inputStreamOVPs.isEmpty()) {
476 _log.error(
477 "Could not find attachments for message " +
478 message.getMessageId());
479 }
480
481 return inputStreamOVPs;
482 }
483
484 private static final Log _log = LogFactoryUtil.getLog(
485 MBMessageStagedModelDataHandler.class);
486
487 }