Search in sources :

Example 16 with FileInfo

use of org.alfresco.jlan.server.filesys.FileInfo in project alfresco-repository by Alfresco.

the class ContentDiskDriver2 method deleteFile2.

/**
 * Delete the specified file.
 *
 * @param session Server session
 * @param tree Tree connection
 * @param rootNode Root node
 * @param path NetworkFile
 * @exception java.io.IOException The exception description.
 * @return NodeRef of deletedFile
 */
public NodeRef deleteFile2(final SrvSession session, final TreeConnection tree, NodeRef rootNode, String path) throws IOException {
    // Get the device context
    final ContentContext ctx = (ContentContext) tree.getContext();
    if (logger.isDebugEnabled()) {
        logger.debug("deleteFile:" + path + ", session:" + session.getUniqueId());
    }
    try {
        // Check if there is a quota manager enabled, if so then we need to save the current file size
        final QuotaManager quotaMgr = ctx.getQuotaManager();
        // Get the node and delete it
        final NodeRef nodeRef = getNodeForPath(tree, path);
        if (fileFolderService.exists(nodeRef)) {
            lockKeeper.removeLock(nodeRef);
            // Get the size of the file being deleted
            final FileInfo fInfo = quotaMgr == null ? null : getFileInformation(session, tree, path);
            if (logger.isDebugEnabled()) {
                logger.debug("deleted file" + path);
            }
            fileFolderService.delete(nodeRef);
            // TODO Needs to be post-commit
            if (quotaMgr != null) {
                quotaMgr.releaseSpace(session, tree, fInfo.getFileId(), path, fInfo.getSize());
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Deleted file: " + path + ", nodeRef=" + nodeRef);
            }
            // void return
            return nodeRef;
        }
    } catch (NodeLockedException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Delete file - access denied (locked)", ex);
        }
        throw new AccessDeniedException("Unable to delete " + path);
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Delete file - access denied", ex);
        }
        // Convert to a filesystem access denied status
        throw new AccessDeniedException("Unable to delete " + path);
    } catch (IOException ex) {
        // Allow I/O Exceptions to pass through
        if (logger.isDebugEnabled()) {
            logger.debug("Delete file error - pass through IO Exception", ex);
        }
        throw ex;
    } catch (Exception ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Delete file error", ex);
        }
        // Convert to a general I/O exception
        IOException ioe = new IOException("Delete file " + path);
        ioe.initCause(ex);
        throw ioe;
    }
    return null;
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) NodeLockedException(org.alfresco.service.cmr.lock.NodeLockedException) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException) QuotaManager(org.alfresco.jlan.server.filesys.quota.QuotaManager) DiskFullException(org.alfresco.jlan.server.filesys.DiskFullException) IOControlNotImplementedException(org.alfresco.jlan.server.filesys.IOControlNotImplementedException) DeviceContextException(org.alfresco.jlan.server.core.DeviceContextException) FileNotFoundException(java.io.FileNotFoundException) QuotaManagerException(org.alfresco.jlan.server.filesys.quota.QuotaManagerException) PermissionDeniedException(org.alfresco.jlan.server.filesys.PermissionDeniedException) NodeLockedException(org.alfresco.service.cmr.lock.NodeLockedException) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) DirectoryNotEmptyException(org.alfresco.jlan.server.filesys.DirectoryNotEmptyException) SMBException(org.alfresco.jlan.smb.SMBException)

Example 17 with FileInfo

use of org.alfresco.jlan.server.filesys.FileInfo in project alfresco-repository by Alfresco.

the class ContentDiskDriverTest method testFileInformationUpdatingByEditorUserForAlf8808.

