The title alone explains the problem, I need to copy a node on Alfresco, but simultaneously copying all its version history. Here is the code I have prepared for this goal, but it doesn't seem to work.
Any help is welcome ...
public static NodeRef copyWithHistory(NodeRef actionedUponNodeRef, NodeRef destinationParent,
boolean deepCopy, boolean overwrite,
ServiceRegistry serviceRegistry) {
CopyService copyService = serviceRegistry.getCopyService();
CheckOutCheckInService checkOutCheckInService = serviceRegistry.getCheckOutCheckInService();
NodeService nodeService = serviceRegistry.getNodeService();
VersionService versionService = serviceRegistry.getVersionService();
ContentService contentService = serviceRegistry.getContentService();
DictionaryService dictionaryService = serviceRegistry.getDictionaryService();
// Since we are overwriting we need to figure out whether the destination node exists
NodeRef copyNodeRef = null;
if (overwrite == true)
{
// Try and find copies of the actioned upon node reference.
// Include the parent folder because that's where the copy will be if this action
// had done the first copy.
PagingResults<CopyInfo> copies = copyService.getCopies(
actionedUponNodeRef,
destinationParent,
new PagingRequest(1000));
for (CopyInfo copyInfo : copies.getPage())
{
NodeRef copy = copyInfo.getNodeRef();
// We know that it is in the destination parent, but avoid working copies
if (checkOutCheckInService.isWorkingCopy(copy))
{
continue;
}
if (copyNodeRef == null)
{
copyNodeRef = copy;
}
else
{
throw new AlfrescoRuntimeException("Cannot override hte file already exists");
}
}
}
if (copyNodeRef != null)
{
// Overwrite the state of the destination node ref with the actioned upon node state
copyService.copy(actionedUponNodeRef, copyNodeRef);
}
else
{
ChildAssociationRef originalAssoc = nodeService.getPrimaryParent(actionedUponNodeRef);
// Create a new copy of the node
copyNodeRef = copyService.copyAndRename(
actionedUponNodeRef,
destinationParent,
originalAssoc.getTypeQName(),
originalAssoc.getQName(),
deepCopy);
}
// ALF-13719 need to taking into account script properties for versionable aspect
if(!nodeService.hasAspect(copyNodeRef, ContentModel.ASPECT_VERSIONABLE)){
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_INITIAL_VERSION, true);
props.put(ContentModel.PROP_VERSION_TYPE, VersionType.MINOR);
props.put(ContentModel.PROP_AUTO_VERSION, Boolean.TRUE);
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, Boolean.TRUE);
versionService.ensureVersioningEnabled(copyNodeRef, props);
}else {
if(dictionaryService!=null) {
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
// MNT-9369, read props from contentModel.xml, sets to false, false if there is no defaults.
Map<QName, PropertyDefinition> versionableProps = dictionaryService.getAspect(ContentModel.ASPECT_VERSIONABLE).getProperties();
String versionType2 = versionableProps.get(ContentModel.PROP_VERSION_TYPE).getDefaultValue();
boolean autoVersion2 = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION).getDefaultValue());
boolean autoVersionProps2 = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION_PROPS).getDefaultValue());
props.put(ContentModel.PROP_VERSION_TYPE, versionType2);
props.put(ContentModel.PROP_AUTO_VERSION, autoVersion2);
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, autoVersionProps2);
versionService.ensureVersioningEnabled(copyNodeRef, props);
}else {
// DO NOTHING
}
}
if(versionService.getVersionHistory(actionedUponNodeRef)!=null) {
String filename = (String) nodeService.getProperty(copyNodeRef, ContentModel.PROP_NAME);
destinationParent = NodeServiceUtilities.getParentNodeRef(copyNodeRef, nodeService);
int j = 1; // indice versioni
// https://docs.alfresco.com/6.1/concepts/dev-api-by-language-alf-rest-get-version-history.html
//boolean alreadyAdded = false;
List<Version> listVersions = new LinkedList<Version>(versionService.getVersionHistory(actionedUponNodeRef).getAllVersions());
Collections.reverse(listVersions);
int total = listVersions.size();
for(Version version : listVersions) {
logger.info("Inizio copia versione numero ["+j+"] del nodo '"+actionedUponNodeRef+"'");
NodeRef frozenNodeRef = version.getFrozenStateNodeRef();
// version=vh.getPredecessor(version); // Going back in history
ContentReader contentReader = null;
try{
contentReader = contentService.getReader(frozenNodeRef, ContentModel.PROP_CONTENT);
NodeRef versionNodeRef = null;
// SE HA UN CONTENUTO E NON E' DI DIEMSNIONE 0
if(contentReader!=null && contentReader.getSize() > 0) {
Map<QName, Serializable> propsVers = new HashMap<QName, Serializable>();
propsVers = nodeService.getProperties(frozenNodeRef);
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(filename));
versionNodeRef = nodeService.createNode(
destinationParent,
ContentModel.ASSOC_CONTAINS,
assocQName,
ContentModel.TYPE_CONTENT,
propsVers).getChildRef();
if(contentService!=null) {
ContentWriter writer = contentService.getWriter(versionNodeRef, ContentModel.PROP_CONTENT, true);
if(writer!=null) {
if(ABDUtilities.isNotBlankAbd(contentReader.getContentData().getMimetype())) {
writer.setMimetype(contentReader.getContentData().getMimetype());
}
if(ABDUtilities.isNotBlankAbd(contentReader.getContentData().getEncoding())) {
writer.setEncoding(contentReader.getContentData().getEncoding());
}
writer.putContent(contentReader.getContentInputStream());
}
}else {
logger.warn("You should set the contentService of Alfresco when create a content");
}
}
// SE NON HA CONTENUTO O E' DI DIMENSIONE 0
else {
Map<QName, Serializable> propsVers = new HashMap<QName, Serializable>();
propsVers = nodeService.getProperties(frozenNodeRef);
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(filename));
versionNodeRef = nodeService.createNode(
destinationParent,
ContentModel.ASSOC_CONTAINS,
assocQName,
ContentModel.TYPE_CONTENT,
propsVers).getChildRef();
}
logger.debug("Generate node version '"+versionNodeRef+"'");
//TODO DA SISTEMARE
Version currentVersion = versionService.getCurrentVersion(versionNodeRef);
if(currentVersion!=null && currentVersion.getVersionProperties()!=null) {
if(version.getVersionProperties()!=null) {
currentVersion.getVersionProperties().put(VersionModel.PROP_VERSION_TYPE,version.getVersionProperties().get(VersionModel.PROP_VERSION_TYPE));
currentVersion.getVersionProperties().put(VersionModel.PROP_VERSION_LABEL,version.getVersionProperties().get(VersionModel.PROP_VERSION_LABEL));
currentVersion.getVersionProperties().put(VersionModel.PROP_VERSION_DESCRIPTION,version.getVersionProperties().get(VersionModel.PROP_VERSION_DESCRIPTION));
}
}else {
Map<String,Serializable> versionProperties = new HashMap<String,Serializable>();
versionProperties.put(VersionModel.PROP_VERSION_TYPE,version.getVersionProperties().get(VersionModel.PROP_VERSION_TYPE));
versionProperties.put(VersionModel.PROP_VERSION_LABEL,version.getVersionProperties().get(VersionModel.PROP_VERSION_LABEL));
versionProperties.put(VersionModel.PROP_VERSION_DESCRIPTION,version.getVersionProperties().get(VersionModel.PROP_VERSION_DESCRIPTION));
if(versionProperties!=null && !versionProperties.isEmpty()) {
for(Map.Entry<String, Serializable> prop : versionProperties.entrySet()) {
if(ABDUtilities.isNotBlankAbd(prop.getKey()) && ABDUtilities.isNotBlankAbd(String.valueOf(prop.getValue()))) {
versionProperties.put(prop.getKey(), (Serializable) prop.getValue());
}
}
}else {
// SI USA IL COMPORTAMENTO DI DEFAULT
//versionProperties = new HashMap<String, Serializable>();
//versionProperties.put(VersionModel.PROP_VERSION_TYPE, versionType);
//versionProperties.put(Version.PROP_DESCRIPTION, "");
}
Version v = null;
try {
v = versionService.createVersion(versionNodeRef, versionProperties);
//versionService.createVersion(targetNodeRef, null);
}catch(Throwable ex) {
// HERE THE ERROR I CANNOT SOLVE
// 10290060 The current version label of the node does not exist in the version history. : null
logger.error(ex.getMessage() + "," + ex.getCause(),ex);
throw ex;
}
}
j = j +1;
copyNodeRef = versionNodeRef;
}finally {
TransformerUtilities.forceCloseContentReader(contentReader);
}
}
}
return copyNodeRef;
}Any suggestion is more than welcome!!!!!!