+
+
+
+
+ {description.title}
+
+
+
+
+
-
-
-
-
-
-
- {description.title}
-
-
-
-
-
{" "}
-
{authorLine}
+
+
+
- {this.renderTags()}
-
+
);
}
-
- renderTags = () => {
- const tags = this.getTags();
- if (tags.length > 0) {
- return (
-
- {tags.map((tag: Tag) => {
- return ;
- })}
-
- );
- }
- return null;
- };
}
export default injectSheet(styles)(translate("repos")(ChangesetRow));
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTag.js b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTag.js
index 6a87400d2e..03c73a8e9f 100644
--- a/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTag.js
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTag.js
@@ -1,32 +1,17 @@
//@flow
import React from "react";
import type { Tag } from "@scm-manager/ui-types";
-import injectSheet from "react-jss";
-import classNames from "classnames";
-
-const styles = {
- spacing: {
- marginRight: "4px"
- }
-};
+import ChangesetTagBase from "./ChangesetTagBase";
type Props = {
- tag: Tag,
-
- // context props
- classes: Object
+ tag: Tag
};
class ChangesetTag extends React.Component
{
render() {
- const { tag, classes } = this.props;
- return (
-
- {" "}
- {tag.name}
-
- );
+ const { tag } = this.props;
+ return ;
}
}
-export default injectSheet(styles)(ChangesetTag);
+export default ChangesetTag;
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagBase.js b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagBase.js
new file mode 100644
index 0000000000..7fc8dabcd2
--- /dev/null
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagBase.js
@@ -0,0 +1,34 @@
+//@flow
+import React from "react";
+import injectSheet from "react-jss";
+import classNames from "classnames";
+
+const styles = {
+ tag: {
+ marginTop: ".5rem"
+ },
+ spacing: {
+ marginRight: ".25rem"
+ }
+};
+
+type Props = {
+ icon: string,
+ label: string,
+
+ // context props
+ classes: Object
+};
+
+class ChangesetTagBase extends React.Component {
+ render() {
+ const { icon, label, classes } = this.props;
+ return (
+
+ {label}
+
+ );
+ }
+}
+
+export default injectSheet(styles)(ChangesetTagBase);
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTags.js b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTags.js
new file mode 100644
index 0000000000..b8bff8ddd2
--- /dev/null
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTags.js
@@ -0,0 +1,31 @@
+//@flow
+import React from "react";
+import type { Changeset} from "@scm-manager/ui-types";
+import ChangesetTag from "./ChangesetTag";
+import ChangesetTagsCollapsed from "./ChangesetTagsCollapsed";
+
+type Props = {
+ changeset: Changeset
+};
+
+class ChangesetTags extends React.Component {
+
+ getTags = () => {
+ const { changeset } = this.props;
+ return changeset._embedded.tags || [];
+ };
+
+ render() {
+ const tags = this.getTags();
+
+ if (tags.length === 1) {
+ return ;
+ } else if (tags.length > 1) {
+ return ;
+ } else {
+ return null;
+ }
+ }
+}
+
+export default ChangesetTags;
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagsCollapsed.js b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagsCollapsed.js
new file mode 100644
index 0000000000..50b09d4d65
--- /dev/null
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/ChangesetTagsCollapsed.js
@@ -0,0 +1,27 @@
+//@flow
+import React from "react";
+import type { Tag } from "@scm-manager/ui-types";
+import ChangesetTagBase from "./ChangesetTagBase";
+import { translate } from "react-i18next";
+import Tooltip from "../../Tooltip";
+
+type Props = {
+ tags: Tag[],
+
+ // context props
+ t: (string) => string
+};
+
+class ChangesetTagsCollapsed extends React.Component {
+ render() {
+ const { tags, t } = this.props;
+ const message = tags.map((tag) => tag.name).join(", ");
+ return (
+
+
+
+ );
+ }
+}
+
+export default translate("repos")(ChangesetTagsCollapsed);
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/changesets.js b/scm-ui-components/packages/ui-components/src/repos/changesets/changesets.js
index f61a89c74b..69227ad75d 100644
--- a/scm-ui-components/packages/ui-components/src/repos/changesets/changesets.js
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/changesets.js
@@ -1,9 +1,19 @@
// @flow
+import type { Changeset, Repository } from "@scm-manager/ui-types";
+
export type Description = {
title: string,
message: string
};
+export function createChangesetLink(repository: Repository, changeset: Changeset) {
+ return `/repo/${repository.namespace}/${repository.name}/changeset/${changeset.id}`;
+}
+
+export function createSourcesLink(repository: Repository, changeset: Changeset) {
+ return `/repo/${repository.namespace}/${repository.name}/sources/${changeset.id}`;
+}
+
export function parseDescription(description?: string): Description {
const desc = description ? description : "";
const lineBreak = desc.indexOf("\n");
diff --git a/scm-ui-components/packages/ui-components/src/repos/changesets/index.js b/scm-ui-components/packages/ui-components/src/repos/changesets/index.js
index 0e7a5e533d..7a07ad8f42 100644
--- a/scm-ui-components/packages/ui-components/src/repos/changesets/index.js
+++ b/scm-ui-components/packages/ui-components/src/repos/changesets/index.js
@@ -3,8 +3,11 @@ import * as changesets from "./changesets";
export { changesets };
export { default as ChangesetAuthor } from "./ChangesetAuthor";
+export { default as ChangesetButtonGroup } from "./ChangesetButtonGroup";
+export { default as ChangesetDiff } from "./ChangesetDiff";
export { default as ChangesetId } from "./ChangesetId";
export { default as ChangesetList } from "./ChangesetList";
export { default as ChangesetRow } from "./ChangesetRow";
export { default as ChangesetTag } from "./ChangesetTag";
-export { default as ChangesetDiff } from "./ChangesetDiff";
+export { default as ChangesetTags } from "./ChangesetTags";
+export { default as ChangesetTagsCollapsed } from "./ChangesetTagsCollapsed";
diff --git a/scm-ui/package.json b/scm-ui/package.json
index bf4e272fb0..2144e50e6c 100644
--- a/scm-ui/package.json
+++ b/scm-ui/package.json
@@ -17,6 +17,7 @@
"i18next": "^11.4.0",
"i18next-browser-languagedetector": "^2.2.2",
"i18next-fetch-backend": "^0.1.0",
+ "jss-nested": "^6.0.1",
"moment": "^2.22.2",
"node-sass": "^4.9.3",
"postcss-easy-import": "^3.0.0",
diff --git a/scm-ui/public/index.mustache b/scm-ui/public/index.mustache
index 590b5e3cdb..75efc78088 100644
--- a/scm-ui/public/index.mustache
+++ b/scm-ui/public/index.mustache
@@ -21,6 +21,8 @@
You need to enable JavaScript to run this app.
+
+
@@ -158,6 +158,24 @@
${resteasy.version}
+
+ org.hibernate
+ hibernate-validator
+ 5.3.6.Final
+
+
+
+ javax.el
+ javax.el-api
+ 2.2.4
+
+
+
+ org.glassfish.web
+ javax.el
+ 2.2.4
+
+
@@ -203,18 +221,6 @@
1.4.01
-
-
-
- commons-beanutils
- commons-beanutils
-
-
-
- commons-collections
- commons-collections
-
-
@@ -561,8 +567,6 @@
2.53.1
1.0
0.8.17
- 3.1.4.Final
- 2.8.9
Tomcat
e1
javascript:S3827
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/NotAllowedExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/rest/NotAllowedExceptionMapper.java
new file mode 100644
index 0000000000..1d268b6855
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/NotAllowedExceptionMapper.java
@@ -0,0 +1,12 @@
+package sonia.scm.api.rest;
+
+import javax.ws.rs.NotAllowedException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class NotAllowedExceptionMapper extends StatusExceptionMapper {
+ public NotAllowedExceptionMapper() {
+ super(NotAllowedException.class, Response.Status.METHOD_NOT_ALLOWED);
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java
index 4253c456fb..dfc0bd2a5d 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java
@@ -37,7 +37,6 @@ package sonia.scm.api.rest.resources;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.net.UrlEscapers;
-import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,6 +46,7 @@ import sonia.scm.ModelObject;
import sonia.scm.PageResult;
import sonia.scm.api.rest.RestExceptionResult;
import sonia.scm.util.AssertUtil;
+import sonia.scm.util.Comparables;
import sonia.scm.util.Util;
import javax.ws.rs.core.CacheControl;
@@ -56,15 +56,10 @@ import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.util.Arrays;
+import java.net.URI;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
-import java.net.URI;
//~--- JDK imports ------------------------------------------------------------
@@ -510,21 +505,11 @@ public abstract class AbstractManagerResource {
return builder.build();
}
- @SuppressWarnings("unchecked")
- private Comparator createComparator(String sortBy, boolean desc)
- {
- checkSortByField(sortBy);
- Comparator comparator;
-
- if (desc)
- {
- comparator = new BeanReverseComparator(sortBy);
+ private Comparator createComparator(String sortBy, boolean desc) {
+ Comparator comparator = Comparables.comparator(type, sortBy);
+ if (desc) {
+ comparator = comparator.reversed();
}
- else
- {
- comparator = new BeanComparator(sortBy);
- }
-
return comparator;
}
@@ -558,21 +543,6 @@ public abstract class AbstractManagerResource {
return items;
}
- // 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);
@@ -608,51 +578,4 @@ public abstract class AbstractManagerResource {
return lastModified;
}
-
- //~--- inner classes --------------------------------------------------------
-
- /**
- * Class description
- *
- *
- * @version Enter version here..., 11/06/09
- * @author Enter your name here...
- */
- private static class BeanReverseComparator extends BeanComparator
- {
-
- /** Field description */
- private static final long serialVersionUID = -8535047820348790009L;
-
- //~--- constructors -------------------------------------------------------
-
- /**
- * Constructs ...
- *
- *
- * @param sortby
- */
- private BeanReverseComparator(String sortby)
- {
- super(sortby);
- }
-
- //~--- methods ------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param o1
- * @param o2
- *
- * @return
- */
- @Override
- @SuppressWarnings("unchecked")
- public int compare(Object o1, Object o2)
- {
- return super.compare(o1, o2) * -1;
- }
- }
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java
index d2ce744c19..79b5dbc2ae 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java
@@ -6,8 +6,6 @@ import sonia.scm.repository.api.CatCommandBuilder;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.util.IOUtil;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java
index d177e05a5e..b7f994b967 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java
@@ -42,7 +42,6 @@ import sonia.scm.repository.api.RepositoryService;
import sonia.scm.util.IOUtil;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchDto.java
index f5bdc850ab..343d9c8bc8 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchDto.java
@@ -1,5 +1,6 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
@@ -12,8 +13,7 @@ public class BranchDto extends HalRepresentation {
private String name;
private String revision;
- @Override
- protected HalRepresentation add(Links links) {
- return super.add(links);
+ BranchDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java
index 658abbded8..71b1127ad8 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java
@@ -26,7 +26,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.IOException;
-import java.util.List;
import static sonia.scm.ContextEntry.ContextBuilder.entity;
import static sonia.scm.NotFoundException.notFound;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java
index 7e6f0c074c..c940b1ffd9 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java
@@ -1,11 +1,11 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.repository.Branch;
import sonia.scm.repository.NamespaceAndName;
@@ -15,7 +15,7 @@ import static de.otto.edison.hal.Link.linkBuilder;
import static de.otto.edison.hal.Links.linkingTo;
@Mapper
-public abstract class BranchToBranchDtoMapper extends LinkAppenderMapper {
+public abstract class BranchToBranchDtoMapper extends HalAppenderMapper {
@Inject
private ResourceLinks resourceLinks;
@@ -23,16 +23,17 @@ public abstract class BranchToBranchDtoMapper extends LinkAppenderMapper {
@Mapping(target = "attributes", ignore = true) // We do not map HAL attributes
public abstract BranchDto map(Branch branch, @Context NamespaceAndName namespaceAndName);
- @AfterMapping
- void appendLinks(Branch source, @MappingTarget BranchDto target, @Context NamespaceAndName namespaceAndName) {
+ @ObjectFactory
+ BranchDto createDto(@Context NamespaceAndName namespaceAndName, Branch branch) {
Links.Builder linksBuilder = linkingTo()
- .self(resourceLinks.branch().self(namespaceAndName, target.getName()))
- .single(linkBuilder("history", resourceLinks.branch().history(namespaceAndName, target.getName())).build())
- .single(linkBuilder("changeset", resourceLinks.changeset().changeset(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())).build())
- .single(linkBuilder("source", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())).build());
+ .self(resourceLinks.branch().self(namespaceAndName, branch.getName()))
+ .single(linkBuilder("history", resourceLinks.branch().history(namespaceAndName, branch.getName())).build())
+ .single(linkBuilder("changeset", resourceLinks.changeset().changeset(namespaceAndName.getNamespace(), namespaceAndName.getName(), branch.getRevision())).build())
+ .single(linkBuilder("source", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), branch.getRevision())).build());
- appendLinks(new EdisonLinkAppender(linksBuilder), source, namespaceAndName);
+ Embedded.Builder embeddedBuilder = Embedded.embeddedBuilder();
+ applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), branch, namespaceAndName);
- target.add(linksBuilder.build());
+ return new BranchDto(linksBuilder.build(), embeddedBuilder.build());
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java
similarity index 64%
rename from scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java
rename to scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java
index 219062d320..479a43aef1 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java
@@ -1,11 +1,11 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.repository.Branch;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.Repository;
@@ -19,11 +19,12 @@ import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
@Mapper
-public abstract class ChangesetToChangesetDtoMapper extends LinkAppenderMapper implements InstantAttributeMapper {
+public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMapper implements InstantAttributeMapper, ChangesetToChangesetDtoMapper{
@Inject
private RepositoryServiceFactory serviceFactory;
@@ -31,7 +32,6 @@ public abstract class ChangesetToChangesetDtoMapper extends LinkAppenderMapper i
@Inject
private ResourceLinks resourceLinks;
-
@Inject
private BranchCollectionToDtoMapper branchCollectionToDtoMapper;
@@ -46,31 +46,35 @@ public abstract class ChangesetToChangesetDtoMapper extends LinkAppenderMapper i
public abstract ChangesetDto map(Changeset changeset, @Context Repository repository);
- @AfterMapping
- void appendLinks(Changeset source, @MappingTarget ChangesetDto target, @Context Repository repository) {
+ @ObjectFactory
+ ChangesetDto createDto(@Context Repository repository, Changeset source) {
String namespace = repository.getNamespace();
String name = repository.getName();
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
+
try (RepositoryService repositoryService = serviceFactory.create(repository)) {
if (repositoryService.isSupported(Command.TAGS)) {
- target.withEmbedded("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name,
+ embeddedBuilder.with("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name,
getListOfObjects(source.getTags(), tagName -> new Tag(tagName, source.getId()))));
}
if (repositoryService.isSupported(Command.BRANCHES)) {
- target.withEmbedded("branches", branchCollectionToDtoMapper.getBranchDtoList(namespace, name,
+ embeddedBuilder.with("branches", branchCollectionToDtoMapper.getBranchDtoList(namespace, name,
getListOfObjects(source.getBranches(), branchName -> new Branch(branchName, source.getId()))));
}
}
- target.withEmbedded("parents", getListOfObjects(source.getParents(), parent -> changesetToParentDtoMapper.map(new Changeset(parent, 0L, null), repository)));
+ embeddedBuilder.with("parents", getListOfObjects(source.getParents(), parent -> changesetToParentDtoMapper.map(new Changeset(parent, 0L, null), repository)));
Links.Builder linksBuilder = linkingTo()
- .self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), target.getId()))
- .single(link("diff", resourceLinks.diff().self(namespace, name, target.getId())))
- .single(link("modifications", resourceLinks.modifications().self(namespace, name, target.getId())));
+ .self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), source.getId()))
+ .single(link("diff", resourceLinks.diff().self(namespace, name, source.getId())))
+ .single(link("sources", resourceLinks.source().self(namespace, name, source.getId())))
+ .single(link("modifications", resourceLinks.modifications().self(namespace, name, source.getId())));
- appendLinks(new EdisonLinkAppender(linksBuilder), source, repository);
- target.add(linksBuilder.build());
+ applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), source, repository);
+
+ return new ChangesetDto(linksBuilder.build(), embeddedBuilder.build());
}
private List getListOfObjects(List list, Function mapFunction) {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonLinkAppender.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonHalAppender.java
similarity index 52%
rename from scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonLinkAppender.java
rename to scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonHalAppender.java
index c4e699cb58..769de2b705 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonLinkAppender.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/EdisonHalAppender.java
@@ -1,27 +1,36 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
+import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Link;
import de.otto.edison.hal.Links;
import java.util.ArrayList;
import java.util.List;
-class EdisonLinkAppender implements LinkAppender {
+class EdisonHalAppender implements HalAppender {
- private final Links.Builder builder;
+ private final Links.Builder linkBuilder;
+ private final Embedded.Builder embeddedBuilder;
- EdisonLinkAppender(Links.Builder builder) {
- this.builder = builder;
+ EdisonHalAppender(Links.Builder linkBuilder, Embedded.Builder embeddedBuilder) {
+ this.linkBuilder = linkBuilder;
+ this.embeddedBuilder = embeddedBuilder;
}
@Override
- public void appendOne(String rel, String href) {
- builder.single(Link.link(rel, href));
+ public void appendLink(String rel, String href) {
+ linkBuilder.single(Link.link(rel, href));
}
@Override
- public LinkArrayBuilder arrayBuilder(String rel) {
- return new EdisonLinkArrayBuilder(builder, rel);
+ public LinkArrayBuilder linkArrayBuilder(String rel) {
+ return new EdisonLinkArrayBuilder(linkBuilder, rel);
+ }
+
+ @Override
+ public void appendEmbedded(String rel, HalRepresentation embedded) {
+ embeddedBuilder.with(rel, embedded);
}
private static class EdisonLinkArrayBuilder implements LinkArrayBuilder {
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 bd889d5de5..d155fbede6 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
@@ -5,7 +5,6 @@ import lombok.Getter;
import lombok.Setter;
import sonia.scm.ContextEntry;
-import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java
index c183d731c6..0bce564e35 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java
@@ -1,6 +1,7 @@
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.annotation.JsonInclude;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
@@ -27,10 +28,8 @@ public class FileObjectDto extends HalRepresentation {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String revision;
- @Override
- @SuppressWarnings("squid:S1185") // We want to have this method available in this package
- protected HalRepresentation add(Links links) {
- return super.add(links);
+ public FileObjectDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
public void setChildren(List children) {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java
index 2432d5168c..608dea9f26 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java
@@ -1,24 +1,22 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.repository.FileObject;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.SubRepository;
import javax.inject.Inject;
-import java.util.List;
-import java.util.stream.Collectors;
-
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
@Mapper
-public abstract class FileObjectToFileObjectDtoMapper extends LinkAppenderMapper implements InstantAttributeMapper {
+public abstract class FileObjectToFileObjectDtoMapper extends HalAppenderMapper implements InstantAttributeMapper {
@Inject
private ResourceLinks resourceLinks;
@@ -28,20 +26,21 @@ public abstract class FileObjectToFileObjectDtoMapper extends LinkAppenderMapper
abstract SubRepositoryDto mapSubrepository(SubRepository subRepository);
- @AfterMapping
- void addLinks(FileObject fileObject, @MappingTarget FileObjectDto dto, @Context NamespaceAndName namespaceAndName, @Context String revision) {
+ @ObjectFactory
+ FileObjectDto createDto(@Context NamespaceAndName namespaceAndName, @Context String revision, FileObject fileObject) {
String path = removeFirstSlash(fileObject.getPath());
Links.Builder links = Links.linkingTo();
- if (dto.isDirectory()) {
+ if (fileObject.isDirectory()) {
links.self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path));
} else {
links.self(resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path));
links.single(link("history", resourceLinks.fileHistory().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path)));
}
- appendLinks(new EdisonLinkAppender(links), fileObject, namespaceAndName, revision);
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
+ applyEnrichers(new EdisonHalAppender(links, embeddedBuilder), fileObject, namespaceAndName, revision);
- dto.add(links.build());
+ return new FileObjectDto(links.build(), embeddedBuilder.build());
}
private String removeFirstSlash(String source) {
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 4c111e6707..6c13dc33a5 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
@@ -10,7 +10,6 @@ import sonia.scm.group.GroupManager;
import sonia.scm.web.VndMediaType;
import javax.inject.Inject;
-import javax.inject.Named;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
index 760beab1da..a150570316 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
@@ -1,12 +1,12 @@
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.annotation.JsonInclude;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.time.Instant;
@@ -28,13 +28,7 @@ public class GroupDto extends HalRepresentation {
private Map properties;
private List members;
- @Override
- @SuppressWarnings("squid:S1185") // We want to have this method available in this package
- protected HalRepresentation add(Links links) {
- return super.add(links);
- }
-
- public HalRepresentation withMembers(List members) {
- return super.withEmbedded("members", members);
+ GroupDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDtoToGroupMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDtoToGroupMapper.java
index be1aca5814..3812f700da 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDtoToGroupMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDtoToGroupMapper.java
@@ -4,8 +4,6 @@ import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import sonia.scm.group.Group;
-import java.time.Instant;
-
@Mapper
public abstract class GroupDtoToGroupMapper extends BaseDtoMapper {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapper.java
index bf866af350..7d5ddae548 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapper.java
@@ -1,9 +1,9 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.group.Group;
import sonia.scm.group.GroupPermissions;
import sonia.scm.security.PermissionPermissions;
@@ -12,6 +12,7 @@ import javax.inject.Inject;
import java.util.List;
import java.util.stream.Collectors;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
@@ -23,28 +24,26 @@ public abstract class GroupToGroupDtoMapper extends BaseMapper
@Inject
private ResourceLinks resourceLinks;
- @AfterMapping
- void appendLinks(Group group, @MappingTarget GroupDto target) {
- Links.Builder linksBuilder = linkingTo().self(resourceLinks.group().self(target.getName()));
+ @ObjectFactory
+ GroupDto createDto(Group group) {
+ Links.Builder linksBuilder = linkingTo().self(resourceLinks.group().self(group.getName()));
if (GroupPermissions.delete(group).isPermitted()) {
- linksBuilder.single(link("delete", resourceLinks.group().delete(target.getName())));
+ linksBuilder.single(link("delete", resourceLinks.group().delete(group.getName())));
}
if (GroupPermissions.modify(group).isPermitted()) {
- linksBuilder.single(link("update", resourceLinks.group().update(target.getName())));
+ linksBuilder.single(link("update", resourceLinks.group().update(group.getName())));
}
if (PermissionPermissions.read().isPermitted()) {
- linksBuilder.single(link("permissions", resourceLinks.groupPermissions().permissions(target.getName())));
+ linksBuilder.single(link("permissions", resourceLinks.groupPermissions().permissions(group.getName())));
}
- appendLinks(new EdisonLinkAppender(linksBuilder), group);
-
- target.add(linksBuilder.build());
- }
-
- @AfterMapping
- void mapMembers(Group group, @MappingTarget GroupDto target) {
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
List memberDtos = group.getMembers().stream().map(this::createMember).collect(Collectors.toList());
- target.withMembers(memberDtos);
+ embeddedBuilder.with("members", memberDtos);
+
+ applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), group);
+
+ return new GroupDto(linksBuilder.build(), embeddedBuilder.build());
}
private MemberDto createMember(String name) {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java
index 9346420f58..16f945332d 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java
@@ -1,5 +1,6 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
@@ -9,8 +10,8 @@ public class IndexDto extends HalRepresentation {
private final String version;
- IndexDto(String version, Links links) {
- super(links);
+ IndexDto(Links links, Embedded embedded, String version) {
+ super(links, embedded);
this.version = version;
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java
index 3eff661385..90445bcdc2 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java
@@ -1,6 +1,7 @@
package sonia.scm.api.v2.resources;
import com.google.common.collect.Lists;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Link;
import de.otto.edison.hal.Links;
import org.apache.shiro.SecurityUtils;
@@ -13,9 +14,10 @@ import sonia.scm.user.UserPermissions;
import javax.inject.Inject;
import java.util.List;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
-public class IndexDtoGenerator extends LinkAppenderMapper {
+public class IndexDtoGenerator extends HalAppenderMapper {
private final ResourceLinks resourceLinks;
private final SCMContextProvider scmContextProvider;
@@ -61,8 +63,9 @@ public class IndexDtoGenerator extends LinkAppenderMapper {
builder.single(link("login", resourceLinks.authentication().jsonLogin()));
}
- appendLinks(new EdisonLinkAppender(builder), new Index());
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
+ applyEnrichers(new EdisonHalAppender(builder, embeddedBuilder), new Index());
- return new IndexDto(scmContextProvider.getVersion(), builder.build());
+ return new IndexDto(builder.build(), embeddedBuilder.build(), scmContextProvider.getVersion());
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistration.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistration.java
index 890e268ed5..8472eb9fc1 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistration.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistration.java
@@ -10,30 +10,30 @@ import javax.servlet.ServletContextListener;
import java.util.Set;
/**
- * Registers every {@link LinkEnricher} which is annotated with an {@link Enrich} annotation.
+ * Registers every {@link HalEnricher} which is annotated with an {@link Enrich} annotation.
*/
@Extension
public class LinkEnricherAutoRegistration implements ServletContextListener {
private static final Logger LOG = LoggerFactory.getLogger(LinkEnricherAutoRegistration.class);
- private final LinkEnricherRegistry registry;
- private final Set enrichers;
+ private final HalEnricherRegistry registry;
+ private final Set enrichers;
@Inject
- public LinkEnricherAutoRegistration(LinkEnricherRegistry registry, Set enrichers) {
+ public LinkEnricherAutoRegistration(HalEnricherRegistry registry, Set enrichers) {
this.registry = registry;
this.enrichers = enrichers;
}
@Override
public void contextInitialized(ServletContextEvent sce) {
- for (LinkEnricher enricher : enrichers) {
+ for (HalEnricher enricher : enrichers) {
Enrich annotation = enricher.getClass().getAnnotation(Enrich.class);
if (annotation != null) {
registry.register(annotation.value(), enricher);
} else {
- LOG.warn("found LinkEnricher extension {} without Enrich annotation", enricher.getClass());
+ LOG.warn("found HalEnricher extension {} without Enrich annotation", enricher.getClass());
}
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
index 859a6481f6..c74f16ad70 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
@@ -28,7 +28,7 @@ public class MapperModule extends AbstractModule {
bind(RepositoryPermissionDtoToRepositoryPermissionMapper.class).to(Mappers.getMapper(RepositoryPermissionDtoToRepositoryPermissionMapper.class).getClass());
bind(RepositoryPermissionToRepositoryPermissionDtoMapper.class).to(Mappers.getMapper(RepositoryPermissionToRepositoryPermissionDtoMapper.class).getClass());
- bind(ChangesetToChangesetDtoMapper.class).to(Mappers.getMapper(ChangesetToChangesetDtoMapper.class).getClass());
+ bind(ChangesetToChangesetDtoMapper.class).to(Mappers.getMapper(DefaultChangesetToChangesetDtoMapper.class).getClass());
bind(ChangesetToParentDtoMapper.class).to(Mappers.getMapper(ChangesetToParentDtoMapper.class).getClass());
bind(TagToTagDtoMapper.class).to(Mappers.getMapper(TagToTagDtoMapper.class).getClass());
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDto.java
index 5488faca28..84fbbfe290 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDto.java
@@ -1,5 +1,6 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
@@ -18,9 +19,7 @@ public class MeDto extends HalRepresentation {
private String mail;
private List groups;
- @Override
- @SuppressWarnings("squid:S1185") // We want to have this method available in this package
- protected HalRepresentation add(Links links) {
- return super.add(links);
+ MeDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDtoFactory.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDtoFactory.java
index 082db7fd94..b5e1998066 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDtoFactory.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MeDtoFactory.java
@@ -1,6 +1,7 @@
package sonia.scm.api.v2.resources;
import com.google.common.collect.ImmutableList;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
@@ -13,10 +14,11 @@ import sonia.scm.user.UserPermissions;
import javax.inject.Inject;
import java.util.Collections;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
-public class MeDtoFactory extends LinkAppenderMapper {
+public class MeDtoFactory extends HalAppenderMapper {
private final ResourceLinks resourceLinks;
private final UserManager userManager;
@@ -29,15 +31,11 @@ public class MeDtoFactory extends LinkAppenderMapper {
public MeDto create() {
PrincipalCollection principals = getPrincipalCollection();
-
- MeDto dto = new MeDto();
-
User user = principals.oneByType(User.class);
+ MeDto dto = createDto(user);
mapUserProperties(user, dto);
mapGroups(principals, dto);
-
- appendLinks(user, dto);
return dto;
}
@@ -61,21 +59,22 @@ public class MeDtoFactory extends LinkAppenderMapper {
}
- private void appendLinks(User user, MeDto target) {
+ private MeDto createDto(User user) {
Links.Builder linksBuilder = linkingTo().self(resourceLinks.me().self());
if (UserPermissions.delete(user).isPermitted()) {
- linksBuilder.single(link("delete", resourceLinks.me().delete(target.getName())));
+ linksBuilder.single(link("delete", resourceLinks.me().delete(user.getName())));
}
if (UserPermissions.modify(user).isPermitted()) {
- linksBuilder.single(link("update", resourceLinks.me().update(target.getName())));
+ linksBuilder.single(link("update", resourceLinks.me().update(user.getName())));
}
if (userManager.isTypeDefault(user) && UserPermissions.changePassword(user).isPermitted()) {
linksBuilder.single(link("password", resourceLinks.me().passwordChange()));
}
- appendLinks(new EdisonLinkAppender(linksBuilder), new Me(), user);
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
+ applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), new Me(), user);
- target.add(linksBuilder.build());
+ return new MeDto(linksBuilder.build(), embeddedBuilder.build());
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionCollectionToDtoMapper.java
index 87d1aeca9f..31269d468e 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionCollectionToDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionCollectionToDtoMapper.java
@@ -1,7 +1,6 @@
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Links;
-import org.mapstruct.Context;
import sonia.scm.security.PermissionDescriptor;
import sonia.scm.security.PermissionPermissions;
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 a9bd5c2424..e1e1260a4d 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
@@ -23,7 +23,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
-import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
public class RepositoryCollectionResource {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java
index ddfe432d73..8b48311bba 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java
@@ -1,9 +1,11 @@
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.annotation.JsonInclude;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
@@ -13,7 +15,7 @@ import java.time.Instant;
import java.util.List;
import java.util.Map;
-@Getter @Setter
+@Getter @Setter @NoArgsConstructor
public class RepositoryDto extends HalRepresentation {
@Email
@@ -31,9 +33,7 @@ public class RepositoryDto extends HalRepresentation {
private String type;
protected Map properties;
- @Override
- @SuppressWarnings("squid:S1185") // We want to have this method available in this package
- protected HalRepresentation add(Links links) {
- return super.add(links);
+ RepositoryDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java
index 09683db488..fe8c2c19b1 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java
@@ -1,6 +1,5 @@
package sonia.scm.api.v2.resources;
-import com.fasterxml.jackson.annotation.JsonInclude;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
@@ -9,7 +8,6 @@ import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.Collection;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
index 19929b63ba..9e680b7e5c 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
@@ -1,11 +1,11 @@
package sonia.scm.api.v2.resources;
import com.google.inject.Inject;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Link;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.repository.Feature;
import sonia.scm.repository.HealthCheckFailure;
import sonia.scm.repository.Repository;
@@ -17,6 +17,7 @@ import sonia.scm.repository.api.ScmProtocol;
import java.util.List;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
import static java.util.stream.Collectors.toList;
@@ -33,17 +34,17 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper properties;
- @Override
- @SuppressWarnings("squid:S1185") // We want to have this method available in this package
- protected HalRepresentation add(Links links) {
- return super.add(links);
+ UserDto(Links links, Embedded embedded) {
+ super(links, embedded);
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserToUserDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserToUserDtoMapper.java
index 3c7e9fd7f1..ac641e3e66 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserToUserDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserToUserDtoMapper.java
@@ -1,10 +1,10 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
-import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
-import org.mapstruct.MappingTarget;
+import org.mapstruct.ObjectFactory;
import sonia.scm.security.PermissionPermissions;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
@@ -12,6 +12,7 @@ import sonia.scm.user.UserPermissions;
import javax.inject.Inject;
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
@@ -31,25 +32,26 @@ public abstract class UserToUserDtoMapper extends BaseMapper {
@Inject
private ResourceLinks resourceLinks;
- @AfterMapping
- protected void appendLinks(User user, @MappingTarget UserDto target) {
- Links.Builder linksBuilder = linkingTo().self(resourceLinks.user().self(target.getName()));
+ @ObjectFactory
+ UserDto createDto(User user) {
+ Links.Builder linksBuilder = linkingTo().self(resourceLinks.user().self(user.getName()));
if (UserPermissions.delete(user).isPermitted()) {
- linksBuilder.single(link("delete", resourceLinks.user().delete(target.getName())));
+ linksBuilder.single(link("delete", resourceLinks.user().delete(user.getName())));
}
if (UserPermissions.modify(user).isPermitted()) {
- linksBuilder.single(link("update", resourceLinks.user().update(target.getName())));
+ linksBuilder.single(link("update", resourceLinks.user().update(user.getName())));
if (userManager.isTypeDefault(user)) {
- linksBuilder.single(link("password", resourceLinks.user().passwordChange(target.getName())));
+ linksBuilder.single(link("password", resourceLinks.user().passwordChange(user.getName())));
}
}
if (PermissionPermissions.read().isPermitted()) {
- linksBuilder.single(link("permissions", resourceLinks.userPermissions().permissions(target.getName())));
+ linksBuilder.single(link("permissions", resourceLinks.userPermissions().permissions(user.getName())));
}
- appendLinks(new EdisonLinkAppender(linksBuilder), user);
+ Embedded.Builder embeddedBuilder = embeddedBuilder();
+ applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), user);
- target.add(linksBuilder.build());
+ return new UserDto(linksBuilder.build(), embeddedBuilder.build());
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
index afaa28bfe8..be5a1e7ac2 100644
--- a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
+++ b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
@@ -33,12 +33,9 @@ package sonia.scm.boot;
//~--- non-JDK imports --------------------------------------------------------
-import com.github.legman.Subscribe;
-
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
-import com.google.inject.servlet.GuiceFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java
index b77a927a2d..fc52ef4eff 100644
--- a/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java
+++ b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java
@@ -42,7 +42,6 @@ import org.slf4j.MDC;
import sonia.scm.SCMContext;
import sonia.scm.security.DefaultKeyGenerator;
-import sonia.scm.security.KeyGenerator;
import sonia.scm.web.filter.HttpFilter;
//~--- JDK imports ------------------------------------------------------------
diff --git a/scm-webapp/src/main/java/sonia/scm/filter/PropagatePrincipleFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/PropagatePrincipleFilter.java
index 508e804d1f..e7d020ae18 100644
--- a/scm-webapp/src/main/java/sonia/scm/filter/PropagatePrincipleFilter.java
+++ b/scm-webapp/src/main/java/sonia/scm/filter/PropagatePrincipleFilter.java
@@ -51,8 +51,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import static sonia.scm.api.v2.resources.ScmPathInfo.REST_API_PATH;
-
//~--- JDK imports ------------------------------------------------------------
/**
diff --git a/scm-webapp/src/main/java/sonia/scm/security/JwtAccessToken.java b/scm-webapp/src/main/java/sonia/scm/security/JwtAccessToken.java
index 64e26405a1..5b895a34fa 100644
--- a/scm-webapp/src/main/java/sonia/scm/security/JwtAccessToken.java
+++ b/scm-webapp/src/main/java/sonia/scm/security/JwtAccessToken.java
@@ -35,7 +35,6 @@ import io.jsonwebtoken.Claims;
import java.util.Collections;
import java.util.Date;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
diff --git a/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java b/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java
index 6b6b06aa9c..1fab500d79 100644
--- a/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java
+++ b/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java
@@ -1,7 +1,5 @@
package sonia.scm.security;
-import org.apache.commons.collections.CollectionUtils;
-
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
@@ -33,8 +31,9 @@ public class RepositoryRole {
if (this == o) return true;
if (!(o instanceof RepositoryRole)) return false;
RepositoryRole that = (RepositoryRole) o;
- return name.equals(that.name) &&
- CollectionUtils.isEqualCollection(this.verbs, that.verbs);
+ return name.equals(that.name)
+ && this.verbs.containsAll(that.verbs)
+ && this.verbs.size() == that.verbs.size();
}
@Override
diff --git a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java
index 77683bd6be..e58945a346 100644
--- a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java
+++ b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java
@@ -17,9 +17,6 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
-import static sonia.scm.util.HttpUtil.AUTHENTICATION_REALM;
-import static sonia.scm.util.HttpUtil.HEADER_WWW_AUTHENTICATE;
-
@Priority(Filters.PRIORITY_AUTHENTICATION)
@WebElement(value = HttpProtocolServlet.PATTERN)
public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter {
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
index 696174d6e0..fd9745be83 100644
--- 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
@@ -21,7 +21,7 @@ import java.util.Comparator;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/JsonFiltersTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/JsonFiltersTest.java
index b60775a73b..8bdbacafc2 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/JsonFiltersTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/JsonFiltersTest.java
@@ -3,7 +3,6 @@ package sonia.scm.api.v2;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import org.junit.Test;
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java
index 4994c11b08..9216922e19 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java
@@ -82,7 +82,7 @@ public class BranchRootResourceTest extends RepositoryTestBase {
@InjectMocks
- private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
+ private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapperTest.java
index d2e202576a..3e64ab95b6 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapperTest.java
@@ -24,12 +24,12 @@ class BranchToBranchDtoMapperTest {
@Test
void shouldAppendLinks() {
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
registry.register(Branch.class, (ctx, appender) -> {
NamespaceAndName namespaceAndName = ctx.oneRequireByType(NamespaceAndName.class);
Branch branch = ctx.oneRequireByType(Branch.class);
- appender.appendOne("ka", "http://" + namespaceAndName.logString() + "/" + branch.getName());
+ appender.appendLink("ka", "http://" + namespaceAndName.logString() + "/" + branch.getName());
});
mapper.setRegistry(registry);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java
index 69695279e6..7653fbe122 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperTest.java
@@ -1,6 +1,5 @@
package sonia.scm.api.v2.resources;
-import org.assertj.core.api.Assertions;
import org.junit.Test;
import sonia.scm.PageResult;
import sonia.scm.repository.Changeset;
@@ -17,7 +16,7 @@ public class ChangesetCollectionToDtoMapperTest {
public static final Repository REPOSITORY = new Repository("", "git", "space", "name");
public static final Changeset CHANGESET = new Changeset();
- private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper = mock(ChangesetToChangesetDtoMapper.class);
+ private final DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper = mock(DefaultChangesetToChangesetDtoMapperImpl.class);
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, ResourceLinksMock.createMock(URI.create("/")));
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 d5c0f91f81..952c8504f6 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
@@ -65,7 +65,7 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
@InjectMocks
- private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
+ private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private ChangesetRootResource changesetRootResource;
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ConfigResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ConfigResourceTest.java
index 4fb25d2371..66689c6ac6 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ConfigResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ConfigResourceTest.java
@@ -18,6 +18,7 @@ import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -68,7 +69,7 @@ public class ConfigResourceTest {
@Test
@SubjectAware(username = "readOnly")
- public void shouldGetGlobalConfig() throws URISyntaxException {
+ public void shouldGetGlobalConfig() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + ConfigResource.CONFIG_PATH_V2);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonHalAppenderTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonHalAppenderTest.java
new file mode 100644
index 0000000000..ff149c5dc5
--- /dev/null
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonHalAppenderTest.java
@@ -0,0 +1,61 @@
+package sonia.scm.api.v2.resources;
+
+import de.otto.edison.hal.Embedded;
+import de.otto.edison.hal.HalRepresentation;
+import de.otto.edison.hal.Link;
+import de.otto.edison.hal.Links;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
+import static de.otto.edison.hal.Links.linkingTo;
+import static org.assertj.core.api.Assertions.assertThat;
+
+class EdisonHalAppenderTest {
+
+ private Links.Builder linksBuilder;
+ private Embedded.Builder embeddedBuilder;
+ private EdisonHalAppender appender;
+
+ @BeforeEach
+ void prepare() {
+ linksBuilder = linkingTo();
+ embeddedBuilder = embeddedBuilder();
+ appender = new EdisonHalAppender(linksBuilder, embeddedBuilder);
+ }
+
+ @Test
+ void shouldAppendOneLink() {
+ appender.appendLink("self", "https://scm.hitchhiker.com");
+
+ Links links = linksBuilder.build();
+ assertThat(links.getLinkBy("self").get().getHref()).isEqualTo("https://scm.hitchhiker.com");
+ }
+
+ @Test
+ void shouldAppendMultipleLinks() {
+ appender.linkArrayBuilder("items")
+ .append("one", "http://one")
+ .append("two", "http://two")
+ .build();
+
+ List items = linksBuilder.build().getLinksBy("items");
+ assertThat(items).hasSize(2);
+ }
+
+ @Test
+ void shouldAppendEmbedded() {
+ HalRepresentation one = new HalRepresentation();
+ appender.appendEmbedded("one", one);
+
+ HalRepresentation two = new HalRepresentation();
+ appender.appendEmbedded("two", new HalRepresentation());
+
+ Embedded embedded = embeddedBuilder.build();
+ assertThat(embedded.getItemsBy("one")).containsOnly(one);
+ assertThat(embedded.getItemsBy("two")).containsOnly(two);
+ }
+
+}
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonLinkAppenderTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonLinkAppenderTest.java
deleted file mode 100644
index e97415cc09..0000000000
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/EdisonLinkAppenderTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package sonia.scm.api.v2.resources;
-
-import de.otto.edison.hal.Link;
-import de.otto.edison.hal.Links;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-
-import static de.otto.edison.hal.Links.linkingTo;
-import static org.assertj.core.api.Assertions.assertThat;
-
-class EdisonLinkAppenderTest {
-
- private Links.Builder builder;
- private EdisonLinkAppender appender;
-
- @BeforeEach
- void prepare() {
- builder = linkingTo();
- appender = new EdisonLinkAppender(builder);
- }
-
- @Test
- void shouldAppendOneLink() {
- appender.appendOne("self", "https://scm.hitchhiker.com");
-
- Links links = builder.build();
- assertThat(links.getLinkBy("self").get().getHref()).isEqualTo("https://scm.hitchhiker.com");
- }
-
- @Test
- void shouldAppendMultipleLinks() {
- appender.arrayBuilder("items")
- .append("one", "http://one")
- .append("two", "http://two")
- .build();
-
- List items = builder.build().getLinksBy("items");
- assertThat(items).hasSize(2);
- }
-
-}
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 52c9a434c0..a8b3c15158 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
@@ -66,7 +66,7 @@ public class FileHistoryResourceTest extends RepositoryTestBase {
private FileHistoryCollectionToDtoMapper fileHistoryCollectionToDtoMapper;
@InjectMocks
- private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
+ private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private FileHistoryRootResource fileHistoryRootResource;
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java
index b25410210f..55058a1684 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java
@@ -73,13 +73,13 @@ public class FileObjectToFileObjectDtoMapperTest {
@Test
public void shouldAppendLinks() {
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
registry.register(FileObject.class, (ctx, appender) -> {
NamespaceAndName repository = ctx.oneRequireByType(NamespaceAndName.class);
FileObject fo = ctx.oneRequireByType(FileObject.class);
String rev = ctx.oneRequireByType(String.class);
- appender.appendOne("hog", "http://" + repository.logString() + "/" + fo.getName() + "/" + rev);
+ appender.appendLink("hog", "http://" + repository.logString() + "/" + fo.getName() + "/" + rev);
});
mapper.setRegistry(registry);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java
index 646e9d0839..3e2d0f9663 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java
@@ -24,6 +24,7 @@ import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -100,7 +101,7 @@ public class GroupRootResourceTest {
}
@Test
- public void shouldGetGroup() throws URISyntaxException {
+ public void shouldGetGroup() throws URISyntaxException, UnsupportedEncodingException {
Group group = createDummyGroup();
when(groupManager.get("admin")).thenReturn(group);
@@ -305,7 +306,7 @@ public class GroupRootResourceTest {
}
@Test
- public void shouldGetAll() throws URISyntaxException {
+ public void shouldGetAll() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2);
MockHttpResponse response = new MockHttpResponse();
@@ -317,7 +318,7 @@ public class GroupRootResourceTest {
}
@Test
- public void shouldGetPermissionLink() throws URISyntaxException {
+ public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2 + "admin");
MockHttpResponse response = new MockHttpResponse();
@@ -329,7 +330,7 @@ public class GroupRootResourceTest {
}
@Test
- public void shouldGetPermissions() throws URISyntaxException {
+ public void shouldGetPermissions() throws URISyntaxException, UnsupportedEncodingException {
when(permissionAssigner.readPermissionsForGroup("admin")).thenReturn(singletonList(new PermissionDescriptor("something:*")));
MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2 + "admin/permissions");
MockHttpResponse response = new MockHttpResponse();
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapperTest.java
index b681dff21f..045124ad91 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupToGroupDtoMapperTest.java
@@ -11,7 +11,6 @@ import org.mockito.InjectMocks;
import sonia.scm.group.Group;
import java.net.URI;
-import java.net.URISyntaxException;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
@@ -91,10 +90,10 @@ public class GroupToGroupDtoMapperTest {
@Test
public void shouldAppendLinks() {
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
registry.register(Group.class, (ctx, appender) -> {
Group group = ctx.oneRequireByType(Group.class);
- appender.appendOne("some", "http://" + group.getName());
+ appender.appendLink("some", "http://" + group.getName());
});
mapper.setRegistry(registry);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/HalEnricherAutoRegistrationTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/HalEnricherAutoRegistrationTest.java
new file mode 100644
index 0000000000..314dcf11c2
--- /dev/null
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/HalEnricherAutoRegistrationTest.java
@@ -0,0 +1,64 @@
+package sonia.scm.api.v2.resources;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.assertj.core.api.Java6Assertions.assertThat;
+
+class HalEnricherAutoRegistrationTest {
+
+ @Test
+ void shouldRegisterAllAvailableLinkEnrichers() {
+ HalEnricher one = new One();
+ HalEnricher two = new Two();
+ HalEnricher three = new Three();
+ HalEnricher four = new Four();
+ Set enrichers = ImmutableSet.of(one, two, three, four);
+
+ HalEnricherRegistry registry = new HalEnricherRegistry();
+
+ LinkEnricherAutoRegistration autoRegistration = new LinkEnricherAutoRegistration(registry, enrichers);
+ autoRegistration.contextInitialized(null);
+
+ assertThat(registry.allByType(String.class)).containsOnly(one, two);
+ assertThat(registry.allByType(Integer.class)).containsOnly(three);
+ }
+
+ @Enrich(String.class)
+ public static class One implements HalEnricher {
+
+ @Override
+ public void enrich(HalEnricherContext context, HalAppender appender) {
+
+ }
+ }
+
+ @Enrich(String.class)
+ public static class Two implements HalEnricher {
+
+ @Override
+ public void enrich(HalEnricherContext context, HalAppender appender) {
+
+ }
+ }
+
+ @Enrich(Integer.class)
+ public static class Three implements HalEnricher {
+
+ @Override
+ public void enrich(HalEnricherContext context, HalAppender appender) {
+
+ }
+ }
+
+ public static class Four implements HalEnricher {
+
+ @Override
+ public void enrich(HalEnricherContext context, HalAppender appender) {
+
+ }
+ }
+
+}
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java
index e4495a0455..b965c2f2c3 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java
@@ -74,7 +74,7 @@ public class IncomingRootResourceTest extends RepositoryTestBase {
private IncomingChangesetCollectionToDtoMapper incomingChangesetCollectionToDtoMapper;
@InjectMocks
- private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
+ private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private IncomingRootResource incomingRootResource;
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistrationTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistrationTest.java
deleted file mode 100644
index a2b72abc49..0000000000
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistrationTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package sonia.scm.api.v2.resources;
-
-import com.google.common.collect.ImmutableSet;
-import org.junit.jupiter.api.Test;
-
-import java.util.Set;
-
-import static org.assertj.core.api.Java6Assertions.assertThat;
-
-class LinkEnricherAutoRegistrationTest {
-
- @Test
- void shouldRegisterAllAvailableLinkEnrichers() {
- LinkEnricher one = new One();
- LinkEnricher two = new Two();
- LinkEnricher three = new Three();
- LinkEnricher four = new Four();
- Set enrichers = ImmutableSet.of(one, two, three, four);
-
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
-
- LinkEnricherAutoRegistration autoRegistration = new LinkEnricherAutoRegistration(registry, enrichers);
- autoRegistration.contextInitialized(null);
-
- assertThat(registry.allByType(String.class)).containsOnly(one, two);
- assertThat(registry.allByType(Integer.class)).containsOnly(three);
- }
-
- @Enrich(String.class)
- public static class One implements LinkEnricher {
-
- @Override
- public void enrich(LinkEnricherContext context, LinkAppender appender) {
-
- }
- }
-
- @Enrich(String.class)
- public static class Two implements LinkEnricher {
-
- @Override
- public void enrich(LinkEnricherContext context, LinkAppender appender) {
-
- }
- }
-
- @Enrich(Integer.class)
- public static class Three implements LinkEnricher {
-
- @Override
- public void enrich(LinkEnricherContext context, LinkAppender appender) {
-
- }
- }
-
- public static class Four implements LinkEnricher {
-
- @Override
- public void enrich(LinkEnricherContext context, LinkAppender appender) {
-
- }
- }
-
-}
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeDtoFactoryTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeDtoFactoryTest.java
index 138387938b..8a00c69229 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeDtoFactoryTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeDtoFactoryTest.java
@@ -15,7 +15,6 @@ import org.mockito.quality.Strictness;
import sonia.scm.group.GroupNames;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
-import sonia.scm.user.UserPermissions;
import sonia.scm.user.UserTestData;
import java.net.URI;
@@ -170,12 +169,12 @@ class MeDtoFactoryTest {
void shouldAppendLinks() {
prepareSubject(UserTestData.createTrillian());
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
meDtoFactory.setRegistry(registry);
registry.register(Me.class, (ctx, appender) -> {
User user = ctx.oneRequireByType(User.class);
- appender.appendOne("profile", "http://hitchhiker.com/users/" + user.getName());
+ appender.appendLink("profile", "http://hitchhiker.com/users/" + user.getName());
});
MeDto dto = meDtoFactory.create();
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java
index 052a059959..cd2a172c1b 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java
@@ -22,12 +22,12 @@ import sonia.scm.user.UserManager;
import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
@@ -78,7 +78,7 @@ public class MeResourceTest {
}
@Test
- public void shouldReturnCurrentlyAuthenticatedUser() throws URISyntaxException {
+ public void shouldReturnCurrentlyAuthenticatedUser() throws URISyntaxException, UnsupportedEncodingException {
applyUserToSubject(originalUser);
MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java
index 2795562b14..4472acb2c5 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java
@@ -36,6 +36,7 @@ import sonia.scm.repository.RepositoryPermission;
import sonia.scm.web.VndMediaType;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
@@ -53,7 +54,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
@@ -214,7 +215,12 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
.expectedResponseStatus(200)
.path(PATH_OF_ALL_PERMISSIONS + expectedPermission.getName())
.responseValidator((response) -> {
- String body = response.getContentAsString();
+ String body = null;
+ try {
+ body = response.getContentAsString();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
ObjectMapper mapper = new ObjectMapper();
try {
RepositoryPermissionDto actualRepositoryPermissionDto = mapper.readValue(body, RepositoryPermissionDto.class);
@@ -268,13 +274,21 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
assertExpectedRequest(requestPOSTPermission
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"verbs\" : [\"read\",\"pull\",\"push\"], \"groupPermission\" : true}")
.expectedResponseStatus(201)
- .responseValidator(response -> assertThat(response.getContentAsString())
+ .responseValidator(response -> assertThat(getContentAsString(response))
.as("POST response has no body")
.isBlank())
);
assertGettingExpectedPermissions(expectedPermissions, PERMISSION_WRITE);
}
+ private String getContentAsString(MockHttpResponse response) {
+ try {
+ return response.getContentAsString();
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("could not get content from response", e);
+ }
+ }
+
@Test
public void shouldNotAddExistingPermission() throws URISyntaxException {
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
@@ -296,7 +310,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
.content("{\"name\" : \"" + modifiedPermission.getName() + "\" , \"verbs\" : [\"*\"], \"groupPermission\" : false}")
.path(PATH_OF_ALL_PERMISSIONS + modifiedPermission.getName())
.expectedResponseStatus(204)
- .responseValidator(response -> assertThat(response.getContentAsString())
+ .responseValidator(response -> assertThat(getContentAsString(response))
.as("PUT response has no body")
.isBlank())
);
@@ -312,7 +326,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
assertExpectedRequest(requestDELETEPermission
.path(PATH_OF_ALL_PERMISSIONS + deletedPermission.getName())
.expectedResponseStatus(204)
- .responseValidator(response -> assertThat(response.getContentAsString())
+ .responseValidator(response -> assertThat(getContentAsString(response))
.as("DELETE response has no body")
.isBlank())
);
@@ -327,7 +341,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
assertExpectedRequest(requestDELETEPermission
.path(PATH_OF_ALL_PERMISSIONS + deletedPermission.getName())
.expectedResponseStatus(204)
- .responseValidator(response -> assertThat(response.getContentAsString())
+ .responseValidator(response -> assertThat(getContentAsString(response))
.as("DELETE response has no body")
.isBlank())
);
@@ -335,7 +349,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
assertExpectedRequest(requestDELETEPermission
.path(PATH_OF_ALL_PERMISSIONS + deletedPermission.getName())
.expectedResponseStatus(204)
- .responseValidator(response -> assertThat(response.getContentAsString())
+ .responseValidator(response -> assertThat(getContentAsString(response))
.as("DELETE response has no body")
.isBlank())
);
@@ -346,7 +360,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
assertExpectedRequest(requestGETAllPermissions
.expectedResponseStatus(200)
.responseValidator((response) -> {
- String body = response.getContentAsString();
+ String body = getContentAsString(response);
ObjectMapper mapper = new ObjectMapper();
try {
HalRepresentation halRepresentation = mapper.readValue(body, HalRepresentation.class);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
index bf4366f0b2..1f6ed6b3a7 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
@@ -27,6 +27,7 @@ import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -41,9 +42,9 @@ import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -120,7 +121,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
}
@Test
- public void shouldFindExistingRepository() throws URISyntaxException {
+ public void shouldFindExistingRepository() throws URISyntaxException, UnsupportedEncodingException {
mockRepository("space", "repo");
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
@@ -133,7 +134,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
}
@Test
- public void shouldMapProperties() throws URISyntaxException {
+ public void shouldMapProperties() throws URISyntaxException, UnsupportedEncodingException {
Repository repository = mockRepository("space", "repo");
repository.setProperty("testKey", "testValue");
@@ -146,7 +147,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
}
@Test
- public void shouldGetAll() throws URISyntaxException {
+ public void shouldGetAll() throws URISyntaxException, UnsupportedEncodingException {
PageResult singletonPageResult = createSingletonPageResult(mockRepository("space", "repo"));
when(repositoryManager.getPage(any(), eq(0), eq(10))).thenReturn(singletonPageResult);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java
index 8469e966c8..4b02508ae8 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapperTest.java
@@ -23,7 +23,7 @@ import static java.util.stream.Stream.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -211,10 +211,10 @@ public class RepositoryToRepositoryDtoMapperTest {
@Test
public void shouldAppendLinks() {
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
registry.register(Repository.class, (ctx, appender) -> {
Repository repository = ctx.oneRequireByType(Repository.class);
- appender.appendOne("id", "http://" + repository.getId());
+ appender.appendLink("id", "http://" + repository.getId());
});
mapper.setRegistry(registry);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java
index aa8eb3e7ab..cd3c18de27 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java
@@ -22,11 +22,11 @@ class TagToTagDtoMapperTest {
@Test
void shouldAppendLinks() {
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
+ HalEnricherRegistry registry = new HalEnricherRegistry();
registry.register(Tag.class, (ctx, appender) -> {
NamespaceAndName repository = ctx.oneRequireByType(NamespaceAndName.class);
Tag tag = ctx.oneRequireByType(Tag.class);
- appender.appendOne("yo", "http://" + repository.logString() + "/" + tag.getName());
+ appender.appendLink("yo", "http://" + repository.logString() + "/" + tag.getName());
});
mapper.setRegistry(registry);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UIRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UIRootResourceTest.java
index 99a1435923..b2dafc8cfe 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UIRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UIRootResourceTest.java
@@ -16,6 +16,7 @@ import sonia.scm.plugin.*;
import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
@@ -87,7 +88,7 @@ public class UIRootResourceTest {
}
@Test
- public void shouldReturnPlugin() throws URISyntaxException {
+ public void shouldReturnPlugin() throws URISyntaxException, UnsupportedEncodingException {
mockPlugins(mockPlugin("awesome", "Awesome", createPluginResources("my/awesome.bundle.js")));
MockHttpRequest request = MockHttpRequest.get("/v2/ui/plugins/awesome");
@@ -101,7 +102,7 @@ public class UIRootResourceTest {
}
@Test
- public void shouldReturnPlugins() throws URISyntaxException {
+ public void shouldReturnPlugins() throws URISyntaxException, UnsupportedEncodingException {
mockPlugins(
mockPlugin("awesome", "Awesome", createPluginResources("my/awesome.bundle.js")),
mockPlugin("special", "Special", createPluginResources("my/special.bundle.js"))
@@ -120,7 +121,7 @@ public class UIRootResourceTest {
}
@Test
- public void shouldNotReturnPluginsWithoutResources() throws URISyntaxException {
+ public void shouldNotReturnPluginsWithoutResources() throws URISyntaxException, UnsupportedEncodingException {
mockPlugins(
mockPlugin("awesome", "Awesome", createPluginResources("my/awesome.bundle.js")),
mockPlugin("special")
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserDtoToUserMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserDtoToUserMapperTest.java
index 19f247b3b2..552009b73f 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserDtoToUserMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserDtoToUserMapperTest.java
@@ -10,7 +10,6 @@ import sonia.scm.user.User;
import java.time.Instant;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
public class UserDtoToUserMapperTest {
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java
index 88142e4d50..4047dfadd2 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java
@@ -14,7 +14,6 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.Spy;
import sonia.scm.ContextEntry;
import sonia.scm.NotFoundException;
import sonia.scm.PageResult;
@@ -26,6 +25,7 @@ import sonia.scm.user.UserManager;
import sonia.scm.web.VndMediaType;
import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -35,8 +35,8 @@ import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
@@ -76,7 +76,7 @@ public class UserRootResourceTest {
private User originalUser;
@Before
- public void prepareEnvironment() throws Exception {
+ public void prepareEnvironment() {
initMocks(this);
originalUser = createDummyUser("Neo");
when(userManager.create(userCaptor.capture())).thenAnswer(invocation -> invocation.getArguments()[0]);
@@ -97,7 +97,7 @@ public class UserRootResourceTest {
}
@Test
- public void shouldCreateFullResponseForAdmin() throws URISyntaxException {
+ public void shouldCreateFullResponseForAdmin() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo");
MockHttpResponse response = new MockHttpResponse();
@@ -137,7 +137,7 @@ public class UserRootResourceTest {
@Test
@SubjectAware(username = "unpriv")
- public void shouldCreateLimitedResponseForSimpleUser() throws URISyntaxException {
+ public void shouldCreateLimitedResponseForSimpleUser() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo");
MockHttpResponse response = new MockHttpResponse();
@@ -331,7 +331,7 @@ public class UserRootResourceTest {
}
@Test
- public void shouldCreatePageForOnePageOnly() throws URISyntaxException {
+ public void shouldCreatePageForOnePageOnly() throws URISyntaxException, UnsupportedEncodingException {
PageResult singletonPageResult = createSingletonPageResult(1);
when(userManager.getPage(any(), eq(0), eq(10))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2);
@@ -347,7 +347,7 @@ public class UserRootResourceTest {
}
@Test
- public void shouldCreatePageForMultiplePages() throws URISyntaxException {
+ public void shouldCreatePageForMultiplePages() throws URISyntaxException, UnsupportedEncodingException {
PageResult singletonPageResult = createSingletonPageResult(3);
when(userManager.getPage(any(), eq(1), eq(1))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "?page=1&pageSize=1");
@@ -365,7 +365,7 @@ public class UserRootResourceTest {
}
@Test
- public void shouldGetPermissionLink() throws URISyntaxException {
+ public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo");
MockHttpResponse response = new MockHttpResponse();
@@ -377,7 +377,7 @@ public class UserRootResourceTest {
}
@Test
- public void shouldGetPermissions() throws URISyntaxException {
+ public void shouldGetPermissions() throws URISyntaxException, UnsupportedEncodingException {
when(permissionAssigner.readPermissionsForUser("Neo")).thenReturn(singletonList(new PermissionDescriptor("something:*")));
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo/permissions");
MockHttpResponse response = new MockHttpResponse();
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserToUserDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserToUserDtoMapperTest.java
index 9924dae81b..ae1d75dddf 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserToUserDtoMapperTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserToUserDtoMapperTest.java
@@ -155,8 +155,8 @@ public class UserToUserDtoMapperTest {
public void shouldAppendLink() {
User trillian = UserTestData.createTrillian();
- LinkEnricherRegistry registry = new LinkEnricherRegistry();
- registry.register(User.class, (ctx, appender) -> appender.appendOne("sample", "http://" + ctx.oneByType(User.class).get().getName()));
+ HalEnricherRegistry registry = new HalEnricherRegistry();
+ registry.register(User.class, (ctx, appender) -> appender.appendLink("sample", "http://" + ctx.oneByType(User.class).get().getName()));
mapper.setRegistry(registry);
UserDto userDto = mapper.map(trillian);
diff --git a/scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java b/scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java
index b8b538c82b..eac4a12340 100644
--- a/scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java
@@ -2,7 +2,6 @@ package sonia.scm.boot;
import com.github.legman.Subscribe;
import com.google.common.base.Charsets;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
diff --git a/scm-webapp/src/test/java/sonia/scm/boot/ServletContextCleanerTest.java b/scm-webapp/src/test/java/sonia/scm/boot/ServletContextCleanerTest.java
index a26cf3b215..c9d8c594b4 100644
--- a/scm-webapp/src/test/java/sonia/scm/boot/ServletContextCleanerTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/boot/ServletContextCleanerTest.java
@@ -13,7 +13,6 @@ import java.util.Enumeration;
import java.util.Set;
import java.util.Vector;
-import static org.junit.Assert.*;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java
index 8cdb162740..a367d171a1 100644
--- a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java
+++ b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java
@@ -136,10 +136,13 @@ public class GitLfsITCase {
}
private void createUser(User user) {
- UserDto dto = new UserToUserDtoMapperImpl(){
- @Override
- protected void appendLinks(User user, UserDto target) {}
- }.map(user);
+ UserDto dto = new UserDto();
+ dto.setName(user.getName());
+ dto.setMail(user.getMail());
+ dto.setDisplayName(user.getDisplayName());
+ dto.setType(user.getType());
+ dto.setActive(user.isActive());
+ dto.setAdmin(user.isAdmin());
dto.setPassword(user.getPassword());
createResource(adminClient, "users")
.accept("*/*")
diff --git a/scm-webapp/src/test/java/sonia/scm/net/ahc/DefaultAdvancedHttpResponseTest.java b/scm-webapp/src/test/java/sonia/scm/net/ahc/DefaultAdvancedHttpResponseTest.java
index a60c884b64..399f20cd3f 100644
--- a/scm-webapp/src/test/java/sonia/scm/net/ahc/DefaultAdvancedHttpResponseTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/net/ahc/DefaultAdvancedHttpResponseTest.java
@@ -41,6 +41,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.io.ByteSource;
+import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,8 +50,6 @@ import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.config.ScmConfiguration;
-import static org.hamcrest.Matchers.*;
-
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@@ -136,7 +135,7 @@ public class DefaultAdvancedHttpResponseTest
connection, 200, "OK");
Multimap headers = response.getHeaders();
- assertThat(headers.get("Test"), contains("One", "Two"));
+ assertThat(headers.get("Test"), Matchers.contains("One", "Two"));
assertTrue(headers.get("Test-2").isEmpty());
}
@@ -144,8 +143,7 @@ public class DefaultAdvancedHttpResponseTest
/** Field description */
private final DefaultAdvancedHttpClient client =
- new DefaultAdvancedHttpClient(new ScmConfiguration(),
- new HashSet(), new SSLContextProvider());
+ new DefaultAdvancedHttpClient(new ScmConfiguration(), new HashSet<>(), new SSLContextProvider());
/** Field description */
@Mock
diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/MultiParentClassLoaderTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/MultiParentClassLoaderTest.java
index ae65f5c1ae..df31977de1 100644
--- a/scm-webapp/src/test/java/sonia/scm/plugin/MultiParentClassLoaderTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/plugin/MultiParentClassLoaderTest.java
@@ -29,9 +29,6 @@
package sonia.scm.plugin;
-import com.google.common.base.Enums;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
diff --git a/scm-webapp/src/test/java/sonia/scm/schedule/QuartzTaskTest.java b/scm-webapp/src/test/java/sonia/scm/schedule/QuartzTaskTest.java
index efaeb702fe..baf4c659cc 100644
--- a/scm-webapp/src/test/java/sonia/scm/schedule/QuartzTaskTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/schedule/QuartzTaskTest.java
@@ -32,12 +32,11 @@
package sonia.scm.schedule;
import org.junit.Test;
-import static org.junit.Assert.*;
+
import static org.mockito.Mockito.*;
-import static org.hamcrest.Matchers.*;
+
import org.junit.Before;
import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.quartz.JobKey;
diff --git a/scm-webapp/src/test/java/sonia/scm/security/BearerRealmTest.java b/scm-webapp/src/test/java/sonia/scm/security/BearerRealmTest.java
index 5c7aa08f37..c2d75358fd 100644
--- a/scm-webapp/src/test/java/sonia/scm/security/BearerRealmTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/security/BearerRealmTest.java
@@ -33,18 +33,13 @@ package sonia.scm.security;
import com.google.common.collect.ImmutableSet;
import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
-import org.junit.Ignore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.stubbing.Answer;
import java.util.HashMap;
import java.util.Set;
@@ -52,7 +47,6 @@ import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
diff --git a/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java b/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java
index cce3fea2b1..f59991f2cc 100644
--- a/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java
@@ -47,7 +47,6 @@ import sonia.scm.store.ConfigurationEntryStoreFactory;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.in;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
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 8e261b75cc..ab31d751fd 100644
--- a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java
@@ -45,9 +45,6 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import sonia.scm.NotFoundException;
-import sonia.scm.repository.InitialRepositoryLocationResolver;
-import sonia.scm.repository.RepositoryDAO;
-import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.store.JAXBConfigurationStoreFactory;
import sonia.scm.user.xml.XmlUserDAO;
diff --git a/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java b/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java
index 29c7dea358..5f95a171d2 100644
--- a/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java
@@ -3,7 +3,7 @@ package sonia.scm.web.cgi;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.http.HttpServletRequest;
diff --git a/scm-webapp/src/test/java/sonia/scm/web/i18n/I18nServletTest.java b/scm-webapp/src/test/java/sonia/scm/web/i18n/I18nServletTest.java
index e028857e2c..bb3c7b5f1e 100644
--- a/scm-webapp/src/test/java/sonia/scm/web/i18n/I18nServletTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/web/i18n/I18nServletTest.java
@@ -35,8 +35,6 @@ import java.util.Enumeration;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.Silent.class)