/** * Resolve the list of {@linkplain ContextConfigurationAttributes context * configuration attributes} for the supplied {@linkplain Class test class} and its * superclasses. * <p>Note that the {@link ContextConfiguration#inheritLocations inheritLocations} and * {@link ContextConfiguration#inheritInitializers() inheritInitializers} flags of * {@link ContextConfiguration @ContextConfiguration} will <strong>not</strong> * be taken into consideration. If these flags need to be honored, that must be * handled manually when traversing the list returned by this method. * @param testClass the class for which to resolve the configuration attributes * (must not be {@code null}) * @return the list of configuration attributes for the specified class, ordered * <em>bottom-up</em> (i.e., as if we were traversing up the class hierarchy); * never {@code null} * @throws IllegalArgumentException if the supplied class is {@code null} or if * {@code @ContextConfiguration} is not <em>present</em> on the supplied class */ static List<ContextConfigurationAttributes> resolveContextConfigurationAttributes(Class<?> testClass) { Assert.notNull(testClass, "Class must not be null"); List<ContextConfigurationAttributes> attributesList = new ArrayList<ContextConfigurationAttributes>(); Class<ContextConfiguration> annotationType = ContextConfiguration.class; AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(testClass, annotationType); if (descriptor == null) { throw new IllegalArgumentException(String.format( "Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", annotationType.getName(), testClass.getName())); } while (descriptor != null) { convertContextConfigToConfigAttributesAndAddToList(descriptor.synthesizeAnnotation(), descriptor.getRootDeclaringClass(), attributesList); descriptor = findAnnotationDescriptor(descriptor.getRootDeclaringClass().getSuperclass(), annotationType); } return attributesList; }
@Test public void assertContextConfigurationLocations() throws Exception { final ContextConfiguration contextConfig = this.testClass.getAnnotation(ContextConfiguration.class); final ContextLoader contextLoader = new GenericXmlContextLoader(); final String[] configuredLocations = (String[]) AnnotationUtils.getValue(contextConfig); final String[] processedLocations = contextLoader.processLocations(this.testClass, configuredLocations); if (logger.isDebugEnabled()) { logger.debug("----------------------------------------------------------------------"); logger.debug("Configured locations: " + ObjectUtils.nullSafeToString(configuredLocations)); logger.debug("Expected locations: " + ObjectUtils.nullSafeToString(this.expectedLocations)); logger.debug("Processed locations: " + ObjectUtils.nullSafeToString(processedLocations)); } assertArrayEquals("Verifying locations for test [" + this.testClass + "].", this.expectedLocations, processedLocations); }
@Test @SuppressWarnings("unchecked") public void findAnnotationDescriptorForTypesWithMetaAnnotationWithDefaultAttributes() throws Exception { Class<?> startClass = MetaConfigWithDefaultAttributesTestCase.class; Class<ContextConfiguration> annotationType = ContextConfiguration.class; UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(startClass, Service.class, ContextConfiguration.class, Order.class, Transactional.class); assertNotNull(descriptor); assertEquals(startClass, descriptor.getRootDeclaringClass()); assertEquals(annotationType, descriptor.getAnnotationType()); assertArrayEquals(new Class[] {}, ((ContextConfiguration) descriptor.getAnnotation()).value()); assertArrayEquals(new Class[] { MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class }, descriptor.getAnnotationAttributes().getClassArray("classes")); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaConfig.class, descriptor.getComposedAnnotationType()); }
@Test @SuppressWarnings("unchecked") public void findAnnotationDescriptorForTypesWithMetaAnnotationWithOverriddenAttributes() throws Exception { Class<?> startClass = MetaConfigWithOverriddenAttributesTestCase.class; Class<ContextConfiguration> annotationType = ContextConfiguration.class; UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(startClass, Service.class, ContextConfiguration.class, Order.class, Transactional.class); assertNotNull(descriptor); assertEquals(startClass, descriptor.getRootDeclaringClass()); assertEquals(annotationType, descriptor.getAnnotationType()); assertArrayEquals(new Class[] {}, ((ContextConfiguration) descriptor.getAnnotation()).value()); assertArrayEquals(new Class[] { MetaAnnotationUtilsTests.class }, descriptor.getAnnotationAttributes().getClassArray("classes")); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaConfig.class, descriptor.getComposedAnnotationType()); }
@Test public void overriddenContextConfigurationValue() throws Exception { Class<?> declaringClass = OverriddenMetaValueConfigTestCase.class; AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass, ContextConfiguration.class); assertNotNull(descriptor); assertEquals(declaringClass, descriptor.getRootDeclaringClass()); assertEquals(MetaValueConfig.class, descriptor.getComposedAnnotationType()); assertEquals(ContextConfiguration.class, descriptor.getAnnotationType()); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaValueConfig.class, descriptor.getComposedAnnotationType()); // direct access to annotation value: assertArrayEquals(new String[] { "foo.xml" }, descriptor.getAnnotation().value()); // overridden attribute: AnnotationAttributes attributes = descriptor.getAnnotationAttributes(); // NOTE: we would like to be able to override the 'value' attribute; however, // Spring currently does not allow overrides for the 'value' attribute. // See SPR-11393 for related discussions. assertArrayEquals(new String[] { "foo.xml" }, attributes.getStringArray("value")); }
@Test public void contextConfigurationLocationsAndInheritLocations() throws Exception { Class<MetaLocationsConfigTestCase> declaringClass = MetaLocationsConfigTestCase.class; AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass, ContextConfiguration.class); assertNotNull(descriptor); assertEquals(declaringClass, descriptor.getRootDeclaringClass()); assertEquals(MetaLocationsConfig.class, descriptor.getComposedAnnotationType()); assertEquals(ContextConfiguration.class, descriptor.getAnnotationType()); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaLocationsConfig.class, descriptor.getComposedAnnotationType()); // direct access to annotation attributes: assertArrayEquals(new String[] { "foo.xml" }, descriptor.getAnnotation().locations()); assertFalse(descriptor.getAnnotation().inheritLocations()); }
@Test public void overriddenContextConfigurationLocationsAndInheritLocations() throws Exception { Class<?> declaringClass = OverriddenMetaLocationsConfigTestCase.class; AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass, ContextConfiguration.class); assertNotNull(descriptor); assertEquals(declaringClass, descriptor.getRootDeclaringClass()); assertEquals(MetaLocationsConfig.class, descriptor.getComposedAnnotationType()); assertEquals(ContextConfiguration.class, descriptor.getAnnotationType()); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaLocationsConfig.class, descriptor.getComposedAnnotationType()); // direct access to annotation attributes: assertArrayEquals(new String[] { "foo.xml" }, descriptor.getAnnotation().locations()); assertFalse(descriptor.getAnnotation().inheritLocations()); // overridden attributes: AnnotationAttributes attributes = descriptor.getAnnotationAttributes(); assertArrayEquals(new String[] { "bar.xml" }, attributes.getStringArray("locations")); assertTrue(attributes.getBoolean("inheritLocations")); }
@Override protected void initializeProcessEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); if (value==null) { throw new ActivitiException("value is mandatory in ContextConfiguration"); } if (value.length!=1) { throw new ActivitiException("SpringActivitiTestCase requires exactly one value in annotation ContextConfiguration"); } String configurationFile = value[0]; processEngine = cachedProcessEngines.get(configurationFile); if (processEngine==null) { processEngine = applicationContext.getBean(ProcessEngine.class); cachedProcessEngines.put(configurationFile, processEngine); } }
/** * 是否需要支持spring */ private boolean isSpringSupport(ExtensionContext context) { Class<?> clazz = context.getTestClass().get(); boolean result = false; while (!clazz.equals(Object.class)) { boolean isContextConfiguration = clazz.isAnnotationPresent(ContextConfiguration.class); if (isContextConfiguration) { result = true; break; } clazz = clazz.getSuperclass(); } return result; }
/** * Convenience method for creating a {@link ContextConfigurationAttributes} * instance from the supplied {@link ContextConfiguration} annotation and * declaring class and then adding the attributes to the supplied list. */ private static void convertContextConfigToConfigAttributesAndAddToList(ContextConfiguration contextConfiguration, Class<?> declaringClass, final List<ContextConfigurationAttributes> attributesList) { if (logger.isTraceEnabled()) { logger.trace(String.format("Retrieved @ContextConfiguration [%s] for declaring class [%s].", contextConfiguration, declaringClass.getName())); } ContextConfigurationAttributes attributes = new ContextConfigurationAttributes(declaringClass, contextConfiguration); if (logger.isTraceEnabled()) { logger.trace("Resolved context configuration attributes: " + attributes); } attributesList.add(attributes); }
@Test public void findAnnotationDescriptorForClassWithLocalMetaAnnotationAndAnnotatedSuperclass() { AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor( MetaAnnotatedAndSuperAnnotatedContextConfigClass.class, ContextConfiguration.class); assertNotNull("AnnotationDescriptor should not be null", descriptor); assertEquals("rootDeclaringClass", MetaAnnotatedAndSuperAnnotatedContextConfigClass.class, descriptor.getRootDeclaringClass()); assertEquals("declaringClass", MetaConfig.class, descriptor.getDeclaringClass()); assertEquals("annotationType", ContextConfiguration.class, descriptor.getAnnotationType()); assertNotNull("composedAnnotation should not be null", descriptor.getComposedAnnotation()); assertEquals("composedAnnotationType", MetaConfig.class, descriptor.getComposedAnnotationType()); assertArrayEquals("configured classes", new Class[] { String.class }, descriptor.getAnnotationAttributes().getClassArray("classes")); }
@Test public void contextConfigurationValue() throws Exception { Class<MetaValueConfigTestCase> declaringClass = MetaValueConfigTestCase.class; AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass, ContextConfiguration.class); assertNotNull(descriptor); assertEquals(declaringClass, descriptor.getRootDeclaringClass()); assertEquals(MetaValueConfig.class, descriptor.getComposedAnnotationType()); assertEquals(ContextConfiguration.class, descriptor.getAnnotationType()); assertNotNull(descriptor.getComposedAnnotation()); assertEquals(MetaValueConfig.class, descriptor.getComposedAnnotationType()); // direct access to annotation value: assertArrayEquals(new String[] { "foo.xml" }, descriptor.getAnnotation().value()); }
@Override protected void initializeContentEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : ContentEngine.class.getName(); ContentEngine engine = this.cachedContentEngines.containsKey(key) ? this.cachedContentEngines.get(key) : this.applicationContext.getBean(ContentEngine.class); this.cachedContentEngines.put(key, engine); this.contentEngine = engine; }
@Override protected void initializeFormEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : FormEngine.class.getName(); FormEngine engine = this.cachedFormEngines.containsKey(key) ? this.cachedFormEngines.get(key) : this.applicationContext.getBean(FormEngine.class); this.cachedFormEngines.put(key, engine); this.formEngine = engine; }
@Override protected void initializeDmnEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : DmnEngine.class.getName(); DmnEngine engine = this.cachedDmnEngines.containsKey(key) ? this.cachedDmnEngines.get(key) : this.applicationContext.getBean(DmnEngine.class); this.cachedDmnEngines.put(key, engine); this.dmnEngine = engine; }
@Override protected void initializeProcessEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : ProcessEngine.class.getName(); ProcessEngine engine = this.cachedProcessEngines.containsKey(key) ? this.cachedProcessEngines.get(key) : this.applicationContext.getBean(ProcessEngine.class); this.cachedProcessEngines.put(key, engine); this.processEngine = engine; }
protected void initializeCmmnEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : CmmnEngine.class.getName(); CmmnEngine engine = this.cachedCmmnEngines.containsKey(key) ? this.cachedCmmnEngines.get(key) : this.applicationContext.getBean(CmmnEngine.class); this.cachedCmmnEngines.put(key, engine); this.cmmnEngine = engine; }
@Override protected void initializeIdmEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); String[] value = contextConfiguration.value(); boolean hasOneArg = value != null && value.length == 1; String key = hasOneArg ? value[0] : IdmEngine.class.getName(); IdmEngine engine = this.cachedIdmEngines.containsKey(key) ? this.cachedIdmEngines.get(key) : this.applicationContext.getBean(IdmEngine.class); this.cachedIdmEngines.put(key, engine); this.idmEngine = engine; }
private String[] extractLocationFromAnnotation(Class<?> clazz) { ContextConfiguration contextConfiguration = InternalUtils.findAnnotation(clazz.getAnnotations(), ContextConfiguration.class); String[] locations = null; if (contextConfiguration != null) { locations = contextConfiguration.locations(); } return locations; }
/** * {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public final MergedContextConfiguration buildMergedContextConfiguration() { Class<?> testClass = getBootstrapContext().getTestClass(); CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = getCacheAwareContextLoaderDelegate(); if (MetaAnnotationUtils.findAnnotationDescriptorForTypes(testClass, ContextConfiguration.class, ContextHierarchy.class) == null) { if (logger.isInfoEnabled()) { logger.info(String.format( "Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s]", testClass.getName())); } return new MergedContextConfiguration(testClass, null, null, null, null); } if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) { Map<String, List<ContextConfigurationAttributes>> hierarchyMap = ContextLoaderUtils.buildContextHierarchyMap(testClass); MergedContextConfiguration parentConfig = null; MergedContextConfiguration mergedConfig = null; for (List<ContextConfigurationAttributes> list : hierarchyMap.values()) { List<ContextConfigurationAttributes> reversedList = new ArrayList<ContextConfigurationAttributes>(list); Collections.reverse(reversedList); // Don't use the supplied testClass; instead ensure that we are // building the MCC for the actual test class that declared the // configuration for the current level in the context hierarchy. Assert.notEmpty(reversedList, "ContextConfigurationAttributes list must not be empty"); Class<?> declaringClass = reversedList.get(0).getDeclaringClass(); mergedConfig = buildMergedContextConfiguration(declaringClass, reversedList, parentConfig, cacheAwareContextLoaderDelegate); parentConfig = mergedConfig; } // Return the last level in the context hierarchy return mergedConfig; } else { return buildMergedContextConfiguration(testClass, ContextLoaderUtils.resolveContextConfigurationAttributes(testClass), null, cacheAwareContextLoaderDelegate); } }
@Parameters(name = "{0}") public static Collection<Object[]> contextConfigurationLocationsData() { @ContextConfiguration class ClasspathNonExistentDefaultLocationsTestCase { } @ContextConfiguration class ClasspathExistentDefaultLocationsTestCase { } @ContextConfiguration({ "context1.xml", "context2.xml" }) class ImplicitClasspathLocationsTestCase { } @ContextConfiguration("classpath:context.xml") class ExplicitClasspathLocationsTestCase { } @ContextConfiguration("file:/testing/directory/context.xml") class ExplicitFileLocationsTestCase { } @ContextConfiguration("http://example.com/context.xml") class ExplicitUrlLocationsTestCase { } @ContextConfiguration({ "context1.xml", "classpath:context2.xml", "/context3.xml", "file:/testing/directory/context.xml", "http://example.com/context.xml" }) class ExplicitMixedPathTypesLocationsTestCase { } return Arrays.asList(new Object[][] { { ClasspathNonExistentDefaultLocationsTestCase.class.getSimpleName(), new String[] {} }, { ClasspathExistentDefaultLocationsTestCase.class.getSimpleName(), new String[] { "classpath:org/springframework/test/context/support/GenericXmlContextLoaderResourceLocationsTests$1ClasspathExistentDefaultLocationsTestCase-context.xml" } }, { ImplicitClasspathLocationsTestCase.class.getSimpleName(), new String[] { "classpath:/org/springframework/test/context/support/context1.xml", "classpath:/org/springframework/test/context/support/context2.xml" } }, { ExplicitClasspathLocationsTestCase.class.getSimpleName(), new String[] { "classpath:context.xml" } }, { ExplicitFileLocationsTestCase.class.getSimpleName(), new String[] { "file:/testing/directory/context.xml" } }, { ExplicitUrlLocationsTestCase.class.getSimpleName(), new String[] { "http://example.com/context.xml" } }, { ExplicitMixedPathTypesLocationsTestCase.class.getSimpleName(), new String[] { "classpath:/org/springframework/test/context/support/context1.xml", "classpath:context2.xml", "classpath:/context3.xml", "file:/testing/directory/context.xml", "http://example.com/context.xml" } } }); }
@Parameters public static Collection<Object[]> contextConfigurationLocationsData() { @ContextConfiguration class ClasspathNonExistentDefaultLocationsTestCase { } @ContextConfiguration class ClasspathExistentDefaultLocationsTestCase { } @ContextConfiguration({ "context1.xml", "context2.xml" }) class ImplicitClasspathLocationsTestCase { } @ContextConfiguration("classpath:context.xml") class ExplicitClasspathLocationsTestCase { } @ContextConfiguration("file:/testing/directory/context.xml") class ExplicitFileLocationsTestCase { } @ContextConfiguration("http://example.com/context.xml") class ExplicitUrlLocationsTestCase { } @ContextConfiguration({ "context1.xml", "classpath:context2.xml", "/context3.xml", "file:/testing/directory/context.xml", "http://example.com/context.xml" }) class ExplicitMixedPathTypesLocationsTestCase { } return Arrays.asList(new Object[][] { { ClasspathNonExistentDefaultLocationsTestCase.class, new String[] {} }, { ClasspathExistentDefaultLocationsTestCase.class, new String[] { "classpath:/org/springframework/test/context/support/GenericXmlContextLoaderResourceLocationsTests$1ClasspathExistentDefaultLocationsTestCase-context.xml" } }, { ImplicitClasspathLocationsTestCase.class, new String[] { "classpath:/org/springframework/test/context/support/context1.xml", "classpath:/org/springframework/test/context/support/context2.xml" } }, { ExplicitClasspathLocationsTestCase.class, new String[] { "classpath:context.xml" } }, { ExplicitFileLocationsTestCase.class, new String[] { "file:/testing/directory/context.xml" } }, { ExplicitUrlLocationsTestCase.class, new String[] { "http://example.com/context.xml" } }, { ExplicitMixedPathTypesLocationsTestCase.class, new String[] { "classpath:/org/springframework/test/context/support/context1.xml", "classpath:context2.xml", "classpath:/context3.xml", "file:/testing/directory/context.xml", "http://example.com/context.xml" } } }); }
@Test public void validationSuccess() { new AnnotationConfigApplicationContext(ContextConfiguration.class) .getBean("simpleConf"); }
@Override protected void initializeProcessEngine() { ContextConfiguration contextConfiguration = getClass().getAnnotation(ContextConfiguration.class); processEngine = applicationContext.getBean(ProcessEngine.class); }