@Test public void testWriteOperations() throws Exception { // ------------------------------------------------------ // Check #createFolder // ------------------------------------------------------ // Not allowed to create a folder in a non FolderItem try { fileSystemItemManagerService.createFolder( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), "A new folder", principal); fail("Folder creation in a non folder item should fail."); } catch (NuxeoException e) { assertEquals( String.format( "Cannot create a folder in file system item with id %s because it is not a folder but is: " + "DocumentBackedFileItem(id=\"%s\", name=\"Joe.odt\")", DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId()), e.getMessage()); } // Folder creation FolderItem newFolderItem = fileSystemItemManagerService.createFolder( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), "A new folder", principal); assertNotNull(newFolderItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), newFolderItem.getParentId()); assertEquals("A new folder", newFolderItem.getName()); DocumentModelList folderChildren = session.query( String.format( "select * from Document where ecm:parentId = '%s' and ecm:primaryType = 'Folder' order by dc:title asc", folder.getId())); DocumentModel newFolder = folderChildren.get(0); assertTrue(newFolder.isFolder()); assertEquals("A new folder", newFolder.getTitle()); // Parent folder children check assertEquals( 6, fileSystemItemManagerService .getChildren(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal) .size()); // ------------------------------------------------------ // Check #createFile // ------------------------------------------------------ // File creation Blob blob = new StringBlob("Content of a new file."); blob.setFilename("New file.odt"); blob.setMimeType("application/vnd.oasis.opendocument.text"); FileItem fileItem = fileSystemItemManagerService.createFile(newFolderItem.getId(), blob, principal); assertNotNull(fileItem); assertEquals(newFolderItem.getId(), fileItem.getParentId()); assertEquals("New file.odt", fileItem.getName()); folderChildren = session.query( String.format("select * from Document where ecm:parentId = '%s'", newFolder.getId())); assertEquals(1, folderChildren.size()); DocumentModel newFile = folderChildren.get(0); assertEquals("File", newFile.getType()); assertEquals("New file.odt", newFile.getTitle()); assertEquals("/syncRoot1/aFolder/A new folder/New file.odt", newFile.getPathAsString()); Blob newFileBlob = (Blob) newFile.getPropertyValue("file:content"); assertEquals("New file.odt", newFileBlob.getFilename()); assertEquals("Content of a new file.", newFileBlob.getString()); assertEquals( "nxfile/test/" + newFile.getId() + "/blobholder:0/New%20file.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(newFileBlob.getDigest(), fileItem.getDigest()); // Parent folder children check assertEquals( 1, fileSystemItemManagerService.getChildren(newFolderItem.getId(), principal).size()); // ------------------------------------------------------ // Check #updateFile // ------------------------------------------------------ String fileItemId = fileItem.getId(); String fileItemParentId = fileItem.getParentId(); blob = new StringBlob("Modified content of an existing file."); fileItem = fileSystemItemManagerService.updateFile(fileItemId, blob, principal); assertNotNull(fileItem); assertEquals(fileItemId, fileItem.getId()); assertEquals(fileItemParentId, fileItem.getParentId()); assertEquals("New file.odt", fileItem.getName()); folderChildren = session.query( String.format("select * from Document where ecm:parentId = '%s'", newFolder.getId())); assertEquals(1, folderChildren.size()); DocumentModel updatedFile = folderChildren.get(0); assertEquals("File", updatedFile.getType()); assertEquals("New file.odt", updatedFile.getTitle()); assertEquals("/syncRoot1/aFolder/A new folder/New file.odt", updatedFile.getPathAsString()); Blob updatedFileBlob = (Blob) updatedFile.getPropertyValue("file:content"); assertEquals("New file.odt", updatedFileBlob.getFilename()); assertEquals("Modified content of an existing file.", updatedFileBlob.getString()); assertEquals( "nxfile/test/" + updatedFile.getId() + "/blobholder:0/New%20file.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(updatedFileBlob.getDigest(), fileItem.getDigest()); // ------------------------------------------------------ // Check #delete // ------------------------------------------------------ // File deletion fileSystemItemManagerService.delete( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + updatedFile.getId(), principal); updatedFile = session.getDocument(new IdRef(updatedFile.getId())); assertEquals("deleted", updatedFile.getCurrentLifeCycleState()); // Parent folder children check assertTrue( fileSystemItemManagerService.getChildren(newFolderItem.getId(), principal).isEmpty()); // ------------------------------------------------------ // Check #rename // ------------------------------------------------------ // Folder rename String fsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(); FileSystemItem fsItem = fileSystemItemManagerService.rename(fsItemId, "Jack's folder has a new name", principal); assertEquals(fsItemId, fsItem.getId()); String expectedSyncRoot1Id = DEFAULT_SYNC_ROOT_ITEM_ID_PREFIX + syncRoot1.getId(); assertEquals(expectedSyncRoot1Id, fsItem.getParentId()); assertEquals("Jack's folder has a new name", fsItem.getName()); folder = session.getDocument(folder.getRef()); assertEquals("Jack's folder has a new name", folder.getTitle()); // File rename with title != filename // => should rename filename but not title assertEquals("aFile", file.getTitle()); assertEquals("Joe.odt", ((Blob) file.getPropertyValue("file:content")).getFilename()); fsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(); fsItem = fileSystemItemManagerService.rename(fsItemId, "File new name.odt", principal); assertEquals(fsItemId, fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); assertEquals("File new name.odt", fsItem.getName()); file = session.getDocument(file.getRef()); assertEquals("aFile", file.getTitle()); Blob fileBlob = (Blob) file.getPropertyValue("file:content"); assertEquals("File new name.odt", fileBlob.getFilename()); fileItem = (FileItem) fsItem; assertEquals( "nxfile/test/" + file.getId() + "/blobholder:0/File%20new%20name.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(fileBlob.getDigest(), fileItem.getDigest()); // File rename with title == filename // => should rename filename and title blob = new StringBlob("File for a doc with title == filename."); blob.setFilename("Title-filename equality.odt"); blob.setMimeType("application/vnd.oasis.opendocument.text"); fileItem = fileSystemItemManagerService.createFile(newFolderItem.getId(), blob, principal); // Note that the PathSegmentService truncates doc title at 24 characters newFile = session.getDocument( new PathRef("/syncRoot1/aFolder/A new folder/Title-filename equality.")); assertEquals("Title-filename equality.odt", newFile.getTitle()); assertEquals( "Title-filename equality.odt", ((Blob) newFile.getPropertyValue("file:content")).getFilename()); fileItem = (FileItem) fileSystemItemManagerService.rename( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + newFile.getId(), "Renamed title-filename equality.odt", principal); assertEquals("Renamed title-filename equality.odt", fileItem.getName()); newFile = session.getDocument(newFile.getRef()); assertEquals("Renamed title-filename equality.odt", newFile.getTitle()); newFileBlob = (Blob) newFile.getPropertyValue("file:content"); assertEquals("Renamed title-filename equality.odt", newFileBlob.getFilename()); assertEquals( "nxfile/test/" + newFile.getId() + "/blobholder:0/Renamed%20title-filename%20equality.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(newFileBlob.getDigest(), fileItem.getDigest()); // ------------------------------------------------------ // Check #move // ------------------------------------------------------ // Not allowed to move a file system item to a non FolderItem String srcFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + note.getId(); String destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(); try { fileSystemItemManagerService.move(srcFsItemId, destFsItemId, principal); fail("Move to a non folder item should fail."); } catch (NuxeoException e) { assertEquals( String.format( "Cannot move a file system item to file system item with id %s because it is not a folder.", DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId()), e.getMessage()); } // Move to a FolderItem destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(); FileSystemItem movedFsItem = fileSystemItemManagerService.move(srcFsItemId, destFsItemId, principal); assertEquals(srcFsItemId, movedFsItem.getId()); assertEquals(destFsItemId, movedFsItem.getParentId()); assertEquals("aNote.txt", movedFsItem.getName()); note = session.getDocument(note.getRef()); assertEquals("/syncRoot1/aFolder/aSubFolder/aNote", note.getPathAsString()); assertEquals("aNote", note.getTitle()); }
@Test public void testReadOperations() throws Exception { // ------------------------------------------------------ // Check #getTopLevelFolder // ------------------------------------------------------ List<FileSystemItem> topLevelChildren = fileSystemItemManagerService.getTopLevelFolder(principal).getChildren(); assertNotNull(topLevelChildren); assertEquals(2, topLevelChildren.size()); FileSystemItem childFsItem = topLevelChildren.get(0); assertTrue(childFsItem instanceof DefaultSyncRootFolderItem); assertEquals("defaultSyncRootFolderItemFactory#test#" + syncRoot1.getId(), childFsItem.getId()); assertTrue(childFsItem.getParentId().endsWith("DefaultTopLevelFolderItemFactory#")); assertEquals("syncRoot1", childFsItem.getName()); childFsItem = topLevelChildren.get(1); assertTrue(childFsItem instanceof DefaultSyncRootFolderItem); assertEquals("defaultSyncRootFolderItemFactory#test#" + syncRoot2.getId(), childFsItem.getId()); assertTrue(childFsItem.getParentId().endsWith("DefaultTopLevelFolderItemFactory#")); assertEquals("syncRoot2", childFsItem.getName()); // ------------------------------------------------------ // Check #exists // ------------------------------------------------------ // Non existent doc id assertFalse( fileSystemItemManagerService.exists( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + "nonExistentId", principal)); // File assertTrue( fileSystemItemManagerService.exists( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), principal)); // Not adaptable as a FileSystemItem assertFalse( fileSystemItemManagerService.exists( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + notAFileSystemItem.getId(), principal)); // Deleted custom.followTransition("delete"); assertFalse( fileSystemItemManagerService.exists( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + custom.getId(), principal)); // ------------------------------------------------------------ // Check #getFileSystemItemById(String id, Principal principal) // ------------------------------------------------------------ // Folder FileSystemItem fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal); assertNotNull(fsItem); assertTrue(fsItem instanceof FolderItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getId()); String expectedSyncRoot1Id = DEFAULT_SYNC_ROOT_ITEM_ID_PREFIX + syncRoot1.getId(); assertEquals(expectedSyncRoot1Id, fsItem.getParentId()); assertEquals("Jack's folder", fsItem.getName()); assertTrue(fsItem.isFolder()); assertTrue(fsItem.getCanRename()); assertTrue(fsItem.getCanDelete()); assertTrue(((FolderItem) fsItem).getCanCreateChild()); List<FileSystemItem> children = ((FolderItem) fsItem).getChildren(); assertNotNull(children); assertEquals(4, children.size()); // File fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), principal); assertNotNull(fsItem); assertTrue(fsItem instanceof FileItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); assertEquals("Joe.odt", fsItem.getName()); assertFalse(fsItem.isFolder()); assertTrue(fsItem.getCanRename()); assertTrue(fsItem.getCanDelete()); FileItem fileFsItem = (FileItem) fsItem; assertTrue(fileFsItem.getCanUpdate()); assertEquals( "nxfile/test/" + file.getId() + "/blobholder:0/Joe.odt", fileFsItem.getDownloadURL()); assertEquals("MD5", fileFsItem.getDigestAlgorithm()); assertEquals(file.getAdapter(BlobHolder.class).getBlob().getDigest(), fileFsItem.getDigest()); Blob fileItemBlob = fileFsItem.getBlob(); assertEquals("Joe.odt", fileItemBlob.getFilename()); assertEquals("Content of Joe's file.", fileItemBlob.getString()); // FolderishFile fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folderishFile.getId(), principal); assertNotNull(fsItem); assertTrue(fsItem instanceof FolderItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folderishFile.getId(), fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); assertEquals("Sarah's folderish file", fsItem.getName()); assertTrue(fsItem.isFolder()); assertTrue(fsItem.getCanRename()); assertTrue(fsItem.getCanDelete()); assertTrue(((FolderItem) fsItem).getCanCreateChild()); assertTrue(((FolderItem) fsItem).getChildren().isEmpty()); // Not adaptable as a FileSystemItem fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + notAFileSystemItem.getId(), principal); assertNull(fsItem); // Deleted assertNull( fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + custom.getId(), principal)); // Sub folder fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(), principal); assertNotNull(fsItem); assertTrue(fsItem instanceof FolderItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(), fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); assertEquals("Tony's sub folder", fsItem.getName()); assertTrue(fsItem.isFolder()); assertTrue(fsItem.getCanRename()); assertTrue(fsItem.getCanDelete()); assertTrue(((FolderItem) fsItem).getCanCreateChild()); assertTrue(((FolderItem) fsItem).getChildren().isEmpty()); // ------------------------------------------------------------------- // Check #getFileSystemItemById(String id, String parentId, Principal // principal) // ------------------------------------------------------------------- fsItem = fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal); assertTrue(fsItem instanceof FileItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); // ------------------------------------------------------ // Check #getChildren // ------------------------------------------------------ // Need to flush VCS cache for the session used in DocumentBackedFolderItem#getChildren() to be // aware of changes // in the current session session.save(); children = fileSystemItemManagerService.getChildren( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal); assertNotNull(children); assertEquals(4, children.size()); // Ordered checkChildren( children, folder.getId(), file.getId(), note.getId(), folderishFile.getId(), subFolder.getId(), true); children = fileSystemItemManagerService.getChildren( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(), principal); assertTrue(children.isEmpty()); // ------------------------------------------------------ // Check #scrollDescendants // ------------------------------------------------------ // Need to flush VCS cache for the session used in DocumentBackedFolderItem#scrollDescendants to // be aware of // changes in the current session session.save(); FolderItem folderItem = (FolderItem) fileSystemItemManagerService.getFileSystemItemById( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal); assertTrue(folderItem.getCanScrollDescendants()); // Scroll through all descendants in one breath ScrollFileSystemItemList folderDescendants = fileSystemItemManagerService.scrollDescendants( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal, null, 10, 1000); assertNotNull(folderDescendants); assertNotNull(folderDescendants.getScrollId()); assertEquals(4, folderDescendants.size()); // Order is not determined checkChildren( folderDescendants, folder.getId(), file.getId(), note.getId(), folderishFile.getId(), subFolder.getId(), false); // Scroll through descendants in several steps folderDescendants.clear(); ScrollFileSystemItemList descendantsBatch; int batchSize = 2; String scrollId = null; while (!(descendantsBatch = folderItem.scrollDescendants(scrollId, batchSize, 1000)) .isEmpty()) { assertTrue(descendantsBatch.size() > 0); scrollId = descendantsBatch.getScrollId(); folderDescendants.addAll(descendantsBatch); } assertEquals(4, folderDescendants.size()); // Order is not determined checkChildren( folderDescendants, folder.getId(), file.getId(), note.getId(), folderishFile.getId(), subFolder.getId(), false); folderDescendants = fileSystemItemManagerService.scrollDescendants( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(), principal, null, 10, 1000); assertTrue(folderDescendants.isEmpty()); // ------------------------------------------------------ // Check #canMove // ------------------------------------------------------ // Not allowed to move a file system item to a non FolderItem String srcFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + note.getId(); String destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(); assertFalse(fileSystemItemManagerService.canMove(srcFsItemId, destFsItemId, principal)); // Not allowed to move a file system item if no REMOVE permission on the // source backing doc Principal joePrincipal = new NuxeoPrincipalImpl("joe"); DocumentModel rootDoc = session.getRootDocument(); setPermission(rootDoc, "joe", SecurityConstants.READ, true); nuxeoDriveManager.registerSynchronizationRoot(joePrincipal, syncRoot1, session); // Under Oracle, the READ ACL optims are not visible from the joe // session while the transaction has not been committed. TransactionHelper.commitOrRollbackTransaction(); TransactionHelper.startTransaction(); destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(); assertFalse(fileSystemItemManagerService.canMove(srcFsItemId, destFsItemId, joePrincipal)); // Not allowed to move a file system item if no ADD_CHILDREN permission // on the destination backing doc setPermission(folder, "joe", SecurityConstants.WRITE, true); setPermission(subFolder, "joe", SecurityConstants.READ, true); setPermission(subFolder, SecurityConstants.ADMINISTRATOR, SecurityConstants.EVERYTHING, true); setPermission(subFolder, SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false); assertFalse(fileSystemItemManagerService.canMove(srcFsItemId, destFsItemId, joePrincipal)); // OK: REMOVE permission on the source backing doc + REMOVE_CHILDREN // permission on its parent + ADD_CHILDREN permission on the destination // backing doc resetPermissions(subFolder, SecurityConstants.EVERYONE); resetPermissions(subFolder, "joe"); setPermission(subFolder, "joe", SecurityConstants.WRITE, true); assertTrue(fileSystemItemManagerService.canMove(srcFsItemId, destFsItemId, joePrincipal)); // Reset permissions resetPermissions(rootDoc, "joe"); resetPermissions(folder, "joe"); resetPermissions(subFolder, "joe"); }