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.exportReferenceStagedModel(
091                            portletDataContext, message, message.getCategory(),
092                            PortletDataContext.REFERENCE_TYPE_PARENT);
093    
094                    Element messageElement = portletDataContext.getExportDataElement(
095                            message);
096    
097                    message.setPriority(message.getPriority());
098    
099                    MBThread thread = message.getThread();
100    
101                    messageElement.addAttribute(
102                            "question", String.valueOf(thread.isQuestion()));
103    
104                    boolean hasAttachmentsFileEntries =
105                            message.getAttachmentsFileEntriesCount() > 0;
106    
107                    messageElement.addAttribute(
108                            "hasAttachmentsFileEntries",
109                            String.valueOf(hasAttachmentsFileEntries));
110    
111                    if (hasAttachmentsFileEntries) {
112                            for (FileEntry fileEntry : message.getAttachmentsFileEntries()) {
113                                    String name = fileEntry.getTitle();
114                                    String binPath = ExportImportPathUtil.getModelPath(
115                                            message, name);
116    
117                                    Element attachmentElement = messageElement.addElement(
118                                            "attachment");
119    
120                                    attachmentElement.addAttribute("name", name);
121                                    attachmentElement.addAttribute("bin-path", binPath);
122    
123                                    portletDataContext.addZipEntry(
124                                            binPath, fileEntry.getContentStream());
125                            }
126    
127                            long folderId = message.getAttachmentsFolderId();
128    
129                            if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
130                                    message.setAttachmentsFolderId(folderId);
131                            }
132                    }
133    
134                    portletDataContext.addClassedModel(
135                            messageElement, ExportImportPathUtil.getModelPath(message), message,
136                            MBPortletDataHandler.NAMESPACE);
137            }
138    
139            @Override
140            protected void doImportStagedModel(
141                            PortletDataContext portletDataContext, MBMessage message)
142                    throws Exception {
143    
144                    long userId = portletDataContext.getUserId(message.getUserUuid());
145    
146                    String userName = message.getUserName();
147    
148                    Map<Long, Long> categoryIds =
149                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
150                                    MBCategory.class);
151    
152                    long parentCategoryId = MapUtil.getLong(
153                            categoryIds, message.getCategoryId(), message.getCategoryId());
154    
155                    Map<Long, Long> threadIds =
156                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
157                                    MBThread.class);
158    
159                    long threadId = MapUtil.getLong(threadIds, message.getThreadId(), 0);
160    
161                    Map<Long, Long> messageIds =
162                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
163                                    MBMessage.class);
164    
165                    long parentMessageId = MapUtil.getLong(
166                            messageIds, message.getParentMessageId(),
167                            message.getParentMessageId());
168    
169                    Element element = portletDataContext.getImportDataStagedModelElement(
170                            message);
171    
172                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
173                            getAttachments(portletDataContext, element, message);
174    
175                    try {
176                            ServiceContext serviceContext =
177                                    portletDataContext.createServiceContext(
178                                            message, MBPortletDataHandler.NAMESPACE);
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.importStagedModel(
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(
251                                    message, importedMessage, MBPortletDataHandler.NAMESPACE);
252                    }
253                    finally {
254                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
255                                            inputStreamOVPs) {
256    
257                                    InputStream inputStream = inputStreamOVP.getValue();
258    
259                                    StreamUtil.cleanUp(inputStream);
260                            }
261                    }
262            }
263    
264            protected List<ObjectValuePair<String, InputStream>> getAttachments(
265                    PortletDataContext portletDataContext, Element messageElement,
266                    MBMessage message) {
267    
268                    boolean hasAttachmentsFileEntries = GetterUtil.getBoolean(
269                            messageElement.attributeValue("hasAttachmentsFileEntries"));
270    
271                    if (!hasAttachmentsFileEntries) {
272                            return Collections.emptyList();
273                    }
274    
275                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
276                            new ArrayList<ObjectValuePair<String, InputStream>>();
277    
278                    List<Element> attachmentElements = messageElement.elements(
279                            "attachment");
280    
281                    for (Element attachmentElement : attachmentElements) {
282                            String name = attachmentElement.attributeValue("name");
283                            String binPath = attachmentElement.attributeValue("bin-path");
284    
285                            InputStream inputStream =
286                                    portletDataContext.getZipEntryAsInputStream(binPath);
287    
288                            if (inputStream == null) {
289                                    continue;
290                            }
291    
292                            ObjectValuePair<String, InputStream> inputStreamOVP =
293                                    new ObjectValuePair<String, InputStream>(name, inputStream);
294    
295                            inputStreamOVPs.add(inputStreamOVP);
296                    }
297    
298                    if (inputStreamOVPs.isEmpty()) {
299                            _log.error(
300                                    "Could not find attachments for message " +
301                                            message.getMessageId());
302                    }
303    
304                    return inputStreamOVPs;
305            }
306    
307            private static Log _log = LogFactoryUtil.getLog(
308                    MBMessageStagedModelDataHandler.class);
309    
310    }