// testDirListing
public void testFileInformationUpdatingByEditorUserForAlf8808() throws Exception {
    final Holder<org.alfresco.service.cmr.model.FileInfo> editorFolder = new Holder<org.alfresco.service.cmr.model.FileInfo>();
    final Holder<org.alfresco.service.cmr.model.FileInfo> testFile = new Holder<org.alfresco.service.cmr.model.FileInfo>();
    // Configuring test server with test server configuration and getting test tree connection for test shared device
    ServerConfiguration config = new ServerConfiguration(ContentDiskDriverTest.TEST_SERVER_NAME);
    TestServer server = new TestServer(ContentDiskDriverTest.TEST_SERVER_NAME, config);
    DiskSharedDevice device = getDiskSharedDevice();
    final TreeConnection treeConnection = server.getTreeConnection(device);
    // Getting target entity for testing - ContentDiskDriver
    final ExtendedDiskInterface deviceInterface = (ExtendedDiskInterface) treeConnection.getInterface();
    // Creating mock-session
    final SrvSession session = new TestSrvSession(13, server, ContentDiskDriverTest.TEST_PROTOTYPE_NAME, ContentDiskDriverTest.TEST_REMOTE_NAME);
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            try {
                NodeRef rootNode = repositoryHelper.getCompanyHome();
                // Creating test user to invite him as Editor for test content. This user will be created correctly (with person and authentication options)
                createUser(ContentDiskDriverTest.TEST_USER_AUTHORITY, ContentDiskDriverTest.TEST_USER_AUTHORITY, rootNode);
                // Safely creating folder for test content
                editorFolder.value = getOrCreateNode(rootNode, PermissionService.EDITOR, ContentModel.TYPE_FOLDER).getFirst();
                // Creating test content which will be editable by user created above
                testFile.value = getOrCreateNode(rootNode, "Test.txt", ContentModel.TYPE_CONTENT).getFirst();
                // Applying 'Editor' role for test user to test file
                permissionService.setPermission(testFile.value.getNodeRef(), ContentDiskDriverTest.TEST_USER_AUTHORITY, PermissionService.EDITOR, true);
                try {
                    // Creating data for target method invocation
                    final FileInfo updatedInfo = new FileInfo();
                    updatedInfo.setFileName(testFile.value.getName());
                    updatedInfo.setFileId(DefaultTypeConverter.INSTANCE.intValue(testFile.value.getProperties().get(ContentModel.PROP_NODE_DBID)));
                    // Testing ContentDiskDriver.setFileInformation() with test user authenticated who has 'Editor' role for test content.
                    // This method should fail if check on 'DELETE' permission was not moved to 'DeleteOnClose' context
                    AuthenticationUtil.runAs(new RunAsWork<Void>() {

                        @Override
                        public Void doWork() throws Exception {
                            deviceInterface.setFileInformation(session, treeConnection, testFile.value.getName(), updatedInfo);
                            return null;
                        }
                    }, ContentDiskDriverTest.TEST_USER_AUTHORITY);
                } catch (Exception e) {
                    // Informing about test failure. Expected exception is 'org.alfresco.jlan.server.filesys.AccessDeniedException'
                    if (e.getCause() instanceof AccessDeniedException) {
                        fail("For user='" + TEST_USER_AUTHORITY + "' " + e.getCause().toString());
                    } else {
                        fail("Unexpected exception was caught: " + e.toString());
                    }
                }
            } finally {
                if (authenticationService.authenticationExists(ContentDiskDriverTest.TEST_USER_AUTHORITY)) {
                    authenticationService.deleteAuthentication(ContentDiskDriverTest.TEST_USER_AUTHORITY);
                }
                if (personService.personExists(ContentDiskDriverTest.TEST_USER_AUTHORITY)) {
                    personService.deletePerson(ContentDiskDriverTest.TEST_USER_AUTHORITY);
                }
                try {
                    if (null != testFile.value) {
                        nodeService.deleteNode(testFile.value.getNodeRef());
                    }
                } catch (Exception e) {
                // Doing nothing
                }
                try {
                    if (null != editorFolder.value) {
                        nodeService.deleteNode(editorFolder.value.getNodeRef());
                    }
                } catch (Exception e) {
                // Doing nothing
                }
            }
            return null;
        }
    }, false, true);
}
Also used : AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) SrvSession(org.alfresco.jlan.server.SrvSession) RunAsWork(org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork) ExtendedDiskInterface(org.alfresco.filesys.alfresco.ExtendedDiskInterface) Holder(javax.xml.ws.Holder) ServerConfiguration(org.alfresco.jlan.server.config.ServerConfiguration) DeviceContextException(org.alfresco.jlan.server.core.DeviceContextException) FileExistsException(org.alfresco.jlan.server.filesys.FileExistsException) FileNotFoundException(java.io.FileNotFoundException) PermissionDeniedException(org.alfresco.jlan.server.filesys.PermissionDeniedException) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) IOException(java.io.IOException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) TreeConnection(org.alfresco.jlan.server.filesys.TreeConnection) DiskSharedDevice(org.alfresco.jlan.server.filesys.DiskSharedDevice)

