package org.javers.core.metamodel.scanner; import org.javers.common.collections.Lists; import org.javers.common.collections.Sets; import org.javers.common.validation.Validate; import org.javers.core.metamodel.annotation.*; import java.lang.annotation.Annotation; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import static org.javers.core.metamodel.scanner.JaversAnnotationsNameSpace.IGNORE_DECLARED_PROPERTIES_ANN; /** * Should scan well known annotations at class level * * @author bartosz walacik */ class ClassAnnotationsScanner { private final AnnotationNamesProvider annotationNamesProvider; private List<Class<? extends Annotation>> JAVERS_TYPE_ANNOTATIONS = Lists.immutableListOf( DiffIgnore.class, Entity.class, ShallowReference.class, ValueObject.class, Value.class ); ClassAnnotationsScanner(AnnotationNamesProvider annotationNamesProvider) { this.annotationNamesProvider = annotationNamesProvider; } public ClassAnnotationsScan scan(Class javaClass){ Validate.argumentIsNotNull(javaClass); Set<Annotation> annotations = Sets.asSet(javaClass.getAnnotations()); Set<Class<? extends Annotation>> annTypes = annotations.stream() .map(a -> a.annotationType()) .collect(Collectors.toSet()); Optional<String> typeName = annotationNamesProvider.findTypeNameAnnValue(annotations); Optional<Class<? extends Annotation>> javersTypeAnnotation = JAVERS_TYPE_ANNOTATIONS.stream().filter(annTypes::contains).findFirst(); boolean hasIgnoreDeclaredProperties = annTypes.contains(IGNORE_DECLARED_PROPERTIES_ANN); return new ClassAnnotationsScan(typeFromAnnotation(annTypes), hasIgnoreDeclaredProperties, typeName); } private TypeFromAnnotation typeFromAnnotation(Set<Class<? extends Annotation>> annTypes) { Optional<Class<? extends Annotation>> javersTypeAnnotation = JAVERS_TYPE_ANNOTATIONS.stream().filter(annTypes::contains).findFirst(); if (javersTypeAnnotation.isPresent()) { return new TypeFromAnnotation(javersTypeAnnotation.get()); } else { boolean hasValue = annotationNamesProvider.hasValueAnnAlias(annTypes); boolean hasValueObject = annotationNamesProvider.hasValueObjectAnnAlias(annTypes); boolean hasEntity = annotationNamesProvider.hasEntityAnnAlias(annTypes); return new TypeFromAnnotation(hasEntity, hasValueObject, hasValue); } } }