Skip to content

Commit f8af6c8

Browse files
committed
Merge branch '1.5.x'
2 parents ffc99b0 + d8b1f16 commit f8af6c8

File tree

5 files changed

+215
-35
lines changed

5 files changed

+215
-35
lines changed

spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeUtils.java

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import javax.lang.model.element.Element;
2626
import javax.lang.model.element.TypeElement;
2727
import javax.lang.model.type.DeclaredType;
28+
import javax.lang.model.type.PrimitiveType;
2829
import javax.lang.model.type.TypeKind;
2930
import javax.lang.model.type.TypeMirror;
31+
import javax.lang.model.util.SimpleTypeVisitor8;
3032
import javax.lang.model.util.Types;
3133

3234
/**
@@ -65,13 +67,16 @@ class TypeUtils {
6567

6668
private final ProcessingEnvironment env;
6769

70+
private final TypeExtractor typeExtractor;
71+
6872
private final TypeMirror collectionType;
6973

7074
private final TypeMirror mapType;
7175

7276
TypeUtils(ProcessingEnvironment env) {
7377
this.env = env;
7478
Types types = env.getTypeUtils();
79+
this.typeExtractor = new TypeExtractor(types);
7580
this.collectionType = getDeclaredType(types, Collection.class, 1);
7681
this.mapType = getDeclaredType(types, Map.class, 2);
7782
}
@@ -100,20 +105,7 @@ private TypeMirror getDeclaredType(Types types, Class<?> typeClass,
100105
* {@link Class#forName(String)}
101106
*/
102107
public String getQualifiedName(Element element) {
103-
if (element == null) {
104-
return null;
105-
}
106-
TypeElement enclosingElement = getEnclosingTypeElement(element.asType());
107-
if (enclosingElement != null) {
108-
return getQualifiedName(enclosingElement) + "$"
109-
+ ((DeclaredType) element.asType()).asElement().getSimpleName()
110-
.toString();
111-
}
112-
if (element instanceof TypeElement) {
113-
return ((TypeElement) element).getQualifiedName().toString();
114-
}
115-
throw new IllegalStateException(
116-
"Could not extract qualified name from " + element);
108+
return this.typeExtractor.getQualifiedName(element);
117109
}
118110

119111
/**
@@ -126,27 +118,7 @@ public String getType(TypeMirror type) {
126118
if (type == null) {
127119
return null;
128120
}
129-
Class<?> wrapper = getWrapperFor(type);
130-
if (wrapper != null) {
131-
return wrapper.getName();
132-
}
133-
TypeElement enclosingElement = getEnclosingTypeElement(type);
134-
if (enclosingElement != null) {
135-
return getQualifiedName(enclosingElement) + "$"
136-
+ ((DeclaredType) type).asElement().getSimpleName().toString();
137-
}
138-
return type.toString();
139-
}
140-
141-
private TypeElement getEnclosingTypeElement(TypeMirror type) {
142-
if (type instanceof DeclaredType) {
143-
DeclaredType declaredType = (DeclaredType) type;
144-
Element enclosingElement = declaredType.asElement().getEnclosingElement();
145-
if (enclosingElement != null && enclosingElement instanceof TypeElement) {
146-
return (TypeElement) enclosingElement;
147-
}
148-
}
149-
return null;
121+
return type.accept(this.typeExtractor, null);
150122
}
151123

152124
public boolean isCollectionOrMap(TypeMirror type) {
@@ -194,4 +166,62 @@ private TypeKind getPrimitiveFor(TypeMirror type) {
194166
return WRAPPER_TO_PRIMITIVE.get(type.toString());
195167
}
196168

169+
170+
/**
171+
* A visitor that extracts the full qualified name of a type, including generic
172+
* information.
173+
*/
174+
private static class TypeExtractor extends SimpleTypeVisitor8<String, Void> {
175+
176+
private final Types types;
177+
178+
TypeExtractor(Types types) {
179+
this.types = types;
180+
}
181+
182+
@Override
183+
public String visitDeclared(DeclaredType type, Void none) {
184+
TypeElement enclosingElement = getEnclosingTypeElement(type);
185+
if (enclosingElement != null) {
186+
return getQualifiedName(enclosingElement) + "$"
187+
+ type.asElement().getSimpleName().toString();
188+
}
189+
return type.toString();
190+
}
191+
192+
@Override
193+
public String visitPrimitive(PrimitiveType t, Void none) {
194+
return this.types.boxedClass(t).getQualifiedName().toString();
195+
}
196+
197+
public String getQualifiedName(Element element) {
198+
if (element == null) {
199+
return null;
200+
}
201+
TypeElement enclosingElement = getEnclosingTypeElement(element.asType());
202+
if (enclosingElement != null) {
203+
return getQualifiedName(enclosingElement) + "$"
204+
+ ((DeclaredType) element.asType()).asElement().getSimpleName()
205+
.toString();
206+
}
207+
if (element instanceof TypeElement) {
208+
return ((TypeElement) element).getQualifiedName().toString();
209+
}
210+
throw new IllegalStateException(
211+
"Could not extract qualified name from " + element);
212+
}
213+
214+
private TypeElement getEnclosingTypeElement(TypeMirror type) {
215+
if (type instanceof DeclaredType) {
216+
DeclaredType declaredType = (DeclaredType) type;
217+
Element enclosingElement = declaredType.asElement().getEnclosingElement();
218+
if (enclosingElement != null && enclosingElement instanceof TypeElement) {
219+
return (TypeElement) enclosingElement;
220+
}
221+
}
222+
return null;
223+
}
224+
225+
}
226+
197227
}

