package com.github.mongobee.utils; import com.github.mongobee.changeset.ChangeEntry; import com.github.mongobee.changeset.ChangeLog; import com.github.mongobee.changeset.ChangeSet; import org.reflections.Reflections; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.*; import static java.util.Arrays.asList; /** * Utilities to deal with reflections and annotations * * @author lstolowski * @since 27/07/2014 */ public class ChangeService { private static final String DEFAULT_PROFILE = "default"; private final String changeLogsBasePackage; private final List<String> activeProfiles; public ChangeService(String changeLogsBasePackage) { this(changeLogsBasePackage, null); } public ChangeService(String changeLogsBasePackage, Environment environment) { this.changeLogsBasePackage = changeLogsBasePackage; if (environment != null && environment.getActiveProfiles() != null && environment.getActiveProfiles().length> 0) { this.activeProfiles = asList(environment.getActiveProfiles()); } else { this.activeProfiles = asList(DEFAULT_PROFILE); } } public List<Class<?>> fetchChangeLogs(){ Reflections reflections = new Reflections(changeLogsBasePackage); Set<Class<?>> changeLogs = reflections.getTypesAnnotatedWith(ChangeLog.class); // TODO remove dependency, do own method List<Class<?>> filteredChangeLogs = (List<Class<?>>) filterByActiveProfiles(changeLogs); Collections.sort(filteredChangeLogs, new ChangeLogComparator()); return filteredChangeLogs; } public List<Method> fetchChangeSets(final Class<?> type) { final List<Method> changeSets = filterChangeSetAnnotation(asList(type.getDeclaredMethods())); final List<Method> filteredChangeSets = (List<Method>) filterByActiveProfiles(changeSets); Collections.sort(filteredChangeSets, new ChangeSetComparator()); return filteredChangeSets; } public boolean isRunAlwaysChangeSet(Method changesetMethod){ if (changesetMethod.isAnnotationPresent(ChangeSet.class)){ ChangeSet annotation = changesetMethod.getAnnotation(ChangeSet.class); return annotation.runAlways(); } else { return false; } } public ChangeEntry createChangeEntry(Method changesetMethod){ if (changesetMethod.isAnnotationPresent(ChangeSet.class)){ ChangeSet annotation = changesetMethod.getAnnotation(ChangeSet.class); return new ChangeEntry( annotation.id(), annotation.author(), new Date(), changesetMethod.getDeclaringClass().getName(), changesetMethod.getName()); } else { return null; } } private boolean matchesActiveSpringProfile(AnnotatedElement element) { if (element.isAnnotationPresent(Profile.class)) { Profile profiles = element.getAnnotation(Profile.class); List<String> values = asList(profiles.value()); return ListUtils.intersection(activeProfiles, values).size() > 0 ? true : false; } else { return true; // no-profiled changeset always matches } } private List<?> filterByActiveProfiles(Collection<? extends AnnotatedElement> annotated) { List<AnnotatedElement> filtered = new ArrayList<>(); for (AnnotatedElement element : annotated) { if (matchesActiveSpringProfile(element)){ filtered.add( element); } } return filtered; } private List<Method> filterChangeSetAnnotation(List<Method> allMethods) { final List<Method> changesetMethods = new ArrayList<>(); for (final Method method : allMethods) { if (method.isAnnotationPresent(ChangeSet.class)) { changesetMethods.add(method); } } return changesetMethods; } }