MNT-17703: Allow Bulk Import versioning without appending a version number to docs

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@136971 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Matt Ward
2017-05-26 15:55:40 +00:00
parent b930f7ca56
commit 64a0f743a2
17 changed files with 482 additions and 234 deletions

View File

@@ -1,36 +1,45 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.bulkimport;
import org.alfresco.service.cmr.repository.NodeRef;
public class BulkImportParameters
{
// MNT-17703: Provide configurable behaviour for when the target file already exists in the repository.
public enum ExistingFileMode
{
// If the file already exists...
SKIP, // skip the import from the source.
REPLACE, // replace the file, loosing any previous version history.
ADD_VERSION // create a new version of the file during import, preserving previous history.
};
private ExistingFileMode existingFileMode = ExistingFileMode.SKIP;
private NodeRef target;
private boolean replaceExisting = false;
private Integer batchSize;
private Integer numThreads;
private Integer loggingInterval;
@@ -60,14 +69,6 @@ public class BulkImportParameters
{
this.target = target;
}
public boolean isReplaceExisting()
{
return replaceExisting;
}
public void setReplaceExisting(boolean replaceExisting)
{
this.replaceExisting = replaceExisting;
}
public Integer getBatchSize()
{
return batchSize;
@@ -84,5 +85,40 @@ public class BulkImportParameters
{
this.numThreads = numThreads;
}
/**
* @deprecated Use {@link #getExistingFileMode} (MNT-17703)
* @return
*/
public boolean isReplaceExisting()
{
return existingFileMode == ExistingFileMode.REPLACE;
}
/**
* @deprecated Use {@link #setExistingFileMode} (MNT-17703)
* @param replaceExisting
*/
@Deprecated()
public void setReplaceExisting(boolean replaceExisting)
{
if (replaceExisting)
{
setExistingFileMode(ExistingFileMode.REPLACE);
}
else
{
setExistingFileMode(ExistingFileMode.SKIP);
}
}
public ExistingFileMode getExistingFileMode()
{
return existingFileMode;
}
public void setExistingFileMode(ExistingFileMode existingFileMode)
{
this.existingFileMode = existingFileMode;
}
}

View File

@@ -120,6 +120,10 @@ public final class ImportableItem
public Set<VersionedContentAndMetadata> getVersionEntries()
{
if (versionEntries == null)
{
return Collections.emptySet();
}
return(Collections.unmodifiableSet(versionEntries));
}

View File

@@ -23,20 +23,20 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.bulkimport;
import java.io.File;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Imports an importable item in the filesystem into the repository by creating a node to represent it.
*
* @since 4.0
*
*/
public interface NodeImporter
{
public NodeRef importImportableItem(ImportableItem importableItem, boolean replaceExisting);
public File getSourceFolder();
}
package org.alfresco.repo.bulkimport;
import java.io.File;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Imports an importable item in the filesystem into the repository by creating a node to represent it.
*
* @since 4.0
*
*/
public interface NodeImporter
{
public NodeRef importImportableItem(ImportableItem importableItem, BulkImportParameters.ExistingFileMode existingFileMode);
public File getSourceFolder();
}

View File

@@ -1,20 +1,20 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
@@ -33,6 +33,7 @@ import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.bulkimport.BulkFilesystemImporter;
import org.alfresco.repo.bulkimport.BulkImportParameters;
import org.alfresco.repo.bulkimport.DirectoryAnalyser;
import org.alfresco.repo.bulkimport.ImportableItem;
import org.alfresco.repo.bulkimport.MetadataLoader;
@@ -99,7 +100,7 @@ public abstract class AbstractNodeImporter implements NodeImporter
this.behaviourFilter = behaviourFilter;
}
protected abstract NodeRef importImportableItemImpl(ImportableItem importableItem, boolean replaceExisting);
protected abstract NodeRef importImportableItemImpl(ImportableItem importableItem, BulkImportParameters.ExistingFileMode existingFileMode);
protected abstract void importContentAndMetadata(NodeRef nodeRef, ImportableItem.ContentAndMetadata contentAndMetadata, MetadataLoader.Metadata metadata);
/*
@@ -181,11 +182,19 @@ public abstract class AbstractNodeImporter implements NodeImporter
return(result);
}
protected final int importImportableItemFile(NodeRef nodeRef, ImportableItem importableItem, MetadataLoader.Metadata metadata, NodeState nodeState)
protected final int importImportableItemFile(NodeRef nodeRef, ImportableItem importableItem, MetadataLoader.Metadata metadata, NodeState nodeState, BulkImportParameters.ExistingFileMode existingFileMode)
{
int result = 0;
if (importableItem.hasVersionEntries())
if (nodeState == NodeState.REPLACED && existingFileMode == BulkImportParameters.ExistingFileMode.ADD_VERSION)
{
// It is being replaced, and ADD_VERSION is the selected method of dealing with overwrites.
Map<QName, Serializable> versionProperties = new HashMap<>();
versionProperties.put(ContentModel.PROP_VERSION_TYPE, VersionType.MAJOR);
versionService.ensureVersioningEnabled(nodeRef, versionProperties);
result = importContentVersions(nodeRef, importableItem, nodeState);
}
else if (importableItem.hasVersionEntries())
{
result = importContentVersions(nodeRef, importableItem, nodeState);
}
@@ -242,9 +251,18 @@ public abstract class AbstractNodeImporter implements NodeImporter
return(result);
}
protected final Triple<NodeRef, Boolean, NodeState> createOrFindNode(NodeRef target, ImportableItem importableItem,
boolean replaceExisting, MetadataLoader.Metadata metadata)
// TODO: this is a confusing method that does too many things. It doesn't just "create or find"
// but also decides whether an existing node (i.e. the 'find' in 'create or find') WILL BE
// skipped or replaced further on in the calling code.
// TODO: refactor?
protected final Triple<NodeRef, Boolean, NodeState> createOrFindNode(
NodeRef target, ImportableItem importableItem,
BulkImportParameters.ExistingFileMode existingFileMode, MetadataLoader.Metadata metadata)
{
// ADD_VERSION isn't strictly a replacement option, but we need to deal with it as such, at least as an
// interim measure while the new ExistingFileMode options are introduced (MNT-17703)
boolean replaceExisting = (existingFileMode == BulkImportParameters.ExistingFileMode.REPLACE ||
existingFileMode == BulkImportParameters.ExistingFileMode.ADD_VERSION);
Triple<NodeRef, Boolean, NodeState> result = null;
boolean isDirectory = false;
NodeState nodeState = replaceExisting ? NodeState.REPLACED : NodeState.SKIPPED;
@@ -424,14 +442,14 @@ public abstract class AbstractNodeImporter implements NodeImporter
return(result);
}
public NodeRef importImportableItem(ImportableItem importableItem, boolean replaceExisting)
public NodeRef importImportableItem(ImportableItem importableItem, BulkImportParameters.ExistingFileMode existingFileMode)
{
if(logger.isDebugEnabled())
{
logger.debug("Importing " + String.valueOf(importableItem));
}
NodeRef nodeRef = importImportableItemImpl(importableItem, replaceExisting);
NodeRef nodeRef = importImportableItemImpl(importableItem, existingFileMode);
// allow parent to be garbage collected
//importableItem.setParent(null);

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.bulkimport.impl;
import java.io.PrintWriter;

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.bulkimport.impl;
import org.alfresco.model.ContentModel;
@@ -126,7 +126,7 @@ public abstract class MultiThreadedBulkFilesystemImporter extends AbstractBulkFi
{
behaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
NodeRef nodeRef = nodeImporter.importImportableItem(importableItem, bulkImportParameters.isReplaceExisting());
NodeRef nodeRef = nodeImporter.importImportableItem(importableItem, bulkImportParameters.getExistingFileMode());
filesystemTracker.itemImported(nodeRef, importableItem);
}
finally

View File

@@ -1,20 +1,20 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
@@ -30,6 +30,7 @@ import java.io.IOException;
import java.nio.file.Files;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.bulkimport.BulkImportParameters;
import org.alfresco.repo.bulkimport.ImportableItem;
import org.alfresco.repo.bulkimport.MetadataLoader;
import org.alfresco.repo.bulkimport.NodeImporter;
@@ -109,7 +110,7 @@ public class StreamingNodeImporterFactory extends AbstractNodeImporterFactory
importImportableItemMetadata(nodeRef, contentAndMetadata.getContentFile(), metadata);
}
protected NodeRef importImportableItemImpl(ImportableItem importableItem, boolean replaceExisting)
protected NodeRef importImportableItemImpl(ImportableItem importableItem, BulkImportParameters.ExistingFileMode existingFileMode)
{
NodeRef target = importableItem.getParent().getNodeRef();
if(target == null)
@@ -120,7 +121,16 @@ public class StreamingNodeImporterFactory extends AbstractNodeImporterFactory
NodeRef result = null;
MetadataLoader.Metadata metadata = loadMetadata(importableItem.getHeadRevision());
Triple<NodeRef, Boolean, NodeState> node = createOrFindNode(target, importableItem, replaceExisting, metadata);
// TODO: we'll get NodeState.REPLACED back from this method (i.e. the node WILL be replaced)
// even if we're using ExistingFileMode.ADD_VERSION - we need to do this currently, otherwise
// the file would be SKIPPED and various other checks that are only computed if replace is being used,
// wouldn't happen.
// TODO: sort this out.
Triple<NodeRef, Boolean, NodeState> node = createOrFindNode(
target,
importableItem,
existingFileMode,
metadata);
boolean isDirectory = node.getSecond() == null ? false : node.getSecond(); // Watch out for NPEs during unboxing!
NodeState nodeState = node.getThird();
@@ -139,7 +149,7 @@ public class StreamingNodeImporterFactory extends AbstractNodeImporterFactory
}
else
{
numVersionProperties = importImportableItemFile(result, importableItem, metadata, nodeState);
numVersionProperties = importImportableItemFile(result, importableItem, metadata, nodeState, existingFileMode);
}
importStatus.incrementNodesWritten(importableItem, isDirectory, nodeState, metadata.getProperties().size() + 4, numVersionProperties);