use of org.alfresco.service.cmr.lock.LockType in project alfresco-repository by Alfresco.
the class ContentDiskDriver method renameFile.
/**
* Rename the specified file.
*
* @param sess Server session
* @param tree Tree connection
* @param oldName java.lang.String
* @param newName java.lang.String
* @exception java.io.IOException The exception description.
*/
public void renameFile(final SrvSession sess, final TreeConnection tree, final String oldName, final String newName) throws IOException {
// Create the transaction (initially read-only)
beginReadTransaction(sess);
// Get the device context
final ContentContext ctx = (ContentContext) tree.getContext();
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename oldName=" + oldName + ", newName=" + newName);
try {
// Get the file/folder to move
final NodeRef nodeToMoveRef = getNodeForPath(tree, oldName);
if (nodeToMoveRef != null && nodeService.getProperty(nodeToMoveRef, ContentModel.PROP_LINK_DESTINATION) != null)
throw new AccessDeniedException("Cannot rename link nodes");
// Get the new target folder - it must be a folder
String[] splitPaths = FileName.splitPath(newName);
String[] oldPaths = FileName.splitPath(oldName);
final NodeRef targetFolderRef = getNodeForPath(tree, splitPaths[0]);
final NodeRef sourceFolderRef = getNodeForPath(tree, oldPaths[0]);
final String name = splitPaths[1];
// Check if this is a rename within the same folder
final boolean sameFolder = splitPaths[0].equalsIgnoreCase(oldPaths[0]);
// Get the file state for the old file, if available
final FileState oldState = ctx.getStateCache().findFileState(oldName, true);
// Check if we are renaming a folder, or the rename is to a different folder
boolean isFolder = cifsHelper.isDirectory(nodeToMoveRef);
if (isFolder == true || sameFolder == false) {
// Rename or move the file/folder
doInWriteTransaction(sess, new CallableIO<Void>() {
public Void call() throws IOException {
if (sameFolder == true)
cifsHelper.rename(nodeToMoveRef, name);
else
cifsHelper.move(nodeToMoveRef, sourceFolderRef, targetFolderRef, name);
return null;
}
});
if (oldState != null) {
// Update the file state index to use the new name
ctx.getStateCache().renameFileState(newName, oldState, isFolder);
}
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Renamed " + (isFolder ? "folder" : "file") + " using " + (sameFolder ? "rename" : "move"));
} else {
// Rename a file within the same folder
//
// Check if the target file already exists
final int newExists = fileExists(sess, tree, newName);
final FileState newState = ctx.getStateCache().findFileState(newName, true);
List<Runnable> postTxn = doInWriteTransaction(sess, new CallableIO<List<Runnable>>() {
public List<Runnable> call() throws IOException {
List<Runnable> postTxn = new LinkedList<Runnable>();
NodeRef targetNodeRef = null;
boolean isFromVersionable = nodeService.hasAspect(nodeToMoveRef, ContentModel.ASPECT_VERSIONABLE);
boolean typesCompatible = true;
// HACK ALF-3856: Version History lost when Versionable Content renamed via CIFS
// This code will move into the repo layer (or just above it)
// and this complexity removed from here.
// Attempt to detect normal renames. Hack alert!
Pattern renameShufflePattern = ctx.getRenameShufflePattern();
boolean renameShuffle = isRenameShuffle(oldName, newName, renameShufflePattern);
if (logger.isDebugEnabled()) {
logger.debug("Rename file: \n" + " Old name: " + oldName + "\n" + " New name: " + newName + "\n" + " Pattern: " + renameShufflePattern.pattern() + "\n" + " Is shuffle: " + renameShuffle + "\n" + " Source folder: " + sourceFolderRef + "\n" + " Target folder: " + targetFolderRef + "\n" + " Node: " + nodeToMoveRef + "\n" + " Aspects: " + nodeService.getAspects(nodeToMoveRef));
}
if (newExists == FileStatus.FileExists) {
// Use the existing file as the target node
targetNodeRef = getNodeForPath(tree, newName);
} else if (renameShuffle) {
logger.debug("is rename shuffle");
if (newState.getFileStatus() == FileRenamed) {
logger.debug("file status == FileRenamed");
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Using renamed node, " + newState);
NodeRef newStateNode = (NodeRef) newState.getFilesystemObject();
QName oldType = nodeService.getType(nodeToMoveRef);
QName newType = nodeService.getType(newStateNode);
if (oldType.equals(newType)) {
// Use the renamed node to clone aspects/state if it is of the correct type
cloneNode(name, newStateNode, nodeToMoveRef, ctx);
} else {
logger.debug("not renamed, must create new node");
// Otherwise we must create a node of the correct type
targetNodeRef = cifsHelper.createNode(ctx.getRootNode(), newName, newType);
// Force a copy to this target
typesCompatible = false;
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Created new node for " + newName + " type " + newType + ", isFromVersionable=false");
// Copy aspects from the original state
cloneNode(name, newStateNode, targetNodeRef, ctx);
}
// Change state for tmp node to allow delete it without special permission
String newStateNodeName = (String) nodeService.getProperty(newStateNode, ContentModel.PROP_NAME);
FileState stateForTmp = ctx.getStateCache().findFileState(newName.substring(0, newName.lastIndexOf("\\")) + "\\" + newStateNodeName, true);
stateForTmp.addAttribute(CanDeleteWithoutPerms, true);
stateForTmp.setFileStatus(FileStatus.FileExists);
stateForTmp.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Set CanDeleteWithoutPerms=true for " + stateForTmp);
} else if (newState.getFileStatus() == DeleteOnClose) {
logger.debug("file state is delete on close");
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Restoring delete-on-close node, " + newState);
// Restore the deleted node so we can relink the new version to the old history/properties
NodeRef archivedNode = getNodeArchiveService().getArchivedNode((NodeRef) newState.getFilesystemObject());
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Found archived node " + archivedNode);
if (archivedNode != null && getNodeService().exists(archivedNode)) {
// Restore the node
targetNodeRef = getNodeService().restoreNode(archivedNode, null, null, null);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Restored node " + targetNodeRef + ", version=" + nodeService.getProperty(targetNodeRef, ContentModel.PROP_VERSION_LABEL));
// Check if the deleted file had a linked node, due to a rename
NodeRef linkNode = (NodeRef) newState.findAttribute(AttrLinkNode);
if (linkNode != null && nodeService.exists(linkNode)) {
// Clone aspects from the linked node onto the restored node
cloneNode(name, linkNode, targetNodeRef, ctx);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME)) {
logger.debug(" Moved aspects from linked node " + linkNode);
// Check if the node is a working copy
NodeRef mainNodeRef = checkOutCheckInService.getCheckedOut(targetNodeRef);
if (mainNodeRef != null) {
// Check if the main document is still locked
LockType lockTyp = lockService.getLockType(mainNodeRef);
logger.debug(" Main node ref lock type = " + lockTyp);
}
}
}
}
} else if (isFromVersionable == true) {
logger.debug("from node is versionable");
// Create a new node for the target
targetNodeRef = cifsHelper.createNode(ctx.getRootNode(), newName, nodeService.getType(nodeToMoveRef));
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Created new node for " + newName + ", isFromVersionable=true");
// Copy aspects from the original file
cloneNode(name, nodeToMoveRef, targetNodeRef, ctx);
// Change state for tmp node to allow delete it without special permission
FileState stateForTmp = ctx.getStateCache().findFileState(newName, true);
stateForTmp.addAttribute(CanDeleteWithoutPerms, true);
stateForTmp.setFileStatus(FileStatus.FileExists);
stateForTmp.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Set CanDeleteWithoutPerms=true for " + stateForTmp);
}
}
// If the original or target nodes are not versionable and types are compatible then just use a standard rename of the node
if (!renameShuffle || (!isFromVersionable && typesCompatible && (targetNodeRef == null || nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_VERSIONABLE) == false))) {
logger.debug("do simple rename");
// Rename the file/folder
cifsHelper.rename(nodeToMoveRef, name);
postTxn.add(new Runnable() {
public void run() {
// Mark the new file as existing
newState.setFileStatus(FileExists);
newState.setFilesystemObject(nodeToMoveRef);
newState.setFileSize(oldState.getFileSize());
// the date is updated to be properly saved when the document is closed, see MNT-214
newState.updateModifyDateTime(oldState.getModifyDateTime());
// Make sure the old file state is cached for a short while, the file may not be open so the
// file state could be expired
oldState.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
// Indicate that this is a renamed file state, set the node ref of the file that was renamed
oldState.setFileStatus(FileRenamed);
oldState.setFilesystemObject(nodeToMoveRef);
}
});
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Use standard rename for " + name + "(versionable=" + isFromVersionable + ", targetNodeRef=" + targetNodeRef + ")");
} else {
if (targetNodeRef == null) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" No target node for rename");
throw new AccessDeniedException("No target node for file rename");
}
// Copy content data from the old file to the new file
copyContentData(sess, tree, nodeToMoveRef, targetNodeRef, newName);
final NodeRef finalTargetNodeRef = targetNodeRef;
postTxn.add(new Runnable() {
public void run() {
// Mark the new file as existing
newState.setFileStatus(FileExists);
newState.setFilesystemObject(finalTargetNodeRef);
newState.setFileSize(oldState.getFileSize());
// the date is updated to be properly saved when the document is closed, see MNT-214
newState.updateModifyDateTime(oldState.getModifyDateTime());
// Make sure the old file state is cached for a short while, the file may not be open so the
// file state could be expired
oldState.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
// Indicate that this is a deleted file state, set the node ref of the file that was renamed
oldState.setFileStatus(DeleteOnClose);
oldState.setFilesystemObject(nodeToMoveRef);
// Link to the new node, a new file may be renamed into place, we need to transfer aspect/locks
oldState.addAttribute(AttrLinkNode, finalTargetNodeRef);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Cached delete state for " + oldName);
}
});
logger.debug("delete the old file");
// Delete the old file
if (renameShuffle && isFromVersionable && permissionService.hasPermission(nodeToMoveRef, PermissionService.EDITOR) == AccessStatus.ALLOWED) {
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
@Override
public Object doWork() throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Rename shuffle for versioning content is assumed. Deleting " + nodeToMoveRef + " as system user");
}
if (renameCSVShufflePattern.matcher(newName.toLowerCase()).matches()) {
Map<QName, Serializable> props = Collections.emptyMap();
nodeService.addAspect(nodeToMoveRef, ContentModel.ASPECT_SOFT_DELETE, props);
} else {
nodeService.deleteNode(nodeToMoveRef);
}
return null;
}
}, AuthenticationUtil.getSystemUserName());
} else {
if (logger.isDebugEnabled()) {
logger.debug("Deleting " + nodeToMoveRef + " as user: " + AuthenticationUtil.getFullyAuthenticatedUser());
}
nodeService.deleteNode(nodeToMoveRef);
}
}
return postTxn;
}
});
logger.debug("running post txns");
// Run the required state-changing logic once the retrying transaction has completed successfully
for (Runnable runnable : postTxn) {
runnable.run();
}
}
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file - access denied, " + oldName);
throw new AccessDeniedException("Rename file " + oldName);
} catch (NodeLockedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file", ex);
throw new AccessDeniedException("Node locked " + oldName);
} catch (InvalidNodeRefException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file - file doesn't exist, " + oldName, ex);
throw new FileNotFoundException("File doesn't exist " + oldName);
} catch (RuntimeException ex) {
// Unexpected Exception being consumed here - hence the error logging.
logger.error("Unable to rename file" + oldName, ex);
throw new AccessDeniedException("Rename file " + oldName);
}
}
use of org.alfresco.service.cmr.lock.LockType in project alfresco-repository by Alfresco.
the class CifsHelper method getFileInformationImpl.
/**
* Helper method to extract file info from a specific node.
* <p>
* This method goes direct to the repo for all information and no data is
* cached here.
*
* @param nodeRef the node
* @param readOnly, should the file be shown as "read only", regardless of its permissions?
* @param lockedFilesAsOffline should a locked file be marked as offline
*
* @return Returns the file information pertinent to the node
* @throws FileNotFoundException if the path refers to a non-existent file
*/
private ContentFileInfo getFileInformationImpl(NodeRef nodeRef, boolean readOnly, boolean lockedFilesAsOffline) throws FileNotFoundException {
// get the file info
org.alfresco.service.cmr.model.FileInfo fileFolderInfo = fileFolderService.getFileInfo(nodeRef);
// retrieve required properties and create new JLAN file info
ContentFileInfo fileInfo = new ContentFileInfo(nodeRef);
// Set the file id from the node's DBID
long id = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID));
fileInfo.setFileId((int) (id & 0xFFFFFFFFL));
// unset all attribute flags
int fileAttributes = 0;
fileInfo.setFileAttributes(fileAttributes);
if (fileFolderInfo.isFolder()) {
// add directory attribute
fileAttributes |= FileAttribute.Directory;
fileInfo.setFileAttributes(fileAttributes);
fileInfo.setFileType(FileType.Directory);
} else {
Map<QName, Serializable> nodeProperties = fileFolderInfo.getProperties();
// Get the file size from the content
ContentData contentData = (ContentData) nodeProperties.get(ContentModel.PROP_CONTENT);
long size = 0L;
if (contentData != null) {
size = contentData.getSize();
}
fileInfo.setSize(size);
if (size > 0) {
fileInfo.setAllocationSize((size + 512L) & 0xFFFFFFFFFFFFFE00L);
}
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE)) {
LockType lockType = lockService.getLockType(nodeRef);
int attr = fileInfo.getFileAttributes();
if (lockType != null) {
switch(lockType) {
case NODE_LOCK:
if ((attr & FileAttribute.ReadOnly) == 0)
attr += FileAttribute.ReadOnly;
break;
case WRITE_LOCK:
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
if (lockStatus == LockStatus.LOCK_OWNER) {
} else {
if ((attr & FileAttribute.ReadOnly) == 0) {
attr += FileAttribute.ReadOnly;
}
if (lockedFilesAsOffline) {
attr += FileAttribute.NTOffline;
}
}
break;
case READ_ONLY_LOCK:
if ((attr & FileAttribute.ReadOnly) == 0) {
attr += FileAttribute.ReadOnly;
}
if (lockedFilesAsOffline) {
attr += FileAttribute.NTOffline;
}
break;
}
fileInfo.setFileAttributes(attr);
}
}
if (fileFolderInfo.isLink()) {
fileInfo.setLinkNodeRef(fileFolderInfo.getLinkNodeRef());
}
}
// created
Date createdDate = fileFolderInfo.getCreatedDate();
if (createdDate != null) {
long created = DefaultTypeConverter.INSTANCE.longValue(createdDate);
fileInfo.setCreationDateTime(created);
}
// modified
Date modifiedDate = fileFolderInfo.getModifiedDate();
if (modifiedDate != null) {
long modified = DefaultTypeConverter.INSTANCE.longValue(modifiedDate);
fileInfo.setModifyDateTime(modified);
fileInfo.setAccessDateTime(modified);
fileInfo.setChangeDateTime(modified);
}
// name
String name = fileFolderInfo.getName();
if (name != null) {
fileInfo.setFileName(name);
// Check for file names that should be hidden
if (hiddenAspect.getVisibility(Client.cifs, fileInfo.getNodeRef()) == Visibility.HiddenAttribute) {
// Add the hidden file attribute
int attr = fileInfo.getFileAttributes();
if ((attr & FileAttribute.Hidden) == 0) {
attr += FileAttribute.Hidden;
fileInfo.setFileAttributes(attr);
}
}
}
if (!fileFolderInfo.isFolder() || isReadOnlyFlagOnFolders) {
boolean deniedPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED;
if (readOnly || deniedPermission) {
int attr = fileInfo.getFileAttributes();
if ((attr & FileAttribute.ReadOnly) == 0) {
attr += FileAttribute.ReadOnly;
fileInfo.setFileAttributes(attr);
}
}
}
if (fileInfo.getFileAttributes() == 0)
fileInfo.setFileAttributes(FileAttribute.NTNormal);
if (logger.isDebugEnabled()) {
logger.debug("Fetched file info: \n" + " info: " + fileInfo);
}
return fileInfo;
}
use of org.alfresco.service.cmr.lock.LockType in project alfresco-repository by Alfresco.
the class LockServiceImplTest method testGetLockTypeEphemeral.
public void testGetLockTypeEphemeral() {
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
// Get the lock type (should be null since the object is not locked)
LockType lockType1 = this.lockService.getLockType(this.parentNode);
assertNull(lockType1);
// Lock the object for writing
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK, 0, Lifetime.EPHEMERAL);
LockType lockType2 = this.lockService.getLockType(this.parentNode);
assertNotNull(lockType2);
assertEquals(LockType.WRITE_LOCK, lockType2);
assertTrue(lockService.isLocked(parentNode));
assertFalse(lockService.isLockedAndReadOnly(parentNode));
// Unlock the node
this.lockService.unlock(this.parentNode);
LockType lockType3 = this.lockService.getLockType(this.parentNode);
assertNull(lockType3);
assertFalse(lockService.isLocked(parentNode));
assertFalse(lockService.isLockedAndReadOnly(parentNode));
// Lock the object for read only
this.lockService.lock(this.parentNode, LockType.READ_ONLY_LOCK, 0, Lifetime.EPHEMERAL);
LockType lockType4 = this.lockService.getLockType(this.parentNode);
assertNotNull(lockType4);
assertEquals(LockType.READ_ONLY_LOCK, lockType4);
assertTrue(lockService.isLocked(parentNode));
assertTrue(lockService.isLockedAndReadOnly(parentNode));
// Lock the object for node lock
this.lockService.lock(this.parentNode, LockType.NODE_LOCK, 0, Lifetime.EPHEMERAL);
LockType lockType5 = this.lockService.getLockType(this.parentNode);
assertNotNull(lockType5);
assertEquals(LockType.NODE_LOCK, lockType5);
assertTrue(lockService.isLocked(parentNode));
assertTrue(lockService.isLockedAndReadOnly(parentNode));
// Unlock the node
this.lockService.unlock(this.parentNode);
LockType lockType6 = this.lockService.getLockType(this.parentNode);
assertNull(lockType6);
assertFalse(lockService.isLocked(parentNode));
assertFalse(lockService.isLockedAndReadOnly(parentNode));
// Test with no apect node
LockType lockType7 = this.lockService.getLockType(this.noAspectNode);
assertTrue("lock type is not null", lockType7 == null);
}
use of org.alfresco.service.cmr.lock.LockType in project alfresco-repository by Alfresco.
the class WorkingCopyAspect method onRestoreNode.
/**
* onRestoreNode policy behaviour
*
* @param nodeRef
* the node reference that was restored
*/
@SuppressWarnings("unchecked")
@Override
public void onRestoreNode(ChildAssociationRef childAssocRef) {
NodeRef workingCopyNodeRef = childAssocRef.getChildRef();
// check that node is working copy
if (nodeService.hasAspect(workingCopyNodeRef, ContentModel.ASPECT_WORKING_COPY)) {
try {
NodeRef checkedOutNodeRef = null;
policyBehaviourFilter.disableBehaviour(workingCopyNodeRef, ContentModel.ASPECT_AUDITABLE);
Map<QName, Serializable> workingCopyProperties = nodeService.getProperties(workingCopyNodeRef);
// get archived lock properties in order to be restored on the original node
String lockOwner = (String) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_LOCK_OWNER);
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_LOCK_OWNER);
Date expiryDate = (Date) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_EXPIRY_DATE);
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_EXPIRY_DATE);
String lockTypeStr = (String) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_LOCK_TYPE);
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_LOCK_TYPE);
LockType lockType = lockTypeStr != null ? LockType.valueOf(lockTypeStr) : null;
String lifetimeStr = (String) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_LOCK_LIFETIME);
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_LOCK_LIFETIME);
Lifetime lifetime = lifetimeStr != null ? Lifetime.valueOf(lifetimeStr) : null;
String additionalInfo = (String) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_LOCK_ADDITIONAL_INFO);
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_LOCK_ADDITIONAL_INFO);
List<AssociationRef> targetAssocList = (ArrayList<AssociationRef>) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_TARGET_ASSOCS);
if (targetAssocList != null && targetAssocList.get(0) != null) {
AssociationRef targetAssoc = (AssociationRef) targetAssocList.get(0);
checkedOutNodeRef = targetAssoc.getSourceRef();
nodeService.createAssociation(targetAssoc.getSourceRef(), targetAssoc.getTargetRef(), ContentModel.ASSOC_ORIGINAL);
}
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_TARGET_ASSOCS);
ArrayList<AssociationRef> sourceAssocList = (ArrayList<AssociationRef>) workingCopyProperties.get(ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS);
if (sourceAssocList != null && sourceAssocList.get(0) != null) {
AssociationRef sourceAssoc = (AssociationRef) sourceAssocList.get(0);
checkedOutNodeRef = sourceAssoc.getSourceRef();
nodeService.createAssociation(sourceAssoc.getSourceRef(), sourceAssoc.getTargetRef(), ContentModel.ASSOC_WORKING_COPY_LINK);
}
workingCopyProperties.remove(ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS);
// clean up the archived aspect and properties for working copy node
nodeService.removeAspect(workingCopyNodeRef, ContentModel.ASPECT_ARCHIVE_LOCKABLE);
nodeService.setProperties(workingCopyNodeRef, workingCopyProperties);
// restore properties on original node
nodeService.addAspect(checkedOutNodeRef, ContentModel.ASPECT_LOCKABLE, null);
Map<QName, Serializable> checkedOutNodeProperties = nodeService.getProperties(checkedOutNodeRef);
checkedOutNodeProperties.put(ContentModel.PROP_LOCK_OWNER, lockOwner);
checkedOutNodeProperties.put(ContentModel.PROP_LOCK_TYPE, lockType);
checkedOutNodeProperties.put(ContentModel.PROP_LOCK_LIFETIME, lifetime);
checkedOutNodeProperties.put(ContentModel.PROP_EXPIRY_DATE, expiryDate);
checkedOutNodeProperties.put(ContentModel.PROP_LOCK_ADDITIONAL_INFO, additionalInfo);
nodeService.setProperties(checkedOutNodeRef, checkedOutNodeProperties);
} finally {
policyBehaviourFilter.enableBehaviour(workingCopyNodeRef, ContentModel.ASPECT_AUDITABLE);
}
}
}
use of org.alfresco.service.cmr.lock.LockType in project alfresco-repository by Alfresco.
the class WorkingCopyAspect method beforeArchiveNode.
/**
* beforeArchiveNode policy behaviour
*
* @param nodeRef
* the node reference about to be archived
*/
@Override
public void beforeArchiveNode(NodeRef workingCopyNodeRef) {
NodeRef checkedOutNodeRef = checkOutCheckInService.getCheckedOut(workingCopyNodeRef);
if (checkedOutNodeRef != null) {
try {
policyBehaviourFilter.disableBehaviour(workingCopyNodeRef, ContentModel.ASPECT_AUDITABLE);
if (nodeService.hasAspect(checkedOutNodeRef, ContentModel.ASPECT_LOCKABLE)) {
Map<QName, Serializable> checkedOutNodeProperties = nodeService.getProperties(checkedOutNodeRef);
Map<QName, Serializable> workingCopyProperties = nodeService.getProperties(workingCopyNodeRef);
Long nodeId = nodeDAO.getNodePair(workingCopyNodeRef).getFirst();
// get lock properties from checked out node and set them on working copy node in order to be available for restore
String lockOwner = (String) checkedOutNodeProperties.get(ContentModel.PROP_LOCK_OWNER);
Date expiryDate = (Date) checkedOutNodeProperties.get(ContentModel.PROP_EXPIRY_DATE);
String lockTypeStr = (String) checkedOutNodeProperties.get(ContentModel.PROP_LOCK_TYPE);
LockType lockType = lockTypeStr != null ? LockType.valueOf(lockTypeStr) : null;
String lifetimeStr = (String) checkedOutNodeProperties.get(ContentModel.PROP_LOCK_LIFETIME);
Lifetime lifetime = lifetimeStr != null ? Lifetime.valueOf(lifetimeStr) : null;
String additionalInfo = (String) checkedOutNodeProperties.get(ContentModel.PROP_LOCK_ADDITIONAL_INFO);
nodeService.addAspect(workingCopyNodeRef, ContentModel.ASPECT_ARCHIVE_LOCKABLE, null);
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_LOCK_OWNER, lockOwner);
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_LOCK_TYPE, lockType);
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_LOCK_LIFETIME, lifetime);
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_EXPIRY_DATE, expiryDate);
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_LOCK_ADDITIONAL_INFO, additionalInfo);
// Target associations
Collection<Pair<Long, AssociationRef>> targetAssocs = nodeDAO.getTargetNodeAssocs(nodeId, null);
for (Pair<Long, AssociationRef> targetAssocPair : targetAssocs) {
if (ContentModel.ASSOC_ORIGINAL.equals(targetAssocPair.getSecond().getTypeQName())) {
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_TARGET_ASSOCS, targetAssocPair.getSecond());
}
}
// Source associations
Collection<Pair<Long, AssociationRef>> sourceAssocs = nodeDAO.getSourceNodeAssocs(nodeId, null);
for (Pair<Long, AssociationRef> sourceAssocPair : sourceAssocs) {
if (ContentModel.ASSOC_WORKING_COPY_LINK.equals(sourceAssocPair.getSecond().getTypeQName())) {
workingCopyProperties.put(ContentModel.PROP_ARCHIVED_SOURCE_ASSOCS, sourceAssocPair.getSecond());
}
}
// update working copy node properties
nodeService.setProperties(workingCopyNodeRef, workingCopyProperties);
}
} finally {
policyBehaviourFilter.enableBehaviour(checkedOutNodeRef, ContentModel.ASPECT_AUDITABLE);
}
}
}
Aggregations