/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.blogs.internal.exportimport.data.handler; import com.liferay.asset.kernel.model.AssetCategory; import com.liferay.blogs.model.BlogsEntry; import com.liferay.blogs.service.BlogsEntryLocalService; import com.liferay.document.library.kernel.exception.NoSuchFileException; import com.liferay.document.library.kernel.model.DLFileEntry; import com.liferay.exportimport.content.processor.ExportImportContentProcessor; import com.liferay.exportimport.data.handler.base.BaseStagedModelDataHandler; import com.liferay.exportimport.kernel.lar.ExportImportPathUtil; import com.liferay.exportimport.kernel.lar.PortletDataContext; import com.liferay.exportimport.kernel.lar.PortletDataException; import com.liferay.exportimport.kernel.lar.StagedModelDataHandler; import com.liferay.exportimport.kernel.lar.StagedModelDataHandlerUtil; import com.liferay.exportimport.kernel.lar.StagedModelModifiedDateComparator; import com.liferay.friendly.url.model.FriendlyURLEntry; import com.liferay.friendly.url.service.FriendlyURLEntryLocalService; import com.liferay.portal.kernel.comment.CommentManagerUtil; import com.liferay.portal.kernel.comment.DiscussionStagingHandler; import com.liferay.portal.kernel.dao.orm.QueryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Image; import com.liferay.portal.kernel.portletfilerepository.PortletFileRepositoryUtil; import com.liferay.portal.kernel.repository.model.FileEntry; import com.liferay.portal.kernel.service.ImageLocalService; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.servlet.taglib.ui.ImageSelector; import com.liferay.portal.kernel.trash.TrashHandler; import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil; import com.liferay.portal.kernel.util.CalendarFactoryUtil; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.MimeTypesUtil; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.StreamUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.xml.Element; import com.liferay.portlet.documentlibrary.lar.FileEntryUtil; import com.liferay.ratings.kernel.model.RatingsEntry; import java.io.InputStream; import java.util.Calendar; import java.util.List; import java.util.Map; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ReferencePolicyOption; /** * @author Zsolt Berentey * @author Roberto Díaz */ @Component(immediate = true, service = StagedModelDataHandler.class) public class BlogsEntryStagedModelDataHandler extends BaseStagedModelDataHandler<BlogsEntry> { public static final String[] CLASS_NAMES = {BlogsEntry.class.getName()}; @Override public void deleteStagedModel(BlogsEntry entry) throws PortalException { _blogsEntryLocalService.deleteEntry(entry); } @Override public void deleteStagedModel( String uuid, long groupId, String className, String extraData) throws PortalException { BlogsEntry entry = fetchStagedModelByUuidAndGroupId(uuid, groupId); if (entry != null) { deleteStagedModel(entry); } } @Override public BlogsEntry fetchStagedModelByUuidAndGroupId( String uuid, long groupId) { return _blogsEntryLocalService.fetchBlogsEntryByUuidAndGroupId( uuid, groupId); } @Override public List<BlogsEntry> fetchStagedModelsByUuidAndCompanyId( String uuid, long companyId) { return _blogsEntryLocalService.getBlogsEntriesByUuidAndCompanyId( uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS, new StagedModelModifiedDateComparator<BlogsEntry>()); } @Override public String[] getClassNames() { return CLASS_NAMES; } @Override public String getDisplayName(BlogsEntry entry) { return entry.getTitle(); } @Override protected void doExportStagedModel( PortletDataContext portletDataContext, BlogsEntry entry) throws Exception { Element entryElement = portletDataContext.getExportDataElement(entry); if (entry.isSmallImage()) { if (entry.getSmallImageFileEntryId() > 0) { FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry( entry.getSmallImageFileEntryId()); StagedModelDataHandlerUtil.exportReferenceStagedModel( portletDataContext, entry, fileEntry, PortletDataContext.REFERENCE_TYPE_WEAK); } else if (entry.getSmallImageId() > 0) { Image smallImage = _imageLocalService.fetchImage( entry.getSmallImageId()); if ((smallImage != null) && (smallImage.getTextObj() != null)) { String smallImagePath = ExportImportPathUtil.getModelPath( entry, smallImage.getImageId() + StringPool.PERIOD + smallImage.getType()); entryElement.addAttribute( "small-image-path", smallImagePath); entry.setSmallImageType(smallImage.getType()); portletDataContext.addZipEntry( smallImagePath, smallImage.getTextObj()); } else { if (_log.isWarnEnabled()) { StringBundler sb = new StringBundler(4); sb.append("Unable to export small image "); sb.append(entry.getSmallImageId()); sb.append(" to blogs entry "); sb.append(entry.getEntryId()); _log.warn(sb.toString()); } entry.setSmallImage(false); entry.setSmallImageId(0); } } } if (entry.getCoverImageFileEntryId() != 0) { FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry( entry.getCoverImageFileEntryId()); StagedModelDataHandlerUtil.exportReferenceStagedModel( portletDataContext, entry, fileEntry, PortletDataContext.REFERENCE_TYPE_WEAK); } _exportFriendlyURLEntries(portletDataContext, entry); String content = _exportImportContentProcessor.replaceExportContentReferences( portletDataContext, entry, entry.getContent(), portletDataContext.getBooleanParameter( "blogs", "referenced-content"), true); entry.setContent(content); portletDataContext.addClassedModel( entryElement, ExportImportPathUtil.getModelPath(entry), entry); } @Override protected void doImportMissingReference( PortletDataContext portletDataContext, String uuid, long groupId, long entryId) throws Exception { BlogsEntry existingEntry = fetchMissingReference(uuid, groupId); if (existingEntry == null) { return; } Map<Long, Long> entryIds = (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap( BlogsEntry.class); entryIds.put(entryId, existingEntry.getEntryId()); } @Override protected void doImportStagedModel( PortletDataContext portletDataContext, BlogsEntry entry) throws Exception { long userId = portletDataContext.getUserId(entry.getUserUuid()); Element entryElement = portletDataContext.getImportDataStagedModelElement(entry); String content = _exportImportContentProcessor.replaceImportContentReferences( portletDataContext, entry, entry.getContent()); entry.setContent(content); Calendar displayDateCal = CalendarFactoryUtil.getCalendar(); displayDateCal.setTime(entry.getDisplayDate()); int displayDateMonth = displayDateCal.get(Calendar.MONTH); int displayDateDay = displayDateCal.get(Calendar.DATE); int displayDateYear = displayDateCal.get(Calendar.YEAR); int displayDateHour = displayDateCal.get(Calendar.HOUR); int displayDateMinute = displayDateCal.get(Calendar.MINUTE); if (displayDateCal.get(Calendar.AM_PM) == Calendar.PM) { displayDateHour += 12; } boolean allowPingbacks = entry.isAllowPingbacks(); boolean allowTrackbacks = entry.isAllowTrackbacks(); String[] trackbacks = StringUtil.split(entry.getTrackbacks()); ServiceContext serviceContext = portletDataContext.createServiceContext( entry); BlogsEntry importedEntry = null; if (portletDataContext.isDataStrategyMirror()) { BlogsEntry existingEntry = fetchStagedModelByUuidAndGroupId( entry.getUuid(), portletDataContext.getScopeGroupId()); if (existingEntry == null) { serviceContext.setUuid(entry.getUuid()); importedEntry = _blogsEntryLocalService.addEntry( userId, entry.getTitle(), entry.getSubtitle(), entry.getDescription(), entry.getContent(), displayDateMonth, displayDateDay, displayDateYear, displayDateHour, displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks, entry.getCoverImageCaption(), null, null, serviceContext); } else { importedEntry = _blogsEntryLocalService.updateEntry( userId, existingEntry.getEntryId(), entry.getTitle(), entry.getSubtitle(), entry.getDescription(), entry.getContent(), displayDateMonth, displayDateDay, displayDateYear, displayDateHour, displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks, entry.getCoverImageCaption(), new ImageSelector(), new ImageSelector(), serviceContext); } } else { importedEntry = _blogsEntryLocalService.addEntry( userId, entry.getTitle(), entry.getSubtitle(), entry.getDescription(), entry.getContent(), displayDateMonth, displayDateDay, displayDateYear, displayDateHour, displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks, entry.getCoverImageCaption(), null, null, serviceContext); } // Cover image ImageSelector coverImageSelector = null; List<Element> attachmentElements = portletDataContext.getReferenceDataElements( entry, DLFileEntry.class, PortletDataContext.REFERENCE_TYPE_WEAK); if (Validator.isNotNull(entry.getCoverImageURL())) { coverImageSelector = new ImageSelector(entry.getCoverImageURL()); } else if (entry.getCoverImageFileEntryId() != 0) { coverImageSelector = _getImageSelector( portletDataContext, entry.getCoverImageFileEntryId(), attachmentElements); } if (coverImageSelector != null) { _blogsEntryLocalService.addCoverImage( importedEntry.getEntryId(), coverImageSelector); } // Small image ImageSelector smallImageSelector = null; if (entry.isSmallImage()) { String smallImagePath = entryElement.attributeValue( "small-image-path"); if (Validator.isNotNull(entry.getSmallImageURL())) { smallImageSelector = new ImageSelector( entry.getSmallImageURL()); } else if (Validator.isNotNull(smallImagePath)) { String smallImageFileName = entry.getSmallImageId() + StringPool.PERIOD + entry.getSmallImageType(); InputStream inputStream = null; try { inputStream = portletDataContext.getZipEntryAsInputStream( smallImagePath); smallImageSelector = new ImageSelector( FileUtil.getBytes(inputStream), smallImageFileName, MimeTypesUtil.getContentType(smallImageFileName), null); } finally { StreamUtil.cleanUp(inputStream); } } else if (entry.getSmallImageFileEntryId() != 0) { smallImageSelector = _getImageSelector( portletDataContext, entry.getSmallImageFileEntryId(), attachmentElements); } } if (smallImageSelector != null) { _blogsEntryLocalService.addSmallImage( importedEntry.getEntryId(), smallImageSelector); } if ((coverImageSelector != null) || (smallImageSelector != null)) { importedEntry = _blogsEntryLocalService.getEntry( importedEntry.getEntryId()); } Map<Long, Long> newPrimaryKeysMap = (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap( BlogsEntry.class); newPrimaryKeysMap.put(entry.getEntryId(), importedEntry.getEntryId()); _importFriendlyURLEntries(portletDataContext, entry, importedEntry); portletDataContext.importClassedModel(entry, importedEntry); } @Override protected void doRestoreStagedModel( PortletDataContext portletDataContext, BlogsEntry entry) throws Exception { long userId = portletDataContext.getUserId(entry.getUserUuid()); BlogsEntry existingEntry = fetchStagedModelByUuidAndGroupId( entry.getUuid(), portletDataContext.getScopeGroupId()); if ((existingEntry == null) || !existingEntry.isInTrash()) { return; } TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler( BlogsEntry.class.getName()); if (trashHandler.isRestorable(existingEntry.getEntryId())) { trashHandler.restoreTrashEntry(userId, existingEntry.getEntryId()); } } protected InputStream getSmallImageInputStream( PortletDataContext portletDataContext, Element attachmentElement) { InputStream inputStream = null; String path = attachmentElement.attributeValue("path"); FileEntry fileEntry = (FileEntry)portletDataContext.getZipEntryAsObject( path); String binPath = attachmentElement.attributeValue("bin-path"); if (Validator.isNull(binPath) && portletDataContext.isPerformDirectBinaryImport()) { try { inputStream = FileEntryUtil.getContentStream(fileEntry); } catch (Exception e) { } } else { inputStream = portletDataContext.getZipEntryAsInputStream(binPath); } if (inputStream == null) { if (_log.isWarnEnabled()) { _log.warn( "Unable to import small image file entry " + fileEntry.getFileEntryId()); } } return inputStream; } @Override protected void importReferenceStagedModels( PortletDataContext portletDataContext, BlogsEntry stagedModel) throws PortletDataException { Element stagedModelElement = portletDataContext.getImportDataStagedModelElement(stagedModel); Element referencesElement = stagedModelElement.element("references"); if (referencesElement == null) { return; } DiscussionStagingHandler discussionStagingHandler = CommentManagerUtil.getDiscussionStagingHandler(); String stagedModelClassName = null; if (discussionStagingHandler != null) { stagedModelClassName = discussionStagingHandler.getClassName(); } List<Element> referenceElements = referencesElement.elements(); for (Element referenceElement : referenceElements) { String className = referenceElement.attributeValue("class-name"); if (className.equals(FriendlyURLEntry.class.getName()) || className.equals(AssetCategory.class.getName()) || className.equals(RatingsEntry.class.getName()) || className.equals(stagedModelClassName)) { continue; } long classPK = GetterUtil.getLong( referenceElement.attributeValue("class-pk")); StagedModelDataHandlerUtil.importReferenceStagedModel( portletDataContext, stagedModel, className, classPK); } } @Reference(unbind = "-") protected void setBlogsEntryLocalService( BlogsEntryLocalService blogsEntryLocalService) { _blogsEntryLocalService = blogsEntryLocalService; } @Reference( policyOption = ReferencePolicyOption.GREEDY, target = "(model.class.name=com.liferay.blogs.kernel.model.BlogsEntry)", unbind = "-" ) protected void setExportImportContentProcessor( ExportImportContentProcessor<String> exportImportContentProcessor) { _exportImportContentProcessor = exportImportContentProcessor; } @Reference(unbind = "-") protected void setFriendlyURLEntryLocalService( FriendlyURLEntryLocalService friendlyURLEntryLocalService) { _friendlyURLEntryLocalService = friendlyURLEntryLocalService; } @Reference(unbind = "-") protected void setImageLocalService(ImageLocalService imageLocalService) { _imageLocalService = imageLocalService; } private void _exportFriendlyURLEntries( PortletDataContext portletDataContext, BlogsEntry blogsEntry) throws PortletDataException { long classNameId = _portal.getClassNameId(BlogsEntry.class); List<FriendlyURLEntry> friendlyURLEntries = _friendlyURLEntryLocalService.getFriendlyURLEntries( blogsEntry.getGroupId(), blogsEntry.getCompanyId(), classNameId, blogsEntry.getEntryId()); for (FriendlyURLEntry friendlyURLEntry : friendlyURLEntries) { StagedModelDataHandlerUtil.exportReferenceStagedModel( portletDataContext, blogsEntry, friendlyURLEntry, PortletDataContext.REFERENCE_TYPE_DEPENDENCY); } } private ImageSelector _getImageSelector( PortletDataContext portletDataContext, long fileEntryId, List<Element> attachmentElements) throws Exception { for (Element attachmentElement : attachmentElements) { String path = attachmentElement.attributeValue("path"); FileEntry fileEntry = (FileEntry)portletDataContext.getZipEntryAsObject(path); if (fileEntryId == fileEntry.getFileEntryId()) { InputStream inputStream = null; try { String binPath = attachmentElement.attributeValue( "bin-path"); if (Validator.isNull(binPath) && portletDataContext.isPerformDirectBinaryImport()) { try { inputStream = FileEntryUtil.getContentStream( fileEntry); } catch (NoSuchFileException nsfe) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsfe, nsfe); } } } else { inputStream = portletDataContext.getZipEntryAsInputStream( binPath); } if (inputStream == null) { if (_log.isWarnEnabled()) { _log.warn( "Unable to import attachment for file entry " + fileEntry.getFileEntryId()); } continue; } return new ImageSelector( FileUtil.getBytes(inputStream), fileEntry.getFileName(), fileEntry.getMimeType(), null); } finally { StreamUtil.cleanUp(inputStream); } } } return null; } private void _importFriendlyURLEntries( PortletDataContext portletDataContext, BlogsEntry blogsEntry, BlogsEntry importedBlogsEntry) throws PortletDataException { List<Element> friendlyURLEntryElements = portletDataContext.getReferenceDataElements( blogsEntry, FriendlyURLEntry.class); for (Element friendlyURLEntryElement : friendlyURLEntryElements) { String path = friendlyURLEntryElement.attributeValue("path"); FriendlyURLEntry friendlyURLEntry = (FriendlyURLEntry)portletDataContext.getZipEntryAsObject(path); friendlyURLEntry.setClassNameId( _portal.getClassNameId(BlogsEntry.class)); friendlyURLEntry.setClassPK(importedBlogsEntry.getPrimaryKey()); StagedModelDataHandlerUtil.importStagedModel( portletDataContext, friendlyURLEntry); } } private static final Log _log = LogFactoryUtil.getLog( BlogsEntryStagedModelDataHandler.class); private BlogsEntryLocalService _blogsEntryLocalService; private ExportImportContentProcessor<String> _exportImportContentProcessor; private FriendlyURLEntryLocalService _friendlyURLEntryLocalService; private ImageLocalService _imageLocalService; @Reference private Portal _portal; }