Example 18 with FileInfo

use of org.alfresco.jlan.server.filesys.FileInfo in project alfresco-repository by Alfresco.

the class ContentDiskDriverTest method testScenarioMacMountainLionPreview_MNT_317.

// testScenarioMacMountainLionPreview_MNT_263
/**
 * This test tries to simulate the cifs shuffling that is done
 * from Save from Mac Mountain Lion by Preview when document is opened/saved few time a row
 *
 * a) Temp file created in temporary folder (temp\image.jpg)
 * b) Original file is renamed for deletion(test\image.jpg -> test\.smbdeleteAAA1b994.4)
 * c) Renamed file has got deleteOnClose flag
 * d) Renamed file is closed.
 * e) Temp file is moved into original file location(temp\image.jpg -> test\image.jgp)
 */
public void testScenarioMacMountainLionPreview_MNT_317() throws Exception {
    logger.debug("testScenarioMacMountainLionPreview_MNT_317");
    final String FILE_NAME = "image.jpg";
    final String TEMP_FILE_NAME = ".smbdeleteAAA1b994.4";
    final String UPDATED_TEXT = "Mac Lion Preview Updated Content";
    class TestContext {

        NetworkFile firstFileHandle;

        NetworkFile tempFileHandle;

        // node ref image.jpg
        NodeRef testNodeRef;
    }
    ;
    final TestContext testContext = new TestContext();
    final String TEST_ROOT_DIR = "\\ContentDiskDriverTest";
    final String TEST_DIR = "\\ContentDiskDriverTest\\testScenarioMountainLionPreview";
    final String TEST_TEMP_DIR = "\\ContentDiskDriverTest\\testScenarioMountainLionPreview\\.Temporary Items";
    ServerConfiguration scfg = new ServerConfiguration("testServer");
    TestServer testServer = new TestServer("testServer", scfg);
    final SrvSession testSession = new TestSrvSession(666, testServer, "test", "remoteName");
    DiskSharedDevice share = getDiskSharedDevice();
    final TreeConnection testConnection = testServer.getTreeConnection(share);
    final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper();
    /**
     * Create a file in the test directory
     */
    RetryingTransactionCallback<Void> createFileCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            /**
             * Create the test directory we are going to use
             */
            FileOpenParams createRootDirParams = new FileOpenParams(TEST_ROOT_DIR, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            FileOpenParams createDirParams = new FileOpenParams(TEST_DIR, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            FileOpenParams createTempDirParams = new FileOpenParams(TEST_TEMP_DIR, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            driver.createDirectory(testSession, testConnection, createRootDirParams);
            driver.createDirectory(testSession, testConnection, createDirParams);
            driver.createDirectory(testSession, testConnection, createTempDirParams);
            /**
             * Create the file we are going to use
             */
            FileOpenParams createFileParams = new FileOpenParams(TEST_DIR + "\\" + FILE_NAME, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            testContext.firstFileHandle = driver.createFile(testSession, testConnection, createFileParams);
            assertNotNull(testContext.firstFileHandle);
            String testContent = "Mac Lion Preview Content";
            byte[] testContentBytes = testContent.getBytes();
            driver.writeFile(testSession, testConnection, testContext.firstFileHandle, testContentBytes, 0, testContentBytes.length, 0);
            driver.closeFile(testSession, testConnection, testContext.firstFileHandle);
            /**
             * Create the temp file we are going to use
             */
            FileOpenParams createTempFileParams = new FileOpenParams(TEST_TEMP_DIR + "\\" + FILE_NAME, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            testContext.tempFileHandle = driver.createFile(testSession, testConnection, createTempFileParams);
            assertNotNull(testContext.tempFileHandle);
            testContent = UPDATED_TEXT;
            testContentBytes = testContent.getBytes();
            driver.writeFile(testSession, testConnection, testContext.tempFileHandle, testContentBytes, 0, testContentBytes.length, 0);
            driver.closeFile(testSession, testConnection, testContext.tempFileHandle);
            /**
             * Also add versionable to target file
             */
            testContext.testNodeRef = getNodeForPath(testConnection, TEST_DIR + "\\" + FILE_NAME);
            nodeService.addAspect(testContext.testNodeRef, ContentModel.ASPECT_VERSIONABLE, null);
            return null;
        }
    };
    tran.doInTransaction(createFileCB, false, true);
    RetryingTransactionCallback<Void> renameFileCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            FileOpenParams openFileParams = new FileOpenParams(TEST_DIR + "\\" + FILE_NAME, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
            testContext.tempFileHandle = driver.openFile(testSession, testConnection, openFileParams);
            driver.renameFile(testSession, testConnection, TEST_DIR + "\\" + FILE_NAME, TEST_DIR + "\\" + TEMP_FILE_NAME);
            return null;
        }
    };
    tran.doInTransaction(renameFileCB, false, true);
    /**
     * Delete file via deleteOnClose flag.
     */
    RetryingTransactionCallback<Void> deleteOnCloseCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            FileInfo info = new FileInfo();
            info.setFileInformationFlags(FileInfo.SetDeleteOnClose);
            info.setDeleteOnClose(true);
            testContext.tempFileHandle.setDeleteOnClose(true);
            driver.setFileInformation(testSession, testConnection, TEST_DIR + "\\" + TEMP_FILE_NAME, info);
            assertNotNull(testContext.tempFileHandle);
            logger.debug("this close should result in a file being deleted");
            driver.closeFile(testSession, testConnection, testContext.tempFileHandle);
            return null;
        }
    };
    tran.doInTransaction(deleteOnCloseCB, false, true);
    // /**
    // * Delete file directly.
    // */
    // RetryingTransactionCallback<Void> deleteTargetFileCB = new RetryingTransactionCallback<Void>()
    // {
    // 
    // @Override
    // public Void execute() throws Throwable
    // {
    // 
    // driver.deleteFile(testSession, testConnection, TEST_DIR + "\\" + TEMP_FILE_NAME);
    // return null;
    // }
    // };
    // tran.doInTransaction(deleteTargetFileCB, false, true);
    RetryingTransactionCallback<Void> moveRenamedTempFileCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            driver.renameFile(testSession, testConnection, TEST_TEMP_DIR + "\\" + FILE_NAME, TEST_DIR + "\\" + FILE_NAME);
            return null;
        }
    };
    tran.doInTransaction(moveRenamedTempFileCB, false, true);
    RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() {

        @Override
        public Void execute() throws Throwable {
            NodeRef shuffledNodeRef = getNodeForPath(testConnection, TEST_DIR + "\\" + FILE_NAME);
            assertTrue("node is not versionable", nodeService.hasAspect(shuffledNodeRef, ContentModel.ASPECT_VERSIONABLE));
            assertEquals("shuffledNode ref is different", shuffledNodeRef, testContext.testNodeRef);
            assertEquals("Unexpected content size", contentService.getReader(shuffledNodeRef, ContentModel.PROP_CONTENT).getSize(), UPDATED_TEXT.length());
            return null;
        }
    };
    tran.doInTransaction(validateCB, false, true);
}
Also used : SrvSession(org.alfresco.jlan.server.SrvSession) RetryingTransactionHelper(org.alfresco.repo.transaction.RetryingTransactionHelper) ServerConfiguration(org.alfresco.jlan.server.config.ServerConfiguration) NodeRef(org.alfresco.service.cmr.repository.NodeRef) FileOpenParams(org.alfresco.jlan.server.filesys.FileOpenParams) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) RetryingTransactionCallback(org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback) TreeConnection(org.alfresco.jlan.server.filesys.TreeConnection) NetworkFile(org.alfresco.jlan.server.filesys.NetworkFile) DiskSharedDevice(org.alfresco.jlan.server.filesys.DiskSharedDevice)

