package io.katharsis.resource.registry; import io.katharsis.locator.JsonServiceLocator; import io.katharsis.repository.RepositoryInstanceBuilder; import io.katharsis.repository.annotations.JsonApiRelationshipRepository; import io.katharsis.repository.annotations.JsonApiResourceRepository; import io.katharsis.resource.registry.repository.AnnotatedRelationshipEntryBuilder; import io.katharsis.resource.registry.repository.AnnotatedResourceEntryBuilder; import io.katharsis.resource.registry.repository.ResourceEntry; import io.katharsis.resource.registry.repository.ResponseRelationshipEntry; import io.katharsis.utils.Predicate1; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * Repository entries builder for classes annotated with repository annotations. */ public class AnnotatedRepositoryEntryBuilder implements RepositoryEntryBuilder { private final JsonServiceLocator jsonServiceLocator; public AnnotatedRepositoryEntryBuilder(JsonServiceLocator jsonServiceLocator) { this.jsonServiceLocator = jsonServiceLocator; } @Override public ResourceEntry<?, ?> buildResourceRepository(ResourceLookup lookup, final Class<?> resourceClass) { Predicate1<Class<?>> classPredicate = new Predicate1<Class<?>>() { @Override public boolean test(Class<?> clazz) { return resourceClass.equals(clazz.getAnnotation(JsonApiResourceRepository.class).value()); } }; List<Class<?>> repositoryClasses = findRepositoryClasses(lookup, classPredicate, JsonApiResourceRepository.class); if (repositoryClasses.size() == 0) { return null; } else { return new AnnotatedResourceEntryBuilder<>(new RepositoryInstanceBuilder<>(jsonServiceLocator, repositoryClasses.get(0))); } } @Override public List<ResponseRelationshipEntry<?, ?>> buildRelationshipRepositories(ResourceLookup lookup, final Class<?> resourceClass) { Predicate1<Class<?>> classPredicate = new Predicate1<Class<?>>() { @Override public boolean test(Class<?> clazz) { JsonApiRelationshipRepository annotation = clazz.getAnnotation(JsonApiRelationshipRepository.class); return resourceClass.equals(annotation.source()); } }; List<Class<?>> repositoryClasses = findRepositoryClasses(lookup, classPredicate, JsonApiRelationshipRepository.class); List<ResponseRelationshipEntry<?, ?>> relationshipEntries = new ArrayList<>(repositoryClasses.size()); for (Class<?> repositoryClass : repositoryClasses) { relationshipEntries.add(new AnnotatedRelationshipEntryBuilder<>(new RepositoryInstanceBuilder<>(jsonServiceLocator, repositoryClass))); } return relationshipEntries; } private List<Class<?>> findRepositoryClasses(ResourceLookup lookup, Predicate1<Class<?>> classPredicate, Class<? extends Annotation> annotation) { List<Class<?>> repositoryClasses = new LinkedList<>(); for (Class<?> clazz : lookup.getResourceRepositoryClasses()) { if (clazz.isAnnotationPresent(annotation) && classPredicate.test(clazz)) { repositoryClasses.add(clazz); } } return repositoryClasses; } }