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