Search in sources :

Example 1 with LockType

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);
    }
}
Also used : FileState(org.alfresco.jlan.server.filesys.cache.FileState) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) Serializable(java.io.Serializable) FileNotFoundException(java.io.FileNotFoundException) LockType(org.alfresco.service.cmr.lock.LockType) NodeRef(org.alfresco.service.cmr.repository.NodeRef) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) List(java.util.List) LinkedList(java.util.LinkedList) InvalidNodeRefException(org.alfresco.service.cmr.repository.InvalidNodeRefException) NodeLockedException(org.alfresco.service.cmr.lock.NodeLockedException) Pattern(java.util.regex.Pattern) QName(org.alfresco.service.namespace.QName) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException)

Example 2 with LockType

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;
}
Also used : Serializable(java.io.Serializable) QName(org.alfresco.service.namespace.QName) LockStatus(org.alfresco.service.cmr.lock.LockStatus) FileInfo(org.alfresco.service.cmr.model.FileInfo) LockType(org.alfresco.service.cmr.lock.LockType) Date(java.util.Date) ContentData(org.alfresco.service.cmr.repository.ContentData)

Example 3 with LockType

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);
}
Also used : LockType(org.alfresco.service.cmr.lock.LockType)

Example 4 with LockType

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);
        }
    }
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) Serializable(java.io.Serializable) Lifetime(org.alfresco.repo.lock.mem.Lifetime) QName(org.alfresco.service.namespace.QName) ArrayList(java.util.ArrayList) LockType(org.alfresco.service.cmr.lock.LockType) Date(java.util.Date) AssociationRef(org.alfresco.service.cmr.repository.AssociationRef) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef)

Example 5 with LockType

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);
        }
    }
}
Also used : Serializable(java.io.Serializable) QName(org.alfresco.service.namespace.QName) LockType(org.alfresco.service.cmr.lock.LockType) Date(java.util.Date) AssociationRef(org.alfresco.service.cmr.repository.AssociationRef) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) NodeRef(org.alfresco.service.cmr.repository.NodeRef) Lifetime(org.alfresco.repo.lock.mem.Lifetime) Pair(org.alfresco.util.Pair)

Aggregations

LockType (org.alfresco.service.cmr.lock.LockType)8 Serializable (java.io.Serializable)4 Date (java.util.Date)4 QName (org.alfresco.service.namespace.QName)4 Lifetime (org.alfresco.repo.lock.mem.Lifetime)3 LockStatus (org.alfresco.service.cmr.lock.LockStatus)3 NodeRef (org.alfresco.service.cmr.repository.NodeRef)3 NodeLockedException (org.alfresco.service.cmr.lock.NodeLockedException)2 AssociationRef (org.alfresco.service.cmr.repository.AssociationRef)2 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)2 Extend (org.alfresco.traitextender.Extend)2 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Pattern (java.util.regex.Pattern)1 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)1 AccessDeniedException (org.alfresco.jlan.server.filesys.AccessDeniedException)1 FileState (org.alfresco.jlan.server.filesys.cache.FileState)1