Example 19 with FileInfo

use of org.alfresco.jlan.server.filesys.FileInfo in project alfresco-repository by Alfresco.

the class ContentDiskDriver method fileExists.

/**
 * Check if the specified file exists, and whether it is a file or directory.
 *
 * <p>
 * WARNING: side effect, commit or roll back current user transaction context.  Current transaction becomes read only.
 *
 * @param sess Server session
 * @param tree Tree connection
 * @param name the path of the file
 * @return FileStatus (0: NotExist, 1 : FileExist, 2: DirectoryExists)
 * @see FileStatus
 */
public int fileExists(SrvSession sess, TreeConnection tree, String name) {
    ContentContext ctx = (ContentContext) tree.getContext();
    int status = FileStatus.Unknown;
    FileState fstate = null;
    try {
        if (ctx.hasStateCache())
            fstate = ctx.getStateCache().findFileState(name, true);
        if (fstate != null && fstate.getFileStatus() != FileUnknown) {
            status = fstate.getFileStatus();
            if (status >= CustomFileStatus)
                status = FileNotExist;
            if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
                logger.debug("Cache hit - fileExists() " + name + ", sts=" + status);
        } else {
            if (status == FileStatus.Unknown) {
                // Create the transaction
                beginReadTransaction(sess);
                // Get the file information to check if the file/folder exists
                FileInfo info = getFileInformation(sess, tree, name);
                NodeRef nodeRef = getNodeOrNull(name, ctx, fstate);
                nodeRef = ((null == nodeRef) && (info instanceof ContentFileInfo)) ? (((ContentFileInfo) info).getNodeRef()) : (nodeRef);
                if ((null == nodeRef) || !fileFolderService.exists(nodeRef)) {
                    status = FileStatus.NotExist;
                } else {
                    if (info.isDirectory()) {
                        status = FileStatus.DirectoryExists;
                    } else {
                        status = FileStatus.FileExists;
                    }
                }
                if (fstate != null)
                    fstate.setFileStatus(status);
            }
        }
    } catch (FileNotFoundException e) {
        status = FileStatus.NotExist;
        if (fstate != null)
            fstate.setFileStatus(status);
    } catch (IOException e) {
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
            logger.debug("File exists error, " + name, e);
        status = FileStatus.NotExist;
    }
    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
        logger.debug("File status determined: name=" + name + " status=" + fileStatusString(fstate.getFileStatus()));
    return status;
}
Also used : FileState(org.alfresco.jlan.server.filesys.cache.FileState) NodeRef(org.alfresco.service.cmr.repository.NodeRef) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) FileNotFoundException(java.io.FileNotFoundException) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException)

