This commit is contained in:
Phillip Webb 2015-02-01 21:37:17 -08:00
parent 3328c1369f
commit 072f873f34
12 changed files with 79 additions and 191 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -128,9 +128,8 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
} }
private boolean runningOnWebSphere() { private boolean runningOnWebSphere() {
return ClassUtils.isPresent( return ClassUtils.isPresent("com.ibm.websphere.jtaextensions."
"com.ibm.websphere.jtaextensions.ExtendedJTATransaction", getClass() + "ExtendedJTATransaction", getClass().getClassLoader());
.getClassLoader());
} }
private void configureWebSphereTransactionPlatform( private void configureWebSphereTransactionPlatform(
@ -142,18 +141,6 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
return getJtaPlatformManager(WEBSHERE_JTA_PLATFORM_CLASSES); return getJtaPlatformManager(WEBSHERE_JTA_PLATFORM_CLASSES);
} }
private Object getJtaPlatformManager(String[] candidates) {
for (String candidate : candidates) {
try {
return Class.forName(candidate).newInstance();
}
catch (Exception ex) {
// Continue searching
}
}
throw new IllegalStateException("Could not configure JTA platform");
}
private void configureSpringJtaPlatform(Map<String, Object> vendorProperties, private void configureSpringJtaPlatform(Map<String, Object> vendorProperties,
JtaTransactionManager jtaTransactionManager) { JtaTransactionManager jtaTransactionManager) {
try { try {
@ -162,18 +149,15 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
} }
catch (NoClassDefFoundError ex) { catch (NoClassDefFoundError ex) {
// Can happen if Hibernate 4.2 is used // Can happen if Hibernate 4.2 is used
if (isUsingJndi()) { if (!isUsingJndi()) {
// Assume that Hibernate will use JNDI
if (logger.isDebugEnabled()) {
logger.debug("Unable to set Hibernate JTA platform : "
+ ex.getMessage());
}
}
else {
throw new IllegalStateException("Unable to set Hibernate JTA " throw new IllegalStateException("Unable to set Hibernate JTA "
+ "platform, are you using the correct " + "platform, are you using the correct "
+ "version of Hibernate?", ex); + "version of Hibernate?", ex);
} }
// Assume that Hibernate will use JNDI
if (logger.isDebugEnabled()) {
logger.debug("Unable to set Hibernate JTA platform : " + ex.getMessage());
}
} }
} }
@ -190,6 +174,18 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
return getJtaPlatformManager(NO_JTA_PLATFORM_CLASSES); return getJtaPlatformManager(NO_JTA_PLATFORM_CLASSES);
} }
private Object getJtaPlatformManager(String[] candidates) {
for (String candidate : candidates) {
try {
return Class.forName(candidate).newInstance();
}
catch (Exception ex) {
// Continue searching
}
}
throw new IllegalStateException("Could not configure JTA platform");
}
@Order(Ordered.HIGHEST_PRECEDENCE + 20) @Order(Ordered.HIGHEST_PRECEDENCE + 20)
static class HibernateEntityManagerCondition extends SpringBootCondition { static class HibernateEntityManagerCondition extends SpringBootCondition {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -144,7 +144,8 @@ public class HttpMessageConvertersAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public StringHttpMessageConverter stringHttpMessageConverter() { public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(this.encodingProperties.getCharset()); StringHttpMessageConverter converter = new StringHttpMessageConverter(
this.encodingProperties.getCharset());
converter.setWriteAcceptCharset(false); converter.setWriteAcceptCharset(false);
return converter; return converter;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -2211,7 +2211,6 @@ functionality.
[[howto-use-java-6-embedded-container]] [[howto-use-java-6-embedded-container]]
==== Embedded servlet container compatibility ==== Embedded servlet container compatibility
If you are using one of Boot's embedded Servlet containers you will have to use a If you are using one of Boot's embedded Servlet containers you will have to use a
Java 6-compatible container. Both Tomcat 7 and Jetty 8 are Java 6 compatible. See Java 6-compatible container. Both Tomcat 7 and Jetty 8 are Java 6 compatible. See
<<howto-use-tomcat-7>> and <<howto-use-jetty-8>> for details. <<howto-use-tomcat-7>> and <<howto-use-jetty-8>> for details.
@ -2220,7 +2219,6 @@ Java 6-compatible container. Both Tomcat 7 and Jetty 8 are Java 6 compatible. Se
[[how-to-use-java-6-jta-api]] [[how-to-use-java-6-jta-api]]
==== JTA API compatibility ==== JTA API compatibility
While the Java Transaction API itself doesn't require Java 7 the official API jar While the Java Transaction API itself doesn't require Java 7 the official API jar
contains classes that have been built to require Java 7. If you are using JTA then contains classes that have been built to require Java 7. If you are using JTA then
you will need to replace the official JTA 1.2 API jar with one that has been built you will need to replace the official JTA 1.2 API jar with one that has been built

View File

@ -1,42 +0,0 @@
/*
* 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();
}

View File

@ -47,6 +47,7 @@ import javax.tools.Diagnostic.Kind;
import org.springframework.boot.configurationprocessor.fieldvalues.FieldValuesParser; import org.springframework.boot.configurationprocessor.fieldvalues.FieldValuesParser;
import org.springframework.boot.configurationprocessor.fieldvalues.javac.JavaCompilerFieldValuesParser; import org.springframework.boot.configurationprocessor.fieldvalues.javac.JavaCompilerFieldValuesParser;
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
/** /**
* Annotation {@link Processor} that writes meta-data file for * Annotation {@link Processor} that writes meta-data file for
@ -74,7 +75,7 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
private MetadataStore metadataStore; private MetadataStore metadataStore;
private BuildHandler buildHandler; private MetadataCollector metadataCollector;
private TypeUtils typeUtils; private TypeUtils typeUtils;
@ -100,7 +101,7 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
super.init(env); super.init(env);
this.typeUtils = new TypeUtils(env); this.typeUtils = new TypeUtils(env);
this.metadataStore = new MetadataStore(env); this.metadataStore = new MetadataStore(env);
this.buildHandler = createBuildHandler(env, this.metadataStore); this.metadataCollector = new MetadataCollector(env, this.metadataStore.readMetadata());
try { try {
this.fieldValuesParser = new JavaCompilerFieldValuesParser(env); this.fieldValuesParser = new JavaCompilerFieldValuesParser(env);
} }
@ -111,21 +112,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
} }
} }
private BuildHandler createBuildHandler(ProcessingEnvironment env,
MetadataStore metadataStore) {
ConfigurationMetadata existingMetadata = metadataStore.readMetadata();
if (existingMetadata != null) {
return new IncrementalBuildHandler(env, existingMetadata);
}
else {
return new StandardBuildHandler();
}
}
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) { RoundEnvironment roundEnv) {
this.buildHandler.processing(roundEnv); this.metadataCollector.processing(roundEnv);
Elements elementUtils = this.processingEnv.getElementUtils(); Elements elementUtils = this.processingEnv.getElementUtils();
for (Element element : roundEnv.getElementsAnnotatedWith(elementUtils for (Element element : roundEnv.getElementsAnnotatedWith(elementUtils
.getTypeElement(configurationPropertiesAnnotation()))) { .getTypeElement(configurationPropertiesAnnotation()))) {
@ -153,7 +143,7 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
private void processAnnotatedTypeElement(String prefix, TypeElement element) { private void processAnnotatedTypeElement(String prefix, TypeElement element) {
String type = this.typeUtils.getType(element); String type = this.typeUtils.getType(element);
this.buildHandler.addGroup(prefix, type, type, null); this.metadataCollector.add(ItemMetadata.newGroup(prefix, type, type, null));
processTypeElement(prefix, element); processTypeElement(prefix, element);
} }
@ -163,9 +153,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
Element returns = this.processingEnv.getTypeUtils().asElement( Element returns = this.processingEnv.getTypeUtils().asElement(
element.getReturnType()); element.getReturnType());
if (returns instanceof TypeElement) { if (returns instanceof TypeElement) {
this.buildHandler.addGroup(prefix, this.typeUtils.getType(returns), this.metadataCollector.add(ItemMetadata.newGroup(prefix,
this.typeUtils.getType(returns),
this.typeUtils.getType(element.getEnclosingElement()), this.typeUtils.getType(element.getEnclosingElement()),
element.toString()); element.toString()));
processTypeElement(prefix, (TypeElement) returns); processTypeElement(prefix, (TypeElement) returns);
} }
} }
@ -210,8 +201,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
boolean deprecated = hasDeprecateAnnotation(getter) boolean deprecated = hasDeprecateAnnotation(getter)
|| hasDeprecateAnnotation(setter) || hasDeprecateAnnotation(setter)
|| hasDeprecateAnnotation(element); || hasDeprecateAnnotation(element);
this.buildHandler.addProperty(prefix, name, dataType, sourceType, null, this.metadataCollector.add(ItemMetadata
description, defaultValue, deprecated); .newProperty(prefix, name, dataType, sourceType, null,
description, defaultValue, deprecated));
} }
} }
} }
@ -238,8 +230,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
Object defaultValue = fieldValues.get(name); Object defaultValue = fieldValues.get(name);
boolean deprecated = hasDeprecateAnnotation(field) boolean deprecated = hasDeprecateAnnotation(field)
|| hasDeprecateAnnotation(element); || hasDeprecateAnnotation(element);
this.buildHandler.addProperty(prefix, name, dataType, sourceType, null, this.metadataCollector.add(ItemMetadata
description, defaultValue, deprecated); .newProperty(prefix, name, dataType, sourceType, null,
description, defaultValue, deprecated));
} }
} }
} }
@ -272,9 +265,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
if (returnType != null && returnType instanceof TypeElement if (returnType != null && returnType instanceof TypeElement
&& annotation == null && isNested) { && annotation == null && isNested) {
String nestedPrefix = ConfigurationMetadata.nestedPrefix(prefix, name); String nestedPrefix = ConfigurationMetadata.nestedPrefix(prefix, name);
this.buildHandler.addGroup(nestedPrefix, this.metadataCollector.add(ItemMetadata.newGroup(nestedPrefix,
this.typeUtils.getType(returnType), this.typeUtils.getType(returnType),
this.typeUtils.getType(element), getter.toString()); this.typeUtils.getType(element), getter.toString()));
processTypeElement(nestedPrefix, (TypeElement) returnType); processTypeElement(nestedPrefix, (TypeElement) returnType);
} }
} }
@ -332,7 +325,7 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
} }
protected ConfigurationMetadata writeMetaData() { protected ConfigurationMetadata writeMetaData() {
ConfigurationMetadata metadata = this.buildHandler.produceMetadata(); ConfigurationMetadata metadata = this.metadataCollector.getMetadata();
metadata = mergeAdditionalMetadata(metadata); metadata = mergeAdditionalMetadata(metadata);
if (!metadata.getItems().isEmpty()) { if (!metadata.getItems().isEmpty()) {
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.configurationprocessor; package org.springframework.boot.configurationprocessor;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -29,73 +30,72 @@ import org.springframework.boot.configurationprocessor.metadata.ConfigurationMet
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
/** /**
* {@code BuildHandler} that provides incremental build support by merging the metadata * Used by {@link ConfigurationMetadataAnnotationProcessor} to collect
* from the current incremental build with any existing metadata. * {@link ConfigurationMetadata}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Kris De Volder * @author Kris De Volder
* @since 1.2.2 * @since 1.2.2
*/ */
public class IncrementalBuildHandler extends StandardBuildHandler { public class MetadataCollector {
private final Set<String> processedSourceTypes = new HashSet<String>(); private final List<ItemMetadata> metadataItems = new ArrayList<ItemMetadata>();
private final ProcessingEnvironment processingEnvironment; private final ProcessingEnvironment processingEnvironment;
private final ConfigurationMetadata existingMetadata; private final ConfigurationMetadata previousMetadata;
private final TypeUtils typeUtils; private final TypeUtils typeUtils;
private final Set<String> processedSourceTypes = new HashSet<String>();
/** /**
* Creates a new {@code IncrementalBuildTracker} that will merge the metadata produced * Creates a new {@code MetadataProcessor} instance.
* by an incremental build with the given {@code existingMetadata}.
*
* @param processingEnvironment The processing environment of the build * @param processingEnvironment The processing environment of the build
* @param existingMetadata The existing metadata * @param previousMetadata Any previous metadata or {@code null}
*/ */
public IncrementalBuildHandler(ProcessingEnvironment processingEnvironment, public MetadataCollector(ProcessingEnvironment processingEnvironment,
ConfigurationMetadata existingMetadata) { ConfigurationMetadata previousMetadata) {
this.existingMetadata = existingMetadata;
this.processingEnvironment = processingEnvironment; this.processingEnvironment = processingEnvironment;
this.previousMetadata = previousMetadata;
this.typeUtils = new TypeUtils(processingEnvironment); this.typeUtils = new TypeUtils(processingEnvironment);
} }
@Override public void processing(RoundEnvironment roundEnv) {
public void processing(RoundEnvironment environment) { for (Element element : roundEnv.getRootElements()) {
for (Element element : environment.getRootElements()) {
markAsProcessed(element); markAsProcessed(element);
} }
} }
@Override
public ConfigurationMetadata produceMetadata() {
ConfigurationMetadata metadata = super.produceMetadata();
mergeExistingMetadata(metadata);
return metadata;
}
private void markAsProcessed(Element element) { private void markAsProcessed(Element element) {
if (element instanceof TypeElement) { if (element instanceof TypeElement) {
this.processedSourceTypes.add(this.typeUtils.getType(element)); this.processedSourceTypes.add(this.typeUtils.getType(element));
} }
} }
private void mergeExistingMetadata(ConfigurationMetadata metadata) { public void add(ItemMetadata metadata) {
List<ItemMetadata> items = this.existingMetadata.getItems(); this.metadataItems.add(metadata);
for (ItemMetadata oldItem : items) { }
if (shouldBeMerged(oldItem)) {
metadata.add(oldItem); public ConfigurationMetadata getMetadata() {
ConfigurationMetadata metadata = new ConfigurationMetadata();
for (ItemMetadata item : this.metadataItems) {
metadata.add(item);
}
if (this.previousMetadata != null) {
List<ItemMetadata> items = this.previousMetadata.getItems();
for (ItemMetadata item : items) {
if (shouldBeMerged(item)) {
metadata.add(item);
}
} }
} }
return metadata;
} }
private boolean shouldBeMerged(ItemMetadata itemMetadata) { private boolean shouldBeMerged(ItemMetadata itemMetadata) {
String sourceType = itemMetadata.getSourceType(); String sourceType = itemMetadata.getSourceType();
if (sourceType == null || deletedInCurrentBuild(sourceType) return (sourceType != null && !deletedInCurrentBuild(sourceType) && !processedInCurrentBuild(sourceType));
|| processedInCurrentBuild(sourceType)) {
return false;
}
return true;
} }
private boolean deletedInCurrentBuild(String sourceType) { private boolean deletedInCurrentBuild(String sourceType) {

View File

@ -1,58 +0,0 @@
/*
* 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;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.