diff --git a/scm-core/src/main/java/sonia/scm/AlreadyExistsException.java b/scm-core/src/main/java/sonia/scm/AlreadyExistsException.java index 4c6a52b878..95fc24ecb2 100644 --- a/scm-core/src/main/java/sonia/scm/AlreadyExistsException.java +++ b/scm-core/src/main/java/sonia/scm/AlreadyExistsException.java @@ -1,11 +1,35 @@ package sonia.scm; -public class AlreadyExistsException extends Exception { +import java.util.List; - public AlreadyExistsException(String message) { - super(message); +import static java.util.Collections.singletonList; +import static java.util.Collections.unmodifiableList; +import static java.util.stream.Collectors.joining; + +public class AlreadyExistsException extends RuntimeException implements ExceptionWithContext { + + private final List context; + + public AlreadyExistsException(ModelObject object) { + this(singletonList(new ContextEntry(object.getClass(), object.getId()))); } - public AlreadyExistsException() { + public static AlreadyExistsException alreadyExists(ContextEntry.ContextBuilder builder) { + return new AlreadyExistsException(builder.build()); + } + + private AlreadyExistsException(List context) { + super(createMessage(context)); + this.context = context; + } + + public List getContext() { + return unmodifiableList(context); + } + + private static String createMessage(List context) { + return context.stream() + .map(c -> c.getType().toLowerCase() + " with id " + c.getId()) + .collect(joining(" in ", "", " already exists")); } } diff --git a/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java b/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java index f0129093a3..2a3e65781d 100644 --- a/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java +++ b/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java @@ -6,7 +6,7 @@ import java.util.List; import static java.util.Collections.unmodifiableList; import static java.util.stream.Collectors.joining; -public class ConcurrentModificationException extends RuntimeException { +public class ConcurrentModificationException extends RuntimeException implements ExceptionWithContext { private final List context; public ConcurrentModificationException(Class type, String id) { diff --git a/scm-core/src/main/java/sonia/scm/ContextEntry.java b/scm-core/src/main/java/sonia/scm/ContextEntry.java index 2dbccbacf7..591f29972a 100644 --- a/scm-core/src/main/java/sonia/scm/ContextEntry.java +++ b/scm-core/src/main/java/sonia/scm/ContextEntry.java @@ -1,7 +1,13 @@ package sonia.scm; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Repository; import sonia.scm.util.AssertUtil; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + public class ContextEntry { private final String type; private final String id; @@ -11,17 +17,60 @@ public class ContextEntry { } ContextEntry(String type, String id) { - AssertUtil.assertIsNotEmpty(type); - AssertUtil.assertIsNotEmpty(id); - this.type = type; - this.id = id; + AssertUtil.assertIsNotEmpty(type); + AssertUtil.assertIsNotEmpty(id); + this.type = type; + this.id = id; + } + + public String getType() { + return type; + } + + public String getId() { + return id; + } + + + public static class ContextBuilder { + private final List context = new LinkedList<>(); + + public static ContextBuilder entity(Repository repository) { + return new ContextBuilder().in(repository.getNamespaceAndName()); } - public String getType () { - return type; + public static ContextBuilder entity(NamespaceAndName namespaceAndName) { + return new ContextBuilder().in(Repository.class, namespaceAndName.logString()); } - public String getId () { - return id; + public static ContextBuilder entity(Class type, String id) { + return new ContextBuilder().in(type, id); + } + + public static ContextBuilder entity(String type, String id) { + return new ContextBuilder().in(type, id); + } + + public ContextBuilder in(Repository repository) { + return in(repository.getNamespaceAndName()); + } + + public ContextBuilder in(NamespaceAndName namespaceAndName) { + return this.in(Repository.class, namespaceAndName.logString()); + } + + public ContextBuilder in(Class type, String id) { + context.add(new ContextEntry(type, id)); + return this; + } + + public ContextBuilder in(String type, String id) { + context.add(new ContextEntry(type, id)); + return this; + } + + public List build() { + return Collections.unmodifiableList(context); } } +} diff --git a/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java new file mode 100644 index 0000000000..d10411ca9a --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java @@ -0,0 +1,9 @@ +package sonia.scm; + +import java.util.List; + +public interface ExceptionWithContext { + List getContext(); + + String getMessage(); +} diff --git a/scm-core/src/main/java/sonia/scm/HandlerBase.java b/scm-core/src/main/java/sonia/scm/HandlerBase.java index bbe78c8cf7..a621f4f697 100644 --- a/scm-core/src/main/java/sonia/scm/HandlerBase.java +++ b/scm-core/src/main/java/sonia/scm/HandlerBase.java @@ -54,25 +54,21 @@ public interface HandlerBase * * @return The persisted object. */ - T create(T object) throws AlreadyExistsException; + T create(T object); /** * Removes a persistent object. * * * @param object to delete - * - * @throws IOException */ - void delete(T object) throws NotFoundException; + void delete(T object); /** * Modifies a persistent object. * * * @param object to modify - * - * @throws IOException */ - void modify(T object) throws NotFoundException; + void modify(T object); } diff --git a/scm-core/src/main/java/sonia/scm/Manager.java b/scm-core/src/main/java/sonia/scm/Manager.java index 20b3a16a8e..390777958d 100644 --- a/scm-core/src/main/java/sonia/scm/Manager.java +++ b/scm-core/src/main/java/sonia/scm/Manager.java @@ -58,7 +58,7 @@ public interface Manager * * @throws NotFoundException */ - void refresh(T object) throws NotFoundException; + void refresh(T object); //~--- get methods ---------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/ManagerDecorator.java b/scm-core/src/main/java/sonia/scm/ManagerDecorator.java index ef20a374cb..f6e91aeced 100644 --- a/scm-core/src/main/java/sonia/scm/ManagerDecorator.java +++ b/scm-core/src/main/java/sonia/scm/ManagerDecorator.java @@ -66,7 +66,7 @@ public class ManagerDecorator implements Manager { } @Override - public T create(T object) throws AlreadyExistsException { + public T create(T object) { return decorated.create(object); } diff --git a/scm-core/src/main/java/sonia/scm/NotFoundException.java b/scm-core/src/main/java/sonia/scm/NotFoundException.java index 36b4d37cb1..110402043d 100644 --- a/scm-core/src/main/java/sonia/scm/NotFoundException.java +++ b/scm-core/src/main/java/sonia/scm/NotFoundException.java @@ -10,7 +10,7 @@ import java.util.List; import static java.util.Collections.unmodifiableList; import static java.util.stream.Collectors.joining; -public class NotFoundException extends RuntimeException { +public class NotFoundException extends RuntimeException implements ExceptionWithContext { private final List context; @@ -22,27 +22,15 @@ public class NotFoundException extends RuntimeException { this(Collections.singletonList(new ContextEntry(type, id))); } + public static NotFoundException notFound(ContextEntry.ContextBuilder contextBuilder) { + return new NotFoundException(contextBuilder.build()); + } + private NotFoundException(List context) { super(createMessage(context)); this.context = context; } - public static NotFoundExceptionBuilder notFound(Repository repository) { - return new NotFoundExceptionBuilder().in(repository); - } - - public static NotFoundExceptionBuilder notFound(NamespaceAndName namespaceAndName) { - return new NotFoundExceptionBuilder().in(namespaceAndName); - } - - public static NotFoundExceptionBuilder notFound(Class type, String id) { - return new NotFoundExceptionBuilder().in(type, id); - } - - public static NotFoundExceptionBuilder notFound(String type, String id) { - return new NotFoundExceptionBuilder().in(type, id); - } - public List getContext() { return unmodifiableList(context); } @@ -52,31 +40,4 @@ public class NotFoundException extends RuntimeException { .map(c -> c.getType().toLowerCase() + " with id " + c.getId()) .collect(joining(" in ", "could not find ", "")); } - - public static class NotFoundExceptionBuilder { - private final List context = new LinkedList<>(); - - public NotFoundExceptionBuilder in(Repository repository) { - return in(repository.getNamespaceAndName()); - } - - public NotFoundExceptionBuilder in(NamespaceAndName namespaceAndName) { - return this.in(Repository.class, namespaceAndName.logString()); - } - - public NotFoundExceptionBuilder in(Class type, String id) { - context.add(new ContextEntry(type, id)); - return this; - } - - public NotFoundExceptionBuilder in(String type, String id) { - context.add(new ContextEntry(type, id)); - return this; - } - - public NotFoundException build() { - return new NotFoundException(context); - } - } - } diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java index 2195e87730..f4438807c6 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstactImportHandler.java @@ -37,7 +37,6 @@ package sonia.scm.repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.AlreadyExistsException; import sonia.scm.repository.ImportResult.Builder; import java.io.File; @@ -243,7 +242,7 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler */ private void importRepository(RepositoryManager manager, String repositoryName) - throws IOException, AlreadyExistsException { + throws IOException { Repository repository = createRepository(getRepositoryDirectory(repositoryName), repositoryName); diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java index a717cdf05b..997413aacb 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java @@ -81,11 +81,11 @@ public abstract class AbstractSimpleRepositoryHandler files = Lists.newArrayList(); while (treeWalk.next()) { @@ -335,7 +335,7 @@ public class GitBrowseCommand extends AbstractGitCommand } private FileObject findFirstMatch(org.eclipse.jgit.lib.Repository repo, - BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, NotFoundException { + BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException { String[] pathElements = request.getPath().split("/"); int currentDepth = 0; int limit = pathElements.length; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java index 40f044ebde..7477e0aee3 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java @@ -44,7 +44,6 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.NotFoundException; import sonia.scm.repository.GitUtil; import sonia.scm.util.Util; @@ -54,6 +53,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + public class GitCatCommand extends AbstractGitCommand implements CatCommand { @@ -101,7 +103,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand { try { entry = revWalk.parseCommit(revId); } catch (MissingObjectException e) { - throw NotFoundException.notFound("Revision", revId.getName()).in(repository).build(); + throw notFound(entity("Revision", revId.getName()).in(repository)); } RevTree revTree = entry.getTree(); @@ -119,7 +121,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand { return new ClosableObjectLoaderContainer(loader, treeWalk, revWalk); } else { - throw NotFoundException.notFound("Path", path).in("Revision", revId.getName()).in(repository).build(); + throw notFound(entity("Path", path).in("Revision", revId.getName()).in(repository)); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 40b25ef75a..8a3745dce7 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -48,7 +48,6 @@ import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.NotFoundException; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.GitChangesetConverter; @@ -61,6 +60,9 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + //~--- JDK imports ------------------------------------------------------------ /** @@ -248,7 +250,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } catch (MissingObjectException e) { - throw NotFoundException.notFound("Revision", e.getObjectId().getName()).in(repository).build(); + throw notFound(entity("Revision", e.getObjectId().getName()).in(repository)); } catch (Exception ex) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java index 22116eff01..5e63adfb70 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java @@ -32,7 +32,6 @@ package sonia.scm.repository.spi; import org.junit.Test; -import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.FileObject; import sonia.scm.repository.GitConstants; @@ -63,7 +62,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase { } @Test - public void testDefaultDefaultBranch() throws IOException, NotFoundException { + public void testDefaultDefaultBranch() throws IOException { // without default branch, the repository head should be used FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile(); assertNotNull(root); @@ -78,7 +77,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase { } @Test - public void testExplicitDefaultBranch() throws IOException, NotFoundException { + public void testExplicitDefaultBranch() throws IOException { repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch"); FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile(); diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java index deff53eeac..b4be68a51f 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java @@ -49,7 +49,6 @@ import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil; import org.tmatesoft.svn.core.internal.util.SVNXMLUtil; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc.SVNClientManager; -import sonia.scm.NotFoundException; import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; @@ -60,6 +59,9 @@ import java.io.PrintWriter; import java.util.List; import java.util.Map; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + //~--- JDK imports ------------------------------------------------------------ /** @@ -114,7 +116,7 @@ public final class SvnUtil } catch (NumberFormatException ex) { - throw NotFoundException.notFound("Revision", v).in(repository).build(); + throw notFound(entity("Revision", v).in(repository)); } } @@ -352,7 +354,7 @@ public final class SvnUtil } catch (NumberFormatException ex) { - throw NotFoundException.notFound("Revision", revision).in(repository).build(); + throw notFound(entity("Revision", revision).in(repository)); } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java index 93d52ea907..9a5c39af46 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java @@ -43,7 +43,6 @@ import org.tmatesoft.svn.core.SVNProperties; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc.SVNClientManager; import org.tmatesoft.svn.core.wc.admin.SVNLookClient; -import sonia.scm.NotFoundException; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Repository; import sonia.scm.repository.SvnUtil; @@ -53,6 +52,9 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + //~--- JDK imports ------------------------------------------------------------ /** @@ -131,9 +133,9 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand private void handleSvnException(CatCommandRequest request, SVNException ex) { int svnErrorCode = ex.getErrorMessage().getErrorCode().getCode(); if (SVNErrorCode.FS_NOT_FOUND.getCode() == svnErrorCode) { - throw NotFoundException.notFound("Path", request.getPath()).in("Revision", request.getRevision()).in(repository).build(); + throw notFound(entity("Path", request.getPath()).in("Revision", request.getRevision()).in(repository)); } else if (SVNErrorCode.FS_NO_SUCH_REVISION.getCode() == svnErrorCode) { - throw NotFoundException.notFound("Revision", request.getRevision()).in(repository).build(); + throw notFound(entity("Revision", request.getRevision()).in(repository)); } else { throw new InternalRepositoryException("could not get content from revision", ex); } diff --git a/scm-test/src/main/java/sonia/scm/repository/DummyRepositoryHandler.java b/scm-test/src/main/java/sonia/scm/repository/DummyRepositoryHandler.java index 5a1dc605bb..df974ab566 100644 --- a/scm-test/src/main/java/sonia/scm/repository/DummyRepositoryHandler.java +++ b/scm-test/src/main/java/sonia/scm/repository/DummyRepositoryHandler.java @@ -71,10 +71,10 @@ public class DummyRepositoryHandler @Override - protected void create(Repository repository, File directory) throws AlreadyExistsException { + protected void create(Repository repository, File directory) { String key = repository.getNamespace() + "/" + repository.getName(); if (existingRepoNames.contains(key)) { - throw new AlreadyExistsException(); + throw new AlreadyExistsException(repository); } else { existingRepoNames.add(key); } diff --git a/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java b/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java index 999ef1dc45..d9985d3332 100644 --- a/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java @@ -35,7 +35,6 @@ package sonia.scm.repository; import org.junit.Test; import sonia.scm.AbstractTestBase; -import sonia.scm.AlreadyExistsException; import sonia.scm.store.ConfigurationStoreFactory; import sonia.scm.store.InMemoryConfigurationStoreFactory; import sonia.scm.util.IOUtil; @@ -61,12 +60,12 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase { ConfigurationStoreFactory factory, File directory); @Test - public void testCreate() throws AlreadyExistsException { + public void testCreate() { createRepository(); } @Test - public void testCreateResourcePath() throws AlreadyExistsException { + public void testCreateResourcePath() { Repository repository = createRepository(); String path = handler.createResourcePath(repository); @@ -76,7 +75,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase { } @Test - public void testDelete() throws Exception { + public void testDelete() { Repository repository = createRepository(); handler.delete(repository); @@ -101,7 +100,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase { } } - private Repository createRepository() throws AlreadyExistsException { + private Repository createRepository() { Repository repository = RepositoryTestData.createHeartOfGold(); handler.create(repository); diff --git a/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java b/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java index 9fe8669fc9..3c684f58c9 100644 --- a/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java @@ -39,12 +39,10 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.junit.Test; import sonia.scm.AlreadyExistsException; -import sonia.scm.ConcurrentModificationException; import sonia.scm.Manager; import sonia.scm.ManagerTestBase; import sonia.scm.NotFoundException; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -63,7 +61,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { public static final int THREAD_COUNT = 10; @Test - public void testCreate() throws AlreadyExistsException { + public void testCreate() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -75,7 +73,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test(expected = AlreadyExistsException.class) - public void testCreateExisting() throws AlreadyExistsException { + public void testCreateExisting() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -87,7 +85,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test - public void testDelete() throws Exception { + public void testDelete() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -102,7 +100,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test - public void testGet() throws AlreadyExistsException { + public void testGet() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -116,7 +114,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test - public void testGetAll() throws AlreadyExistsException { + public void testGetAll() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -181,7 +179,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test - public void testModify() throws AlreadyExistsException { + public void testModify() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -238,7 +236,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { } @Test - public void testRefresh() throws AlreadyExistsException { + public void testRefresh() { User zaphod = UserTestData.createZaphod(); manager.create(zaphod); @@ -289,7 +287,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase { finished = true; } - private User createUser() throws AlreadyExistsException { + private User createUser() { String id = UUID.randomUUID().toString(); User user = new User(id, id.concat(" displayName"), id.concat("@mail.com")); diff --git a/scm-webapp/src/main/java/sonia/scm/ManagerDaoAdapter.java b/scm-webapp/src/main/java/sonia/scm/ManagerDaoAdapter.java index 4fdd74063e..fb5cd9f5cc 100644 --- a/scm-webapp/src/main/java/sonia/scm/ManagerDaoAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/ManagerDaoAdapter.java @@ -34,15 +34,15 @@ public class ManagerDaoAdapter { } } - public T create(T newObject, Supplier permissionCheck, AroundHandler beforeCreate, AroundHandler afterCreate) throws AlreadyExistsException { + public T create(T newObject, Supplier permissionCheck, AroundHandler beforeCreate, AroundHandler afterCreate) { return create(newObject, permissionCheck, beforeCreate, afterCreate, dao::contains); } - public T create(T newObject, Supplier permissionCheck, AroundHandler beforeCreate, AroundHandler afterCreate, Predicate existsCheck) throws AlreadyExistsException { + public T create(T newObject, Supplier permissionCheck, AroundHandler beforeCreate, AroundHandler afterCreate, Predicate existsCheck) { permissionCheck.get().check(); AssertUtil.assertIsValid(newObject); if (existsCheck.test(newObject)) { - throw new AlreadyExistsException(); + throw new AlreadyExistsException(newObject); } newObject.setCreationDate(System.currentTimeMillis()); beforeCreate.handle(newObject); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/AlreadyExistsExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/rest/AlreadyExistsExceptionMapper.java index 13d341e1e6..f923eef693 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/AlreadyExistsExceptionMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/AlreadyExistsExceptionMapper.java @@ -1,6 +1,8 @@ package sonia.scm.api.rest; import sonia.scm.AlreadyExistsException; +import sonia.scm.api.v2.resources.ErrorDto; +import sonia.scm.web.VndMediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -12,7 +14,8 @@ public class AlreadyExistsExceptionMapper implements ExceptionMapper branchName.equals(branch.getName())); if (!branchExists){ - throw NotFoundException.notFound(Branch.class, branchName).in(Repository.class, namespace + "/" + name).build(); + throw notFound(entity(Branch.class, branchName).in(Repository.class, namespace + "/" + name)); } Repository repository = repositoryService.getRepository(); RepositoryPermissions.read(repository).check(); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionResourceManagerAdapter.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionResourceManagerAdapter.java index 3ef19f7294..052bf771b1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionResourceManagerAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionResourceManagerAdapter.java @@ -1,7 +1,6 @@ package sonia.scm.api.v2.resources; import de.otto.edison.hal.HalRepresentation; -import sonia.scm.AlreadyExistsException; import sonia.scm.Manager; import sonia.scm.ModelObject; import sonia.scm.PageResult; @@ -47,7 +46,7 @@ class CollectionResourceManagerAdapter modelObjectSupplier, Function uriCreator) throws AlreadyExistsException { + public Response create(DTO dto, Supplier modelObjectSupplier, Function uriCreator) { if (dto == null) { return Response.status(BAD_REQUEST).build(); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ErrorDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ErrorDto.java index 3b43c37c5a..a047aece38 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ErrorDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ErrorDto.java @@ -3,9 +3,8 @@ package sonia.scm.api.v2.resources; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Getter; import org.slf4j.MDC; -import sonia.scm.ConcurrentModificationException; import sonia.scm.ContextEntry; -import sonia.scm.NotFoundException; +import sonia.scm.ExceptionWithContext; import java.util.List; @@ -30,11 +29,7 @@ public class ErrorDto { this.url = url; } - static ErrorDto from(NotFoundException notFoundException) { - return new ErrorDto(MDC.get("transaction_id"), "todo", notFoundException.getContext(), notFoundException.getMessage()); - } - - public static ErrorDto from(ConcurrentModificationException concurrentModificationException) { - return new ErrorDto(MDC.get("transaction_id"), "todo", concurrentModificationException.getContext(), concurrentModificationException.getMessage()); + public static ErrorDto from(ExceptionWithContext exception) { + return new ErrorDto(MDC.get("transaction_id"), "todo", exception.getContext(), exception.getMessage()); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java index 8abab0f720..d845aa181e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java @@ -5,7 +5,6 @@ import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.ResponseHeaders; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; -import sonia.scm.AlreadyExistsException; import sonia.scm.group.Group; import sonia.scm.group.GroupManager; import sonia.scm.web.VndMediaType; @@ -86,7 +85,7 @@ public class GroupCollectionResource { }) @TypeHint(TypeHint.NO_CONTENT.class) @ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created group")) - public Response create(@Valid GroupDto groupDto) throws AlreadyExistsException { + public Response create(@Valid GroupDto groupDto) { return adapter.create(groupDto, () -> dtoToGroupMapper.map(groupDto), group -> resourceLinks.group().self(group.getName())); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java index 308b40b1a5..f2341262ce 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java @@ -3,8 +3,6 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; -import sonia.scm.ConcurrentModificationException; -import sonia.scm.NotFoundException; import sonia.scm.group.Group; import sonia.scm.group.GroupManager; import sonia.scm.web.VndMediaType; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java index d2e4bd856a..2b2a4cf0ad 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IdResourceManagerAdapter.java @@ -1,8 +1,6 @@ package sonia.scm.api.v2.resources; import de.otto.edison.hal.HalRepresentation; -import sonia.scm.AlreadyExistsException; -import sonia.scm.ConcurrentModificationException; import sonia.scm.Manager; import sonia.scm.ModelObject; import sonia.scm.NotFoundException; @@ -51,7 +49,7 @@ class IdResourceManagerAdapter modelObjectSupplier, Function uriCreator) throws AlreadyExistsException { + public Response create(DTO dto, Supplier modelObjectSupplier, Function uriCreator) { return collectionAdapter.create(dto, modelObjectSupplier, uriCreator); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java index 4b088a62a5..c997a706fd 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java @@ -29,6 +29,9 @@ import java.net.URI; import java.util.Optional; import java.util.function.Predicate; +import static sonia.scm.AlreadyExistsException.alreadyExists; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; import static sonia.scm.api.v2.resources.PermissionDto.GROUP_PREFIX; @Slf4j @@ -70,7 +73,7 @@ public class PermissionRootResource { @TypeHint(TypeHint.NO_CONTENT.class) @Consumes(VndMediaType.PERMISSION) @Path("") - public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name,@Valid PermissionDto permission) throws AlreadyExistsException, NotFoundException { + public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name,@Valid PermissionDto permission) { log.info("try to add new permission: {}", permission); Repository repository = load(namespace, name); RepositoryPermissions.permissionWrite(repository).check(); @@ -108,7 +111,7 @@ public class PermissionRootResource { .filter(filterPermission(permissionName)) .map(permission -> modelToDtoMapper.map(permission, repository)) .findFirst() - .orElseThrow(() -> NotFoundException.notFound(Permission.class, namespace).in(Repository.class, namespace + "/" + name).build()) + .orElseThrow(() -> notFound(entity(Permission.class, namespace).in(Repository.class, namespace + "/" + name))) ).build(); } @@ -157,23 +160,23 @@ public class PermissionRootResource { public Response update(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("permission-name") String permissionName, - @Valid PermissionDto permission) throws AlreadyExistsException { + @Valid PermissionDto permission) { log.info("try to update the permission with name: {}. the modified permission is: {}", permissionName, permission); Repository repository = load(namespace, name); RepositoryPermissions.permissionWrite(repository).check(); String extractedPermissionName = getPermissionName(permissionName); if (!isPermissionExist(new PermissionDto(extractedPermissionName, isGroupPermission(permissionName)), repository)) { - throw NotFoundException.notFound(Permission.class, namespace).in(Repository.class, namespace + "/" + name).build(); + throw notFound(entity(Permission.class, namespace).in(Repository.class, namespace + "/" + name)); } permission.setGroupPermission(isGroupPermission(permissionName)); if (!extractedPermissionName.equals(permission.getName())) { - checkPermissionAlreadyExists(permission, repository, "target permission " + permission.getName() + " already exists"); + checkPermissionAlreadyExists(permission, repository); } Permission existingPermission = repository.getPermissions() .stream() .filter(filterPermission(permissionName)) .findFirst() - .orElseThrow(() -> NotFoundException.notFound(Permission.class, namespace).in(Repository.class, namespace + "/" + name).build()); + .orElseThrow(() -> notFound(entity(Permission.class, namespace).in(Repository.class, namespace + "/" + name))); dtoToModelMapper.modify(existingPermission, permission); manager.modify(repository); log.info("the permission with name: {} is updated.", permissionName); @@ -241,7 +244,7 @@ public class PermissionRootResource { private Repository load(String namespace, String name) { NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); return Optional.ofNullable(manager.get(namespaceAndName)) - .orElseThrow(() -> NotFoundException.notFound(namespaceAndName).build()); + .orElseThrow(() -> notFound(entity(namespaceAndName))); } /** @@ -249,12 +252,11 @@ public class PermissionRootResource { * * @param permission the searched permission * @param repository the repository to be inspected - * @param errorMessage error message * @throws AlreadyExistsException if the permission already exists in the repository */ - private void checkPermissionAlreadyExists(PermissionDto permission, Repository repository, String errorMessage) throws AlreadyExistsException { + private void checkPermissionAlreadyExists(PermissionDto permission, Repository repository) { if (isPermissionExist(permission, repository)) { - throw new AlreadyExistsException(errorMessage); + throw alreadyExists(entity("permission", permission.getName()).in(repository)); } } @@ -263,10 +265,6 @@ public class PermissionRootResource { .stream() .anyMatch(p -> p.getName().equals(permission.getName()) && p.isGroupPermission() == permission.isGroupPermission()); } - - private void checkPermissionAlreadyExists(PermissionDto permission, Repository repository) throws AlreadyExistsException { - checkPermissionAlreadyExists(permission, repository, "the permission " + permission.getName() + " already exist."); - } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionResource.java index 9f4858d2f6..665e2131d9 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionResource.java @@ -5,7 +5,6 @@ import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.ResponseHeaders; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; -import sonia.scm.AlreadyExistsException; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; import sonia.scm.web.VndMediaType; @@ -87,7 +86,7 @@ public class RepositoryCollectionResource { }) @TypeHint(TypeHint.NO_CONTENT.class) @ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created repository")) - public Response create(@Valid RepositoryDto repositoryDto) throws AlreadyExistsException { + public Response create(@Valid RepositoryDto repositoryDto) { return adapter.create(repositoryDto, () -> dtoToRepositoryMapper.map(repositoryDto, null), repository -> resourceLinks.repository().self(repository.getNamespace(), repository.getName())); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java index f8b56229b1..141cf64ff6 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java @@ -3,8 +3,6 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; -import sonia.scm.ConcurrentModificationException; -import sonia.scm.NotFoundException; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryIsNotArchivedException; @@ -26,6 +24,9 @@ import java.util.Optional; import java.util.function.Predicate; import java.util.function.Supplier; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + public class RepositoryResource { private final RepositoryToRepositoryDtoMapper repositoryToDtoMapper; @@ -205,7 +206,7 @@ public class RepositoryResource { private Supplier loadBy(String namespace, String name) { NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); - return () -> Optional.ofNullable(manager.get(namespaceAndName)).orElseThrow(() -> NotFoundException.notFound(namespaceAndName).build()); + return () -> Optional.ofNullable(manager.get(namespaceAndName)).orElseThrow(() -> notFound(entity(namespaceAndName))); } private Predicate nameAndNamespaceStaysTheSame(String namespace, String name) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java index 963f25eaf6..e61a9f3455 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SingleResourceManagerAdapter.java @@ -11,7 +11,6 @@ import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.Response; import java.util.Collection; import java.util.Optional; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index 632c428e62..7acd59e3e1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -21,6 +21,9 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import java.io.IOException; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + public class TagRootResource { private final RepositoryServiceFactory serviceFactory; @@ -91,7 +94,7 @@ public class TagRootResource { } private NotFoundException createNotFoundException(String namespace, String name, String tagName) { - return NotFoundException.notFound("Tag", tagName).in("Repository", namespace + "/" + name).build(); + return notFound(entity("Tag", tagName).in("Repository", namespace + "/" + name)); } private Tags getTags(RepositoryService repositoryService) throws IOException { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java index 9b39888104..e7a49bc1fd 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java @@ -6,7 +6,6 @@ import com.webcohesion.enunciate.metadata.rs.ResponseHeaders; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; import org.apache.shiro.authc.credential.PasswordService; -import sonia.scm.AlreadyExistsException; import sonia.scm.user.User; import sonia.scm.user.UserManager; import sonia.scm.web.VndMediaType; @@ -91,7 +90,7 @@ public class UserCollectionResource { }) @TypeHint(TypeHint.NO_CONTENT.class) @ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created user")) - public Response create(@Valid UserDto userDto) throws AlreadyExistsException { + public Response create(@Valid UserDto userDto) { return adapter.create(userDto, () -> dtoToUserMapper.map(userDto, passwordService.encryptPassword(userDto.getPassword())), user -> resourceLinks.user().self(user.getName())); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java index c2fbc00453..d0ce8c8a63 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java @@ -4,7 +4,6 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; import org.apache.shiro.authc.credential.PasswordService; -import sonia.scm.ConcurrentModificationException; import sonia.scm.user.User; import sonia.scm.user.UserManager; import sonia.scm.web.VndMediaType; diff --git a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java index 662d9407ca..6bf850f99d 100644 --- a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java +++ b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java @@ -42,7 +42,6 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.AlreadyExistsException; import sonia.scm.HandlerEventType; import sonia.scm.ManagerDaoAdapter; import sonia.scm.NotFoundException; @@ -106,7 +105,7 @@ public class DefaultGroupManager extends AbstractGroupManager } @Override - public Group create(Group group) throws AlreadyExistsException { + public Group create(Group group) { String type = group.getType(); if (Util.isEmpty(type)) { group.setType(groupDAO.getType()); diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java index dc4767e024..6c903815a7 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -65,6 +65,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + /** * Default implementation of {@link RepositoryManager}. * @@ -122,11 +125,11 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { } @Override - public Repository create(Repository repository) throws AlreadyExistsException { + public Repository create(Repository repository) { return create(repository, true); } - public Repository create(Repository repository, boolean initRepository) throws AlreadyExistsException { + public Repository create(Repository repository, boolean initRepository) { repository.setId(keyGenerator.createKey()); repository.setNamespace(namespaceStrategy.createNamespace(repository)); @@ -170,7 +173,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { } @Override - public void importRepository(Repository repository) throws AlreadyExistsException { + public void importRepository(Repository repository) { create(repository, false); } @@ -207,7 +210,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { if (fresh != null) { fresh.copyProperties(repository); } else { - throw NotFoundException.notFound(repository).build(); + throw notFound(entity(repository)); } } diff --git a/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java b/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java index 61d488d641..8057db53dc 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java @@ -33,7 +33,6 @@ import com.google.common.collect.ImmutableList; import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.ConcurrentModificationException; import sonia.scm.NotFoundException; import java.util.Set; diff --git a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java index 0f2f45ff0b..807024c36b 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java +++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java @@ -39,7 +39,6 @@ import com.google.inject.Singleton; import org.apache.shiro.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.AlreadyExistsException; import sonia.scm.EagerSingleton; import sonia.scm.HandlerEventType; import sonia.scm.ManagerDaoAdapter; @@ -137,7 +136,7 @@ public class DefaultUserManager extends AbstractUserManager * @throws IOException */ @Override - public User create(User user) throws AlreadyExistsException { + public User create(User user) { String type = user.getType(); if (Util.isEmpty(type)) { user.setType(userDAO.getType()); diff --git a/scm-webapp/src/main/java/sonia/scm/web/i18n/I18nServlet.java b/scm-webapp/src/main/java/sonia/scm/web/i18n/I18nServlet.java index f80b90e22a..b074781fec 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/i18n/I18nServlet.java +++ b/scm-webapp/src/main/java/sonia/scm/web/i18n/I18nServlet.java @@ -30,6 +30,9 @@ import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + /** * Collect the plugin translations. @@ -69,7 +72,7 @@ public class I18nServlet extends HttpServlet { createdFile.ifPresent(map -> createdJsonFileConsumer.accept(path, map)); return createdFile.orElse(null); } - )).orElseThrow(() -> NotFoundException.notFound("jsonprovider", path).build()); + )).orElseThrow(() -> notFound(entity("jsonprovider", path))); } @VisibleForTesting diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java index 4e1a0f90f1..098ec40c3f 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -20,6 +20,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java index e762e5d186..f1a1c3b441 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java @@ -19,6 +19,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.NotFoundException; import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.api.DiffCommandBuilder; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java index 8a71abb670..7dff9f5ff0 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java @@ -6,6 +6,7 @@ import sonia.scm.api.rest.AlreadyExistsExceptionMapper; import sonia.scm.api.rest.AuthorizationExceptionMapper; import sonia.scm.api.rest.ConcurrentModificationExceptionMapper; import sonia.scm.api.rest.IllegalArgumentExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; public class DispatcherMock { public static Dispatcher createDispatcher(Object resource) { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java index 322995eaa7..2963f5d813 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java @@ -20,6 +20,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.NotFoundException; import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.InternalRepositoryException; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java index 64942fb84b..0377fe0942 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java @@ -19,6 +19,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Modifications; import sonia.scm.repository.NamespaceAndName; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java index 635d994763..0487e445c1 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java @@ -164,10 +164,7 @@ public class PermissionRootResourceTest extends RepositoryTestBase { @TestFactory @DisplayName("test endpoints on missing permissions and user is Admin") Stream missedPermissionTestFactory() { - Repository mockRepository = mock(Repository.class); - when(mockRepository.getId()).thenReturn(REPOSITORY_NAME); - when(mockRepository.getNamespace()).thenReturn(REPOSITORY_NAMESPACE); - when(mockRepository.getName()).thenReturn(REPOSITORY_NAME); + Repository mockRepository = new Repository(REPOSITORY_NAME, "git", REPOSITORY_NAMESPACE, REPOSITORY_NAME); when(repositoryManager.get(any(NamespaceAndName.class))).thenReturn(mockRepository); return createDynamicTestsToAssertResponses( requestGETPermission.expectedResponseStatus(404), @@ -180,10 +177,6 @@ public class PermissionRootResourceTest extends RepositoryTestBase { @TestFactory @DisplayName("test endpoints on missing permissions and user is not Admin") Stream missedPermissionUserForbiddenTestFactory() { - Repository mockRepository = mock(Repository.class); - when(mockRepository.getId()).thenReturn(REPOSITORY_NAME); - when(mockRepository.getNamespace()).thenReturn(REPOSITORY_NAMESPACE); - when(mockRepository.getName()).thenReturn(REPOSITORY_NAME); doThrow(AuthorizationException.class).when(repositoryManager).get(any(NamespaceAndName.class)); return createDynamicTestsToAssertResponses( requestGETPermission.expectedResponseStatus(403), @@ -413,6 +406,7 @@ public class PermissionRootResourceTest extends RepositoryTestBase { when(mockRepository.getId()).thenReturn(REPOSITORY_NAME); when(mockRepository.getNamespace()).thenReturn(REPOSITORY_NAMESPACE); when(mockRepository.getName()).thenReturn(REPOSITORY_NAME); + when(mockRepository.getNamespaceAndName()).thenReturn(new NamespaceAndName(REPOSITORY_NAMESPACE, REPOSITORY_NAME)); when(repositoryManager.get(any(NamespaceAndName.class))).thenReturn(mockRepository); when(subject.isPermitted(userPermission != null ? eq(userPermission) : any(String.class))).thenReturn(true); return mockRepository; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java index 5f49f31183..803f2b106c 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java @@ -18,6 +18,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.Tag; diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index 8876903637..2b5aeb7f53 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -110,7 +110,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { private String mockedNamespace = "default_namespace"; @Test - public void testCreate() throws AlreadyExistsException { + public void testCreate() { Repository heartOfGold = createTestRepository(); Repository dbRepo = manager.get(heartOfGold.getId()); @@ -122,18 +122,18 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { username = "unpriv" ) @Test(expected = UnauthorizedException.class) - public void testCreateWithoutPrivileges() throws AlreadyExistsException { + public void testCreateWithoutPrivileges() { createTestRepository(); } @Test(expected = AlreadyExistsException.class) - public void testCreateExisting() throws AlreadyExistsException { + public void testCreateExisting() { createTestRepository(); createTestRepository(); } @Test - public void testDelete() throws Exception { + public void testDelete() { delete(manager, createTestRepository()); } @@ -141,12 +141,12 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { username = "unpriv" ) @Test(expected = UnauthorizedException.class) - public void testDeleteWithoutPrivileges() throws Exception { + public void testDeleteWithoutPrivileges() { delete(manager, createTestRepository()); } @Test(expected = RepositoryIsNotArchivedException.class) - public void testDeleteNonArchived() throws Exception { + public void testDeleteNonArchived() { configuration.setEnableRepositoryArchive(true); delete(manager, createTestRepository()); } @@ -157,7 +157,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testDeleteWithEnabledArchive() throws Exception { + public void testDeleteWithEnabledArchive() { Repository repository = createTestRepository(); repository.setArchived(true); @@ -167,7 +167,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testGet() throws AlreadyExistsException { + public void testGet() { Repository heartOfGold = createTestRepository(); String id = heartOfGold.getId(); String description = heartOfGold.getDescription(); @@ -185,7 +185,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { @SubjectAware( username = "crato" ) - public void testGetWithoutRequiredPrivileges() throws AlreadyExistsException { + public void testGetWithoutRequiredPrivileges() { Repository heartOfGold = RepositoryTestData.createHeartOfGold(); manager.create(heartOfGold); @@ -194,7 +194,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testGetAll() throws AlreadyExistsException { + public void testGetAll() { Repository heartOfGold = createTestRepository(); Repository happyVerticalPeopleTransporter = createSecondTestRepository(); boolean foundHeart = false; @@ -232,7 +232,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { @Test @SuppressWarnings("unchecked") @SubjectAware(username = "dent") - public void testGetAllWithPermissionsForTwoOrThreeRepos() throws AlreadyExistsException { + public void testGetAllWithPermissionsForTwoOrThreeRepos() { // mock key generator KeyGenerator keyGenerator = mock(KeyGenerator.class); Stack keys = new Stack<>(); @@ -273,7 +273,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testEvents() throws Exception { + public void testEvents() { RepositoryManager repoManager = createRepositoryManager(false); repoManager.init(contextProvider); TestListener listener = new TestListener(); @@ -304,7 +304,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testModify() throws AlreadyExistsException { + public void testModify() { Repository heartOfGold = createTestRepository(); heartOfGold.setDescription("prototype ship"); @@ -318,7 +318,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { @Test @SubjectAware(username = "crato") - public void testModifyWithoutRequiredPermissions() throws AlreadyExistsException, NotFoundException { + public void testModifyWithoutRequiredPermissions() { Repository heartOfGold = RepositoryTestData.createHeartOfGold(); manager.create(heartOfGold); heartOfGold.setDescription("prototype ship"); @@ -333,7 +333,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testRefresh() throws AlreadyExistsException { + public void testRefresh() { Repository heartOfGold = createTestRepository(); String description = heartOfGold.getDescription(); @@ -344,7 +344,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { @Test @SubjectAware(username = "crato") - public void testRefreshWithoutRequiredPermissions() throws AlreadyExistsException, NotFoundException { + public void testRefreshWithoutRequiredPermissions() { Repository heartOfGold = RepositoryTestData.createHeartOfGold(); manager.create(heartOfGold); heartOfGold.setDescription("prototype ship"); @@ -359,7 +359,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testRepositoryHook() throws AlreadyExistsException { + public void testRepositoryHook() { CountingReceiveHook hook = new CountingReceiveHook(); RepositoryManager repoManager = createRepositoryManager(false); @@ -379,7 +379,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void testNamespaceSet() throws Exception { + public void testNamespaceSet() { RepositoryManager repoManager = createRepositoryManager(false); Repository repository = spy(createTestRepository()); repository.setName("Testrepo"); @@ -388,14 +388,14 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { } @Test - public void shouldSetNamespace() throws AlreadyExistsException { + public void shouldSetNamespace() { Repository repository = new Repository(null, "hg", null, "scm"); manager.create(repository); assertNotNull(repository.getId()); assertNotNull(repository.getNamespace()); } - private void createUriTestRepositories(RepositoryManager m) throws AlreadyExistsException { + private void createUriTestRepositories(RepositoryManager m) { mockedNamespace = "namespace"; createRepository(m, new Repository("1", "hg", "namespace", "scm")); createRepository(m, new Repository("2", "hg", "namespace", "scm-test")); @@ -448,7 +448,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { keyGenerator, repositoryDAO, handlerSet, namespaceStrategy); } - private void createRepository(RepositoryManager m, Repository repository) throws AlreadyExistsException { + private void createRepository(RepositoryManager m, Repository repository) { m.create(repository); } @@ -471,7 +471,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { assertEquals(repo.getLastModified(), other.getLastModified()); } - private Repository createRepository(Repository repository) throws AlreadyExistsException { + private Repository createRepository(Repository repository) { manager.create(repository); assertNotNull(repository.getId()); assertNotNull(manager.get(repository.getId())); @@ -486,12 +486,12 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { return repository; } - private Repository createSecondTestRepository() throws AlreadyExistsException { + private Repository createSecondTestRepository() { return createRepository( RepositoryTestData.createHappyVerticalPeopleTransporter()); } - private Repository createTestRepository() throws AlreadyExistsException { + private Repository createTestRepository() { return createRepository(RepositoryTestData.createHeartOfGold()); } diff --git a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java index df32528e5e..1614bf790a 100644 --- a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java @@ -40,7 +40,6 @@ import com.github.sdorra.shiro.SubjectAware; import com.google.common.collect.Lists; import org.assertj.core.api.Assertions; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -48,7 +47,6 @@ import org.mockito.ArgumentCaptor; import sonia.scm.NotFoundException; import sonia.scm.store.JAXBConfigurationStoreFactory; import sonia.scm.user.xml.XmlUserDAO; -import sonia.scm.util.MockUtil; import static org.mockito.Mockito.*; @@ -57,7 +55,6 @@ import static org.mockito.Mockito.*; import java.util.Collections; import java.util.List; import org.junit.Rule; -import sonia.scm.store.ConfigurationStoreFactory; /** *