diff --git a/scm-annotations/src/main/java/sonia/scm/api/v2/resources/Enrich.java b/scm-annotations/src/main/java/sonia/scm/api/v2/resources/Enrich.java new file mode 100644 index 0000000000..a1269dfc00 --- /dev/null +++ b/scm-annotations/src/main/java/sonia/scm/api/v2/resources/Enrich.java @@ -0,0 +1,26 @@ +package sonia.scm.api.v2.resources; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to specify the source of an enricher. + * + * @author Sebastian Sdorra + * @since 2.0.0 + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Enrich { + + /** + * Source mapping class. + * + * @return source mapping class + */ + Class value(); +} diff --git a/scm-core/src/main/java/sonia/scm/api/v2/resources/LinkEnricher.java b/scm-core/src/main/java/sonia/scm/api/v2/resources/LinkEnricher.java index b9cc3c5059..c16d6f6482 100644 --- a/scm-core/src/main/java/sonia/scm/api/v2/resources/LinkEnricher.java +++ b/scm-core/src/main/java/sonia/scm/api/v2/resources/LinkEnricher.java @@ -1,11 +1,18 @@ package sonia.scm.api.v2.resources; +import sonia.scm.plugin.ExtensionPoint; + /** * A {@link LinkEnricher} can be used to append hateoas links to a specific json response. + * To register an enricher use the {@link Enrich} annotation or the {@link LinkEnricherRegistry} which is available + * via injection. + * + * Warning: enrichers are always registered as singletons. * * @author Sebastian Sdorra * @since 2.0.0 */ +@ExtensionPoint @FunctionalInterface public interface LinkEnricher { 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 new file mode 100644 index 0000000000..890e268ed5 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistration.java @@ -0,0 +1,45 @@ +package sonia.scm.api.v2.resources; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.plugin.Extension; + +import javax.inject.Inject; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.Set; + +/** + * Registers every {@link LinkEnricher} 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; + + @Inject + public LinkEnricherAutoRegistration(LinkEnricherRegistry registry, Set enrichers) { + this.registry = registry; + this.enrichers = enrichers; + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + for (LinkEnricher 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()); + } + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // nothing todo + } +} 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 new file mode 100644 index 0000000000..a2b72abc49 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/LinkEnricherAutoRegistrationTest.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 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) { + + } + } + +}