diff --git a/scm-core/src/main/java/sonia/scm/HandlerBase.java b/scm-core/src/main/java/sonia/scm/HandlerBase.java index ba7c26ea09..6ce7d9a6a6 100644 --- a/scm-core/src/main/java/sonia/scm/HandlerBase.java +++ b/scm-core/src/main/java/sonia/scm/HandlerBase.java @@ -55,7 +55,7 @@ public interface HandlerBase * * @return The persisted object. */ - public T create(T object) throws E, IOException; + public T create(T object) throws E; /** * Removes a persistent object. @@ -66,7 +66,7 @@ public interface HandlerBase * @throws E * @throws IOException */ - public void delete(T object) throws E, IOException; + public void delete(T object) throws E; /** * Modifies a persistent object. @@ -77,5 +77,5 @@ public interface HandlerBase * @throws E * @throws IOException */ - public void modify(T object) throws E, IOException; + public void modify(T object) throws E; } diff --git a/scm-core/src/main/java/sonia/scm/Manager.java b/scm-core/src/main/java/sonia/scm/Manager.java index 79155b56a2..c0d074520a 100644 --- a/scm-core/src/main/java/sonia/scm/Manager.java +++ b/scm-core/src/main/java/sonia/scm/Manager.java @@ -33,7 +33,6 @@ package sonia.scm; -import java.io.IOException; import java.util.Collection; import java.util.Comparator; @@ -56,9 +55,8 @@ public interface Manager * @param object to refresh * * @throws E - * @throws IOException */ - void refresh(T object) throws E, IOException; + void refresh(T object) throws E; //~--- 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 4a8227574a..3b90002d13 100644 --- a/scm-core/src/main/java/sonia/scm/ManagerDecorator.java +++ b/scm-core/src/main/java/sonia/scm/ManagerDecorator.java @@ -77,7 +77,7 @@ public class ManagerDecorator * {@inheritDoc} */ @Override - public T create(T object) throws E, IOException + public T create(T object) throws E { return decorated.create(object); } @@ -86,7 +86,7 @@ public class ManagerDecorator * {@inheritDoc} */ @Override - public void delete(T object) throws E, IOException + public void delete(T object) throws E { decorated.delete(object); } @@ -104,7 +104,7 @@ public class ManagerDecorator * {@inheritDoc} */ @Override - public void modify(T object) throws E, IOException + public void modify(T object) throws E { decorated.modify(object); } @@ -113,7 +113,7 @@ public class ManagerDecorator * {@inheritDoc} */ @Override - public void refresh(T object) throws E, IOException + public void refresh(T object) throws E { decorated.refresh(object); } diff --git a/scm-core/src/main/java/sonia/scm/group/GroupAlreadyExistsException.java b/scm-core/src/main/java/sonia/scm/group/GroupAlreadyExistsException.java index 8389900098..e63ee1d78b 100644 --- a/scm-core/src/main/java/sonia/scm/group/GroupAlreadyExistsException.java +++ b/scm-core/src/main/java/sonia/scm/group/GroupAlreadyExistsException.java @@ -48,9 +48,9 @@ public class GroupAlreadyExistsException extends GroupException /** * Constructs a new instance. * - * @param message exception message + * @param name The name (aka id) of the group */ - public GroupAlreadyExistsException(String message) { - super(message); + public GroupAlreadyExistsException(String name) { + super(name + " group already exists"); } } diff --git a/scm-core/src/main/java/sonia/scm/group/GroupNotFoundException.java b/scm-core/src/main/java/sonia/scm/group/GroupNotFoundException.java index f4b9934128..d4c06a1559 100644 --- a/scm-core/src/main/java/sonia/scm/group/GroupNotFoundException.java +++ b/scm-core/src/main/java/sonia/scm/group/GroupNotFoundException.java @@ -52,39 +52,7 @@ public class GroupNotFoundException extends GroupException * Constructs a new GroupNotFoundException. * */ - public GroupNotFoundException() {} - - /** - * Constructs a new GroupNotFoundException. - * - * - * @param message message for the exception - */ - public GroupNotFoundException(String message) - { - super(message); - } - - /** - * Constructs a new GroupNotFoundException. - * - * - * @param throwable root cause - */ - public GroupNotFoundException(Throwable throwable) - { - super(throwable); - } - - /** - * Constructs a new GroupNotFoundException. - * - * - * @param message message for the exception - * @param throwable root cause - */ - public GroupNotFoundException(String message, Throwable throwable) - { - super(message, throwable); + public GroupNotFoundException() { + super("group does not exists"); } } 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 3e71bbb368..fb044a325c 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java @@ -106,7 +106,7 @@ public abstract class AbstractSimpleRepositoryHandler manager; + private final Class type; - /** - * Constructs ... - * - * - * @param manager - */ - public AbstractManagerResource(Manager manager) - { + protected int cacheMaxAge = 0; + protected boolean disableCache = false; + + public AbstractManagerResource(Manager manager, Class type) { this.manager = manager; + this.type = type; } //~--- methods -------------------------------------------------------------- @@ -526,45 +529,25 @@ public abstract class AbstractManagerResource createComparator(String sortby, boolean desc) + private Comparator createComparator(String sortBy, boolean desc) { + checkSortByField(sortBy); Comparator comparator; if (desc) { - comparator = new BeanReverseComparator(sortby); + comparator = new BeanReverseComparator(sortBy); } else { - comparator = new BeanComparator(sortby); + comparator = new BeanComparator(sortBy); } return comparator; } - /** - * Method description - * - * - * - * @param sortby - * @param desc - * @param start - * @param limit - * - * @return - */ - private Collection fetchItems(String sortby, boolean desc, int start, + private Collection fetchItems(String sortBy, boolean desc, int start, int limit) { AssertUtil.assertPositive(start); @@ -573,18 +556,18 @@ public abstract class AbstractManagerResource 0) { - if (Util.isEmpty(sortby)) + if (Util.isEmpty(sortBy)) { // replace with something useful - sortby = "id"; + sortBy = "id"; } - items = manager.getAll(createComparator(sortby, desc), start, limit); + items = manager.getAll(createComparator(sortBy, desc), start, limit); } - else if (Util.isNotEmpty(sortby)) + else if (Util.isNotEmpty(sortBy)) { - items = manager.getAll(createComparator(sortby, desc)); + items = manager.getAll(createComparator(sortBy, desc)); } else { @@ -594,17 +577,32 @@ public abstract class AbstractManagerResource fetchPage(String sortby, boolean desc, int pageNumber, + // We have to handle IntrospectionException here, because it's a checked exception + // It shouldn't occur really - so creating a new unchecked exception would be over-engineered here + @SuppressWarnings("squid:S00112") + private void checkSortByField(String sortBy) { + try { + BeanInfo info = Introspector.getBeanInfo(type); + PropertyDescriptor[] pds = info.getPropertyDescriptors(); + if (Arrays.stream(pds).noneMatch(p -> p.getName().equals(sortBy))) { + throw new IllegalArgumentException("sortBy"); + } + } catch (IntrospectionException e) { + throw new RuntimeException("error introspecting model type " + type.getName(), e); + } + } + + protected PageResult fetchPage(String sortBy, boolean desc, int pageNumber, int pageSize) { AssertUtil.assertPositive(pageNumber); AssertUtil.assertPositive(pageSize); - if (Util.isEmpty(sortby)) { + if (Util.isEmpty(sortBy)) { // replace with something useful - sortby = "id"; + sortBy = "id"; } - return manager.getPage(createComparator(sortby, desc), pageNumber, pageSize); + return manager.getPage(createComparator(sortBy, desc), pageNumber, pageSize); } //~--- get methods ---------------------------------------------------------- @@ -676,16 +674,4 @@ public abstract class AbstractManagerResource manager; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java index 364a1b200e..b9701f7e38 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java @@ -41,18 +41,12 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; - import org.apache.shiro.SecurityUtils; - import sonia.scm.group.Group; import sonia.scm.group.GroupException; import sonia.scm.group.GroupManager; import sonia.scm.security.Role; -//~--- JDK imports ------------------------------------------------------------ - -import java.util.Collection; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; @@ -69,6 +63,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import java.util.Collection; + +//~--- JDK imports ------------------------------------------------------------ /** * RESTful Web Service Resource to manage groups and their members. @@ -97,7 +94,7 @@ public class GroupResource @Inject public GroupResource(GroupManager groupManager) { - super(groupManager); + super(groupManager, Group.class); } //~--- methods -------------------------------------------------------------- diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 0fe6f8df1d..f336bbb6e7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -40,12 +40,13 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.io.Files; import com.google.inject.Inject; - +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.ResponseHeader; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; +import com.webcohesion.enunciate.metadata.rs.TypeHint; import org.apache.shiro.SecurityUtils; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import sonia.scm.NotSupportedFeatuerException; import sonia.scm.Type; import sonia.scm.api.rest.RestActionUploadResult; @@ -65,26 +66,6 @@ import sonia.scm.repository.api.UnbundleCommandBuilder; import sonia.scm.security.Role; import sonia.scm.util.IOUtil; -import static com.google.common.base.Preconditions.*; - -//~--- JDK imports ------------------------------------------------------------ - -import com.webcohesion.enunciate.metadata.rs.ResponseCode; -import com.webcohesion.enunciate.metadata.rs.ResponseHeader; -import com.webcohesion.enunciate.metadata.rs.StatusCodes; -import com.webcohesion.enunciate.metadata.rs.TypeHint; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import java.net.URI; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; - import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.FormParam; @@ -100,10 +81,22 @@ import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +//~--- JDK imports ------------------------------------------------------------ /** * Rest resource for importing repositories. @@ -564,10 +557,6 @@ public class RepositoryImportResource { handleGenericCreationFailure(ex, type, name); } - catch (IOException ex) - { - handleGenericCreationFailure(ex, type, name); - } return repository; } @@ -716,10 +705,6 @@ public class RepositoryImportResource { manager.delete(repository); } - catch (IOException e) - { - logger.error("can not delete repository", e); - } catch (RepositoryException e) { logger.error("can not delete repository", e); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 740f841f18..6fc8b9ef48 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -127,7 +127,7 @@ public class RepositoryResource extends AbstractManagerResource @Inject public UserResource(UserManager userManager, PasswordService passwordService) { - super(userManager); + super(userManager, User.class); this.passwordService = passwordService; } 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 0ba56aae1a..00f5f9914b 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 @@ -30,8 +30,8 @@ class CollectionResourceManagerAdapter extends AbstractManagerResource { - CollectionResourceManagerAdapter(Manager manager) { - super(manager); + CollectionResourceManagerAdapter(Manager manager, Class type) { + super(manager, type); } /** @@ -47,7 +47,7 @@ class CollectionResourceManagerAdapter modelObjectSupplier, Function uriCreator) throws IOException, EXCEPTION { + public Response create(DTO dto, Supplier modelObjectSupplier, Function uriCreator) throws EXCEPTION { if (dto == null) { return Response.status(BAD_REQUEST).build(); } 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 195efc56ae..d806d3cee7 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 @@ -36,16 +36,17 @@ public class GroupCollectionResource { this.dtoToGroupMapper = dtoToGroupMapper; this.groupCollectionToDtoMapper = groupCollectionToDtoMapper; this.resourceLinks = resourceLinks; - this.adapter = new IdResourceManagerAdapter<>(manager); + this.adapter = new IdResourceManagerAdapter<>(manager, Group.class); } /** * Returns all groups for a given page number with a given page size (default page size is {@value DEFAULT_PAGE_SIZE}). - * + * * Note: This method requires "group" privilege. - * @param page the number of the requested page + * + * @param page the number of the requested page * @param pageSize the page size (default page size is {@value DEFAULT_PAGE_SIZE}) - * @param sortBy sort parameter + * @param sortBy sort parameter (if empty - undefined sorting) * @param desc sort direction desc or aesc */ @GET @@ -54,6 +55,7 @@ public class GroupCollectionResource { @TypeHint(GroupDto[].class) @StatusCodes({ @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 400, condition = "\"sortBy\" field unknown"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group\" privilege"), @ResponseCode(code = 500, condition = "internal server error") 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 7a490b6d7a..c9f066790b 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 @@ -29,7 +29,7 @@ public class GroupResource { GroupDtoToGroupMapper groupDtoToGroupMapper) { this.groupToGroupDtoMapper = groupToGroupDtoMapper; this.dtoToGroupMapper = groupDtoToGroupMapper; - this.adapter = new IdResourceManagerAdapter<>(manager); + this.adapter = new IdResourceManagerAdapter<>(manager, Group.class); } /** 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 db5133dbf3..64c5a063f5 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 @@ -23,10 +23,10 @@ class IdResourceManagerAdapter singleAdapter; private final CollectionResourceManagerAdapter collectionAdapter; - IdResourceManagerAdapter(Manager manager) { + IdResourceManagerAdapter(Manager manager, Class type) { this.manager = manager; - singleAdapter = new SingleResourceManagerAdapter<>(manager); - collectionAdapter = new CollectionResourceManagerAdapter<>(manager); + singleAdapter = new SingleResourceManagerAdapter<>(manager, type); + collectionAdapter = new CollectionResourceManagerAdapter<>(manager, type); } Response get(String id, Function mapToDto) { 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 11078090af..1a90e3cf8d 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 @@ -30,7 +30,7 @@ public class RepositoryCollectionResource { @Inject public RepositoryCollectionResource(RepositoryManager manager, RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper, RepositoryDtoToRepositoryMapper dtoToRepositoryMapper, ResourceLinks resourceLinks) { - this.adapter = new CollectionResourceManagerAdapter<>(manager); + this.adapter = new CollectionResourceManagerAdapter<>(manager, Repository.class); this.repositoryCollectionToDtoMapper = repositoryCollectionToDtoMapper; this.dtoToRepositoryMapper = dtoToRepositoryMapper; this.resourceLinks = resourceLinks; 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 ee251051b1..7fd3600c65 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 @@ -43,7 +43,7 @@ public class RepositoryResource { this.dtoToRepositoryMapper = dtoToRepositoryMapper; this.manager = manager; this.repositoryToDtoMapper = repositoryToDtoMapper; - this.adapter = new SingleResourceManagerAdapter<>(manager); + this.adapter = new SingleResourceManagerAdapter<>(manager, Repository.class); this.tagRootResource = tagRootResource; this.branchRootResource = branchRootResource; this.changesetRootResource = changesetRootResource; 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 547fd3654b..96c9d05d2c 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 @@ -28,8 +28,8 @@ class SingleResourceManagerAdapter extends AbstractManagerResource { - SingleResourceManagerAdapter(Manager manager) { - super(manager); + SingleResourceManagerAdapter(Manager manager, Class type) { + super(manager, type); } /** 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 8daddd67c1..578361424c 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 @@ -35,7 +35,7 @@ public class UserCollectionResource { UserCollectionToDtoMapper userCollectionToDtoMapper, ResourceLinks resourceLinks) { this.dtoToUserMapper = dtoToUserMapper; this.userCollectionToDtoMapper = userCollectionToDtoMapper; - this.adapter = new IdResourceManagerAdapter<>(manager); + this.adapter = new IdResourceManagerAdapter<>(manager, User.class); this.resourceLinks = resourceLinks; } @@ -43,9 +43,10 @@ public class UserCollectionResource { * Returns all users for a given page number with a given page size (default page size is {@value DEFAULT_PAGE_SIZE}). * * Note: This method requires "user" privilege. - * @param page the number of the requested page + * + * @param page the number of the requested page * @param pageSize the page size (default page size is {@value DEFAULT_PAGE_SIZE}) - * @param sortBy sort parameter + * @param sortBy sort parameter (if empty - undefined sorting) * @param desc sort direction desc or asc */ @GET @@ -54,6 +55,7 @@ public class UserCollectionResource { @TypeHint(UserDto[].class) @StatusCodes({ @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 400, condition = "\"sortBy\" field unknown"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"), @ResponseCode(code = 500, condition = "internal server error") 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 2cfcdfe772..2dc070d815 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 @@ -29,7 +29,7 @@ public class UserResource { public UserResource(UserDtoToUserMapper dtoToUserMapper, UserToUserDtoMapper userToDtoMapper, UserManager manager) { this.dtoToUserMapper = dtoToUserMapper; this.userToDtoMapper = userToDtoMapper; - this.adapter = new IdResourceManagerAdapter<>(manager); + this.adapter = new IdResourceManagerAdapter<>(manager, User.class); } /** 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 cc54f9cd86..ed1d7723b2 100644 --- a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java +++ b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java @@ -111,7 +111,7 @@ public class DefaultGroupManager extends AbstractGroupManager * @throws IOException */ @Override - public Group create(Group group) throws GroupException, IOException + public Group create(Group group) throws GroupException { String type = group.getType(); @@ -132,7 +132,7 @@ public class DefaultGroupManager extends AbstractGroupManager if (groupDAO.contains(name)) { - throw new GroupAlreadyExistsException(name.concat(" group already exists")); + throw new GroupAlreadyExistsException(name); } removeDuplicateMembers(group); @@ -153,7 +153,7 @@ public class DefaultGroupManager extends AbstractGroupManager * @throws IOException */ @Override - public void delete(Group group) throws GroupException, IOException + public void delete(Group group) throws GroupException { if (logger.isInfoEnabled()) { @@ -172,7 +172,7 @@ public class DefaultGroupManager extends AbstractGroupManager } else { - throw new GroupNotFoundException("user does not exists"); + throw new GroupNotFoundException(); } } @@ -195,7 +195,7 @@ public class DefaultGroupManager extends AbstractGroupManager * @throws IOException */ @Override - public void modify(Group group) throws GroupException, IOException + public void modify(Group group) throws GroupException { if (logger.isInfoEnabled()) { @@ -218,7 +218,7 @@ public class DefaultGroupManager extends AbstractGroupManager } else { - throw new GroupNotFoundException("group does not exists"); + throw new GroupNotFoundException(); } } @@ -232,7 +232,7 @@ public class DefaultGroupManager extends AbstractGroupManager * @throws IOException */ @Override - public void refresh(Group group) throws GroupException, IOException + public void refresh(Group group) throws GroupException { String name = group.getName(); if (logger.isInfoEnabled()) @@ -245,7 +245,7 @@ public class DefaultGroupManager extends AbstractGroupManager if (fresh == null) { - throw new GroupNotFoundException("group does not exists"); + throw new GroupNotFoundException(); } fresh.copyProperties(group); 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 0cc39c132c..877d228f87 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -139,7 +139,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { * @throws RepositoryException */ public Repository create(Repository repository, boolean initRepository) - throws RepositoryException, IOException { + throws RepositoryException { logger.info("create repository {} of type {}", repository.getName(), repository.getType()); @@ -175,7 +175,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { */ @Override public Repository create(Repository repository) - throws RepositoryException, IOException { + throws RepositoryException { return create(repository, true); } @@ -190,7 +190,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { */ @Override public void delete(Repository repository) - throws RepositoryException, IOException { + throws RepositoryException { if (logger.isInfoEnabled()) { logger.info("delete repository {} of type {}", repository.getName(), repository.getType()); @@ -250,7 +250,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { */ @Override public void modify(Repository repository) - throws RepositoryException, IOException { + throws RepositoryException { if (logger.isInfoEnabled()) { logger.info("modify repository {} of type {}", repository.getName(), repository.getType()); @@ -285,7 +285,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { */ @Override public void refresh(Repository repository) - throws RepositoryException, IOException { + throws RepositoryException { AssertUtil.assertIsNotNull(repository); RepositoryPermissions.read(repository).check(); diff --git a/scm-webapp/src/main/java/sonia/scm/repository/LastModifiedUpdateListener.java b/scm-webapp/src/main/java/sonia/scm/repository/LastModifiedUpdateListener.java index f8afe61200..bf868b2027 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/LastModifiedUpdateListener.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/LastModifiedUpdateListener.java @@ -35,10 +35,8 @@ package sonia.scm.repository; import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import sonia.scm.EagerSingleton; import sonia.scm.plugin.Extension; import sonia.scm.web.security.AdministrationContext; @@ -46,8 +44,6 @@ import sonia.scm.web.security.PrivilegedAction; //~--- JDK imports ------------------------------------------------------------ -import java.io.IOException; - /** * * @author Sebastian Sdorra @@ -154,7 +150,7 @@ public final class LastModifiedUpdateListener { repositoryManager.modify(dbr); } - catch (RepositoryException | IOException ex) + catch (RepositoryException ex) { logger.error("could not modify repository", ex); } 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 39f5ae639d..5a13a7fef8 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java +++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java @@ -137,7 +137,7 @@ public class DefaultUserManager extends AbstractUserManager * @throws UserException */ @Override - public User create(User user) throws UserException, IOException + public User create(User user) throws UserException { String type = user.getType(); @@ -155,7 +155,7 @@ public class DefaultUserManager extends AbstractUserManager if (userDAO.contains(user.getName())) { - throw new UserAlreadyExistsException(user.getName().concat(" user already exists")); + throw new UserAlreadyExistsException(user.getName()); } AssertUtil.assertIsValid(user); @@ -176,7 +176,7 @@ public class DefaultUserManager extends AbstractUserManager * @throws UserException */ @Override - public void delete(User user) throws UserException, IOException + public void delete(User user) throws UserException { if (logger.isInfoEnabled()) { @@ -194,7 +194,7 @@ public class DefaultUserManager extends AbstractUserManager } else { - throw new UserNotFoundException("user does not exists"); + throw new UserNotFoundException(); } } @@ -225,7 +225,7 @@ public class DefaultUserManager extends AbstractUserManager * @throws UserException */ @Override - public void modify(User user) throws UserException, IOException + public void modify(User user) throws UserException { String name = user.getName(); if (logger.isInfoEnabled()) @@ -246,7 +246,7 @@ public class DefaultUserManager extends AbstractUserManager } else { - throw new UserNotFoundException("user does not exists"); + throw new UserNotFoundException(); } } @@ -260,7 +260,7 @@ public class DefaultUserManager extends AbstractUserManager * @throws UserException */ @Override - public void refresh(User user) throws UserException, IOException + public void refresh(User user) throws UserException { if (logger.isInfoEnabled()) { @@ -272,7 +272,7 @@ public class DefaultUserManager extends AbstractUserManager if (fresh == null) { - throw new UserNotFoundException("user does not exists"); + throw new UserNotFoundException(); } fresh.copyProperties(user); diff --git a/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java new file mode 100644 index 0000000000..e8421bc417 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java @@ -0,0 +1,122 @@ +package sonia.scm.api.rest.resources; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import sonia.scm.Manager; +import sonia.scm.ModelObject; + +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.Request; +import java.util.Collection; +import java.util.Comparator; + +import static java.util.Collections.emptyList; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AbstractManagerResourceTest { + + @Mock + private Manager manager; + @Mock + private Request request; + @Captor + private ArgumentCaptor> comparatorCaptor; + + private AbstractManagerResource abstractManagerResource; + + @Before + public void captureComparator() { + when(manager.getAll(comparatorCaptor.capture(), eq(0), eq(1))).thenReturn(emptyList()); + abstractManagerResource = new SimpleManagerResource(); + } + + @Test + public void shouldAcceptDefaultSortByParameter() { + abstractManagerResource.getAll(request, 0, 1, null, true); + + Comparator comparator = comparatorCaptor.getValue(); + assertTrue(comparator.compare(new Simple("1", null), new Simple("2", null)) > 0); + } + + @Test + public void shouldAcceptValidSortByParameter() { + abstractManagerResource.getAll(request, 0, 1, "data", true); + + Comparator comparator = comparatorCaptor.getValue(); + assertTrue(comparator.compare(new Simple("", "1"), new Simple("", "2")) > 0); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailForIllegalSortByParameter() { + abstractManagerResource.getAll(request, 0, 1, "x", true); + } + + + private class SimpleManagerResource extends AbstractManagerResource { + + { + disableCache = true; + } + + private SimpleManagerResource() { + super(AbstractManagerResourceTest.this.manager, Simple.class); + } + + @Override + protected GenericEntity> createGenericEntity(Collection items) { + return null; + } + + @Override + protected String getId(Simple item) { + return null; + } + + @Override + protected String getPathPart() { + return null; + } + } + + public static class Simple implements ModelObject { + + private String id; + private String data; + + Simple(String id, String data) { + this.id = id; + this.data = data; + } + + public String getData() { + return data; + } + + @Override + public String getId() { + return id; + } + + @Override + public Long getLastModified() { + return null; + } + + @Override + public String getType() { + return null; + } + @Override + public boolean isValid() { + return false; + } + } +}