From 0adccaeca86d852766a4420b98aabb89ccf58ad9 Mon Sep 17 00:00:00 2001 From: Britt Park Date: Sun, 14 Jan 2007 00:56:55 +0000 Subject: [PATCH] Made revert to version behave better. Now when a node is reverted a clone of the version being reverted to is created. This clone has the previous head version as its ancestor and a wcm:reverted aspect applied. wcm:reverted contains wcm:revertedid, the node id that the reversion is a clone of. Revert to version is now a simple call to a new AVMService method, revert(). Propagated this to the remote API. Modified the the AVMRevertToVersionAction to use this mechanism. Though really the action isn't really needed now. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4824 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/action-services-context.xml | 3 -- config/alfresco/model/wcmModel.xml | 14 ++++++ source/java/org/alfresco/model/WCMModel.java | 4 ++ .../java/org/alfresco/repo/avm/AVMNode.java | 6 +++ .../org/alfresco/repo/avm/AVMNodeImpl.java | 14 ++++++ .../org/alfresco/repo/avm/AVMRemoteLocal.java | 8 ++++ .../repo/avm/AVMRemoteTransportService.java | 9 ++++ .../org/alfresco/repo/avm/AVMRepository.java | 28 ++++++++++++ .../org/alfresco/repo/avm/AVMServiceImpl.java | 25 ++++++++++- .../org/alfresco/repo/avm/AVMServiceTest.java | 1 - .../java/org/alfresco/repo/avm/AVMStore.java | 10 +++++ .../org/alfresco/repo/avm/AVMStoreImpl.java | 44 +++++++++++++++++++ .../avm/actions/AVMRevertToVersionAction.java | 28 +----------- .../alfresco/repo/remote/AVMRemoteImpl.java | 8 ++++ .../alfresco/service/cmr/avm/AVMService.java | 10 +++++ .../service/cmr/remote/AVMRemote.java | 10 +++++ .../cmr/remote/AVMRemoteTransport.java | 10 +++++ 17 files changed, 200 insertions(+), 32 deletions(-) diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml index b04f80f4e4..e7260d6245 100644 --- a/config/alfresco/action-services-context.xml +++ b/config/alfresco/action-services-context.xml @@ -458,9 +458,6 @@ - - - diff --git a/config/alfresco/model/wcmModel.xml b/config/alfresco/model/wcmModel.xml index 4cc90da7fa..309d276c07 100644 --- a/config/alfresco/model/wcmModel.xml +++ b/config/alfresco/model/wcmModel.xml @@ -64,4 +64,18 @@ + + + + Contains a reference to the node that this node was reverted from. + + + The id of the node this was reverted from. + d:long + true + + + + + diff --git a/source/java/org/alfresco/model/WCMModel.java b/source/java/org/alfresco/model/WCMModel.java index 057b3d7e5a..64493f0d41 100644 --- a/source/java/org/alfresco/model/WCMModel.java +++ b/source/java/org/alfresco/model/WCMModel.java @@ -36,4 +36,8 @@ public interface WCMModel static final QName TYPE_AVM_PLAIN_FOLDER = QName.createQName(NamespaceService.WCM_MODEL_1_0_URI, "avmplainfolder"); static final QName TYPE_AVM_LAYERED_FOLDER = QName.createQName(NamespaceService.WCM_MODEL_1_0_URI, "avmlayeredfolder"); static final QName PROP_AVM_DIR_INDIRECTION = QName.createQName(NamespaceService.WCM_MODEL_1_0_URI, "avmdirindirection"); + + // Reverted Aspect. + static final QName ASPECT_REVERTED = QName.createQName(NamespaceService.WCM_MODEL_1_0_URI, "reverted"); + static final QName PROP_REVERTED_ID = QName.createQName(NamespaceService.WCM_MODEL_1_0_URI, "revertedid"); } diff --git a/source/java/org/alfresco/repo/avm/AVMNode.java b/source/java/org/alfresco/repo/avm/AVMNode.java index 18b672665e..7d03f2a9ee 100644 --- a/source/java/org/alfresco/repo/avm/AVMNode.java +++ b/source/java/org/alfresco/repo/avm/AVMNode.java @@ -34,6 +34,12 @@ public interface AVMNode * @param ancestor The ancestor to set. */ public void setAncestor(AVMNode ancestor); + + /** + * Change the ancestor of a node. + * @param ancestor The ancestor node that should be set. + */ + public void changeAncestor(AVMNode ancestor); /** * Get the ancestor of this node. diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java index a9be1cd879..1290d4437d 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java @@ -121,6 +121,20 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable AVMDAOs.Instance().fHistoryLinkDAO.save(link); } + /** + * Change the ancestor of this node. + * @param ancestor The new ancestor to give it. + */ + public void changeAncestor(AVMNode ancestor) + { + HistoryLink old = AVMDAOs.Instance().fHistoryLinkDAO.getByDescendent(this); + if (old != null) + { + AVMDAOs.Instance().fHistoryLinkDAO.delete(old); + } + setAncestor(ancestor); + } + /** * Get the ancestor of this node. * @return The ancestor of this node. diff --git a/source/java/org/alfresco/repo/avm/AVMRemoteLocal.java b/source/java/org/alfresco/repo/avm/AVMRemoteLocal.java index a72815381f..2599376b03 100644 --- a/source/java/org/alfresco/repo/avm/AVMRemoteLocal.java +++ b/source/java/org/alfresco/repo/avm/AVMRemoteLocal.java @@ -479,4 +479,12 @@ public class AVMRemoteLocal implements AVMRemote { fService.removeAspect(path, aspectName); } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.remote.AVMRemote#revert(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void revert(String path, AVMNodeDescriptor toRevertTo) + { + fService.revert(path, toRevertTo); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java b/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java index 6c052c4333..1d2ec8a229 100644 --- a/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java +++ b/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java @@ -999,4 +999,13 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable fAuthService.validate(ticket); fAVMService.removeAspect(path, aspectName); } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.remote.AVMRemoteTransport#revert(java.lang.String, java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void revert(String ticket, String path, AVMNodeDescriptor toRevertTo) + { + fAuthService.validate(ticket); + fAVMService.revert(path, toRevertTo); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index a8aea075d7..8adc0a48c8 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -2338,4 +2338,32 @@ public class AVMRepository fPurgeStoreTxnListener.storePurged(sourceName); fCreateStoreTxnListener.storeCreated(destName); } + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the parent directory. + * @param name The name of the node. + * @param toRevertTo The descriptor of the version to revert to. + */ + public void revert(String path, String name, AVMNodeDescriptor toRevertTo) + { + fLookupCount.set(1); + try + { + String [] pathParts = SplitPath(path); + AVMStore store = getAVMStoreByName(pathParts[0]); + if (store == null) + { + throw new AVMNotFoundException("Store not found: " + pathParts[0]); + } + fLookupCache.onWrite(pathParts[0]); + store.revert(pathParts[1], name, toRevertTo); + } + finally + { + fLookupCount.set(null); + } + } } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java index 98c7d9aacb..d0e5357bc8 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java @@ -511,7 +511,7 @@ public class AVMServiceImpl implements AVMService String [] basePath = AVMNodeConverter.SplitBase(path); if (basePath[0] == null) { - throw new AVMBadArgumentException("Cannot remove root node."); + throw new AVMBadArgumentException("Cannot remove root node: " + path); } AlfrescoTransactionSupport.bindListener(fTransactionListener); fAVMRepository.remove(basePath[0], basePath[1]); @@ -1417,4 +1417,27 @@ public class AVMServiceImpl implements AVMService } fAVMRepository.renameStore(sourceName, destName); } + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + * @throws AVMNotFoundException + */ + public void revert(String path, AVMNodeDescriptor toRevertTo) + { + if (path == null || toRevertTo == null) + { + throw new AVMBadArgumentException("Illegal Null Argument."); + } + String [] baseName = AVMNodeConverter.SplitBase(path); + if (baseName.length != 2) + { + throw new AVMBadArgumentException("Cannot revert store root: " + path); + } + AlfrescoTransactionSupport.bindListener(fTransactionListener); + fAVMRepository.revert(baseName[0], baseName[1], toRevertTo); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index be9eea6350..fef0d386c9 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -109,7 +109,6 @@ public class AVMServiceTest extends AVMServiceTestBase }; TransactionUtil.executeInUserTransaction((TransactionService)fContext.getBean("transactionComponent"), new TxnWork()); - assertEquals(toRevert.getId(), fService.lookup(-1, "main:/a/b/c/foo").getId()); } catch (Exception e) { diff --git a/source/java/org/alfresco/repo/avm/AVMStore.java b/source/java/org/alfresco/repo/avm/AVMStore.java index b4677f3a2b..1dfb17c007 100644 --- a/source/java/org/alfresco/repo/avm/AVMStore.java +++ b/source/java/org/alfresco/repo/avm/AVMStore.java @@ -454,4 +454,14 @@ public interface AVMStore * @param toLink The node to link. */ public void link(String parentPath, String name, AVMNodeDescriptor toLink); + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the parent directory. + * @param name The name of the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + */ + public void revert(String path, String name, AVMNodeDescriptor toRevertTo); } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index 935ec0aae9..25239cfa96 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -30,6 +30,8 @@ import java.util.SortedMap; import java.util.TreeMap; import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMModel; +import org.alfresco.repo.avm.AVMAspectName; import org.alfresco.repo.avm.util.RawServices; import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.domain.DbAccessControlList; @@ -1305,4 +1307,46 @@ public class AVMStoreImpl implements AVMStore, Serializable DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); dir.link(lPath, name, toLink); } + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the parent directory. + * @param name The name of the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + */ + public void revert(String path, String name, AVMNodeDescriptor toRevertTo) + { + Lookup lPath = lookupDirectory(-1, path, true); + if (lPath == null) + { + throw new AVMNotFoundException("Path " + path + " not found."); + } + DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); + AVMNode child = dir.lookupChild(lPath, name, true); + if (child == null) + { + throw new AVMNotFoundException("Node not found: " + name); + } + AVMNode revertNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(toRevertTo.getId()); + if (revertNode == null) + { + throw new AVMNotFoundException(toRevertTo.toString()); + } + AVMNode toLink = revertNode.copy(lPath); + dir.putChild(name, toLink); + toLink.changeAncestor(child); + toLink.setVersionID(child.getVersionID() + 1); + if (AVMDAOs.Instance().fAVMAspectNameDAO.exists(toLink, WCMModel.ASPECT_REVERTED)) + { + AVMDAOs.Instance().fAVMAspectNameDAO.delete(toLink, WCMModel.ASPECT_REVERTED); + } + AVMAspectName aspect = new AVMAspectNameImpl(); + aspect.setNode(toLink); + aspect.setName(WCMModel.ASPECT_REVERTED); + AVMDAOs.Instance().fAVMAspectNameDAO.save(aspect); + PropertyValue value = new PropertyValue(null, toRevertTo.getId()); + toLink.setProperty(WCMModel.PROP_REVERTED_ID, value); + } } diff --git a/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java b/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java index 3300cadc55..37c516541a 100644 --- a/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java +++ b/source/java/org/alfresco/repo/avm/actions/AVMRevertToVersionAction.java @@ -3,10 +3,8 @@ */ package org.alfresco.repo.avm.actions; -import java.util.ArrayList; import java.util.List; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.avm.AVMNodeConverter; @@ -14,8 +12,6 @@ import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.util.Pair; @@ -37,8 +33,6 @@ public class AVMRevertToVersionAction extends ActionExecuterAbstractBase private AVMService fAVMService; - private AVMSyncService fAVMSyncService; - /** * Set the AVMService. */ @@ -47,14 +41,6 @@ public class AVMRevertToVersionAction extends ActionExecuterAbstractBase fAVMService = service; } - /** - * Set the AVMSyncService. - */ - public void setAvmSyncService(AVMSyncService service) - { - fAVMSyncService = service; - } - /* (non-Javadoc) * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) */ @@ -65,19 +51,7 @@ public class AVMRevertToVersionAction extends ActionExecuterAbstractBase AVMNodeConverter.ToAVMVersionPath(actionedUponNodeRef); AVMNodeDescriptor toRevert = (AVMNodeDescriptor)action.getParameterValue(TOREVERT); - List> paths = fAVMService.getPaths(toRevert); - if (paths.size() == 0) - { - fgLogger.error("Unable to find path for: " + toRevert); - throw new AlfrescoRuntimeException("Could not find path for: " + toRevert); - } - AVMDifference diff = new AVMDifference(paths.get(0).getFirst(), paths.get(0).getSecond(), - -1, versionPath.getSecond(), - AVMDifference.NEWER); - List diffs = new ArrayList(1); - diffs.add(diff); - String message = "Reverted " + versionPath.getSecond() + " to version in snapshot " + paths.get(0).getFirst() + "."; - fAVMSyncService.update(diffs, null, false, false, true, true, "Reverted", message); + fAVMService.revert(versionPath.getSecond(), toRevert); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/remote/AVMRemoteImpl.java b/source/java/org/alfresco/repo/remote/AVMRemoteImpl.java index a875abf89b..96649bbf04 100644 --- a/source/java/org/alfresco/repo/remote/AVMRemoteImpl.java +++ b/source/java/org/alfresco/repo/remote/AVMRemoteImpl.java @@ -483,4 +483,12 @@ public class AVMRemoteImpl implements AVMRemote { fTransport.removeAspect(ClientTicketHolder.GetTicket(), path, aspectName); } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.remote.AVMRemote#revert(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void revert(String path, AVMNodeDescriptor toRevertTo) + { + fTransport.revert(ClientTicketHolder.GetTicket(), path, toRevertTo); + } } diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java index 65f1cb50c9..d003dd001e 100644 --- a/source/java/org/alfresco/service/cmr/avm/AVMService.java +++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java @@ -800,4 +800,14 @@ public interface AVMService * @throws AVMExistsException */ public void renameStore(String sourceName, String destName); + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + * @throws AVMNotFoundException + */ + public void revert(String path, AVMNodeDescriptor toRevertTo); } diff --git a/source/java/org/alfresco/service/cmr/remote/AVMRemote.java b/source/java/org/alfresco/service/cmr/remote/AVMRemote.java index 8bd30ab4cf..9e69adc80f 100644 --- a/source/java/org/alfresco/service/cmr/remote/AVMRemote.java +++ b/source/java/org/alfresco/service/cmr/remote/AVMRemote.java @@ -443,4 +443,14 @@ public interface AVMRemote * @throws AVMNotFoundException */ public boolean hasAspect(int version, String path, QName aspectName); + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + * @throws AVMNotFoundException + */ + public void revert(String path, AVMNodeDescriptor toRevertTo); } diff --git a/source/java/org/alfresco/service/cmr/remote/AVMRemoteTransport.java b/source/java/org/alfresco/service/cmr/remote/AVMRemoteTransport.java index 47c09f38f8..77732053a5 100644 --- a/source/java/org/alfresco/service/cmr/remote/AVMRemoteTransport.java +++ b/source/java/org/alfresco/service/cmr/remote/AVMRemoteTransport.java @@ -461,4 +461,14 @@ public interface AVMRemoteTransport * @throws AVMNotFoundException */ public boolean hasAspect(String ticket, int version, String path, QName aspectName); + + /** + * Revert a head path to a given version. This works by cloning + * the version to revert to, and then linking that new version into head. + * The reverted version will have the previous head version as ancestor. + * @param path The path to the node to revert. + * @param toRevertTo The descriptor of the version to revert to. + * @throws AVMNotFoundException + */ + public void revert(String ticket, String path, AVMNodeDescriptor toRevertTo); }