Mind LSP for sub classes

This commit is contained in:
René Pfeuffer
2018-08-30 09:19:10 +02:00
parent 715ac0dab4
commit 87044d0a92
5 changed files with 49 additions and 63 deletions

View File

@@ -11,6 +11,7 @@ import sonia.scm.PageResult;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import static com.damnhandy.uri.template.UriTemplate.fromTemplate; import static com.damnhandy.uri.template.UriTemplate.fromTemplate;
@@ -24,7 +25,7 @@ abstract class BasicCollectionToDtoMapper<E extends ModelObject, D extends HalRe
private final String collectionName; private final String collectionName;
protected final M entityToDtoMapper; private final M entityToDtoMapper;
@Inject @Inject
public BasicCollectionToDtoMapper(String collectionName, M entityToDtoMapper) { public BasicCollectionToDtoMapper(String collectionName, M entityToDtoMapper) {
@@ -32,15 +33,15 @@ abstract class BasicCollectionToDtoMapper<E extends ModelObject, D extends HalRe
this.entityToDtoMapper = entityToDtoMapper; this.entityToDtoMapper = entityToDtoMapper;
} }
public CollectionDto map(int pageNumber, int pageSize, PageResult<E> pageResult) { CollectionDto map(int pageNumber, int pageSize, PageResult<E> pageResult, String selfLink, Optional<String> createLink) {
return map(pageNumber, pageSize, pageResult, entityToDtoMapper::map, createSelfLink()); return map(pageNumber, pageSize, pageResult, selfLink, createLink, entityToDtoMapper::map);
} }
public CollectionDto map(int pageNumber, int pageSize, PageResult<E> pageResult, Function<E, D> mapper, String selfLink) { CollectionDto map(int pageNumber, int pageSize, PageResult<E> pageResult, String selfLink, Optional<String> createLink, Function<E, ? extends HalRepresentation> mapper) {
NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.getOverallCount()); NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.getOverallCount());
List<D> dtos = pageResult.getEntities().stream().map(mapper).collect(toList()); List<HalRepresentation> dtos = pageResult.getEntities().stream().map(mapper).collect(toList());
CollectionDto collectionDto = new CollectionDto( CollectionDto collectionDto = new CollectionDto(
createLinks(paging, selfLink), createLinks(paging, selfLink, createLink),
embedDtos(dtos)); embedDtos(dtos));
collectionDto.setPage(pageNumber); collectionDto.setPage(pageNumber);
collectionDto.setPageTotal(computePageTotal(pageSize, pageResult)); collectionDto.setPageTotal(computePageTotal(pageSize, pageResult));
@@ -55,24 +56,16 @@ abstract class BasicCollectionToDtoMapper<E extends ModelObject, D extends HalRe
} }
} }
private Links createLinks(NumberedPaging page, String baseUrl) { private Links createLinks(NumberedPaging page, String selfLink, Optional<String> createLink) {
Links.Builder linksBuilder = linkingTo() Links.Builder linksBuilder = linkingTo()
.with(page.links( .with(page.links(
fromTemplate(baseUrl + "{?page,pageSize}"), fromTemplate(selfLink + "{?page,pageSize}"),
EnumSet.allOf(PagingRel.class))); EnumSet.allOf(PagingRel.class)));
if (isCreatePermitted()) { createLink.ifPresent(link -> linksBuilder.single(link("create", link)));
linksBuilder.single(link("create", createCreateLink()));
}
return linksBuilder.build(); return linksBuilder.build();
} }
abstract boolean isCreatePermitted(); private Embedded embedDtos(List<HalRepresentation> dtos) {
abstract String createCreateLink();
abstract String createSelfLink();
private Embedded embedDtos(List<D> dtos) {
return embeddedBuilder() return embeddedBuilder()
.with(collectionName, dtos) .with(collectionName, dtos)
.build(); .build();

View File

@@ -5,38 +5,25 @@ import sonia.scm.repository.Changeset;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Optional;
public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper<Changeset, ChangesetDto, ChangesetToChangesetDtoMapper> { public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper<Changeset, ChangesetDto, ChangesetToChangesetDtoMapper> {
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
private final ResourceLinks resourceLinks; private final ResourceLinks resourceLinks;
@Inject @Inject
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
super("changesets", changesetToChangesetDtoMapper); super("changesets", changesetToChangesetDtoMapper);
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
this.resourceLinks = resourceLinks; this.resourceLinks = resourceLinks;
} }
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) { public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
return super.map(pageNumber, pageSize, pageResult, changeset -> super.entityToDtoMapper.map(changeset, repository), createSelfLink(repository)); return super.map(pageNumber, pageSize, pageResult, createSelfLink(repository), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
}
@Override
String createCreateLink() {
return null;
}
@Override
String createSelfLink() {
return null;
} }
private String createSelfLink(Repository repository) { private String createSelfLink(Repository repository) {
return resourceLinks.changeset().all(repository.getNamespace(), repository.getName()); return resourceLinks.changeset().all(repository.getNamespace(), repository.getName());
} }
@Override
boolean isCreatePermitted() {
return false;
}
} }

