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.portlet.messageboards.lar;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.repository.model.FileEntry;
026    import com.liferay.portal.kernel.trash.TrashHandler;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.MapUtil;
029    import com.liferay.portal.kernel.util.ObjectValuePair;
030    import com.liferay.portal.kernel.util.StreamUtil;
031    import com.liferay.portal.kernel.xml.Element;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
034    import com.liferay.portlet.messageboards.model.MBCategory;
035    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
036    import com.liferay.portlet.messageboards.model.MBMessage;
037    import com.liferay.portlet.messageboards.model.MBThread;
038    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
039    import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
040    
041    import java.io.InputStream;
042    
043    import java.util.ArrayList;
044    import java.util.Collections;
045    import java.util.List;
046    import java.util.Map;
047    
048    /**
049     * @author Daniel Kocsis
050     */
051    public class MBMessageStagedModelDataHandler
052            extends BaseStagedModelDataHandler<MBMessage> {
053    
054            public static final String[] CLASS_NAMES = {MBMessage.class.getName()};
055    
056            @Override
057            public void deleteStagedModel(
058                            String uuid, long groupId, String className, String extraData)
059                    throws PortalException, SystemException {
060    
061                    MBMessage message =
062                            MBMessageLocalServiceUtil.fetchMBMessageByUuidAndGroupId(
063                                    uuid, groupId);
064    
065                    if (message != null) {
066                            MBMessageLocalServiceUtil.deleteMessage(message);
067                    }
068            }
069    
070            @Override
071            public String[] getClassNames() {
072                    return CLASS_NAMES;
073            }
074    
075            @Override
076            public String getDisplayName(MBMessage message) {
077                    return message.getSubject();
078            }
079    
080            @Override
081            protected void doExportStagedModel(
082                            PortletDataContext portletDataContext, MBMessage message)
083                    throws Exception {
084    
085                    if (message.getCategoryId() ==
086                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
087    
088                            return;
089                    }
090    
091                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
092                            portletDataContext, message, message.getCategory(),
093                            PortletDataContext.REFERENCE_TYPE_PARENT);
094    
095                    Element messageElement = portletDataContext.getExportDataElement(
096                            message);
097    
098                    message.setPriority(message.getPriority());
099    
100                    MBThread thread = message.getThread();
101    
102                    messageElement.addAttribute(
103                            "question", String.valueOf(thread.isQuestion()));
104    
105                    boolean hasAttachmentsFileEntries =
106                            message.getAttachmentsFileEntriesCount() > 0;
107    
108                    messageElement.addAttribute(
109                            "hasAttachmentsFileEntries",
110                            String.valueOf(hasAttachmentsFileEntries));
111    
112                    if (hasAttachmentsFileEntries) {
113                            for (FileEntry fileEntry : message.getAttachmentsFileEntries()) {
114                                    String name = fileEntry.getTitle();
115                                    String binPath = ExportImportPathUtil.getModelPath(
116                                            message, name);
117    
118                                    Element attachmentElement = messageElement.addElement(
119                                            "attachment");
120    
121                                    attachmentElement.addAttribute("name", name);
122                                    attachmentElement.addAttribute("bin-path", binPath);
123    
124                                    portletDataContext.addZipEntry(
125                                            binPath, fileEntry.getContentStream());
126                            }
127    
128                            long folderId = message.getAttachmentsFolderId();
129    
130                            if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
131                                    message.setAttachmentsFolderId(folderId);
132                            }
133                    }
134    
135                    portletDataContext.addClassedModel(
136                            messageElement, ExportImportPathUtil.getModelPath(message),
137                            message);
138            }
139    
140            @Override
141            protected void doImportStagedModel(
142                            PortletDataContext portletDataContext, MBMessage message)
143                    throws Exception {
144    
145                    long userId = portletDataContext.getUserId(message.getUserUuid());
146    
147                    String userName = message.getUserName();
148    
149                    Map<Long, Long> categoryIds =
150                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
151                                    MBCategory.class);
152    
153                    long parentCategoryId = MapUtil.getLong(
154                            categoryIds, message.getCategoryId(), message.getCategoryId());
155    
156                    Map<Long, Long> threadIds =
157                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
158                                    MBThread.class);
159    
160                    long threadId = MapUtil.getLong(threadIds, message.getThreadId(), 0);
161    
162                    Map<Long, Long> messageIds =
163                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
164                                    MBMessage.class);
165    
166                    long parentMessageId = MapUtil.getLong(
167                            messageIds, message.getParentMessageId(),
168                            message.getParentMessageId());
169    
170                    Element element = portletDataContext.getImportDataStagedModelElement(
171                            message);
172    
173                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
174                            getAttachments(portletDataContext, element, message);
175    
176                    try {
177                            ServiceContext serviceContext =
178                                    portletDataContext.createServiceContext(message);
179    
180                            if ((parentCategoryId !=
181                                            MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
182                                    (parentCategoryId !=
183                                            MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
184                                    (parentCategoryId == message.getCategoryId())) {
185    
186                                    String categoryPath = ExportImportPathUtil.getModelPath(
187                                            portletDataContext, MBCategory.class.getName(),
188                                            parentCategoryId);
189    
190                                    MBCategory category =
191                                            (MBCategory)portletDataContext.getZipEntryAsObject(
192                                                    categoryPath);
193    
194                                    StagedModelDataHandlerUtil.importReferenceStagedModel(
195                                            portletDataContext, category);
196    
197                                    parentCategoryId = MapUtil.getLong(
198                                            categoryIds, message.getCategoryId(),
199                                            message.getCategoryId());
200                            }
201    
202                            MBMessage importedMessage = null;
203    
204                            if (portletDataContext.isDataStrategyMirror()) {
205                                    MBMessage existingMessage =
206                                            MBMessageLocalServiceUtil.fetchMBMessageByUuidAndGroupId(
207                                                    message.getUuid(),
208                                                    portletDataContext.getScopeGroupId());
209    
210                                    if (existingMessage == null) {
211                                            serviceContext.setUuid(message.getUuid());
212    
213                                            importedMessage = MBMessageLocalServiceUtil.addMessage(
214                                                    userId, userName, portletDataContext.getScopeGroupId(),
215                                                    parentCategoryId, threadId, parentMessageId,
216                                                    message.getSubject(), message.getBody(),
217                                                    message.getFormat(), inputStreamOVPs,
218                                                    message.getAnonymous(), message.getPriority(),
219                                                    message.getAllowPingbacks(), serviceContext);
220                                    }
221                                    else {
222                                            importedMessage = MBMessageLocalServiceUtil.updateMessage(
223                                                    userId, existingMessage.getMessageId(),
224                                                    message.getSubject(), message.getBody(),
225                                                    inputStreamOVPs, new ArrayList<String>(),
226                                                    message.getPriority(), message.getAllowPingbacks(),
227                                                    serviceContext);
228                                    }
229                            }
230                            else {
231                                    importedMessage = MBMessageLocalServiceUtil.addMessage(
232                                            userId, userName, portletDataContext.getScopeGroupId(),
233                                            parentCategoryId, threadId, parentMessageId,
234                                            message.getSubject(), message.getBody(),
235                                            message.getFormat(), inputStreamOVPs,
236                                            message.getAnonymous(), message.getPriority(),
237                                            message.getAllowPingbacks(), serviceContext);
238                            }
239    
240                            importedMessage.setAnswer(message.getAnswer());
241    
242                            if (importedMessage.isRoot()) {
243                                    MBThreadLocalServiceUtil.updateQuestion(
244                                            importedMessage.getThreadId(),
245                                            GetterUtil.getBoolean(element.attributeValue("question")));
246                            }
247    
248                            threadIds.put(message.getThreadId(), importedMessage.getThreadId());
249    
250                            portletDataContext.importClassedModel(message, importedMessage);
251                    }
252                    finally {
253                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
254                                            inputStreamOVPs) {
255    
256                                    InputStream inputStream = inputStreamOVP.getValue();
257    
258                                    StreamUtil.cleanUp(inputStream);
259                            }
260                    }
261            }
262    
263            @Override
264            protected void doRestoreStagedModel(
265                            PortletDataContext portletDataContext, MBMessage message)
266                    throws Exception {
267    
268                    long userId = portletDataContext.getUserId(message.getUserUuid());
269    
270                    MBMessage existingMessage =
271                            MBMessageLocalServiceUtil.fetchMBMessageByUuidAndGroupId(
272                                    message.getUuid(), portletDataContext.getScopeGroupId());
273    
274                    if (existingMessage == null) {
275                            return;
276                    }
277    
278                    if (existingMessage.isInTrash()) {
279                            TrashHandler trashHandler = existingMessage.getTrashHandler();
280    
281                            if (trashHandler.isRestorable(existingMessage.getMessageId())) {
282                                    trashHandler.restoreTrashEntry(
283                                            userId, existingMessage.getMessageId());
284                            }
285                    }
286    
287                    if (existingMessage.isInTrashContainer()) {
288                            MBThread existingThread = existingMessage.getThread();
289    
290                            TrashHandler trashHandler = existingThread.getTrashHandler();
291    
292                            if (trashHandler.isRestorable(existingThread.getThreadId())) {
293                                    trashHandler.restoreTrashEntry(
294                                            userId, existingThread.getThreadId());
295                            }
296                    }
297            }
298    
299            protected List<ObjectValuePair<String, InputStream>> getAttachments(
300                    PortletDataContext portletDataContext, Element messageElement,
301                    MBMessage message) {
302    
303                    boolean hasAttachmentsFileEntries = GetterUtil.getBoolean(
304                            messageElement.attributeValue("hasAttachmentsFileEntries"));
305    
306                    if (!hasAttachmentsFileEntries) {
307                            return Collections.emptyList();
308                    }
309    
310                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
311                            new ArrayList<ObjectValuePair<String, InputStream>>();
312    
313                    List<Element> attachmentElements = messageElement.elements(
314                            "attachment");
315    
316                    for (Element attachmentElement : attachmentElements) {
317                            String name = attachmentElement.attributeValue("name");
318                            String binPath = attachmentElement.attributeValue("bin-path");
319    
320                            InputStream inputStream =
321                                    portletDataContext.getZipEntryAsInputStream(binPath);
322    
323                            if (inputStream == null) {
324                                    continue;
325                            }
326    
327                            ObjectValuePair<String, InputStream> inputStreamOVP =
328                                    new ObjectValuePair<String, InputStream>(name, inputStream);
329    
330                            inputStreamOVPs.add(inputStreamOVP);
331                    }
332    
333                    if (inputStreamOVPs.isEmpty()) {
334                            _log.error(
335                                    "Could not find attachments for message " +
336                                            message.getMessageId());
337                    }
338    
339                    return inputStreamOVPs;
340            }
341    
342            private static Log _log = LogFactoryUtil.getLog(
343                    MBMessageStagedModelDataHandler.class);
344    
345    }