How to copy a node WITH THE FULL VERSION HISTORY with java ?

cancel
Showing results for 
Search instead for 
Did you mean: 
4535992
Senior Member

How to copy a node WITH THE FULL VERSION HISTORY with java ?

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!!!!!!

1 Reply
EddieMay
Community Manager
Community Manager

Re: How to copy a node WITH THE FULL VERSION HISTORY with java ?

Hi @4535992 

Could you be a little more specific when you say it doesn't work? Does it fall over with an error, does it fail at a particular point in your code, are there any error message in the logs, etc? 

Including information like this wil help others to help you.

Cheers,

Digital Community Manager, Alfresco Software.
Problem solved? Click Accept as Solution!