package gov.samhsa.consent2share.web.config.report; import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import gov.samhsa.consent2share.infrastructure.report.AbstractReportConfig; import gov.samhsa.consent2share.infrastructure.report.ReportFormat; import gov.samhsa.consent2share.infrastructure.report.ReportParameterConfigurerTask; import gov.samhsa.consent2share.infrastructure.report.ReportProps; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Stream; import javax.servlet.ServletContext; import net.sf.jasperreports.engine.JRDataSource; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.RegexPatternTypeFilter; @RunWith(MockitoJUnitRunner.class) public class ReportConfigUniqueBeanNamesTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testAll() { final List<String> configNames = getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportConfigName).collect( toList()); final List<String> reportNames = getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportName).collect(toList()); final List<String> reportDataProviders = getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportDataProviderName).collect( toList()); assertEquals("All report bean names must be unique", Arrays.asList(configNames, reportNames, reportDataProviders) .stream().flatMap(List::stream).distinct().count(), Arrays.asList(configNames, reportNames, reportDataProviders) .stream().flatMap(List::stream).count()); } @Test public void testGetReportConfigName() { assertEquals( "Duplicate report config names found, report config names must be unique!", getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportConfigName) .distinct().count(), getAbstractReportConfigSubclassesAsStream().map( AbstractReportConfig::getReportConfigName).count()); } @Test public void testGetReportDataProviderName() { assertEquals( "Duplicate report data provider names found, report data provider names must be unique!", getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportDataProviderName) .distinct().count(), getAbstractReportConfigSubclassesAsStream().map( AbstractReportConfig::getReportDataProviderName) .count()); } @Test public void testGetReportName() { assertEquals( "Duplicate report names found, report names must be unique!", getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportName).distinct() .count(), getAbstractReportConfigSubclassesAsStream() .map(AbstractReportConfig::getReportName).count()); } private Stream<AbstractReportConfig> getAbstractReportConfigSubclassesAsStream() { // create scanner and disable default filters (that is the 'false' // argument) final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider( false); // add include filters which matches all the classes (or use your own) provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern .compile(".*"))); // get matching classes defined in the package final String package1 = ManagerReportConfig.class.getPackage() .getName(); final Set<BeanDefinition> classes = provider .findCandidateComponents(package1); return classes .stream() .map(this::getAsClass) .filter(clazz -> clazz.getSuperclass() == AbstractReportConfig.class) .map(this::getAsAbstractReportConfig); } @SuppressWarnings({ "unchecked", "rawtypes" }) private AbstractReportConfig getAsAbstractReportConfig(Class clazz) { try { final List<Supplier<ReportParameterConfigurerTask>> list = Arrays .asList(() -> new ReportParameterConfigurerTaskImpl()); return (AbstractReportConfig) clazz.getConstructor( ServletContext.class, List.class).newInstance(null, list); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { throw new RuntimeException(e); } } @SuppressWarnings("rawtypes") private Class getAsClass(BeanDefinition bean) { try { return Class.forName(bean.getBeanClassName()); } catch (final ClassNotFoundException e) { throw new RuntimeException(e); } } public class ReportParameterConfigurerTaskImpl implements ReportParameterConfigurerTask { @Override public Map<String, Object> configure(ReportProps reportProps, ReportFormat reportFormat, JRDataSource datasource) { return null; } } }