/* * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.context.index; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.annotation.ManagedBean; import javax.inject.Named; import javax.persistence.Converter; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.springframework.context.index.sample.AbstractController; import org.springframework.context.index.sample.MetaControllerIndexed; import org.springframework.context.index.sample.SampleComponent; import org.springframework.context.index.sample.SampleController; import org.springframework.context.index.sample.SampleMetaController; import org.springframework.context.index.sample.SampleMetaIndexedController; import org.springframework.context.index.sample.SampleNone; import org.springframework.context.index.sample.SampleRepository; import org.springframework.context.index.sample.SampleService; import org.springframework.context.index.sample.cdi.SampleManagedBean; import org.springframework.context.index.sample.cdi.SampleNamed; import org.springframework.context.index.sample.jpa.SampleConverter; import org.springframework.context.index.sample.jpa.SampleEmbeddable; import org.springframework.context.index.sample.jpa.SampleEntity; import org.springframework.context.index.sample.jpa.SampleMappedSuperClass; import org.springframework.context.index.sample.type.Repo; import org.springframework.context.index.sample.type.SampleRepo; import org.springframework.context.index.sample.type.SampleSmartRepo; import org.springframework.context.index.sample.type.SampleSpecializedRepo; import org.springframework.context.index.sample.type.SmartRepo; import org.springframework.context.index.sample.type.SpecializedRepo; import org.springframework.context.index.test.TestCompiler; import org.springframework.stereotype.Component; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.springframework.context.index.Metadata.*; /** * Tests for {@link CandidateComponentsIndexer}. * * @author Stephane Nicoll */ public class CandidateComponentsIndexerTests { private TestCompiler compiler; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Rule public ExpectedException thrown = ExpectedException.none(); @Before public void createCompiler() throws IOException { this.compiler = new TestCompiler(this.temporaryFolder); } @Test public void noCandidate() throws IOException { CandidateComponentsMetadata metadata = compile(SampleNone.class); assertThat(metadata.getItems(), hasSize(0)); } @Test public void noAnnotation() throws IOException { CandidateComponentsMetadata metadata = compile(CandidateComponentsIndexerTests.class); assertThat(metadata.getItems(), hasSize(0)); } @Test public void stereotypeComponent() throws IOException { testComponent(SampleComponent.class); } @Test public void stereotypeService() throws IOException { testComponent(SampleService.class); } @Test public void stereotypeController() throws IOException { testComponent(SampleController.class); } @Test public void stereotypeControllerMetaAnnotation() throws IOException { testComponent(SampleMetaController.class); } @Test public void stereotypeRepository() throws IOException { testSingleComponent(SampleRepository.class, Component.class); } @Test public void stereotypeControllerMetaIndex() throws IOException { testSingleComponent(SampleMetaIndexedController.class, Component.class, MetaControllerIndexed.class); } @Test public void stereotypeOnAbstractClass() throws IOException { testComponent(AbstractController.class); } @Test public void cdiManagedBean() throws IOException { testSingleComponent(SampleManagedBean.class, ManagedBean.class); } @Test public void cdiNamed() throws IOException { testSingleComponent(SampleNamed.class, Named.class); } @Test public void persistenceEntity() throws IOException { testSingleComponent(SampleEntity.class, Entity.class); } @Test public void persistenceMappedSuperClass() throws IOException { testSingleComponent(SampleMappedSuperClass.class, MappedSuperclass.class); } @Test public void persistenceEmbeddable() throws IOException { testSingleComponent(SampleEmbeddable.class, Embeddable.class); } @Test public void persistenceConverter() throws IOException { testSingleComponent(SampleConverter.class, Converter.class); } @Test public void packageInfo() throws IOException { CandidateComponentsMetadata metadata = compile( "org/springframework/context/index/sample/jpa/package-info"); assertThat(metadata, hasComponent( "org.springframework.context.index.sample.jpa", "package-info")); } @Test public void typeStereotypeFromMetaInterface() throws IOException { testSingleComponent(SampleSpecializedRepo.class, Repo.class); } @Test public void typeStereotypeFromInterfaceFromSuperClass() throws IOException { testSingleComponent(SampleRepo.class, Repo.class); } @Test public void typeStereotypeFromSeveralInterfaces() throws IOException { testSingleComponent(SampleSmartRepo.class, Repo.class, SmartRepo.class); } @Test public void typeStereotypeOnInterface() throws IOException { testSingleComponent(SpecializedRepo.class, Repo.class); } @Test public void typeStereotypeOnInterfaceFromSeveralInterfaces() throws IOException { testSingleComponent(SmartRepo.class, Repo.class, SmartRepo.class); } @Test public void typeStereotypeOnIndexedInterface() throws IOException { testSingleComponent(Repo.class, Repo.class); } private void testComponent(Class<?>... classes) throws IOException { CandidateComponentsMetadata metadata = compile(classes); for (Class<?> c : classes) { assertThat(metadata, hasComponent(c, Component.class)); } assertThat(metadata.getItems(), hasSize(classes.length)); } private void testSingleComponent(Class<?> target, Class<?>... stereotypes) throws IOException { CandidateComponentsMetadata metadata = compile(target); assertThat(metadata, hasComponent(target, stereotypes)); assertThat(metadata.getItems(), hasSize(1)); } private CandidateComponentsMetadata compile(Class<?>... types) throws IOException { CandidateComponentsIndexer processor = new CandidateComponentsIndexer(); this.compiler.getTask(types).call(processor); return readGeneratedMetadata(this.compiler.getOutputLocation()); } private CandidateComponentsMetadata compile(String... types) throws IOException { CandidateComponentsIndexer processor = new CandidateComponentsIndexer(); this.compiler.getTask(types).call(processor); return readGeneratedMetadata(this.compiler.getOutputLocation()); } private CandidateComponentsMetadata readGeneratedMetadata(File outputLocation) { try { File metadataFile = new File(outputLocation, MetadataStore.METADATA_PATH); if (metadataFile.isFile()) { return PropertiesMarshaller.read(new FileInputStream(metadataFile)); } else { return new CandidateComponentsMetadata(); } } catch (IOException ex) { throw new IllegalStateException("Failed to read metadata from disk", ex); } } }