001    /**
002     * Copyright (c) 2000-present 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.wiki.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.lar.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
021    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
022    import com.liferay.portal.kernel.lar.PortletDataContext;
023    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
024    import com.liferay.portal.kernel.lar.StagedModelModifiedDateComparator;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.repository.model.FileEntry;
028    import com.liferay.portal.kernel.trash.TrashHandler;
029    import com.liferay.portal.kernel.util.ListUtil;
030    import com.liferay.portal.kernel.util.MapUtil;
031    import com.liferay.portal.kernel.util.MimeTypesUtil;
032    import com.liferay.portal.kernel.util.StreamUtil;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.kernel.xml.Element;
035    import com.liferay.portal.service.ServiceContext;
036    import com.liferay.portlet.documentlibrary.NoSuchFileException;
037    import com.liferay.portlet.documentlibrary.lar.FileEntryUtil;
038    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
039    import com.liferay.portlet.wiki.model.WikiNode;
040    import com.liferay.portlet.wiki.model.WikiPage;
041    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
042    
043    import java.io.InputStream;
044    
045    import java.util.List;
046    import java.util.Map;
047    
048    /**
049     * @author Zsolt Berentey
050     */
051    public class WikiPageStagedModelDataHandler
052            extends BaseStagedModelDataHandler<WikiPage> {
053    
054            public static final String[] CLASS_NAMES = {WikiPage.class.getName()};
055    
056            @Override
057            public void deleteStagedModel(
058                            String uuid, long groupId, String className, String extraData)
059                    throws PortalException {
060    
061                    WikiPage wikiPage = fetchStagedModelByUuidAndGroupId(uuid, groupId);
062    
063                    if (wikiPage != null) {
064                            WikiPageLocalServiceUtil.deletePage(wikiPage);
065                    }
066            }
067    
068            @Override
069            public WikiPage fetchStagedModelByUuidAndCompanyId(
070                    String uuid, long companyId) {
071    
072                    List<WikiPage> pages =
073                            WikiPageLocalServiceUtil.getWikiPagesByUuidAndCompanyId(
074                                    uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
075                                    new StagedModelModifiedDateComparator<WikiPage>());
076    
077                    if (ListUtil.isEmpty(pages)) {
078                            return null;
079                    }
080    
081                    return pages.get(0);
082            }
083    
084            @Override
085            public WikiPage fetchStagedModelByUuidAndGroupId(
086                    String uuid, long groupId) {
087    
088                    return WikiPageLocalServiceUtil.fetchWikiPageByUuidAndGroupId(
089                            uuid, groupId);
090            }
091    
092            @Override
093            public String[] getClassNames() {
094                    return CLASS_NAMES;
095            }
096    
097            @Override
098            protected void doExportStagedModel(
099                            PortletDataContext portletDataContext, WikiPage page)
100                    throws Exception {
101    
102                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
103                            portletDataContext, page, page.getNode(),
104                            PortletDataContext.REFERENCE_TYPE_PARENT);
105    
106                    String content = ExportImportHelperUtil.replaceExportContentReferences(
107                            portletDataContext, page, page.getContent(),
108                            portletDataContext.getBooleanParameter(
109                                    WikiPortletDataHandler.NAMESPACE, "referenced-content"));
110    
111                    page.setContent(content);
112    
113                    if (page.isHead()) {
114                            for (FileEntry fileEntry : page.getAttachmentsFileEntries()) {
115                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
116                                            portletDataContext, page, fileEntry,
117                                            PortletDataContext.REFERENCE_TYPE_WEAK);
118                            }
119                    }
120    
121                    Element pageElement = portletDataContext.getExportDataElement(page);
122    
123                    portletDataContext.addClassedModel(
124                            pageElement, ExportImportPathUtil.getModelPath(page), page);
125            }
126    
127            @Override
128            protected void doImportMissingReference(
129                            PortletDataContext portletDataContext, String uuid, long groupId,
130                            long pageId)
131                    throws Exception {
132    
133                    WikiPage existingPage = fetchMissingReference(uuid, groupId);
134    
135                    Map<Long, Long> pageIds =
136                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
137                                    WikiPage.class);
138    
139                    pageIds.put(pageId, existingPage.getPageId());
140            }
141    
142            @Override
143            protected void doImportStagedModel(
144                            PortletDataContext portletDataContext, WikiPage page)
145                    throws Exception {
146    
147                    long userId = portletDataContext.getUserId(page.getUserUuid());
148    
149                    Element pageElement =
150                            portletDataContext.getImportDataStagedModelElement(page);
151    
152                    String content = ExportImportHelperUtil.replaceImportContentReferences(
153                            portletDataContext, page, page.getContent());
154    
155                    page.setContent(content);
156    
157                    ServiceContext serviceContext = portletDataContext.createServiceContext(
158                            page);
159    
160                    serviceContext.setUuid(page.getUuid());
161    
162                    Map<Long, Long> nodeIds =
163                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
164                                    WikiNode.class);
165    
166                    long nodeId = MapUtil.getLong(
167                            nodeIds, page.getNodeId(), page.getNodeId());
168    
169                    WikiPage importedPage = null;
170    
171                    WikiPage existingPage = WikiPageLocalServiceUtil.fetchPage(
172                            nodeId, page.getTitle());
173    
174                    if (existingPage == null) {
175                            importedPage = WikiPageLocalServiceUtil.addPage(
176                                    userId, nodeId, page.getTitle(), page.getVersion(),
177                                    page.getContent(), page.getSummary(), page.isMinorEdit(),
178                                    page.getFormat(), page.getHead(), page.getParentTitle(),
179                                    page.getRedirectTitle(), serviceContext);
180                    }
181                    else {
182                            existingPage = fetchStagedModelByUuidAndGroupId(
183                                    page.getUuid(), portletDataContext.getScopeGroupId());
184    
185                            if (existingPage == null) {
186                                    existingPage = WikiPageLocalServiceUtil.fetchPage(
187                                            nodeId, page.getTitle(), page.getVersion());
188                            }
189    
190                            if (existingPage == null) {
191                                    importedPage = WikiPageLocalServiceUtil.updatePage(
192                                            userId, nodeId, page.getTitle(), 0.0, page.getContent(),
193                                            page.getSummary(), page.isMinorEdit(), page.getFormat(),
194                                            page.getParentTitle(), page.getRedirectTitle(),
195                                            serviceContext);
196                            }
197                            else {
198                                    importedPage = existingPage;
199                            }
200                    }
201    
202                    if (page.isHead()) {
203                            List<Element> attachmentElements =
204                                    portletDataContext.getReferenceDataElements(
205                                            pageElement, DLFileEntry.class,
206                                            PortletDataContext.REFERENCE_TYPE_WEAK);
207    
208                            for (Element attachmentElement : attachmentElements) {
209                                    String path = attachmentElement.attributeValue("path");
210    
211                                    FileEntry fileEntry =
212                                            (FileEntry)portletDataContext.getZipEntryAsObject(path);
213    
214                                    InputStream inputStream = null;
215                                    String mimeType = null;
216    
217                                    try {
218                                            String binPath = attachmentElement.attributeValue(
219                                                    "bin-path");
220    
221                                            if (Validator.isNull(binPath) &&
222                                                    portletDataContext.isPerformDirectBinaryImport()) {
223    
224                                                    try {
225                                                            inputStream = FileEntryUtil.getContentStream(
226                                                                    fileEntry);
227                                                    }
228                                                    catch (NoSuchFileException nsfe) {
229                                                    }
230                                            }
231                                            else {
232                                                    inputStream =
233                                                            portletDataContext.getZipEntryAsInputStream(
234                                                                    binPath);
235                                            }
236    
237                                            if (inputStream == null) {
238                                                    if (_log.isWarnEnabled()) {
239                                                            _log.warn(
240                                                                    "Unable to import attachment for file entry " +
241                                                                            fileEntry.getFileEntryId());
242                                                    }
243    
244                                                    continue;
245                                            }
246    
247                                            mimeType = MimeTypesUtil.getContentType(
248                                                    inputStream, fileEntry.getTitle());
249    
250                                            WikiPageLocalServiceUtil.addPageAttachment(
251                                                    userId, importedPage.getNodeId(),
252                                                    importedPage.getTitle(), fileEntry.getTitle(),
253                                                    inputStream, mimeType);
254                                    }
255                                    finally {
256                                            StreamUtil.cleanUp(inputStream);
257                                    }
258                            }
259                    }
260    
261                    portletDataContext.importClassedModel(page, importedPage);
262    
263                    Map<Long, Long> pageIds =
264                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
265                                    WikiPage.class + ".pageId");
266    
267                    pageIds.put(page.getPageId(), importedPage.getPageId());
268            }
269    
270            @Override
271            protected void doRestoreStagedModel(
272                            PortletDataContext portletDataContext, WikiPage page)
273                    throws Exception {
274    
275                    long userId = portletDataContext.getUserId(page.getUserUuid());
276    
277                    WikiPage existingPage = fetchStagedModelByUuidAndGroupId(
278                            page.getUuid(), portletDataContext.getScopeGroupId());
279    
280                    if ((existingPage == null) || !existingPage.isInTrash()) {
281                            return;
282                    }
283    
284                    TrashHandler trashHandler = existingPage.getTrashHandler();
285    
286                    if (trashHandler.isRestorable(existingPage.getResourcePrimKey())) {
287                            trashHandler.restoreTrashEntry(
288                                    userId, existingPage.getResourcePrimKey());
289                    }
290            }
291    
292            private static final Log _log = LogFactoryUtil.getLog(
293                    WikiPageStagedModelDataHandler.class);
294    
295    }