spring-boot-tests/spring-boot-integration-tests/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<java.version>1.8</java.version>
1717
</properties>
1818
<modules>
19+
<module>spring-boot-configuration-processor-tests</module>
1920
<module>spring-boot-devtools-tests</module>
2021
<module>spring-boot-server-tests</module>
2122
<module>spring-boot-launch-script-tests</module>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>org.springframework.boot</groupId>
8+
<artifactId>spring-boot-integration-tests</artifactId>
9+
<version>${revision}</version>
10+
</parent>
11+
<artifactId>spring-boot-configuration-processor-tests</artifactId>
12+
<name>Spring Boot Configuration Processor Tests</name>
13+
<description>${project.name}</description>
14+
<properties>
15+
<main.basedir>${basedir}/../../..</main.basedir>
16+
</properties>
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.springframework.boot</groupId>
20+
<artifactId>spring-boot</artifactId>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-configuration-metadata</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>javax.validation</groupId>
28+
<artifactId>validation-api</artifactId>
29+
</dependency>
30+
31+
<dependency>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-configuration-processor</artifactId>
34+
<optional>true</optional>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-test</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
</dependencies>
42+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example;
18+
19+
import javax.validation.Valid;
20+
21+
import org.springframework.boot.context.properties.ConfigurationProperties;
22+
23+
/**
24+
* Test that a valid type is generated if an annotation is present.
25+
*
26+
* @author Stephane Nicoll
27+
*/
28+
@ConfigurationProperties("annotated")
29+
public class AnnotatedSample {
30+
31+
/**
32+
* A valid name.
33+
*/
34+
private String name;
35+
36+
@Valid
37+
public String getName() {
38+
return this.name;
39+
}
40+
41+
public void setName(String name) {
42+
this.name = name;
43+
}
44+
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.configurationprocessor.tests;
18+
19+
import java.io.IOException;
20+
21+
import org.junit.BeforeClass;
22+
import org.junit.Test;
23+
24+
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
25+
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
26+
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepositoryJsonBuilder;
27+
import org.springframework.core.io.ClassPathResource;
28+
import org.springframework.core.io.Resource;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
32+
/**
33+
* Integration tests for the configuration metadata annotation processor.
34+
*
35+
* @author Stephane Nicoll
36+
*/
37+
public class ConfigurationProcessorIntegrationTests {
38+
39+
private static ConfigurationMetadataRepository repository;
40+
41+
@BeforeClass
42+
public static void readMetadata() throws IOException {
43+
Resource resource = new ClassPathResource(
44+
"META-INF/spring-configuration-metadata.json");
45+
assertThat(resource.exists()).isTrue();
46+
// Make sure the right file is detected
47+
assertThat(resource.getURL().toString()).contains(
48+
"spring-boot-configuration-processor-tests");
49+
repository = ConfigurationMetadataRepositoryJsonBuilder
50+
.create(resource.getInputStream()).build();
51+
52+
}
53+
54+
@Test
55+
public void extractTypeFromAnnotatedGetter() {
56+
ConfigurationMetadataProperty property = repository.getAllProperties().get(
57+
"annotated.name");
58+
assertThat(property).isNotNull();
59+
assertThat(property.getType()).isEqualTo("java.lang.String");
60+
}
61+
62+
}

0 commit comments

Comments
 (0)