use of org.alfresco.service.cmr.version.VersionServiceException in project alfresco-repository by Alfresco.
the class VersionServiceImpl method restore.
/**
* @see org.alfresco.service.cmr.version.VersionService#restore(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName, boolean)
*/
public NodeRef restore(NodeRef nodeRef, NodeRef parentNodeRef, QName assocTypeQName, QName assocQName, boolean deep) {
if (logger.isDebugEnabled()) {
logger.debug("Run as user " + AuthenticationUtil.getRunAsUser());
logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser());
}
NodeRef restoredNodeRef = null;
// Check that the node does not exist
if (this.nodeService.exists(nodeRef) == true) {
// Error since you can not restore a node that already exists
throw new VersionServiceException(MSGID_ERR_RESTORE_EXISTS, new Object[] { nodeRef.toString() });
}
// Try and get the version details that we want to restore to
Version version = getHeadVersion(nodeRef);
if (version == null) {
// Error since there is no version information available to restore the node from
throw new VersionServiceException(MSGID_ERR_RESTORE_NO_VERSION, new Object[] { nodeRef.toString() });
}
// Set the uuid of the new node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NODE_UUID, version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID));
// Get the type of the node node
QName type = (QName) version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_TYPE);
// Disable auto-version behaviour
this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
try {
// Create the restored node
restoredNodeRef = this.nodeService.createNode(parentNodeRef, assocTypeQName, assocQName, type, props).getChildRef();
} finally {
// Enable auto-version behaviour
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
}
// Now we need to revert the newly restored node
revert(restoredNodeRef, version, deep);
return restoredNodeRef;
}
use of org.alfresco.service.cmr.version.VersionServiceException in project alfresco-repository by Alfresco.
the class VersionServiceImpl method buildVersionHistory.
/**
* Builds a version history object from the version history reference.
* <p>
* The node ref is passed to enable the version history to be scoped to the
* appropriate branch in the version history.
*
* @param versionHistoryRef the node ref for the version history
* @param nodeRef the node reference
* @return a constructed version history object
*/
protected VersionHistory buildVersionHistory(NodeRef versionHistoryRef, NodeRef nodeRef) {
VersionHistory versionHistory = null;
// List of versions with current one last and root one first.
ArrayList<NodeRef> versionHistoryNodeRefs = new ArrayList<NodeRef>();
NodeRef currentVersion;
if (this.nodeService.exists(nodeRef)) {
currentVersion = getCurrentVersionNodeRef(versionHistoryRef, nodeRef);
} else {
currentVersion = VersionUtil.convertNodeRef(getLatestVersion(nodeRef).getFrozenStateNodeRef());
}
while (currentVersion != null) {
AssociationRef preceedingVersion = null;
versionHistoryNodeRefs.add(0, currentVersion);
List<AssociationRef> preceedingVersions = this.dbNodeService.getSourceAssocs(currentVersion, VersionModel.ASSOC_SUCCESSOR);
if (preceedingVersions.size() == 1) {
preceedingVersion = (AssociationRef) preceedingVersions.toArray()[0];
currentVersion = preceedingVersion.getSourceRef();
} else if (preceedingVersions.size() > 1) {
// Error since we only currently support one preceeding version
throw new VersionServiceException(MSGID_ERR_ONE_PRECEEDING);
} else {
currentVersion = null;
}
}
// Build the version history object
boolean isRoot = true;
Version preceeding = null;
for (NodeRef versionRef : versionHistoryNodeRefs) {
Version version = getVersion(versionRef);
if (isRoot == true) {
versionHistory = new VersionHistoryImpl(version, versionComparatorDesc);
isRoot = false;
} else {
((VersionHistoryImpl) versionHistory).addVersion(version, preceeding);
}
preceeding = version;
}
return versionHistory;
}
use of org.alfresco.service.cmr.version.VersionServiceException in project alfresco-repository by Alfresco.
the class Version2ServiceImpl method revert.
@Override
@Extend(extensionAPI = VersionServiceExtension.class, traitAPI = VersionServiceTrait.class)
public void revert(NodeRef nodeRef, Version version, boolean deep) {
if (logger.isDebugEnabled()) {
logger.debug("Run as user " + AuthenticationUtil.getRunAsUser());
logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser());
}
if (logger.isDebugEnabled()) {
logger.debug("revert nodeRef:" + nodeRef);
}
// Check the mandatory parameters
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("version", version);
// Cross check that the version provided relates to the node reference provided
if (nodeRef.getId().equals(((NodeRef) version.getVersionProperty(Version2Model.PROP_FROZEN_NODE_REF)).getId()) == false) {
// Error since the version provided does not correspond to the node reference provided
throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH);
}
// Turn off any auto-version policy behaviours
this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
try {
// The current (old) values
Map<QName, Serializable> oldProps = this.nodeService.getProperties(nodeRef);
Set<QName> oldAspectQNames = this.nodeService.getAspects(nodeRef);
QName oldNodeTypeQName = nodeService.getType(nodeRef);
// Store the current version label
String currentVersionLabel = (String) this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL);
// The frozen (which will become new) values
// Get the node that represents the frozen state
NodeRef versionNodeRef = version.getFrozenStateNodeRef();
boolean needToRestoreDiscussion = !this.nodeService.hasAspect(versionNodeRef, ForumModel.ASPECT_DISCUSSABLE) && this.nodeService.hasAspect(nodeRef, ForumModel.ASPECT_DISCUSSABLE);
Map<QName, Serializable> forumProps = null;
// always collect forum properties
Map<QName, Serializable> currentVersionProp = this.nodeService.getProperties(nodeRef);
forumProps = new HashMap<QName, Serializable>();
for (QName key : currentVersionProp.keySet()) {
if (key.getNamespaceURI().equals(NamespaceService.FORUMS_MODEL_1_0_URI)) {
forumProps.put(key, currentVersionProp.get(key));
}
}
Map<QName, Serializable> newProps = this.nodeService.getProperties(versionNodeRef);
VersionUtil.convertFrozenToOriginalProps(newProps);
Set<QName> newAspectQNames = this.nodeService.getAspects(versionNodeRef);
QName newNodeTypeQName = nodeService.getType(versionNodeRef);
// RevertDetails - given to policy behaviours
VersionRevertDetailsImpl revertDetails = new VersionRevertDetailsImpl();
revertDetails.setNodeRef(nodeRef);
revertDetails.setNodeType(newNodeTypeQName);
// Do we want to maintain any existing property values?
Collection<QName> propsToLeaveAlone = new ArrayList<QName>();
Collection<QName> assocsToLeaveAlone = new ArrayList<QName>();
// see MNT-14688
if (newNodeTypeQName.equals(oldNodeTypeQName)) {
// The node did not change the type, check the associations
TypeDefinition typeDef = dictionaryService.getType(oldNodeTypeQName);
if (typeDef != null) {
for (QName assocName : typeDef.getAssociations().keySet()) {
if (getRevertAssocAction(oldNodeTypeQName, assocName, revertDetails) == RevertAssocAction.IGNORE) {
assocsToLeaveAlone.add(assocName);
}
}
}
}
for (QName aspect : oldAspectQNames) {
AspectDefinition aspectDef = dictionaryService.getAspect(aspect);
if (aspectDef != null) {
if (getRevertAspectAction(aspect, revertDetails) == RevertAspectAction.IGNORE) {
propsToLeaveAlone.addAll(aspectDef.getProperties().keySet());
}
for (QName assocName : aspectDef.getAssociations().keySet()) {
if (getRevertAssocAction(aspect, assocName, revertDetails) == RevertAssocAction.IGNORE) {
assocsToLeaveAlone.addAll(aspectDef.getAssociations().keySet());
}
}
}
}
for (QName prop : propsToLeaveAlone) {
if (oldProps.containsKey(prop)) {
newProps.put(prop, oldProps.get(prop));
}
}
this.nodeService.setProperties(nodeRef, newProps);
// Restore forum properties
this.nodeService.addProperties(nodeRef, forumProps);
// Restore the type
this.nodeService.setType(nodeRef, newNodeTypeQName);
Set<QName> aspectsToRemove = new HashSet<QName>(oldAspectQNames);
aspectsToRemove.removeAll(newAspectQNames);
Set<QName> aspectsToAdd = new HashSet<QName>(newAspectQNames);
aspectsToAdd.removeAll(oldAspectQNames);
// add aspects that are not on the current node
for (QName aspect : aspectsToAdd) {
if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) {
this.nodeService.addAspect(nodeRef, aspect, null);
}
}
// Don't remove forum aspects
if (needToRestoreDiscussion) {
Set<QName> ignoredAspects = new HashSet<QName>();
for (QName aspectForCheck : aspectsToRemove) {
if (aspectForCheck.getNamespaceURI().equals(NamespaceService.FORUMS_MODEL_1_0_URI)) {
ignoredAspects.add(aspectForCheck);
}
}
aspectsToRemove.removeAll(ignoredAspects);
}
// remove aspects that are not on the frozen node
for (QName aspect : aspectsToRemove) {
if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) {
this.nodeService.removeAspect(nodeRef, aspect);
}
}
// Re-add the versionable aspect to the reverted node
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) {
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null);
}
// Re-set the version label property (since it should not be modified from the original)
this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel);
// Add/remove the child nodes
List<ChildAssociationRef> children = new ArrayList<ChildAssociationRef>(this.nodeService.getChildAssocs(nodeRef));
List<ChildAssociationRef> versionedChildren = this.nodeService.getChildAssocs(versionNodeRef);
for (ChildAssociationRef versionedChild : versionedChildren) {
if (children.contains(versionedChild) == false) {
NodeRef childRef = null;
ChildAssociationRef assocToKeep = null;
if (this.nodeService.exists(versionedChild.getChildRef()) == true) {
// The node was a primary child of the parent, but that is no longer the case. Despite this
// the node still exits so this means it has been moved.
// The best thing to do in this situation will be to re-add the node as a child, but it will not
// be a primary child
String childRefName = (String) this.nodeService.getProperty(versionedChild.getChildRef(), ContentModel.PROP_NAME);
childRef = this.nodeService.getChildByName(nodeRef, versionedChild.getTypeQName(), childRefName);
// we can faced with association that allow duplicate names
if (childRef == null) {
List<ChildAssociationRef> allAssocs = nodeService.getParentAssocs(versionedChild.getChildRef(), versionedChild.getTypeQName(), RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef assocToCheck : allAssocs) {
if (children.contains(assocToCheck)) {
childRef = assocToCheck.getChildRef();
assocToKeep = assocToCheck;
break;
}
}
}
if (childRef == null) {
childRef = this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName()).getChildRef();
}
} else {
if (versionedChild.isPrimary() == true) {
// Look and see if we have a version history for the child node
if (deep == true && getVersionHistoryNodeRef(versionedChild.getChildRef()) != null) {
// We're going to try and restore the missing child node and recreate the assoc
childRef = restore(versionedChild.getChildRef(), nodeRef, versionedChild.getTypeQName(), versionedChild.getQName());
}
// else the deleted child did not have a version history so we can't restore the child
// and so we can't revert the association
}
// else
// Since this was never a primary assoc and the child has been deleted we won't recreate
// the missing node as it was never owned by the node and we wouldn't know where to put it.
}
if (childRef != null) {
if (assocToKeep != null) {
children.remove(assocToKeep);
} else {
children.remove(nodeService.getPrimaryParent(childRef));
}
}
} else {
children.remove(versionedChild);
}
}
// Don't remove forum children
if (needToRestoreDiscussion) {
List<ChildAssociationRef> ignoredChildren = new ArrayList<ChildAssociationRef>();
for (ChildAssociationRef childForCheck : children) {
if (childForCheck.getTypeQName().getNamespaceURI().equals(NamespaceService.FORUMS_MODEL_1_0_URI)) {
ignoredChildren.add(childForCheck);
}
}
children.removeAll(ignoredChildren);
}
for (ChildAssociationRef ref : children) {
if (!assocsToLeaveAlone.contains(ref.getTypeQName())) {
this.nodeService.removeChild(nodeRef, ref.getChildRef());
}
}
// Add/remove the target associations
for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL)) {
if (!assocsToLeaveAlone.contains(assocRef.getTypeQName())) {
this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName());
}
}
for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL)) {
if (!assocsToLeaveAlone.contains(versionedAssoc.getTypeQName())) {
if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true) {
this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName());
}
}
// else
// Since the target of the assoc no longer exists we can't recreate the assoc
}
} finally {
// Turn auto-version policies back on
this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
}
invokeAfterVersionRevert(nodeRef, version);
}
use of org.alfresco.service.cmr.version.VersionServiceException in project alfresco-repository by Alfresco.
the class VersionServiceImpl method revert.
/**
* @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version, boolean)
*/
public void revert(NodeRef nodeRef, Version version, boolean deep) {
if (logger.isDebugEnabled()) {
logger.debug("Run as user " + AuthenticationUtil.getRunAsUser());
logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser());
}
// Check the mandatory parameters
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("version", version);
// Cross check that the version provided relates to the node reference provided
if (nodeRef.getId().equals(version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID)) == false) {
// Error since the version provided does not correspond to the node reference provided
throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH);
}
// Turn off any auto-version policy behaviours
this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
try {
// Store the current version label
String currentVersionLabel = (String) this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL);
// Get the node that represents the frozen state
NodeRef versionNodeRef = version.getFrozenStateNodeRef();
// Revert the property values
this.nodeService.setProperties(nodeRef, this.nodeService.getProperties(versionNodeRef));
// Apply/remove the aspects as required
Set<QName> aspects = new HashSet<QName>(this.nodeService.getAspects(nodeRef));
for (QName versionAspect : this.nodeService.getAspects(versionNodeRef)) {
if (aspects.contains(versionAspect) == false) {
this.nodeService.addAspect(nodeRef, versionAspect, null);
} else {
aspects.remove(versionAspect);
}
}
for (QName aspect : aspects) {
this.nodeService.removeAspect(nodeRef, aspect);
}
// Re-add the versionable aspect to the reverted node
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) {
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null);
}
// Re-set the version label property (since it should not be modified from the origional)
this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel);
// Add/remove the child nodes
List<ChildAssociationRef> children = new ArrayList<ChildAssociationRef>(this.nodeService.getChildAssocs(nodeRef));
for (ChildAssociationRef versionedChild : this.nodeService.getChildAssocs(versionNodeRef)) {
if (children.contains(versionedChild) == false) {
if (this.nodeService.exists(versionedChild.getChildRef()) == true) {
// The node was a primary child of the parent, but that is no longer the case. Dispite this
// the node still exits so this means it has been moved.
// The best thing to do in this situation will be to re-add the node as a child, but it will not
// be a primary child.
this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName());
} else {
if (versionedChild.isPrimary() == true) {
// Look and see if we have a version history for the child node
if (deep == true && getVersionHistoryNodeRef(versionedChild.getChildRef()) != null) {
// We're going to try and restore the missing child node and recreate the assoc
restore(versionedChild.getChildRef(), nodeRef, versionedChild.getTypeQName(), versionedChild.getQName());
}
// else the deleted child did not have a version history so we can't restore the child
// and so we can't revert the association
}
// else
// Since this was never a primary assoc and the child has been deleted we won't recreate
// the missing node as it was never owned by the node and we wouldn't know where to put it.
}
} else {
children.remove(versionedChild);
}
}
for (ChildAssociationRef ref : children) {
this.nodeService.removeChild(nodeRef, ref.getChildRef());
}
// Add/remove the target associations
for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL)) {
this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName());
}
for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL)) {
if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true) {
this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName());
}
// else
// Since the tareget of the assoc no longer exists we can't recreate the assoc
}
} finally {
// Turn auto-version policies back on
this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE);
}
}
use of org.alfresco.service.cmr.version.VersionServiceException in project alfresco-repository by Alfresco.
the class VersionServiceImpl method createVersion.
/**
* Creates a new version of the passed node assigning the version properties
* accordingly.
*
* @param nodeRef a node reference
* @param origVersionProperties the version properties
* @param versionNumber the version number
* @return the newly created version
* @throws ReservedVersionNameException
* thrown if there is a name clash in the version properties
*/
protected Version createVersion(NodeRef nodeRef, Map<String, Serializable> origVersionProperties, int versionNumber) throws ReservedVersionNameException {
long startTime = System.currentTimeMillis();
// Copy the version properties (to prevent unexpected side effects to the caller)
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
if (origVersionProperties != null) {
versionProperties.putAll(origVersionProperties);
}
// If the version aspect is not there then add it
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) {
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null);
}
// Call the policy behaviour
invokeBeforeCreateVersion(nodeRef);
// Check that the supplied additional version properties do not clash with the reserved ones
VersionUtil.checkVersionPropertyNames(versionProperties.keySet());
// Check the repository for the version history for this node
NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef);
NodeRef currentVersionRef = null;
if (versionHistoryRef == null) {
// Create the version history
versionHistoryRef = createVersionHistory(nodeRef);
} else {
// Since we have an exisiting version history we should be able to lookup
// the current version
currentVersionRef = getCurrentVersionNodeRef(versionHistoryRef, nodeRef);
if (currentVersionRef == null) {
throw new VersionServiceException(MSGID_ERR_NOT_FOUND);
}
// Need to check that we are not about to create branch since this is not currently supported
VersionHistory versionHistory = buildVersionHistory(versionHistoryRef, nodeRef);
Version currentVersion = getVersion(currentVersionRef);
if (versionHistory.getSuccessors(currentVersion).size() != 0) {
throw new VersionServiceException(MSGID_ERR_NO_BRANCHES);
}
}
// Create the node details
QName classRef = this.nodeService.getType(nodeRef);
PolicyScope nodeDetails = new PolicyScope(classRef);
// Get the node details by calling the onVersionCreate policy behaviour
invokeOnCreateVersion(nodeRef, versionProperties, nodeDetails);
// Create the new version node (child of the version history)
NodeRef newVersionRef = createNewVersion(nodeRef, versionHistoryRef, getStandardVersionProperties(versionProperties, nodeRef, currentVersionRef, versionNumber), versionProperties, nodeDetails);
if (currentVersionRef == null) {
// Set the new version to be the root version in the version history
this.dbNodeService.createAssociation(versionHistoryRef, newVersionRef, VersionServiceImpl.ASSOC_ROOT_VERSION);
} else {
// Relate the new version to the current version as its successor
this.dbNodeService.createAssociation(currentVersionRef, newVersionRef, VersionServiceImpl.ASSOC_SUCCESSOR);
}
// Create the version data object
Version version = this.getVersion(newVersionRef);
// Set the new version label on the versioned node
this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, version.getVersionLabel());
// Freeze the version label property
Map<QName, Serializable> versionLabelAsMap = new HashMap<QName, Serializable>(1);
versionLabelAsMap.put(ContentModel.PROP_VERSION_LABEL, version.getVersionLabel());
this.freezeProperties(newVersionRef, versionLabelAsMap);
// Invoke the policy behaviour
invokeAfterCreateVersion(nodeRef, version);
if (logger.isTraceEnabled()) {
logger.trace("created Version (" + getVersionStoreReference() + ") " + nodeRef + " in " + (System.currentTimeMillis() - startTime) + " ms");
}
// Return the data object representing the newly created version
return version;
}
Aggregations