Example 20 with FileInfo

use of org.alfresco.jlan.server.filesys.FileInfo in project alfresco-repository by Alfresco.

the class ContentDiskDriver method openFile.

/**
 * Open a file or folder
 *
 * @param sess SrvSession
 * @param tree TreeConnection
 * @param params FileOpenParams
 * @return NetworkFile
 * @exception IOException
 */
public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException {
    // Create the transaction
    beginReadTransaction(sess);
    ContentContext ctx = (ContentContext) tree.getContext();
    try {
        // Not a pseudo file, try and open a normal file/folder node
        NodeRef nodeRef = getNodeForPath(tree, params.getPath());
        if (params.hasAccessMode(AccessMode.NTRead) && permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED)
            throw new AccessDeniedException("No read access to " + params.getFullPath());
        if (params.hasAccessMode(AccessMode.NTWrite) && permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED)
            throw new AccessDeniedException("No write access to " + params.getFullPath());
        // Check for delete access
        // if ( params.hasAccessMode(AccessMode.NTDelete) &&
        // permissionService.hasPermission(nodeRef, PermissionService.DELETE) == AccessStatus.DENIED)
        // throw new AccessDeniedException("No delete access to " + params.getFullPath());
        // Check if the file has a lock
        String lockTypeStr = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_TYPE);
        if (params.hasAccessMode(AccessMode.NTWrite) && lockTypeStr != null)
            throw new AccessDeniedException("File is locked, no write access to " + params.getFullPath());
        // Check if there is a file state for the file
        FileState fstate = null;
        if (ctx.hasStateCache()) {
            // Check if there is a file state for the file
            fstate = ctx.getStateCache().findFileState(params.getPath());
            if (fstate != null) {
                if (fstate.exists() == false)
                    throw new FileNotFoundException();
            } else {
                // Create a file state for the path
                fstate = ctx.getStateCache().findFileState(params.getPath(), true);
            }
            // Check if the current file open allows the required shared access
            boolean nosharing = false;
            String noshrReason = null;
            if (params.getAccessMode() == AccessMode.NTFileGenericExecute && params.getPath().toLowerCase().endsWith(".exe") == false) {
                if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE)) {
                    logger.debug("Execute access mode, path" + params.getPath());
                    logger.debug("  Fstate=" + fstate);
                }
                throw new AccessDeniedException("Invalid access mode");
            }
            if (fstate.getOpenCount() > 0 && params.isAttributesOnlyAccess() == false) {
                if (params.getSecurityLevel() == WinNT.SecurityImpersonation && params.getProcessId() == fstate.getProcessId())
                    nosharing = false;
                else if (params.isReadOnlyAccess() && (fstate.getSharedAccess() & SharingMode.READ) != 0)
                    nosharing = false;
                else if ((params.isReadWriteAccess() || params.isWriteOnlyAccess()) && (fstate.getSharedAccess() & SharingMode.WRITE) == 0) {
                    nosharing = true;
                    noshrReason = "Sharing mode disallows write";
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Sharing mode disallows write access path=" + params.getPath());
                } else if (fstate.getSharedAccess() == SharingMode.NOSHARING) {
                    nosharing = true;
                    noshrReason = "Sharing mode exclusive";
                } else if ((fstate.getSharedAccess() & params.getSharedAccess()) != params.getSharedAccess()) {
                    nosharing = true;
                    noshrReason = "Sharing mode mismatch";
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Local share mode=0x" + Integer.toHexString(fstate.getSharedAccess()) + ", params share mode=0x" + Integer.toHexString(params.getSharedAccess()));
                } else if (params.getSharedAccess() == SharingMode.NOSHARING) {
                    nosharing = true;
                    noshrReason = "Requestor wants exclusive mode";
                }
            }
            if (nosharing == true) {
                if (params.getPath().equals("\\") == false) {
                    if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                        logger.debug("Sharing violation path=" + params.getPath() + ", sharing=0x" + Integer.toHexString(fstate.getSharedAccess()) + ",reason=" + noshrReason);
                    throw new FileSharingException("File already open, " + params.getPath());
                }
            }
            // Update the file sharing mode and process id, if this is the first file open
            fstate.setSharedAccess(params.getSharedAccess());
            fstate.setProcessId(params.getProcessId());
            if (logger.isDebugEnabled() && fstate.getOpenCount() == 0 && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                logger.debug("Path " + params.getPath() + ", sharing=0x" + Integer.toHexString(params.getSharedAccess()) + ", PID=" + params.getProcessId());
        }
        // Check if the node is a link node
        NodeRef linkRef = (NodeRef) nodeService.getProperty(nodeRef, ContentModel.PROP_LINK_DESTINATION);
        AlfrescoNetworkFile netFile = null;
        if (linkRef == null) {
            if (tree.openFileCount() > 0 && params.isAttributesOnlyAccess() == false) {
                // Search the open file table for this session/virtual circuit
                int idx = 0;
                while (idx < tree.getFileTableLength() && netFile == null) {
                    // Get the current file from the open file table
                    NetworkFile curFile = tree.findFile(idx);
                    if (curFile != null && curFile instanceof ContentNetworkFile) {
                        // Check if the file is the same path and process id
                        ContentNetworkFile contentFile = (ContentNetworkFile) curFile;
                        if (contentFile.getProcessId() == params.getProcessId() && contentFile.getFullName().equalsIgnoreCase(params.getFullPath())) {
                            if ((params.isReadWriteAccess() && contentFile.getGrantedAccess() == NetworkFile.READWRITE) || (params.isReadOnlyAccess() && contentFile.getGrantedAccess() == NetworkFile.READONLY)) {
                                // Found a match, re-use the open file
                                netFile = contentFile;
                                // Increment the file open count, last file close will actually close the file/stream
                                contentFile.incrementOpenCount();
                                if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                                    logger.debug("Re-use existing file open Path " + params.getPath() + ", PID=" + params.getProcessId() + ", params=" + (params.isReadOnlyAccess() ? "ReadOnly" : "Write") + ", file=" + (contentFile.getGrantedAccess() <= NetworkFile.READONLY ? "ReadOnly" : "Write"));
                            } else if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
                                logger.debug("Not re-using file path=" + params.getPath() + ", readWrite=" + (params.isReadWriteAccess() ? "true" : "false") + ", readOnly=" + (params.isReadOnlyAccess() ? "true" : "false") + ", grantedAccess=" + contentFile.getGrantedAccessAsString());
                        }
                    }
                    // Update the file table index
                    idx++;
                }
            }
            if (netFile == null) {
                // Create a new network file for the open request
                netFile = ContentNetworkFile.createFile(nodeService, contentService, mimetypeService, cifsHelper, nodeRef, params.getPath(), params.isReadOnlyAccess(), params.isAttributesOnlyAccess(), sess);
            }
        } else {
            // Get the CIFS server name
            String srvName = null;
            SMBServer cifsServer = (SMBServer) sess.getServer().getConfiguration().findServer("CIFS");
            if (sess instanceof SMBSrvSession) {
                SMBSrvSession smbSess = (SMBSrvSession) sess;
                srvName = smbSess.getShareHostName();
            } else if (cifsServer != null) {
                // Use the CIFS server name in the URL
                srvName = cifsServer.getServerName();
            } else {
                // Use the local server name in the URL
                srvName = InetAddress.getLocalHost().getHostName();
            }
            // Convert the target node to a path, convert to URL format
            String path = getPathForNode(tree, linkRef);
            path = path.replace(FileName.DOS_SEPERATOR, '/');
            // Build the URL file data
            StringBuilder urlStr = new StringBuilder();
            urlStr.append("[InternetShortcut]\r\n");
            urlStr.append("URL=file://");
            urlStr.append(srvName);
            urlStr.append("/");
            urlStr.append(tree.getSharedDevice().getName());
            urlStr.append(path);
            urlStr.append("\r\n");
            // Create the in memory pseudo file for the URL link
            byte[] urlData = urlStr.toString().getBytes();
            // Get the file information for the link node
            FileInfo fInfo = cifsHelper.getFileInformation(nodeRef, isReadOnly, isLockedFilesAsOffline);
            // Set the file size to the actual data length
            fInfo.setFileSize(urlData.length);
            // Create the network file using the in-memory file data
            netFile = new LinkMemoryNetworkFile(fInfo.getFileName(), urlData, fInfo, nodeRef);
            netFile.setFullName(params.getPath());
        }
        if (netFile != null) {
            long id = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID));
            netFile.setFileId((int) (id & 0xFFFFFFFFL));
            // Indicate the file is open
            netFile.setClosed(false);
        }
        if (params.isOverwrite() && netFile != null) {
            // Truncate the file to zero length
            netFile.truncateFile(0L);
        }
        if (ctx.hasStateCache()) {
            if (fstate == null)
                fstate = ctx.getStateCache().findFileState(params.getPath(), true);
            if (netFile.getGrantedAccess() > NetworkFile.ATTRIBUTESONLY)
                fstate.incrementOpenCount();
            fstate.setFilesystemObject(nodeRef);
            // Store the state with the file
            netFile.setFileState(fstate);
            if (fstate.hasFileSize())
                netFile.setFileSize(fstate.getFileSize());
        }
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Opened network file: path=" + params.getPath() + " file open parameters=" + params + " network file=" + netFile);
        return netFile;
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Open file - access denied, " + params.getFullPath());
        throw new AccessDeniedException("Open file " + params.getFullPath());
    } catch (RuntimeException ex) {
        if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
            logger.debug("Open file error", ex);
        throw new IOException("Open file " + params.getFullPath());
    }
}
Also used : FileState(org.alfresco.jlan.server.filesys.cache.FileState) AccessDeniedException(org.alfresco.jlan.server.filesys.AccessDeniedException) FileNotFoundException(java.io.FileNotFoundException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) AlfrescoNetworkFile(org.alfresco.filesys.alfresco.AlfrescoNetworkFile) FileInfo(org.alfresco.jlan.server.filesys.FileInfo) SMBSrvSession(org.alfresco.jlan.smb.server.SMBSrvSession) NetworkFile(org.alfresco.jlan.server.filesys.NetworkFile) AlfrescoNetworkFile(org.alfresco.filesys.alfresco.AlfrescoNetworkFile) SMBServer(org.alfresco.jlan.smb.server.SMBServer) ContentIOException(org.alfresco.service.cmr.repository.ContentIOException) IOException(java.io.IOException) FileSharingException(org.alfresco.jlan.server.filesys.FileSharingException)