View File

@@ -1,9 +1,14 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import sonia.scm.PageResult;
import sonia.scm.group.Group; import sonia.scm.group.Group;
import sonia.scm.group.GroupPermissions; import sonia.scm.group.GroupPermissions;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Optional;
import static java.util.Optional.empty;
import static java.util.Optional.of;
public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper<Group, GroupDto, GroupToGroupDtoMapper> { public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper<Group, GroupDto, GroupToGroupDtoMapper> {
@@ -15,18 +20,15 @@ public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper<Group
this.resourceLinks = resourceLinks; this.resourceLinks = resourceLinks;
} }
@Override public CollectionDto map(int pageNumber, int pageSize, PageResult<Group> pageResult) {
String createCreateLink() { return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink());
return resourceLinks.groupCollection().create();
} }
@Override private Optional<String> createCreateLink() {
String createSelfLink() { return GroupPermissions.create().isPermitted() ? of(resourceLinks.groupCollection().create()): empty();
}
private String createSelfLink() {
return resourceLinks.groupCollection().self(); return resourceLinks.groupCollection().self();
} }
@Override
boolean isCreatePermitted() {
return GroupPermissions.create().isPermitted();
}
} }

View File

@@ -1,9 +1,14 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import sonia.scm.PageResult;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.RepositoryPermissions;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Optional;
import static java.util.Optional.empty;
import static java.util.Optional.of;
// Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection.
@SuppressWarnings("squid:S3306") @SuppressWarnings("squid:S3306")
@@ -17,18 +22,15 @@ public class RepositoryCollectionToDtoMapper extends BasicCollectionToDtoMapper<
this.resourceLinks = resourceLinks; this.resourceLinks = resourceLinks;
} }
@Override public CollectionDto map(int pageNumber, int pageSize, PageResult<Repository> pageResult) {
String createCreateLink() { return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink());
return resourceLinks.repositoryCollection().create(); }
Optional<String> createCreateLink() {
return RepositoryPermissions.create().isPermitted() ? of(resourceLinks.repositoryCollection().create()): empty();
} }
@Override
String createSelfLink() { String createSelfLink() {
return resourceLinks.repositoryCollection().self(); return resourceLinks.repositoryCollection().self();
} }
@Override
boolean isCreatePermitted() {
return RepositoryPermissions.create().isPermitted();
}
} }

View File

@@ -1,9 +1,14 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import sonia.scm.PageResult;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.user.UserPermissions; import sonia.scm.user.UserPermissions;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Optional;
import static java.util.Optional.empty;
import static java.util.Optional.of;
// Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection.
@SuppressWarnings("squid:S3306") @SuppressWarnings("squid:S3306")
@@ -17,18 +22,15 @@ public class UserCollectionToDtoMapper extends BasicCollectionToDtoMapper<User,
this.resourceLinks = resourceLinks; this.resourceLinks = resourceLinks;
} }
@Override public CollectionDto map(int pageNumber, int pageSize, PageResult<User> pageResult) {
String createCreateLink() { return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink());
return resourceLinks.userCollection().create(); }
Optional<String> createCreateLink() {
return UserPermissions.create().isPermitted() ? of(resourceLinks.userCollection().create()): empty();
} }
@Override
String createSelfLink() { String createSelfLink() {
return resourceLinks.userCollection().self(); return resourceLinks.userCollection().self();
} }
@Override
boolean isCreatePermitted() {
return UserPermissions.create().isPermitted();
}
} }