From 8a65660278e75a700f51578a1745be9371b74c59 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Tue, 14 Sep 2021 09:26:47 +0200 Subject: [PATCH] Auto mapper binding (#1807) Bind mapper implementations automatically to related mappers using the annotation processor. With this change it is not longer required to bind mapper explicitly using mapper modules which reduces some boilerplate code. --- gradle/changelog/auto_mapper_binding.yaml | 2 + scm-annotation-processor/build.gradle | 3 + .../annotation/ScmAnnotationProcessor.java | 36 +--- .../main/java/sonia/scm/plugin/ScmModule.java | 154 ++++---------- .../scm/api/v2/resources/MapperModule.java | 55 +---- .../sonia/scm/plugin/ExtensionBinder.java | 111 ++++------ .../sonia/scm/plugin/ExtensionCollector.java | 195 ++++-------------- 7 files changed, 133 insertions(+), 423 deletions(-) create mode 100644 gradle/changelog/auto_mapper_binding.yaml diff --git a/gradle/changelog/auto_mapper_binding.yaml b/gradle/changelog/auto_mapper_binding.yaml new file mode 100644 index 0000000000..77148546f6 --- /dev/null +++ b/gradle/changelog/auto_mapper_binding.yaml @@ -0,0 +1,2 @@ +- type: Changed + description: Bind mappers automatically to mapper implementations ([#1807](https://github.com/scm-manager/scm-manager/pull/1807)) diff --git a/scm-annotation-processor/build.gradle b/scm-annotation-processor/build.gradle index c10d1c1077..721577db36 100644 --- a/scm-annotation-processor/build.gradle +++ b/scm-annotation-processor/build.gradle @@ -37,6 +37,9 @@ dependencies { // rest api implementation libraries.jaxRs + // mapper + implementation libraries.mapstruct + // events implementation libraries.legman diff --git a/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java b/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java index ab5cb51349..ca7ad63f86 100644 --- a/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java +++ b/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java @@ -24,46 +24,26 @@ package sonia.scm.annotation; -//~--- non-JDK imports -------------------------------------------------------- - import com.github.legman.Subscribe; - import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; - import org.kohsuke.MetaInfServices; - +import org.mapstruct.Mapper; import org.w3c.dom.DOMException; import org.w3c.dom.Document; - import org.xml.sax.SAXException; - import sonia.scm.annotation.ClassSetElement.ClassWithAttributes; import sonia.scm.plugin.PluginAnnotation; import sonia.scm.plugin.Requires; -//~--- JDK imports ------------------------------------------------------------ - -import java.io.File; -import java.io.IOException; - -import java.lang.annotation.Annotation; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; - import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -72,14 +52,11 @@ import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; - import javax.tools.Diagnostic.Kind; import javax.tools.FileObject; import javax.tools.StandardLocation; - import javax.ws.rs.Path; import javax.ws.rs.ext.Provider; - import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -91,6 +68,14 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import static javax.lang.model.util.ElementFilter.methodsIn; @@ -112,7 +97,8 @@ public final class ScmAnnotationProcessor extends AbstractProcessor { ImmutableSet.of(Subscribe.class.getName()); private static final Set CLASS_ANNOTATIONS = ImmutableSet.of(new ClassAnnotation("rest-resource", Path.class), - new ClassAnnotation("rest-provider", Provider.class)); + new ClassAnnotation("rest-provider", Provider.class), + new ClassAnnotation("mapper", Mapper.class)); @Override public boolean process(Set annotations, diff --git a/scm-core/src/main/java/sonia/scm/plugin/ScmModule.java b/scm-core/src/main/java/sonia/scm/plugin/ScmModule.java index 9d98254ffd..7038ff7251 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/ScmModule.java +++ b/scm-core/src/main/java/sonia/scm/plugin/ScmModule.java @@ -24,8 +24,6 @@ package sonia.scm.plugin; -//~--- non-JDK imports -------------------------------------------------------- - import com.google.common.collect.ImmutableSet; import javax.xml.bind.annotation.XmlAccessType; @@ -34,93 +32,70 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.Set; -//~--- JDK imports ------------------------------------------------------------ - /** - * * @author Sebastian Sdorra * @since 2.0.0 */ @XmlRootElement(name = "module") @XmlAccessorType(XmlAccessType.FIELD) -public class ScmModule -{ - //~--- get methods ---------------------------------------------------------- +public class ScmModule { - /** - * Method description - * - * - * @return - */ - public Iterable getEvents() - { + @XmlElement(name = "indexed-type") + private Set indexedTypes; + + @XmlElement(name = "event") + private Set events; + + @XmlElement(name = "extension-point") + private Set extensionPoints; + + @XmlElement(name = "extension") + private Set extensions; + + @XmlElement(name = "rest-provider") + private Set restProviders; + + @XmlElement(name = "rest-resource") + private Set restResources; + + @XmlElement(name = "mapper") + private Set mappers; + + @XmlElement(name = "subscriber") + private Set subscribers; + + @XmlElement(name = "web-element") + private Set webElements; + + public Iterable getEvents() { return nonNull(events); } - /** - * Method description - * - * - * @return - */ - public Iterable getExtensionPoints() - { + public Iterable getExtensionPoints() { return nonNull(extensionPoints); } - /** - * Method description - * - * - * @return - */ - public Iterable getExtensions() - { + public Iterable getExtensions() { return nonNull(extensions); } - /** - * Method description - * - * - * @return - */ - public Iterable getRestProviders() - { + public Iterable getRestProviders() { return nonNull(restProviders); } - /** - * Method description - * - * - * @return - */ - public Iterable getRestResources() - { + public Iterable getRestResources() { return nonNull(restResources); } - /** - * Method description - * - * - * @return - */ - public Iterable getSubscribers() - { + public Iterable getMappers() { + return nonNull(mappers); + } + + public Iterable getSubscribers() { return nonNull(subscribers); } - /** - * Method description - * - * - * @return - */ - public Iterable getWebElements() - { + public Iterable getWebElements() { return nonNull(webElements); } @@ -128,58 +103,11 @@ public class ScmModule return nonNull(indexedTypes); } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param iterable - * @param - * - * @return - */ - private Iterable nonNull(Iterable iterable) - { - if (iterable == null) - { + private Iterable nonNull(Iterable iterable) { + if (iterable == null) { iterable = ImmutableSet.of(); } return iterable; } - - - //~--- fields --------------------------------------------------------------- - - @XmlElement(name = "indexed-type") - private Set indexedTypes; - - /** Field description */ - @XmlElement(name = "event") - private Set events; - - /** Field description */ - @XmlElement(name = "extension-point") - private Set extensionPoints; - - /** Field description */ - @XmlElement(name = "extension") - private Set extensions; - - /** Field description */ - @XmlElement(name = "rest-provider") - private Set restProviders; - - /** Field description */ - @XmlElement(name = "rest-resource") - private Set restResources; - - /** Field description */ - @XmlElement(name = "subscriber") - private Set subscribers; - - /** Field description */ - @XmlElement(name = "web-element") - private Set webElements; } 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 6543b63862..a0fbf30393 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 @@ -27,73 +27,20 @@ package sonia.scm.api.v2.resources; import com.google.inject.AbstractModule; import com.google.inject.servlet.ServletScopes; import org.mapstruct.factory.Mappers; -import sonia.scm.security.gpg.PublicKeyMapper; import sonia.scm.web.api.RepositoryToHalMapper; public class MapperModule extends AbstractModule { @Override protected void configure() { - bind(UserDtoToUserMapper.class).to(Mappers.getMapperClass(UserDtoToUserMapper.class)); - bind(UserToUserDtoMapper.class).to(Mappers.getMapperClass(UserToUserDtoMapper.class)); - bind(UserCollectionToDtoMapper.class); - bind(PublicKeyMapper.class).to(Mappers.getMapperClass(PublicKeyMapper.class)); - - bind(GroupDtoToGroupMapper.class).to(Mappers.getMapperClass(GroupDtoToGroupMapper.class)); - bind(GroupToGroupDtoMapper.class).to(Mappers.getMapperClass(GroupToGroupDtoMapper.class)); - bind(GroupCollectionToDtoMapper.class); - - bind(ScmConfigurationToConfigDtoMapper.class).to(Mappers.getMapperClass(ScmConfigurationToConfigDtoMapper.class)); - bind(ConfigDtoToScmConfigurationMapper.class).to(Mappers.getMapperClass(ConfigDtoToScmConfigurationMapper.class)); - - bind(RepositoryToRepositoryDtoMapper.class).to(Mappers.getMapperClass(RepositoryToRepositoryDtoMapper.class)); - bind(RepositoryDtoToRepositoryMapper.class).to(Mappers.getMapperClass(RepositoryDtoToRepositoryMapper.class)); - - bind(RepositoryTypeToRepositoryTypeDtoMapper.class).to(Mappers.getMapperClass(RepositoryTypeToRepositoryTypeDtoMapper.class)); - bind(RepositoryTypeCollectionToDtoMapper.class); - - bind(BranchToBranchDtoMapper.class).to(Mappers.getMapperClass(BranchToBranchDtoMapper.class)); - bind(RepositoryPermissionDtoToRepositoryPermissionMapper.class).to(Mappers.getMapperClass(RepositoryPermissionDtoToRepositoryPermissionMapper.class)); - bind(RepositoryPermissionToRepositoryPermissionDtoMapper.class).to(Mappers.getMapperClass(RepositoryPermissionToRepositoryPermissionDtoMapper.class)); - - bind(RepositoryRoleToRepositoryRoleDtoMapper.class).to(Mappers.getMapperClass(RepositoryRoleToRepositoryRoleDtoMapper.class)); - bind(RepositoryRoleDtoToRepositoryRoleMapper.class).to(Mappers.getMapperClass(RepositoryRoleDtoToRepositoryRoleMapper.class)); - bind(RepositoryRoleCollectionToDtoMapper.class); - + // These mappers are special and cannot be bound automatically by the annotation processor bind(ChangesetToChangesetDtoMapper.class).to(Mappers.getMapperClass(DefaultChangesetToChangesetDtoMapper.class)); - bind(ChangesetToParentDtoMapper.class).to(Mappers.getMapperClass(ChangesetToParentDtoMapper.class)); - - bind(TagToTagDtoMapper.class).to(Mappers.getMapperClass(TagToTagDtoMapper.class)); - - bind(BrowserResultToFileObjectDtoMapper.class).to(Mappers.getMapperClass(BrowserResultToFileObjectDtoMapper.class)); - bind(ModificationsToDtoMapper.class).to(Mappers.getMapperClass(ModificationsToDtoMapper.class)); - - bind(ReducedObjectModelToDtoMapper.class).to(Mappers.getMapperClass(ReducedObjectModelToDtoMapper.class)); - - bind(ResteasyViolationExceptionToErrorDtoMapper.class).to(Mappers.getMapperClass(ResteasyViolationExceptionToErrorDtoMapper.class)); - bind(ScmViolationExceptionToErrorDtoMapper.class).to(Mappers.getMapperClass(ScmViolationExceptionToErrorDtoMapper.class)); - bind(ExceptionWithContextToErrorDtoMapper.class).to(Mappers.getMapperClass(ExceptionWithContextToErrorDtoMapper.class)); - bind(RepositoryToHalMapper.class).to(Mappers.getMapperClass(RepositoryToRepositoryDtoMapper.class)); - bind(BlameResultToBlameDtoMapper.class).to(Mappers.getMapperClass(BlameResultToBlameDtoMapper.class)); - bind(UpdateInfoMapper.class).to(Mappers.getMapperClass(UpdateInfoMapper.class)); - // no mapstruct required bind(MeDtoFactory.class); bind(UIPluginDtoMapper.class); bind(UIPluginDtoCollectionMapper.class); bind(ScmPathInfoStore.class).in(ServletScopes.REQUEST); - - bind(PluginDtoMapper.class).to(Mappers.getMapperClass(PluginDtoMapper.class)); - - bind(ApiKeyToApiKeyDtoMapper.class).to(Mappers.getMapperClass(ApiKeyToApiKeyDtoMapper.class)); - - bind(RepositoryExportInformationToDtoMapper.class).to(Mappers.getMapperClass(RepositoryExportInformationToDtoMapper.class)); - bind(RepositoryImportDtoToRepositoryImportParametersMapper.class).to(Mappers.getMapperClass(RepositoryImportDtoToRepositoryImportParametersMapper.class)); - - bind(QueryResultMapper.class).to(Mappers.getMapperClass(QueryResultMapper.class)); - bind(SearchableTypeMapper.class).to(Mappers.getMapperClass(SearchableTypeMapper.class)); - } } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionBinder.java b/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionBinder.java index 304a8499ff..302e91cdc4 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionBinder.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionBinder.java @@ -21,51 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - -package sonia.scm.plugin; -//~--- non-JDK imports -------------------------------------------------------- +package sonia.scm.plugin; import com.google.inject.Binder; import com.google.inject.Singleton; import com.google.inject.binder.AnnotatedBindingBuilder; import com.google.inject.binder.ScopedBindingBuilder; import com.google.inject.multibindings.Multibinder; - +import org.mapstruct.factory.Mappers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import sonia.scm.EagerSingleton; import sonia.scm.util.Util; /** - * * @author Sebastian Sdorra */ -@SuppressWarnings("unchecked") -public final class ExtensionBinder -{ +@SuppressWarnings({"unchecked", "rawtypes"}) +public final class ExtensionBinder { private static final String TYPE_LOOSE_EXT = "loose extension"; private static final String TYPE_REST_RESOURCE = "rest resource"; private static final String AS_EAGER_SINGLETON = " as eager singleton"; - /** - * the logger for ExtensionBinder - */ private static final Logger logger = LoggerFactory.getLogger(ExtensionBinder.class); - public ExtensionBinder(Binder binder) - { + public ExtensionBinder(Binder binder) { this.binder = binder; } - public void bind(ExtensionCollector collector) - { + public void bind(ExtensionCollector collector) { logger.debug("bind extensions to extension points"); - for (ExtensionPointElement epe : collector.getExtensionPointElements()) - { + for (ExtensionPointElement epe : collector.getExtensionPointElements()) { bindExtensionPoint(collector, epe); } @@ -75,63 +64,49 @@ public final class ExtensionBinder bindRestProviders(collector.getRestProviders()); logger.debug("bind rest resources"); bindRestResource(collector.getRestResources()); + logger.debug("bind mapper modules"); + bindMapperModules(collector.getMappers()); } private void bindExtensionPoint(ExtensionCollector collector, - ExtensionPointElement epe) - { - if (epe.isAutoBind()) - { - if (epe.isMultiple()) - { + ExtensionPointElement epe) { + if (epe.isAutoBind()) { + if (epe.isMultiple()) { bindMultiExtensionPoint(epe, collector.byExtensionPoint(epe)); - } - else - { + } else { Class extension = collector.oneByExtensionPoint(epe); - if (extension != null) - { + if (extension != null) { bindSingleInstance(epe, extension); - } - else - { + } else { logger.warn("could not find extension for extension point {}", epe.getClazz()); } } - } - else - { + } else { logger.debug("bind type of {} is manual", epe.getClazz()); } } - private void bindLooseExtensions(Iterable extensions) - { - for (Class extension : extensions) - { + private void bindLooseExtensions(Iterable extensions) { + for (Class extension : extensions) { singleBind(TYPE_LOOSE_EXT, extension); } } - private void bindMultiExtensionPoint(ExtensionPointElement extensionPoint, Iterable extensions) - { + private void bindMultiExtensionPoint(ExtensionPointElement extensionPoint, Iterable extensions) { Class extensionPointClass = extensionPoint.getClazz(); logger.debug("create multibinder for {}", extensionPointClass.getName()); Multibinder multibinder = Multibinder.newSetBinder(binder, extensionPointClass); - for (Class extensionClass : extensions) - { + for (Class extensionClass : extensions) { boolean eagerSingleton = isEagerSingleton(extensionClass); - if (logger.isDebugEnabled()) - { + if (logger.isDebugEnabled()) { String as = Util.EMPTY_STRING; - if (eagerSingleton) - { + if (eagerSingleton) { as = AS_EAGER_SINGLETON; } @@ -141,42 +116,40 @@ public final class ExtensionBinder ScopedBindingBuilder sbb = multibinder.addBinding().to(extensionClass); - if (eagerSingleton) - { + if (eagerSingleton) { sbb.asEagerSingleton(); } } } - private void bindRestProviders(Iterable restProviders) - { - for (Class restProvider : restProviders) - { + private void bindRestProviders(Iterable restProviders) { + for (Class restProvider : restProviders) { logger.debug("bind rest provider {}", restProvider); binder.bind(restProvider).in(Singleton.class); } } - private void bindRestResource(Iterable restResources) - { - for (Class restResource : restResources) - { + private void bindRestResource(Iterable restResources) { + for (Class restResource : restResources) { singleBind(TYPE_REST_RESOURCE, restResource); } } + private void bindMapperModules(Iterable mapperModules) { + for (Class mapperModule : mapperModules) { + binder.bind(mapperModule).to(Mappers.getMapperClass(mapperModule)); + } + } + private void bindSingleInstance(ExtensionPointElement extensionPoint, - Class extensionClass) - { + Class extensionClass) { Class extensionPointClass = extensionPoint.getClazz(); boolean eagerSingleton = isEagerSingleton(extensionClass); - if (logger.isDebugEnabled()) - { + if (logger.isDebugEnabled()) { String as = Util.EMPTY_STRING; - if (eagerSingleton) - { + if (eagerSingleton) { as = AS_EAGER_SINGLETON; } @@ -187,22 +160,19 @@ public final class ExtensionBinder ScopedBindingBuilder sbb = binder.bind(extensionPointClass).to(extensionClass); - if (eagerSingleton) - { + if (eagerSingleton) { sbb.asEagerSingleton(); } } - private void singleBind(String type, Class extension) - { + private void singleBind(String type, Class extension) { StringBuilder log = new StringBuilder(); log.append("bind ").append(type).append(" ").append(extension); AnnotatedBindingBuilder abb = binder.bind(extension); - if (isEagerSingleton(extension)) - { + if (isEagerSingleton(extension)) { log.append(AS_EAGER_SINGLETON); abb.asEagerSingleton(); } @@ -212,8 +182,7 @@ public final class ExtensionBinder } } - private boolean isEagerSingleton(Class extensionClass) - { + private boolean isEagerSingleton(Class extensionClass) { return extensionClass.isAnnotationPresent(EagerSingleton.class); } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionCollector.java b/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionCollector.java index 20f300fcf2..f848a9d4b8 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/ExtensionCollector.java @@ -24,8 +24,6 @@ package sonia.scm.plugin; -//~--- non-JDK imports -------------------------------------------------------- - import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; @@ -42,20 +40,22 @@ import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; -//~--- JDK imports ------------------------------------------------------------ - -/** - * - * @author Sebastian Sdorra - */ -@SuppressWarnings("unchecked") -public final class ExtensionCollector -{ +@SuppressWarnings({"unchecked", "rawtypes"}) +public final class ExtensionCollector { private static final Logger LOG = LoggerFactory.getLogger(ExtensionCollector.class); private final Set pluginIndex; + private final Set webElements = Sets.newHashSet(); + private final Set> indexedTypes = Sets.newHashSet(); + private final Set restResources = Sets.newHashSet(); + private final Set restProviders = Sets.newHashSet(); + private final Set mappers = Sets.newHashSet(); + private final Set looseExtensions = Sets.newHashSet(); + private final Multimap extensions = HashMultimap.create(); + private final Map extensionPointIndex = Maps.newHashMap(); + public ExtensionCollector(ClassLoader moduleClassLoader, Set modules, Set installedPlugins) { this.pluginIndex = createPluginIndex(installedPlugins); @@ -82,144 +82,62 @@ public final class ExtensionCollector .collect(Collectors.toSet()); } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param epe - * - * @return - */ - public Collection byExtensionPoint(ExtensionPointElement epe) - { + public Collection byExtensionPoint(ExtensionPointElement epe) { Collection collection = extensions.get(epe); - if (collection == null) - { + if (collection == null) { collection = Collections.emptySet(); } return collection; } - /** - * Method description - * - * - * @param clazz - * - * @return - */ - public Collection byExtensionPoint(Class clazz) - { + public Collection byExtensionPoint(Class clazz) { Collection exts; ExtensionPointElement epe = extensionPointIndex.get(clazz); - if (epe != null) - { + if (epe != null) { exts = byExtensionPoint(epe); - } - else - { + } else { exts = Collections.emptySet(); } return exts; } - /** - * Method description - * - * - * @param epe - * - * @return - */ - public Class oneByExtensionPoint(ExtensionPointElement epe) - { + public Class oneByExtensionPoint(ExtensionPointElement epe) { return Iterables.getFirst(byExtensionPoint(epe), null); } - /** - * Method description - * - * - * @param clazz - * - * @return - */ - public Class oneByExtensionPoint(Class clazz) - { + public Class oneByExtensionPoint(Class clazz) { return Iterables.getFirst(byExtensionPoint(clazz), null); } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public Iterable getExtensionPointElements() - { + public Iterable getExtensionPointElements() { return extensionPointIndex.values(); } - /** - * Method description - * - * - * @return - */ - public Multimap getExtensions() - { + public Multimap getExtensions() { return extensions; } - /** - * Method description - * - * - * @return - */ - public Set getLooseExtensions() - { + public Set getLooseExtensions() { return looseExtensions; } - /** - * Method description - * - * - * @return - */ - public Set getRestProviders() - { + public Set getRestProviders() { return restProviders; } - /** - * Method description - * - * - * @return - */ - public Set getRestResources() - { + public Set getRestResources() { return restResources; } - /** - * Method description - * - * - * @return - */ - public Set getWebElements() - { + public Set getMappers() { + return mappers; + } + + public Set getWebElements() { return webElements; } @@ -227,22 +145,11 @@ public final class ExtensionCollector return indexedTypes; } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param extension - */ - private void appendExtension(Class extension) - { + private void appendExtension(Class extension) { boolean found = false; - for (Entry e : extensionPointIndex.entrySet()) - { - if (e.getKey().isAssignableFrom(extension)) - { + for (Entry e : extensionPointIndex.entrySet()) { + if (e.getKey().isAssignableFrom(extension)) { extensions.put(e.getValue(), extension); found = true; @@ -250,8 +157,7 @@ public final class ExtensionCollector } } - if (!found) - { + if (!found) { looseExtensions.add(extension); } } @@ -316,47 +222,16 @@ public final class ExtensionCollector return true; } - /** - * Method description - * - * - * @param module - */ - private void collectRootElements(ClassLoader classLoader, ScmModule module) - { - for (ExtensionPointElement epe : module.getExtensionPoints()) - { + private void collectRootElements(ClassLoader classLoader, ScmModule module) { + for (ExtensionPointElement epe : module.getExtensionPoints()) { extensionPointIndex.put(epe.getClazz(), epe); } restProviders.addAll(collectClasses(classLoader, module.getRestProviders())); restResources.addAll(collectClasses(classLoader, module.getRestResources())); + mappers.addAll(collectClasses(classLoader, module.getMappers())); webElements.addAll(collectWebElementExtensions(classLoader, module.getWebElements())); indexedTypes.addAll(collectIndexedTypes(classLoader, module.getIndexedTypes())); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private final Set webElements = Sets.newHashSet(); - - private final Set> indexedTypes = Sets.newHashSet(); - - /** Field description */ - private final Set restResources = Sets.newHashSet(); - - /** Field description */ - private final Set restProviders = Sets.newHashSet(); - - /** Field description */ - private final Set looseExtensions = Sets.newHashSet(); - - /** Field description */ - private final Multimap extensions = - HashMultimap.create(); - - /** Field description */ - private final Map extensionPointIndex = - Maps.newHashMap(); }