diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java index f26ca1b6d08..b2d96398ac7 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java @@ -18,6 +18,7 @@ package org.springframework.boot.configurationprocessor; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -112,19 +113,31 @@ public class MetadataStore { // Most build systems will have copied the file to the class output location FileObject fileObject = this.environment.getFiler() .getResource(StandardLocation.CLASS_OUTPUT, "", ADDITIONAL_METADATA_PATH); - File file = new File(fileObject.toUri()); - if (!file.exists()) { - // Gradle keeps things separate - String path = file.getPath(); - int index = path.lastIndexOf(CLASSES_FOLDER); - if (index >= 0) { - path = path.substring(0, index) + RESOURCES_FOLDER - + path.substring(index + CLASSES_FOLDER.length()); - file = new File(path); - } - } + File file = locateAdditionalMetadataFile(new File(fileObject.toUri())); return (file.exists() ? new FileInputStream(file) : fileObject.toUri().toURL().openStream()); } + File locateAdditionalMetadataFile(File standardLocation) throws IOException { + if (standardLocation.exists()) { + return standardLocation; + } + return new File(locateGradleResourcesFolder(standardLocation), + ADDITIONAL_METADATA_PATH); + } + + private File locateGradleResourcesFolder(File standardAdditionalMetadataLocation) + throws FileNotFoundException { + String path = standardAdditionalMetadataLocation.getPath(); + int index = path.lastIndexOf(CLASSES_FOLDER); + if (index < 0) { + throw new FileNotFoundException(); + } + String buildFolderPath = path.substring(0, index); + File classOutputLocation = standardAdditionalMetadataLocation.getParentFile() + .getParentFile(); + return new File(buildFolderPath, + RESOURCES_FOLDER + '/' + classOutputLocation.getName()); + } + } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MetadataStoreTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MetadataStoreTests.java new file mode 100644 index 00000000000..c54e0579725 --- /dev/null +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MetadataStoreTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012-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.boot.configurationprocessor; + +import java.io.File; +import java.io.IOException; + +import javax.annotation.processing.ProcessingEnvironment; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link MetadataStore}. + * + * @author Andy Wilkinson + */ +public class MetadataStoreTests { + + @Rule + public final TemporaryFolder temp = new TemporaryFolder(); + + private final MetadataStore metadataStore = new MetadataStore( + mock(ProcessingEnvironment.class)); + + @Test + public void additionalMetadataIsLocatedInMavenBuild() throws IOException { + File app = this.temp.newFolder("app"); + File classesLocation = new File(app, "target/classes"); + File metaInf = new File(classesLocation, "META-INF"); + metaInf.mkdirs(); + File additionalMetadata = new File(metaInf, + "additional-spring-configuration-metadata.json"); + additionalMetadata.createNewFile(); + assertThat( + this.metadataStore.locateAdditionalMetadataFile(new File(classesLocation, + "META-INF/additional-spring-configuration-metadata.json"))) + .isEqualTo(additionalMetadata); + } + + @Test + public void additionalMetadataIsLocatedInGradle3Build() throws IOException { + File app = this.temp.newFolder("app"); + File classesLocation = new File(app, "build/classes/main"); + File resourcesLocation = new File(app, "build/resources/main"); + File metaInf = new File(resourcesLocation, "META-INF"); + metaInf.mkdirs(); + File additionalMetadata = new File(metaInf, + "additional-spring-configuration-metadata.json"); + additionalMetadata.createNewFile(); + assertThat( + this.metadataStore.locateAdditionalMetadataFile(new File(classesLocation, + "META-INF/additional-spring-configuration-metadata.json"))) + .isEqualTo(additionalMetadata); + } + + @Test + public void additionalMetadataIsLocatedInGradle4Build() throws IOException { + File app = this.temp.newFolder("app"); + File classesLocation = new File(app, "build/classes/java/main"); + File resourcesLocation = new File(app, "build/resources/main"); + File metaInf = new File(resourcesLocation, "META-INF"); + metaInf.mkdirs(); + File additionalMetadata = new File(metaInf, + "additional-spring-configuration-metadata.json"); + additionalMetadata.createNewFile(); + assertThat( + this.metadataStore.locateAdditionalMetadataFile(new File(classesLocation, + "META-INF/additional-spring-configuration-metadata.json"))) + .isEqualTo(additionalMetadata); + } + +}