Commit 2b5183e6 authored by Matija Obreza's avatar Matija Obreza

Merge branch 'manage-folders' into 'master'

Manage folders

See merge request !27
parents b3bd1647 cf98e1f0
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.filerepository;
/**
* The Class NoSuchRepositoryFileException.
*/
public class NoSuchRepositoryFolderException extends FileRepositoryException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/**
* Instantiates a new no such repository file exception.
*/
public NoSuchRepositoryFolderException() {
}
/**
* Instantiates a new no such repository file exception.
*
* @param message the message
*/
public NoSuchRepositoryFolderException(final String message) {
super(message);
}
}
...@@ -33,6 +33,7 @@ import javax.persistence.Table; ...@@ -33,6 +33,7 @@ import javax.persistence.Table;
import org.genesys.blocks.model.AuditedVersionedModel; import org.genesys.blocks.model.AuditedVersionedModel;
import org.genesys.blocks.model.Copyable; import org.genesys.blocks.model.Copyable;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.security.model.AclAwareModel; import org.genesys.blocks.security.model.AclAwareModel;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
...@@ -40,6 +41,7 @@ import com.fasterxml.jackson.annotation.JsonIdentityInfo; ...@@ -40,6 +41,7 @@ import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference; import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.fasterxml.jackson.annotation.JsonProperty.Access;
import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.annotation.ObjectIdGenerators;
...@@ -86,6 +88,7 @@ public class ImageGallery extends AuditedVersionedModel implements AclAwareModel ...@@ -86,6 +88,7 @@ public class ImageGallery extends AuditedVersionedModel implements AclAwareModel
@ManyToMany(cascade = { CascadeType.REFRESH }) @ManyToMany(cascade = { CascadeType.REFRESH })
@JoinTable(name = "repository_gallery_image", joinColumns = @JoinColumn(name = "galleryId"), inverseJoinColumns = @JoinColumn(name = "imageId")) @JoinTable(name = "repository_gallery_image", joinColumns = @JoinColumn(name = "galleryId"), inverseJoinColumns = @JoinColumn(name = "imageId"))
@OrderColumn(name = "position") @OrderColumn(name = "position")
@JsonView({ JsonViews.Root.class })
private List<RepositoryImage> images; private List<RepositoryImage> images;
/** The folder. */ /** The folder. */
......
...@@ -32,6 +32,7 @@ import javax.persistence.PrePersist; ...@@ -32,6 +32,7 @@ import javax.persistence.PrePersist;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient; import javax.persistence.Transient;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.UuidModel; import org.genesys.blocks.model.UuidModel;
import org.genesys.blocks.security.model.AclAwareModel; import org.genesys.blocks.security.model.AclAwareModel;
import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.InvalidRepositoryPathException;
...@@ -41,6 +42,7 @@ import org.hibernate.annotations.Type; ...@@ -41,6 +42,7 @@ import org.hibernate.annotations.Type;
import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference; import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.annotation.ObjectIdGenerators;
/** /**
...@@ -73,6 +75,7 @@ public class RepositoryFolder extends UuidModel implements AclAwareModel { ...@@ -73,6 +75,7 @@ public class RepositoryFolder extends UuidModel implements AclAwareModel {
@OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "parent") @OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "parent")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "path") @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "path")
@JsonIdentityReference(alwaysAsId = true) @JsonIdentityReference(alwaysAsId = true)
@JsonView({ JsonViews.Root.class })
private List<RepositoryFolder> children; private List<RepositoryFolder> children;
/** List of files in this folder. */ /** List of files in this folder. */
......
...@@ -64,4 +64,13 @@ public interface RepositoryFolderRepository extends RepositoryPersistence<Reposi ...@@ -64,4 +64,13 @@ public interface RepositoryFolderRepository extends RepositoryPersistence<Reposi
* @return the list * @return the list
*/ */
List<RepositoryFolder> findByPathStartingWith(String prefix, Pageable pageable); List<RepositoryFolder> findByPathStartingWith(String prefix, Pageable pageable);
/**
* Find by uuid and version.
*
* @param uuid the uuid
* @param version the version
* @return the repository folder
*/
RepositoryFolder findByUuidAndVersion(UUID uuid, int version);
} }
...@@ -26,6 +26,7 @@ import org.genesys.filerepository.FolderNotEmptyException; ...@@ -26,6 +26,7 @@ import org.genesys.filerepository.FolderNotEmptyException;
import org.genesys.filerepository.InvalidRepositoryFileDataException; import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException; import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.NoSuchRepositoryFolderException;
import org.genesys.filerepository.metadata.ImageMetadata; import org.genesys.filerepository.metadata.ImageMetadata;
import org.genesys.filerepository.model.RepositoryFile; import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.model.RepositoryFolder; import org.genesys.filerepository.model.RepositoryFolder;
...@@ -246,6 +247,14 @@ public interface RepositoryService { ...@@ -246,6 +247,14 @@ public interface RepositoryService {
*/ */
RepositoryImage removeImage(RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, IOException; RepositoryImage removeImage(RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, IOException;
/**
* Get folder by UUID
*
* @param uuid folder UUID
* @return the folder
*/
RepositoryFolder getFolder(UUID uuid);
/** /**
* Gets the folder by path * Gets the folder by path
* *
...@@ -255,6 +264,15 @@ public interface RepositoryService { ...@@ -255,6 +264,15 @@ public interface RepositoryService {
*/ */
RepositoryFolder getFolder(Path folderPath) throws InvalidRepositoryPathException; RepositoryFolder getFolder(Path folderPath) throws InvalidRepositoryPathException;
/**
* Update folder metadata. Note that path and name are immutable.
*
* @param folder the folder
* @return the updated repository folder
* @throws NoSuchRepositoryFolderException
*/
RepositoryFolder updateFolder(RepositoryFolder folder) throws NoSuchRepositoryFolderException;
/** /**
* Test if repository contains the path. * Test if repository contains the path.
* *
......
...@@ -38,6 +38,7 @@ import org.genesys.filerepository.FolderNotEmptyException; ...@@ -38,6 +38,7 @@ import org.genesys.filerepository.FolderNotEmptyException;
import org.genesys.filerepository.InvalidRepositoryFileDataException; import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException; import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.NoSuchRepositoryFolderException;
import org.genesys.filerepository.model.QRepositoryFile; import org.genesys.filerepository.model.QRepositoryFile;
import org.genesys.filerepository.model.QRepositoryFolder; import org.genesys.filerepository.model.QRepositoryFolder;
import org.genesys.filerepository.model.RepositoryFile; import org.genesys.filerepository.model.RepositoryFile;
...@@ -68,6 +69,10 @@ import com.querydsl.core.types.dsl.BooleanExpression; ...@@ -68,6 +69,10 @@ import com.querydsl.core.types.dsl.BooleanExpression;
* @author Matija Obreza * @author Matija Obreza
* *
*/ */
/**
* @author Matija Obreza
*
*/
@Service @Service
@Transactional(readOnly = true) @Transactional(readOnly = true)
public class RepositoryServiceImpl implements RepositoryService, InitializingBean { public class RepositoryServiceImpl implements RepositoryService, InitializingBean {
...@@ -375,12 +380,32 @@ public class RepositoryServiceImpl implements RepositoryService, InitializingBea ...@@ -375,12 +380,32 @@ public class RepositoryServiceImpl implements RepositoryService, InitializingBea
} }
} }
@Override
public RepositoryFolder getFolder(UUID uuid) {
return folderRepository.findByUuid(uuid);
}
@Override @Override
public RepositoryFolder getFolder(Path folderPath) throws InvalidRepositoryPathException { public RepositoryFolder getFolder(Path folderPath) throws InvalidRepositoryPathException {
PathValidator.checkValidPath(folderPath); PathValidator.checkValidPath(folderPath);
return folderRepository.findByPath(folderPath.normalize().toAbsolutePath().toString()); return folderRepository.findByPath(folderPath.normalize().toAbsolutePath().toString());
} }
/* (non-Javadoc)
* @see org.genesys.filerepository.service.RepositoryService#updateFolder(org.genesys.filerepository.model.RepositoryFolder)
*/
@Override
@Transactional
public RepositoryFolder updateFolder(RepositoryFolder folder) throws NoSuchRepositoryFolderException {
RepositoryFolder databaseFolder = folderRepository.findByUuidAndVersion(folder.getUuid(), folder.getVersion());
if (databaseFolder == null) {
throw new NoSuchRepositoryFolderException("Folder version doesn't match or folder not found");
}
databaseFolder.setTitle(folder.getTitle());
databaseFolder.setDescription(folder.getDescription());
return folderRepository.save(databaseFolder);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see * @see
......
...@@ -25,6 +25,7 @@ import java.util.List; ...@@ -25,6 +25,7 @@ import java.util.List;
import org.genesys.filerepository.FolderNotEmptyException; import org.genesys.filerepository.FolderNotEmptyException;
import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFolderException;
import org.genesys.filerepository.model.RepositoryFolder; import org.genesys.filerepository.model.RepositoryFolder;
import org.junit.Test; import org.junit.Test;
import org.springframework.security.test.context.support.WithMockUser; import org.springframework.security.test.context.support.WithMockUser;
...@@ -119,7 +120,7 @@ public class RepositoryFolderTest extends RepositoryServiceTest { ...@@ -119,7 +120,7 @@ public class RepositoryFolderTest extends RepositoryServiceTest {
Path newPath = path.getRoot().resolve("bbbb"); Path newPath = path.getRoot().resolve("bbbb");
repositoryService.renamePath(path, newPath); repositoryService.renamePath(path, newPath);
} }
@Test(expected = InvalidRepositoryPathException.class) @Test(expected = InvalidRepositoryPathException.class)
public void failRenamePathToExisting2() throws InvalidRepositoryPathException { public void failRenamePathToExisting2() throws InvalidRepositoryPathException {
Path path = Paths.get("/bbbb/cccc/dddd/eeee"); Path path = Paths.get("/bbbb/cccc/dddd/eeee");
...@@ -130,14 +131,54 @@ public class RepositoryFolderTest extends RepositoryServiceTest { ...@@ -130,14 +131,54 @@ public class RepositoryFolderTest extends RepositoryServiceTest {
Path newPath = path.getParent().getParent().resolve("dddd"); Path newPath = path.getParent().getParent().resolve("dddd");
repositoryService.renamePath(path, newPath); repositoryService.renamePath(path, newPath);
} }
@Test @Test
public void deleteEmptyFolder() throws InvalidRepositoryPathException, FolderNotEmptyException { public void deleteEmptyFolder() throws InvalidRepositoryPathException, FolderNotEmptyException {
Path path = Paths.get("/bbbb/cccc/dddd/eeee"); Path path = Paths.get("/bbbb/cccc/dddd/eeee");
RepositoryFolder folder = repositoryService.ensureFolder(path); RepositoryFolder folder = repositoryService.ensureFolder(path);
assertThat(folder, notNullValue()); assertThat(folder, notNullValue());
RepositoryFolder deleted = repositoryService.deleteFolder(path); RepositoryFolder deleted = repositoryService.deleteFolder(path);
assertThat(deleted, notNullValue()); assertThat(deleted, notNullValue());
} }
@Test
public void getFolderByUuid() throws InvalidRepositoryPathException {
Path path = Paths.get("/eeee/" + System.currentTimeMillis());
RepositoryFolder folder = repositoryService.ensureFolder(path);
RepositoryFolder folderByUuid = repositoryService.getFolder(folder.getUuid());
assertThat(folder.getUuid(), equalTo(folderByUuid.getUuid()));
}
@Test
public void updateTest() throws InvalidRepositoryPathException, NoSuchRepositoryFolderException {
Path path = Paths.get("/eeee/" + System.currentTimeMillis());
RepositoryFolder folder = repositoryService.ensureFolder(path);
assertThat(folder.getTitle(), nullValue());
assertThat(folder.getDescription(), nullValue());
folder.setTitle("Folder name");
folder.setDescription("Folder description");
RepositoryFolder folderUpdated = repositoryService.updateFolder(folder);
assertThat(folderUpdated.getUuid(), equalTo(folder.getUuid()));
assertThat(folderUpdated.getVersion(), equalTo(folder.getVersion() + 1));
assertThat(folderUpdated.getTitle(), equalTo(folder.getTitle()));
assertThat(folderUpdated.getDescription(), equalTo(folder.getDescription()));
}
@Test
public void updateTestNoNameChange() throws InvalidRepositoryPathException, NoSuchRepositoryFolderException {
String folderName = "" + System.currentTimeMillis();
Path path = Paths.get("/eeee/" + folderName);
RepositoryFolder folder = repositoryService.ensureFolder(path);
folder.setName("New name");
RepositoryFolder folderUpdated = repositoryService.updateFolder(folder);
assertThat(folderUpdated.getUuid(), equalTo(folder.getUuid()));
assertThat(folderUpdated.getVersion(), equalTo(folder.getVersion()));
assertThat(folderUpdated.getName(), equalTo(folderName));
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment