/**
* 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.portal.convert.documentlibrary;
import com.liferay.document.library.kernel.model.DLFileEntry;
import com.liferay.document.library.kernel.service.DLFileEntryLocalServiceUtil;
import com.liferay.document.library.kernel.store.Store;
import com.liferay.document.library.kernel.util.DLPreviewableProcessor;
import com.liferay.document.library.kernel.util.comparator.FileVersionVersionComparator;
import com.liferay.portal.convert.BaseConvertProcess;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
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.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.FileVersion;
import com.liferay.portal.kernel.service.ImageLocalServiceUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
import com.liferay.portal.util.MaintenanceUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.documentlibrary.store.StoreFactory;
import com.liferay.registry.Registry;
import com.liferay.registry.RegistryUtil;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
/**
* @author Minhchau Dang
* @author Alexander Chow
* @author László Csontos
*/
public class DocumentLibraryConvertProcess
extends BaseConvertProcess implements DLStoreConverter {
@Override
public String getConfigurationErrorMessage() {
return "there-are-no-stores-configured";
}
@Override
public String getDescription() {
return "migrate-documents-from-one-repository-to-another";
}
@Override
public String getParameterDescription() {
return "please-select-a-new-repository-hook";
}
@Override
public String[] getParameterNames() {
StoreFactory storeFactory = StoreFactory.getInstance();
Store store = storeFactory.getStore();
if (store == null) {
return null;
}
String[] storeTypes = storeFactory.getStoreTypes();
StringBundler sb = new StringBundler(storeTypes.length * 2 + 2);
sb.append(PropsKeys.DL_STORE_IMPL);
sb.append(StringPool.EQUAL);
for (String storeType : storeTypes) {
Class<?> clazz = store.getClass();
if (!storeType.equals(clazz.getName())) {
sb.append(storeType);
sb.append(StringPool.SEMICOLON);
}
}
return new String[] {
sb.toString(), "delete-files-from-previous-repository=checkbox"
};
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public void migrateDLFileEntry(
long companyId, long repositoryId, FileEntry fileEntry) {
Object model = fileEntry.getModel();
if (!(model instanceof DLFileEntry)) {
throw new IllegalArgumentException(
"Unsupported file entry model " + model.getClass());
}
String fileName = ((DLFileEntry)model).getName();
List<FileVersion> fileVersions = getFileVersions(fileEntry);
if (fileVersions.isEmpty()) {
String versionNumber = Store.VERSION_DEFAULT;
migrateFile(companyId, repositoryId, fileName, versionNumber);
return;
}
for (FileVersion fileVersion : fileVersions) {
String versionNumber = fileVersion.getVersion();
migrateFile(companyId, repositoryId, fileName, versionNumber);
}
}
@Override
public void validate() {
String sourceStoreClassName = getSourceStoreClassName();
if (!sourceStoreClassName.endsWith(_FILE_SYSTEM_STORE_SUFFIX)) {
return;
}
String targetStoreClassName = getTargetStoreClassName();
if (!targetStoreClassName.endsWith(_FILE_SYSTEM_STORE_SUFFIX)) {
return;
}
}
@Override
protected void doConvert() throws Exception {
StoreFactory storeFactory = StoreFactory.getInstance();
_sourceStore = storeFactory.getStore();
String targetStoreClassName = getTargetStoreClassName();
_targetStore = storeFactory.getStore(targetStoreClassName);
migratePortlets();
storeFactory.setStore(targetStoreClassName);
MaintenanceUtil.appendStatus(
"Please set " + PropsKeys.DL_STORE_IMPL +
" in your portal-ext.properties to use " +
targetStoreClassName);
PropsValues.DL_STORE_IMPL = targetStoreClassName;
}
protected List<FileVersion> getFileVersions(FileEntry fileEntry) {
List<FileVersion> fileVersions = fileEntry.getFileVersions(
WorkflowConstants.STATUS_ANY);
return ListUtil.sort(
fileVersions, new FileVersionVersionComparator(true));
}
protected String getSourceStoreClassName() {
StoreFactory storeFactory = StoreFactory.getInstance();
Store sourceStore = storeFactory.getStore();
Class<?> clazz = sourceStore.getClass();
return clazz.getName();
}
protected String getTargetStoreClassName() {
String[] values = getParameterValues();
return values[0];
}
protected boolean isDeleteFilesFromSourceStore() {
String[] values = getParameterValues();
return GetterUtil.getBoolean(values[1]);
}
protected void migrateDL() throws PortalException {
int count = DLFileEntryLocalServiceUtil.getFileEntriesCount();
MaintenanceUtil.appendStatus(
"Migrating " + count + " documents and media files");
ActionableDynamicQuery actionableDynamicQuery =
DLFileEntryLocalServiceUtil.getActionableDynamicQuery();
actionableDynamicQuery.setAddCriteriaMethod(
new ActionableDynamicQuery.AddCriteriaMethod() {
@Override
public void addCriteria(DynamicQuery dynamicQuery) {
Property classNameIdProperty = PropertyFactoryUtil.forName(
"classNameId");
dynamicQuery.add(classNameIdProperty.eq(0L));
}
});
actionableDynamicQuery.setPerformActionMethod(
new ActionableDynamicQuery.PerformActionMethod<DLFileEntry>() {
@Override
public void performAction(DLFileEntry dlFileEntry) {
migrateDLFileEntry(
dlFileEntry.getCompanyId(),
dlFileEntry.getDataRepositoryId(),
new LiferayFileEntry(dlFileEntry));
}
});
actionableDynamicQuery.performActions();
if (isDeleteFilesFromSourceStore()) {
DLPreviewableProcessor.deleteFiles();
}
}
protected void migrateFile(
long companyId, long repositoryId, String fileName,
String versionNumber) {
try {
InputStream is = _sourceStore.getFileAsStream(
companyId, repositoryId, fileName, versionNumber);
if (versionNumber.equals(Store.VERSION_DEFAULT)) {
_targetStore.addFile(companyId, repositoryId, fileName, is);
}
else {
_targetStore.updateFile(
companyId, repositoryId, fileName, versionNumber, is);
}
if (isDeleteFilesFromSourceStore()) {
_sourceStore.deleteFile(
companyId, repositoryId, fileName, versionNumber);
}
}
catch (Exception e) {
_log.error("Migration failed for " + fileName, e);
}
}
protected void migrateImages() throws PortalException {
int count = ImageLocalServiceUtil.getImagesCount();
MaintenanceUtil.appendStatus("Migrating " + count + " images");
ActionableDynamicQuery actionableDynamicQuery =
ImageLocalServiceUtil.getActionableDynamicQuery();
actionableDynamicQuery.setPerformActionMethod(
new ActionableDynamicQuery.PerformActionMethod<Image>() {
@Override
public void performAction(Image image) {
String fileName =
image.getImageId() + StringPool.PERIOD +
image.getType();
migrateFile(0, 0, fileName, Store.VERSION_DEFAULT);
}
});
actionableDynamicQuery.performActions();
}
protected void migratePortlets() throws Exception {
migrateImages();
migrateDL();
Collection<DLStoreConvertProcess> dlStoreConvertProcesses =
_getDLStoreConvertProcesses();
for (DLStoreConvertProcess dlStoreConvertProcess :
dlStoreConvertProcesses) {
dlStoreConvertProcess.migrate(this);
}
}
private Collection<DLStoreConvertProcess> _getDLStoreConvertProcesses() {
try {
Registry registry = RegistryUtil.getRegistry();
return registry.getServices(DLStoreConvertProcess.class, null);
}
catch (Exception e) {
throw new SystemException(e);
}
}
private static final String _FILE_SYSTEM_STORE_SUFFIX = "FileSystemStore";
private static final Log _log = LogFactoryUtil.getLog(
DocumentLibraryConvertProcess.class);
private Store _sourceStore;
private Store _targetStore;
}