Aggregations

FileInfo (org.alfresco.jlan.server.filesys.FileInfo)22 NodeRef (org.alfresco.service.cmr.repository.NodeRef)17 FileNotFoundException (java.io.FileNotFoundException)13 IOException (java.io.IOException)13 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)9 AccessDeniedException (org.alfresco.jlan.server.filesys.AccessDeniedException)8 ContentIOException (org.alfresco.service.cmr.repository.ContentIOException)8 SrvSession (org.alfresco.jlan.server.SrvSession)7 ServerConfiguration (org.alfresco.jlan.server.config.ServerConfiguration)7 DiskSharedDevice (org.alfresco.jlan.server.filesys.DiskSharedDevice)7 NetworkFile (org.alfresco.jlan.server.filesys.NetworkFile)7 TreeConnection (org.alfresco.jlan.server.filesys.TreeConnection)7 FileState (org.alfresco.jlan.server.filesys.cache.FileState)6 RetryingTransactionHelper (org.alfresco.repo.transaction.RetryingTransactionHelper)6 FileOpenParams (org.alfresco.jlan.server.filesys.FileOpenParams)5 RetryingTransactionCallback (org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback)5 Serializable (java.io.Serializable)4 DeviceContextException (org.alfresco.jlan.server.core.DeviceContextException)4 FileExistsException (org.alfresco.jlan.server.filesys.FileExistsException)4 Date (java.util.Date)3