Merge branch 'gh-2313'
commit
afe3bc0938
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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 javax.annotation.processing.RoundEnvironment;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
|
||||
/**
|
||||
* A {@code BuildTracker} tracks a build in which configuration processing has been
|
||||
* performed and is responsible for managing the associated state including the resulting
|
||||
* metadata.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public interface BuildHandler {
|
||||
|
||||
void addGroup(String name, String type, String sourceType, String sourceMethod);
|
||||
|
||||
void addProperty(String prefix, String name, String type, String sourceType,
|
||||
String sourceMethod, String description, Object defaultValue,
|
||||
boolean deprecated);
|
||||
|
||||
void processing(RoundEnvironment environment);
|
||||
|
||||
ConfigurationMetadata produceMetadata();
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
|
||||
|
||||
/**
|
||||
* {@code BuildHandler} that provides incremental build support by merging the metadata
|
||||
* from the current incremental build with any existing metadata.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Kris De Volder
|
||||
* @since 1.2.2
|
||||
*/
|
||||
public class IncrementalBuildHandler extends StandardBuildHandler {
|
||||
|
||||
private final Set<String> processedSourceTypes = new HashSet<String>();
|
||||
|
||||
private final ProcessingEnvironment processingEnvironment;
|
||||
|
||||
private final ConfigurationMetadata existingMetadata;
|
||||
|
||||
private final TypeUtils typeUtils;
|
||||
|
||||
/**
|
||||
* Creates a new {@code IncrementalBuildTracker} that will merge the metadata produced
|
||||
* by an incremental build with the given {@code existingMetadata}.
|
||||
*
|
||||
* @param processingEnvironment The processing environment of the build
|
||||
* @param existingMetadata The existing metadata
|
||||
*/
|
||||
public IncrementalBuildHandler(ProcessingEnvironment processingEnvironment,
|
||||
ConfigurationMetadata existingMetadata) {
|
||||
this.existingMetadata = existingMetadata;
|
||||
this.processingEnvironment = processingEnvironment;
|
||||
this.typeUtils = new TypeUtils(processingEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(RoundEnvironment environment) {
|
||||
for (Element element : environment.getRootElements()) {
|
||||
markAsProcessed(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationMetadata produceMetadata() {
|
||||
ConfigurationMetadata metadata = super.produceMetadata();
|
||||
mergeExistingMetadata(metadata);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private void markAsProcessed(Element element) {
|
||||
if (element instanceof TypeElement) {
|
||||
this.processedSourceTypes.add(this.typeUtils.getType(element));
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeExistingMetadata(ConfigurationMetadata metadata) {
|
||||
List<ItemMetadata> items = this.existingMetadata.getItems();
|
||||
for (ItemMetadata oldItem : items) {
|
||||
if (shouldBeMerged(oldItem)) {
|
||||
metadata.add(oldItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldBeMerged(ItemMetadata itemMetadata) {
|
||||
String sourceType = itemMetadata.getSourceType();
|
||||
if (sourceType == null || deletedInCurrentBuild(sourceType)
|
||||
|| processedInCurrentBuild(sourceType)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean deletedInCurrentBuild(String sourceType) {
|
||||
return this.processingEnvironment.getElementUtils().getTypeElement(sourceType) == null;
|
||||
}
|
||||
|
||||
private boolean processedInCurrentBuild(String sourceType) {
|
||||
return this.processedSourceTypes.contains(sourceType);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
|
||||
/**
|
||||
* A {@code MetadataStore} is responsible for the storage of metadata on the filesystem
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.2
|
||||
*/
|
||||
public class MetadataStore {
|
||||
|
||||
static final String METADATA_PATH = "META-INF/spring-configuration-metadata.json";
|
||||
|
||||
private static final String ADDITIONAL_METADATA_PATH = "META-INF/additional-spring-configuration-metadata.json";
|
||||
|
||||
private static final String RESOURCES_FOLDER = "resources";
|
||||
|
||||
private static final String CLASSES_FOLDER = "classes";
|
||||
|
||||
private final ProcessingEnvironment environment;
|
||||
|
||||
public MetadataStore(ProcessingEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public ConfigurationMetadata readMetadata() {
|
||||
try {
|
||||
return readMetadata(getMetadataResource().openInputStream());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeMetadata(ConfigurationMetadata metadata) throws IOException {
|
||||
if (!metadata.getItems().isEmpty()) {
|
||||
OutputStream outputStream = createMetadataResource().openOutputStream();
|
||||
try {
|
||||
new JsonMarshaller().write(metadata, outputStream);
|
||||
}
|
||||
finally {
|
||||
outputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigurationMetadata readAdditionalMetadata() throws IOException {
|
||||
return readMetadata(getAdditionalMetadataStream());
|
||||
}
|
||||
|
||||
private ConfigurationMetadata readMetadata(InputStream in) throws IOException {
|
||||
try {
|
||||
return new JsonMarshaller().read(in);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
private FileObject getMetadataResource() throws IOException {
|
||||
FileObject resource = this.environment.getFiler().getResource(
|
||||
StandardLocation.CLASS_OUTPUT, "", METADATA_PATH);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private FileObject createMetadataResource() throws IOException {
|
||||
FileObject resource = this.environment.getFiler().createResource(
|
||||
StandardLocation.CLASS_OUTPUT, "", METADATA_PATH);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private InputStream getAdditionalMetadataStream() throws IOException {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
return (file.exists() ? new FileInputStream(file) : fileObject.toUri().toURL()
|
||||
.openStream());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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 javax.annotation.processing.RoundEnvironment;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@code BuildHandler} that handles the state of a single
|
||||
* build.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.2
|
||||
*/
|
||||
public class StandardBuildHandler implements BuildHandler {
|
||||
|
||||
private final ConfigurationMetadata metadata = new ConfigurationMetadata();
|
||||
|
||||
@Override
|
||||
public void addGroup(String name, String type, String sourceType, String sourceMethod) {
|
||||
this.metadata.add(ItemMetadata.newGroup(name, type, sourceType, sourceMethod));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProperty(String prefix, String name, String type, String sourceType,
|
||||
String sourceMethod, String description, Object defaultValue,
|
||||
boolean deprecated) {
|
||||
this.metadata.add(ItemMetadata.newProperty(prefix, name, type, sourceType,
|
||||
sourceMethod, description, defaultValue, deprecated));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(RoundEnvironment environment) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationMetadata produceMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
@SupportedAnnotationTypes({ "*" })
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class TestConfigurationMetadataAnnotationProcessor extends
|
||||
ConfigurationMetadataAnnotationProcessor {
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_ANNOTATION = "org.springframework.boot.configurationsample.ConfigurationProperties";
|
||||
|
||||
static final String NESTED_CONFIGURATION_PROPERTY_ANNOTATION = "org.springframework.boot.configurationsample.NestedConfigurationProperty";
|
||||
|
||||
private ConfigurationMetadata metadata;
|
||||
|
||||
private final File outputLocation;
|
||||
|
||||
public TestConfigurationMetadataAnnotationProcessor(File outputLocation) {
|
||||
this.outputLocation = outputLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String configurationPropertiesAnnotation() {
|
||||
return CONFIGURATION_PROPERTIES_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String nestedConfigurationPropertyAnnotation() {
|
||||
return NESTED_CONFIGURATION_PROPERTY_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigurationMetadata writeMetaData() {
|
||||
super.writeMetaData();
|
||||
try {
|
||||
File metadataFile = new File(this.outputLocation,
|
||||
"META-INF/spring-configuration-metadata.json");
|
||||
if (metadataFile.isFile()) {
|
||||
this.metadata = new JsonMarshaller().read(new FileInputStream(
|
||||
metadataFile));
|
||||
}
|
||||
else {
|
||||
this.metadata = new ConfigurationMetadata();
|
||||
}
|
||||
return this.metadata;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("Failed to read metadata from disk", e);
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigurationMetadata getMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.boot.configurationprocessor.TestCompiler.TestCompilationTask;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
import org.springframework.boot.configurationsample.NestedConfigurationProperty;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
|
||||
import static org.springframework.boot.configurationprocessor.TestCompiler.ORIGINAL_SOURCE_FOLDER;
|
||||
import static org.springframework.boot.configurationprocessor.TestCompiler.sourcePathFor;
|
||||
|
||||
/**
|
||||
* A TestProject contains a copy of a subset of test sample code.
|
||||
* <p>
|
||||
* Why a copy? Because when doing incremental build testing, we need to make modifications
|
||||
* to the contents of the 'test project'. But we don't want to actually modify the
|
||||
* original content itself.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class TestProject {
|
||||
|
||||
private static final Class<?>[] ALWAYS_INCLUDE = { ConfigurationProperties.class,
|
||||
NestedConfigurationProperty.class };
|
||||
|
||||
/**
|
||||
* Contains copies of the original source so we can modify it safely to test
|
||||
* incremental builds.
|
||||
*/
|
||||
private File sourceFolder;
|
||||
private TestCompiler compiler;
|
||||
|
||||
private Set<File> sourceFiles = new LinkedHashSet<File>();
|
||||
|
||||
public TestProject(TemporaryFolder tempFolder, Class<?>... classes)
|
||||
throws IOException {
|
||||
this.sourceFolder = tempFolder.newFolder();
|
||||
this.compiler = new TestCompiler(tempFolder) {
|
||||
@Override
|
||||
protected File getSourceFolder() {
|
||||
return TestProject.this.sourceFolder;
|
||||
}
|
||||
};
|
||||
Set<Class<?>> contents = new HashSet<Class<?>>(Arrays.asList(classes));
|
||||
contents.addAll(Arrays.asList(ALWAYS_INCLUDE));
|
||||
copySources(contents);
|
||||
}
|
||||
|
||||
private void copySources(Set<Class<?>> contents) throws IOException {
|
||||
for (Class<?> klass : contents) {
|
||||
copySources(klass);
|
||||
}
|
||||
}
|
||||
|
||||
private void copySources(Class<?> klass) throws IOException {
|
||||
File original = getOriginalSourceFile(klass);
|
||||
File target = getSourceFile(klass);
|
||||
target.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy(original, target);
|
||||
this.sourceFiles.add(target);
|
||||
}
|
||||
|
||||
public File getSourceFile(Class<?> klass) {
|
||||
return new File(this.sourceFolder, sourcePathFor(klass));
|
||||
}
|
||||
|
||||
public ConfigurationMetadata fullBuild() {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
TestCompilationTask task = this.compiler.getTask(this.sourceFiles);
|
||||
deleteFolderContents(this.compiler.getOutputLocation());
|
||||
task.call(processor);
|
||||
return processor.getMetadata();
|
||||
}
|
||||
|
||||
public ConfigurationMetadata incrementalBuild(Class<?>... toRecompile) {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
TestCompilationTask task = this.compiler.getTask(toRecompile);
|
||||
task.call(processor);
|
||||
return processor.getMetadata();
|
||||
}
|
||||
|
||||
private void deleteFolderContents(File outputFolder) {
|
||||
FileSystemUtils.deleteRecursively(outputFolder);
|
||||
outputFolder.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve File relative to project's output folder.
|
||||
*/
|
||||
public File getOutputFile(String relativePath) {
|
||||
Assert.assertFalse(new File(relativePath).isAbsolute());
|
||||
return new File(this.compiler.getOutputLocation(), relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source code at the end of file, just before last '}'
|
||||
*/
|
||||
public void addSourceCode(Class<?> target, InputStream snippetStream)
|
||||
throws Exception {
|
||||
File targetFile = getSourceFile(target);
|
||||
String contents = getContents(targetFile);
|
||||
int insertAt = contents.lastIndexOf('}');
|
||||
String additionalSource = FileCopyUtils.copyToString(new InputStreamReader(
|
||||
snippetStream));
|
||||
contents = contents.substring(0, insertAt) + additionalSource
|
||||
+ contents.substring(insertAt);
|
||||
putContents(targetFile, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete source file for given class from project.
|
||||
*/
|
||||
public void delete(Class<?> klass) {
|
||||
File target = getSourceFile(klass);
|
||||
target.delete();
|
||||
this.sourceFiles.remove(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore source code of given class to its original contents.
|
||||
*/
|
||||
public void revert(Class<?> klass) throws IOException {
|
||||
Assert.assertTrue(getSourceFile(klass).exists());
|
||||
copySources(klass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source code of given class to this project.
|
||||
*/
|
||||
public void add(Class<?> klass) throws IOException {
|
||||
Assert.assertFalse(getSourceFile(klass).exists());
|
||||
copySources(klass);
|
||||
}
|
||||
|
||||
public void replaceText(Class<?> klass, String find, String replace) throws Exception {
|
||||
File target = getSourceFile(klass);
|
||||
String contents = getContents(target);
|
||||
contents = contents.replace(find, replace);
|
||||
putContents(target, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the 'original' source code for given test class. Clients or subclasses should
|
||||
* have no need to know about these. They should work only with the copied source
|
||||
* code.
|
||||
*/
|
||||
private File getOriginalSourceFile(Class<?> klass) {
|
||||
return new File(ORIGINAL_SOURCE_FOLDER, sourcePathFor(klass));
|
||||
}
|
||||
|
||||
private static void putContents(File targetFile, String contents)
|
||||
throws FileNotFoundException, IOException, UnsupportedEncodingException {
|
||||
FileCopyUtils.copy(new StringReader(contents), new FileWriter(targetFile));
|
||||
}
|
||||
|
||||
private static String getContents(File file) throws Exception {
|
||||
return FileCopyUtils.copyToString(new FileReader(file));
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.configurationsample.incremental;
|
||||
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties("bar")
|
||||
public class BarProperties {
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* A nice counter description.
|
||||
*/
|
||||
private Integer counter = 0;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getCounter() {
|
||||
return this.counter;
|
||||
}
|
||||
|
||||
public void setCounter(Integer counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.configurationsample.incremental;
|
||||
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties("foo")
|
||||
public class FooProperties {
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* A nice counter description.
|
||||
*/
|
||||
private Integer counter = 0;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getCounter() {
|
||||
return this.counter;
|
||||
}
|
||||
|
||||
public void setCounter(Integer counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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.configurationsample.incremental;
|
||||
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties("bar")
|
||||
public class RenamedBarProperties {
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* A nice counter description.
|
||||
*/
|
||||
private Integer counter = 0;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getCounter() {
|
||||
return this.counter;
|
||||
}
|
||||
|
||||
public void setCounter(Integer counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
private String extra;
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
Loading…
Reference in New Issue