Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
3125f424
Commit
3125f424
authored
Feb 26, 2019
by
Stephane Nicoll
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add metadata support for immutable ConfigurationProperties type
Closes gh-16071
parent
35d7fccb
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1422 additions
and
24 deletions
+1422
-24
configuration-metadata.adoc
...cs/src/main/asciidoc/appendix/configuration-metadata.adoc
+5
-2
ConfigurationMetadataAnnotationProcessor.java
...onprocessor/ConfigurationMetadataAnnotationProcessor.java
+9
-2
ConstructorParameterPropertyDescriptor.java
...tionprocessor/ConstructorParameterPropertyDescriptor.java
+224
-0
JavaBeanPropertyDescriptor.java
...ot/configurationprocessor/JavaBeanPropertyDescriptor.java
+5
-0
LombokPropertyDescriptor.java
...boot/configurationprocessor/LombokPropertyDescriptor.java
+5
-0
MetadataGenerationEnvironment.java
...configurationprocessor/MetadataGenerationEnvironment.java
+40
-3
PropertyDescriptor.java
...ework/boot/configurationprocessor/PropertyDescriptor.java
+4
-5
PropertyDescriptorResolver.java
...ot/configurationprocessor/PropertyDescriptorResolver.java
+60
-12
TypeUtils.java
...pringframework/boot/configurationprocessor/TypeUtils.java
+49
-0
ConfigurationMetadataAnnotationProcessorTests.java
...cessor/ConfigurationMetadataAnnotationProcessorTests.java
+25
-0
ConstructorParameterPropertyDescriptorTests.java
...rocessor/ConstructorParameterPropertyDescriptorTests.java
+318
-0
ImmutablePropertiesMetadataGenerationTests.java
...processor/ImmutablePropertiesMetadataGenerationTests.java
+52
-0
MetadataGenerationEnvironmentFactory.java
...rationprocessor/MetadataGenerationEnvironmentFactory.java
+1
-0
PropertyDescriptorResolverTests.java
...nfigurationprocessor/PropertyDescriptorResolverTests.java
+17
-0
TestConfigurationMetadataAnnotationProcessor.java
...or/test/TestConfigurationMetadataAnnotationProcessor.java
+7
-0
DefaultValue.java
...pringframework/boot/configurationsample/DefaultValue.java
+38
-0
ImmutableCollectionProperties.java
...rationsample/immutable/ImmutableCollectionProperties.java
+45
-0
ImmutableInnerClassProperties.java
...rationsample/immutable/ImmutableInnerClassProperties.java
+106
-0
ImmutablePrimitiveProperties.java
...urationsample/immutable/ImmutablePrimitiveProperties.java
+55
-0
ImmutablePrimitiveWithDefaultsProperties.java
...e/immutable/ImmutablePrimitiveWithDefaultsProperties.java
+60
-0
ImmutablePrimitiveWrapperWithDefaultsProperties.java
...able/ImmutablePrimitiveWrapperWithDefaultsProperties.java
+60
-0
ImmutableSimpleProperties.java
...figurationsample/immutable/ImmutableSimpleProperties.java
+71
-0
InvalidDefaultValueCharacterProperties.java
...mple/specific/InvalidDefaultValueCharacterProperties.java
+40
-0
InvalidDefaultValueFloatingPointProperties.java
.../specific/InvalidDefaultValueFloatingPointProperties.java
+42
-0
InvalidDefaultValueNumberProperties.java
...nsample/specific/InvalidDefaultValueNumberProperties.java
+40
-0
TwoConstructorsExample.java
.../configurationsample/specific/TwoConstructorsExample.java
+43
-0
checkstyle-suppressions.xml
src/checkstyle/checkstyle-suppressions.xml
+1
-0
No files found.
spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix/configuration-metadata.adoc
View file @
3125f424
...
@@ -809,8 +809,11 @@ is used to populate the `description` attribute.
...
@@ -809,8 +809,11 @@ is used to populate the `description` attribute.
NOTE
:
You
should
only
use
simple
text
with
`@
ConfigurationProperties
`
field
Javadoc
,
since
NOTE
:
You
should
only
use
simple
text
with
`@
ConfigurationProperties
`
field
Javadoc
,
since
they
are
not
processed
before
being
added
to
the
JSON
.
they
are
not
processed
before
being
added
to
the
JSON
.
Properties
are
discovered
through
the
presence
of
standard
getters
and
setters
with
If
the
class
has
a
single
constructor
with
at
least
one
parameters
,
one
property
is
special
handling
for
collection
types
(
that
is
detected
even
if
only
a
getter
is
present
).
created
per
constructor
parameter
.
Otherwise
,
properties
are
discovered
through
the
presence
of
standard
getters
and
setters
with
special
handling
for
collection
types
(
that
is
detected
even
if
only
a
getter
is
present
).
The
annotation
processor
also
supports
the
use
of
the
`@
Data
`,
`@
Getter
`,
and
`@
Setter
`
The
annotation
processor
also
supports
the
use
of
the
`@
Data
`,
`@
Getter
`,
and
`@
Setter
`
lombok
annotations
.
lombok
annotations
.
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java
View file @
3125f424
...
@@ -73,6 +73,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
...
@@ -73,6 +73,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
static
final
String
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
=
"org.springframework.boot."
static
final
String
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
=
"org.springframework.boot."
+
"context.properties.DeprecatedConfigurationProperty"
;
+
"context.properties.DeprecatedConfigurationProperty"
;
static
final
String
DEFAULT_VALUE_ANNOTATION
=
"org.springframework.boot."
+
"context.properties.bind.DefaultValue"
;
static
final
String
ENDPOINT_ANNOTATION
=
"org.springframework.boot.actuate."
static
final
String
ENDPOINT_ANNOTATION
=
"org.springframework.boot.actuate."
+
"endpoint.annotation.Endpoint"
;
+
"endpoint.annotation.Endpoint"
;
...
@@ -100,6 +103,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
...
@@ -100,6 +103,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
return
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
;
return
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
;
}
}
protected
String
defaultValueAnnotation
()
{
return
DEFAULT_VALUE_ANNOTATION
;
}
protected
String
endpointAnnotation
()
{
protected
String
endpointAnnotation
()
{
return
ENDPOINT_ANNOTATION
;
return
ENDPOINT_ANNOTATION
;
}
}
...
@@ -127,8 +134,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
...
@@ -127,8 +134,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
this
.
metadataEnv
=
new
MetadataGenerationEnvironment
(
env
,
this
.
metadataEnv
=
new
MetadataGenerationEnvironment
(
env
,
configurationPropertiesAnnotation
(),
configurationPropertiesAnnotation
(),
nestedConfigurationPropertyAnnotation
(),
nestedConfigurationPropertyAnnotation
(),
deprecatedConfigurationPropertyAnnotation
(),
endpoint
Annotation
(),
deprecatedConfigurationPropertyAnnotation
(),
defaultValue
Annotation
(),
readOperationAnnotation
());
endpointAnnotation
(),
readOperationAnnotation
());
}
}
@Override
@Override
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptor.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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.List
;
import
java.util.stream.Collectors
;
import
javax.lang.model.element.AnnotationMirror
;
import
javax.lang.model.element.Element
;
import
javax.lang.model.element.ExecutableElement
;
import
javax.lang.model.element.TypeElement
;
import
javax.lang.model.element.VariableElement
;
import
javax.lang.model.type.PrimitiveType
;
import
javax.lang.model.type.TypeMirror
;
import
javax.lang.model.util.TypeKindVisitor8
;
import
javax.tools.Diagnostic.Kind
;
/**
* A {@link PropertyDescriptor} for a constructor parameter.
*
* @author Stephane Nicoll
*/
class
ConstructorParameterPropertyDescriptor
extends
PropertyDescriptor
<
VariableElement
>
{
ConstructorParameterPropertyDescriptor
(
TypeElement
ownerElement
,
ExecutableElement
factoryMethod
,
VariableElement
source
,
String
name
,
TypeMirror
type
,
VariableElement
field
,
ExecutableElement
getter
,
ExecutableElement
setter
)
{
super
(
ownerElement
,
factoryMethod
,
source
,
name
,
type
,
field
,
getter
,
setter
);
}
@Override
protected
boolean
isProperty
(
MetadataGenerationEnvironment
env
)
{
// If it's a constructor parameter, it doesn't matter as we must be able to bind
// it to build the object.
return
!
isNested
(
env
);
}
@Override
protected
Object
resolveDefaultValue
(
MetadataGenerationEnvironment
environment
)
{
Object
defaultValue
=
getDefaultValueFromAnnotation
(
environment
,
getSource
());
if
(
defaultValue
!=
null
)
{
return
defaultValue
;
}
return
getSource
().
asType
().
accept
(
DefaultPrimitiveTypeVisitor
.
INSTANCE
,
null
);
}
private
Object
getDefaultValueFromAnnotation
(
MetadataGenerationEnvironment
environment
,
Element
element
)
{
AnnotationMirror
defaultValueAnnotation
=
environment
.
getDefaultValueAnnotation
(
element
);
if
(
defaultValueAnnotation
!=
null
)
{
List
<
String
>
defaultValue
=
(
List
<
String
>)
environment
.
getAnnotationElementValues
(
defaultValueAnnotation
).
get
(
"value"
);
if
(
defaultValue
!=
null
)
{
try
{
TypeMirror
specificType
=
determineSpecificType
(
environment
);
if
(
defaultValue
.
size
()
==
1
)
{
return
coerceValue
(
specificType
,
defaultValue
.
get
(
0
));
}
return
defaultValue
.
stream
()
.
map
((
value
)
->
coerceValue
(
specificType
,
value
))
.
collect
(
Collectors
.
toList
());
}
catch
(
IllegalArgumentException
ex
)
{
environment
.
getMessager
().
printMessage
(
Kind
.
ERROR
,
ex
.
getMessage
(),
element
,
defaultValueAnnotation
);
}
}
}
return
null
;
}
private
TypeMirror
determineSpecificType
(
MetadataGenerationEnvironment
environment
)
{
TypeMirror
candidate
=
getSource
().
asType
();
TypeMirror
elementCandidate
=
environment
.
getTypeUtils
()
.
extractElementType
(
candidate
);
if
(
elementCandidate
!=
null
)
{
candidate
=
elementCandidate
;
}
PrimitiveType
primitiveType
=
environment
.
getTypeUtils
()
.
getPrimitiveType
(
candidate
);
return
(
primitiveType
!=
null
)
?
primitiveType
:
candidate
;
}
private
Object
coerceValue
(
TypeMirror
type
,
String
value
)
{
Object
coercedValue
=
type
.
accept
(
DefaultValueCoercionTypeVisitor
.
INSTANCE
,
value
);
return
(
coercedValue
!=
null
)
?
coercedValue
:
value
;
}
private
static
class
DefaultValueCoercionTypeVisitor
extends
TypeKindVisitor8
<
Object
,
String
>
{
private
static
final
DefaultValueCoercionTypeVisitor
INSTANCE
=
new
DefaultValueCoercionTypeVisitor
();
private
Integer
parseInteger
(
String
value
)
{
try
{
return
Integer
.
valueOf
(
value
);
}
catch
(
NumberFormatException
ex
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"Invalid number representation '%s'"
,
value
));
}
}
private
Double
parseFloatingPoint
(
String
value
)
{
try
{
return
Double
.
valueOf
(
value
);
}
catch
(
NumberFormatException
ex
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"Invalid floating point representation '%s'"
,
value
));
}
}
@Override
public
Object
visitPrimitiveAsBoolean
(
PrimitiveType
t
,
String
value
)
{
return
Boolean
.
parseBoolean
(
value
);
}
@Override
public
Object
visitPrimitiveAsByte
(
PrimitiveType
t
,
String
value
)
{
return
parseInteger
(
value
);
}
@Override
public
Object
visitPrimitiveAsShort
(
PrimitiveType
t
,
String
value
)
{
return
parseInteger
(
value
);
}
@Override
public
Object
visitPrimitiveAsInt
(
PrimitiveType
t
,
String
value
)
{
return
parseInteger
(
value
);
}
@Override
public
Object
visitPrimitiveAsLong
(
PrimitiveType
t
,
String
value
)
{
return
parseInteger
(
value
);
}
@Override
public
Object
visitPrimitiveAsChar
(
PrimitiveType
t
,
String
value
)
{
if
(
value
.
length
()
>
1
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"Invalid character representation '%s'"
,
value
));
}
return
value
;
}
@Override
public
Object
visitPrimitiveAsFloat
(
PrimitiveType
t
,
String
value
)
{
return
parseFloatingPoint
(
value
);
}
@Override
public
Object
visitPrimitiveAsDouble
(
PrimitiveType
t
,
String
value
)
{
return
parseFloatingPoint
(
value
);
}
}
private
static
class
DefaultPrimitiveTypeVisitor
extends
TypeKindVisitor8
<
Object
,
Void
>
{
private
static
final
DefaultPrimitiveTypeVisitor
INSTANCE
=
new
DefaultPrimitiveTypeVisitor
();
@Override
public
Object
visitPrimitiveAsBoolean
(
PrimitiveType
t
,
Void
ignore
)
{
return
false
;
}
@Override
public
Object
visitPrimitiveAsByte
(
PrimitiveType
t
,
Void
ignore
)
{
return
0
;
}
@Override
public
Object
visitPrimitiveAsShort
(
PrimitiveType
t
,
Void
ignore
)
{
return
0
;
}
@Override
public
Object
visitPrimitiveAsInt
(
PrimitiveType
t
,
Void
ignore
)
{
return
0
;
}
@Override
public
Object
visitPrimitiveAsLong
(
PrimitiveType
t
,
Void
ignore
)
{
return
0L
;
}
@Override
public
Object
visitPrimitiveAsChar
(
PrimitiveType
t
,
Void
ignore
)
{
return
null
;
}
@Override
public
Object
visitPrimitiveAsFloat
(
PrimitiveType
t
,
Void
ignore
)
{
return
0
;
}
@Override
public
Object
visitPrimitiveAsDouble
(
PrimitiveType
t
,
Void
ignore
)
{
return
0
D
;
}
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/JavaBeanPropertyDescriptor.java
View file @
3125f424
...
@@ -41,4 +41,9 @@ class JavaBeanPropertyDescriptor extends PropertyDescriptor<ExecutableElement> {
...
@@ -41,4 +41,9 @@ class JavaBeanPropertyDescriptor extends PropertyDescriptor<ExecutableElement> {
&&
(
getSetter
()
!=
null
||
isCollection
);
&&
(
getSetter
()
!=
null
||
isCollection
);
}
}
@Override
protected
Object
resolveDefaultValue
(
MetadataGenerationEnvironment
environment
)
{
return
environment
.
getFieldDefaultValue
(
getOwnerElement
(),
getName
());
}
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/LombokPropertyDescriptor.java
View file @
3125f424
...
@@ -57,6 +57,11 @@ class LombokPropertyDescriptor extends PropertyDescriptor<VariableElement> {
...
@@ -57,6 +57,11 @@ class LombokPropertyDescriptor extends PropertyDescriptor<VariableElement> {
return
!
env
.
isExcluded
(
getType
())
&&
(
hasSetter
(
env
)
||
isCollection
);
return
!
env
.
isExcluded
(
getType
())
&&
(
hasSetter
(
env
)
||
isCollection
);
}
}
@Override
protected
Object
resolveDefaultValue
(
MetadataGenerationEnvironment
environment
)
{
return
environment
.
getFieldDefaultValue
(
getOwnerElement
(),
getName
());
}
@Override
@Override
protected
boolean
isNested
(
MetadataGenerationEnvironment
environment
)
{
protected
boolean
isNested
(
MetadataGenerationEnvironment
environment
)
{
if
(!
hasLombokPublicAccessor
(
environment
,
true
))
{
if
(!
hasLombokPublicAccessor
(
environment
,
true
))
{
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java
View file @
3125f424
...
@@ -16,14 +16,18 @@
...
@@ -16,14 +16,18 @@
package
org
.
springframework
.
boot
.
configurationprocessor
;
package
org
.
springframework
.
boot
.
configurationprocessor
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
javax.annotation.processing.Messager
;
import
javax.annotation.processing.ProcessingEnvironment
;
import
javax.annotation.processing.ProcessingEnvironment
;
import
javax.lang.model.element.AnnotationMirror
;
import
javax.lang.model.element.AnnotationMirror
;
import
javax.lang.model.element.AnnotationValue
;
import
javax.lang.model.element.Element
;
import
javax.lang.model.element.Element
;
import
javax.lang.model.element.ExecutableElement
;
import
javax.lang.model.element.ExecutableElement
;
import
javax.lang.model.element.TypeElement
;
import
javax.lang.model.element.TypeElement
;
...
@@ -51,6 +55,8 @@ class MetadataGenerationEnvironment {
...
@@ -51,6 +55,8 @@ class MetadataGenerationEnvironment {
private
final
Elements
elements
;
private
final
Elements
elements
;
private
final
Messager
messager
;
private
final
FieldValuesParser
fieldValuesParser
;
private
final
FieldValuesParser
fieldValuesParser
;
private
final
Map
<
TypeElement
,
Map
<
String
,
Object
>>
defaultValues
=
new
HashMap
<>();
private
final
Map
<
TypeElement
,
Map
<
String
,
Object
>>
defaultValues
=
new
HashMap
<>();
...
@@ -61,6 +67,8 @@ class MetadataGenerationEnvironment {
...
@@ -61,6 +67,8 @@ class MetadataGenerationEnvironment {
private
final
String
deprecatedConfigurationPropertyAnnotation
;
private
final
String
deprecatedConfigurationPropertyAnnotation
;
private
final
String
defaultValueAnnotation
;
private
final
String
endpointAnnotation
;
private
final
String
endpointAnnotation
;
private
final
String
readOperationAnnotation
;
private
final
String
readOperationAnnotation
;
...
@@ -68,15 +76,18 @@ class MetadataGenerationEnvironment {
...
@@ -68,15 +76,18 @@ class MetadataGenerationEnvironment {
MetadataGenerationEnvironment
(
ProcessingEnvironment
environment
,
MetadataGenerationEnvironment
(
ProcessingEnvironment
environment
,
String
configurationPropertiesAnnotation
,
String
configurationPropertiesAnnotation
,
String
nestedConfigurationPropertyAnnotation
,
String
nestedConfigurationPropertyAnnotation
,
String
deprecatedConfigurationPropertyAnnotation
,
String
endpointAnnotation
,
String
deprecatedConfigurationPropertyAnnotation
,
String
defaultValueAnnotation
,
String
endpointAnnotation
,
String
readOperationAnnotation
)
{
String
readOperationAnnotation
)
{
this
.
typeExcludes
=
determineTypeExcludes
();
this
.
typeExcludes
=
determineTypeExcludes
();
this
.
typeUtils
=
new
TypeUtils
(
environment
);
this
.
typeUtils
=
new
TypeUtils
(
environment
);
this
.
elements
=
environment
.
getElementUtils
();
this
.
elements
=
environment
.
getElementUtils
();
this
.
messager
=
environment
.
getMessager
();
this
.
fieldValuesParser
=
resolveFieldValuesParser
(
environment
);
this
.
fieldValuesParser
=
resolveFieldValuesParser
(
environment
);
this
.
configurationPropertiesAnnotation
=
configurationPropertiesAnnotation
;
this
.
configurationPropertiesAnnotation
=
configurationPropertiesAnnotation
;
this
.
nestedConfigurationPropertyAnnotation
=
nestedConfigurationPropertyAnnotation
;
this
.
nestedConfigurationPropertyAnnotation
=
nestedConfigurationPropertyAnnotation
;
this
.
deprecatedConfigurationPropertyAnnotation
=
deprecatedConfigurationPropertyAnnotation
;
this
.
deprecatedConfigurationPropertyAnnotation
=
deprecatedConfigurationPropertyAnnotation
;
this
.
defaultValueAnnotation
=
defaultValueAnnotation
;
this
.
endpointAnnotation
=
endpointAnnotation
;
this
.
endpointAnnotation
=
endpointAnnotation
;
this
.
readOperationAnnotation
=
readOperationAnnotation
;
this
.
readOperationAnnotation
=
readOperationAnnotation
;
}
}
...
@@ -112,7 +123,18 @@ class MetadataGenerationEnvironment {
...
@@ -112,7 +123,18 @@ class MetadataGenerationEnvironment {
return
this
.
typeUtils
;
return
this
.
typeUtils
;
}
}
public
Object
getDefaultValue
(
TypeElement
type
,
String
name
)
{
public
Messager
getMessager
()
{
return
this
.
messager
;
}
/**
* Return the default value of the field with the specified {@code name}.
* @param type the type to consider
* @param name the name of the field
* @return the default value or {@code null} if the field does not exist or no default
* value has been detected
*/
public
Object
getFieldDefaultValue
(
TypeElement
type
,
String
name
)
{
return
this
.
defaultValues
.
computeIfAbsent
(
type
,
this
::
resolveFieldValues
)
return
this
.
defaultValues
.
computeIfAbsent
(
type
,
this
::
resolveFieldValues
)
.
get
(
name
);
.
get
(
name
);
}
}
...
@@ -171,10 +193,21 @@ class MetadataGenerationEnvironment {
...
@@ -171,10 +193,21 @@ class MetadataGenerationEnvironment {
public
Map
<
String
,
Object
>
getAnnotationElementValues
(
AnnotationMirror
annotation
)
{
public
Map
<
String
,
Object
>
getAnnotationElementValues
(
AnnotationMirror
annotation
)
{
Map
<
String
,
Object
>
values
=
new
LinkedHashMap
<>();
Map
<
String
,
Object
>
values
=
new
LinkedHashMap
<>();
annotation
.
getElementValues
().
forEach
((
name
,
value
)
->
values
annotation
.
getElementValues
().
forEach
((
name
,
value
)
->
values
.
put
(
name
.
getSimpleName
().
toString
(),
value
.
getValue
(
)));
.
put
(
name
.
getSimpleName
().
toString
(),
getAnnotationValue
(
value
)));
return
values
;
return
values
;
}
}
private
Object
getAnnotationValue
(
AnnotationValue
annotationValue
)
{
Object
value
=
annotationValue
.
getValue
();
if
(
value
instanceof
List
)
{
List
<
Object
>
values
=
new
ArrayList
<>();
((
List
<?>)
value
)
.
forEach
((
v
)
->
values
.
add
(((
AnnotationValue
)
v
).
getValue
()));
return
values
;
}
return
value
;
}
public
TypeElement
getConfigurationPropertiesAnnotationElement
()
{
public
TypeElement
getConfigurationPropertiesAnnotationElement
()
{
return
this
.
elements
.
getTypeElement
(
this
.
configurationPropertiesAnnotation
);
return
this
.
elements
.
getTypeElement
(
this
.
configurationPropertiesAnnotation
);
}
}
...
@@ -187,6 +220,10 @@ class MetadataGenerationEnvironment {
...
@@ -187,6 +220,10 @@ class MetadataGenerationEnvironment {
return
getAnnotation
(
element
,
this
.
nestedConfigurationPropertyAnnotation
);
return
getAnnotation
(
element
,
this
.
nestedConfigurationPropertyAnnotation
);
}
}
public
AnnotationMirror
getDefaultValueAnnotation
(
Element
element
)
{
return
getAnnotation
(
element
,
this
.
defaultValueAnnotation
);
}
public
TypeElement
getEndpointAnnotationElement
()
{
public
TypeElement
getEndpointAnnotationElement
()
{
return
this
.
elements
.
getTypeElement
(
this
.
endpointAnnotation
);
return
this
.
elements
.
getTypeElement
(
this
.
endpointAnnotation
);
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptor.java
View file @
3125f424
...
@@ -33,7 +33,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
...
@@ -33,7 +33,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
* @param <S> the type of the source element that determines the property
* @param <S> the type of the source element that determines the property
* @author Stephane Nicoll
* @author Stephane Nicoll
*/
*/
abstract
class
PropertyDescriptor
<
S
>
{
abstract
class
PropertyDescriptor
<
S
extends
Element
>
{
private
final
TypeElement
ownerElement
;
private
final
TypeElement
ownerElement
;
...
@@ -98,6 +98,9 @@ abstract class PropertyDescriptor<S> {
...
@@ -98,6 +98,9 @@ abstract class PropertyDescriptor<S> {
protected
abstract
boolean
isProperty
(
MetadataGenerationEnvironment
environment
);
protected
abstract
boolean
isProperty
(
MetadataGenerationEnvironment
environment
);
protected
abstract
Object
resolveDefaultValue
(
MetadataGenerationEnvironment
environment
);
protected
ItemDeprecation
resolveItemDeprecation
(
protected
ItemDeprecation
resolveItemDeprecation
(
MetadataGenerationEnvironment
environment
)
{
MetadataGenerationEnvironment
environment
)
{
boolean
deprecated
=
environment
.
isDeprecated
(
getGetter
())
boolean
deprecated
=
environment
.
isDeprecated
(
getGetter
())
...
@@ -164,10 +167,6 @@ abstract class PropertyDescriptor<S> {
...
@@ -164,10 +167,6 @@ abstract class PropertyDescriptor<S> {
return
environment
.
getTypeUtils
().
getJavaDoc
(
getField
());
return
environment
.
getTypeUtils
().
getJavaDoc
(
getField
());
}
}
private
Object
resolveDefaultValue
(
MetadataGenerationEnvironment
environment
)
{
return
environment
.
getDefaultValue
(
getOwnerElement
(),
getName
());
}
private
boolean
isCyclePresent
(
Element
returnType
,
Element
element
)
{
private
boolean
isCyclePresent
(
Element
returnType
,
Element
element
)
{
if
(!(
element
.
getEnclosingElement
()
instanceof
TypeElement
))
{
if
(!(
element
.
getEnclosingElement
()
instanceof
TypeElement
))
{
return
false
;
return
false
;
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java
View file @
3125f424
...
@@ -16,13 +16,16 @@
...
@@ -16,13 +16,16 @@
package
org
.
springframework
.
boot
.
configurationprocessor
;
package
org
.
springframework
.
boot
.
configurationprocessor
;
import
java.util.
ArrayList
;
import
java.util.
LinkedHashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Stream
;
import
java.util.stream.Stream
;
import
javax.lang.model.element.ExecutableElement
;
import
javax.lang.model.element.ExecutableElement
;
import
javax.lang.model.element.TypeElement
;
import
javax.lang.model.element.TypeElement
;
import
javax.lang.model.element.VariableElement
;
import
javax.lang.model.type.TypeMirror
;
import
javax.lang.model.type.TypeMirror
;
import
javax.lang.model.util.ElementFilter
;
/**
/**
* Resolve {@link PropertyDescriptor} instances.
* Resolve {@link PropertyDescriptor} instances.
...
@@ -49,23 +52,59 @@ class PropertyDescriptorResolver {
...
@@ -49,23 +52,59 @@ class PropertyDescriptorResolver {
public
Stream
<
PropertyDescriptor
<?>>
resolve
(
TypeElement
type
,
public
Stream
<
PropertyDescriptor
<?>>
resolve
(
TypeElement
type
,
ExecutableElement
factoryMethod
)
{
ExecutableElement
factoryMethod
)
{
TypeElementMembers
members
=
new
TypeElementMembers
(
this
.
environment
,
type
);
TypeElementMembers
members
=
new
TypeElementMembers
(
this
.
environment
,
type
);
List
<
PropertyDescriptor
<?>>
candidates
=
new
ArrayList
<>();
ExecutableElement
constructor
=
resolveConstructor
(
type
);
if
(
constructor
!=
null
)
{
return
resolveConstructorProperties
(
type
,
factoryMethod
,
members
,
constructor
);
}
else
{
return
resolveJavaBeanProperties
(
type
,
factoryMethod
,
members
);
}
}
public
Stream
<
PropertyDescriptor
<?>>
resolveConstructorProperties
(
TypeElement
type
,
ExecutableElement
factoryMethod
,
TypeElementMembers
members
,
ExecutableElement
constructor
)
{
Map
<
String
,
PropertyDescriptor
<?>>
candidates
=
new
LinkedHashMap
<>();
constructor
.
getParameters
().
forEach
((
parameter
)
->
{
String
name
=
parameter
.
getSimpleName
().
toString
();
TypeMirror
propertyType
=
parameter
.
asType
();
ExecutableElement
getter
=
members
.
getPublicGetter
(
name
,
propertyType
);
ExecutableElement
setter
=
members
.
getPublicSetter
(
name
,
propertyType
);
VariableElement
field
=
members
.
getFields
().
get
(
name
);
register
(
candidates
,
new
ConstructorParameterPropertyDescriptor
(
type
,
factoryMethod
,
parameter
,
name
,
propertyType
,
field
,
getter
,
setter
));
});
return
candidates
.
values
().
stream
();
}
public
Stream
<
PropertyDescriptor
<?>>
resolveJavaBeanProperties
(
TypeElement
type
,
ExecutableElement
factoryMethod
,
TypeElementMembers
members
)
{
// First check if we have regular java bean properties there
// First check if we have regular java bean properties there
Map
<
String
,
PropertyDescriptor
<?>>
candidates
=
new
LinkedHashMap
<>();
members
.
getPublicGetters
().
forEach
((
name
,
getter
)
->
{
members
.
getPublicGetters
().
forEach
((
name
,
getter
)
->
{
TypeMirror
returnType
=
getter
.
getReturnType
();
TypeMirror
propertyType
=
getter
.
getReturnType
();
candidates
.
add
(
new
JavaBeanPropertyDescriptor
(
type
,
factoryMethod
,
getter
,
register
(
candidates
,
name
,
returnType
,
members
.
getFields
().
get
(
name
),
new
JavaBeanPropertyDescriptor
(
type
,
factoryMethod
,
getter
,
name
,
members
.
getPublicSetter
(
name
,
returnType
)));
propertyType
,
members
.
getFields
().
get
(
name
),
members
.
getPublicSetter
(
name
,
propertyType
)));
});
});
// Then check for Lombok ones
// Then check for Lombok ones
members
.
getFields
().
forEach
((
name
,
field
)
->
{
members
.
getFields
().
forEach
((
name
,
field
)
->
{
TypeMirror
return
Type
=
field
.
asType
();
TypeMirror
property
Type
=
field
.
asType
();
ExecutableElement
getter
=
members
.
getPublicGetter
(
name
,
return
Type
);
ExecutableElement
getter
=
members
.
getPublicGetter
(
name
,
property
Type
);
ExecutableElement
setter
=
members
.
getPublicSetter
(
name
,
return
Type
);
ExecutableElement
setter
=
members
.
getPublicSetter
(
name
,
property
Type
);
candidates
.
add
(
new
LombokPropertyDescriptor
(
type
,
factoryMethod
,
field
,
name
,
register
(
candidates
,
new
LombokPropertyDescriptor
(
type
,
factoryMethod
,
field
,
return
Type
,
getter
,
setter
));
name
,
property
Type
,
getter
,
setter
));
});
});
return
candidates
.
stream
().
filter
(
this
::
isCandidate
);
return
candidates
.
values
().
stream
();
}
private
void
register
(
Map
<
String
,
PropertyDescriptor
<?>>
candidates
,
PropertyDescriptor
<?>
descriptor
)
{
if
(!
candidates
.
containsKey
(
descriptor
.
getName
())
&&
isCandidate
(
descriptor
))
{
candidates
.
put
(
descriptor
.
getName
(),
descriptor
);
}
}
}
private
boolean
isCandidate
(
PropertyDescriptor
<?>
descriptor
)
{
private
boolean
isCandidate
(
PropertyDescriptor
<?>
descriptor
)
{
...
@@ -73,4 +112,13 @@ class PropertyDescriptorResolver {
...
@@ -73,4 +112,13 @@ class PropertyDescriptorResolver {
||
descriptor
.
isNested
(
this
.
environment
);
||
descriptor
.
isNested
(
this
.
environment
);
}
}
private
ExecutableElement
resolveConstructor
(
TypeElement
type
)
{
List
<
ExecutableElement
>
constructors
=
ElementFilter
.
constructorsIn
(
type
.
getEnclosedElements
());
if
(
constructors
.
size
()
==
1
&&
constructors
.
get
(
0
).
getParameters
().
size
()
>
0
)
{
return
constructors
.
get
(
0
);
}
return
null
;
}
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeUtils.java
View file @
3125f424
...
@@ -142,6 +142,42 @@ class TypeUtils {
...
@@ -142,6 +142,42 @@ class TypeUtils {
return
type
.
accept
(
this
.
typeExtractor
,
createTypeDescriptor
(
element
));
return
type
.
accept
(
this
.
typeExtractor
,
createTypeDescriptor
(
element
));
}
}
/**
* Extract the target element type from the specified container type or {@code null}
* if no element type was found.
* @param type a type, potentially wrapping an element type
* @return the element type or {@code null} if no specific type was found
*/
public
TypeMirror
extractElementType
(
TypeMirror
type
)
{
if
(!
this
.
env
.
getTypeUtils
().
isAssignable
(
type
,
this
.
collectionType
))
{
return
null
;
}
return
getCollectionElementType
(
type
);
}
private
TypeMirror
getCollectionElementType
(
TypeMirror
type
)
{
if
(((
TypeElement
)
this
.
types
.
asElement
(
type
)).
getQualifiedName
()
.
contentEquals
(
Collection
.
class
.
getName
()))
{
DeclaredType
declaredType
=
(
DeclaredType
)
type
;
// raw type, just "Collection"
if
(
declaredType
.
getTypeArguments
().
size
()
==
0
)
{
return
this
.
types
.
getDeclaredType
(
this
.
env
.
getElementUtils
()
.
getTypeElement
(
Object
.
class
.
getName
()));
}
else
{
// return type argument to Collection<...>
return
declaredType
.
getTypeArguments
().
get
(
0
);
}
}
// recursively walk the supertypes, looking for Collection<...>
for
(
TypeMirror
superType
:
this
.
env
.
getTypeUtils
().
directSupertypes
(
type
))
{
if
(
this
.
types
.
isAssignable
(
superType
,
this
.
collectionType
))
{
return
getCollectionElementType
(
superType
);
}
}
return
null
;
}
public
boolean
isCollectionOrMap
(
TypeMirror
type
)
{
public
boolean
isCollectionOrMap
(
TypeMirror
type
)
{
return
this
.
env
.
getTypeUtils
().
isAssignable
(
type
,
this
.
collectionType
)
return
this
.
env
.
getTypeUtils
().
isAssignable
(
type
,
this
.
collectionType
)
||
this
.
env
.
getTypeUtils
().
isAssignable
(
type
,
this
.
mapType
);
||
this
.
env
.
getTypeUtils
().
isAssignable
(
type
,
this
.
mapType
);
...
@@ -156,6 +192,19 @@ class TypeUtils {
...
@@ -156,6 +192,19 @@ class TypeUtils {
return
""
.
equals
(
javadoc
)
?
null
:
javadoc
;
return
""
.
equals
(
javadoc
)
?
null
:
javadoc
;
}
}
/**
* Return the {@link PrimitiveType} of the specified type or {@code null} if the type
* does not represent a valid wrapper type.
* @param typeMirror a type
* @return the primitive type or {@code null} if the type is not a wrapper type
*/
public
PrimitiveType
getPrimitiveType
(
TypeMirror
typeMirror
)
{
if
(
getPrimitiveFor
(
typeMirror
)
!=
null
)
{
return
this
.
types
.
unboxedType
(
typeMirror
);
}
return
null
;
}
public
TypeMirror
getWrapperOrPrimitiveFor
(
TypeMirror
typeMirror
)
{
public
TypeMirror
getWrapperOrPrimitiveFor
(
TypeMirror
typeMirror
)
{
Class
<?>
candidate
=
getWrapperFor
(
typeMirror
);
Class
<?>
candidate
=
getWrapperFor
(
typeMirror
);
if
(
candidate
!=
null
)
{
if
(
candidate
!=
null
)
{
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java
View file @
3125f424
...
@@ -43,6 +43,9 @@ import org.springframework.boot.configurationsample.specific.InnerClassHierarchi
...
@@ -43,6 +43,9 @@ import org.springframework.boot.configurationsample.specific.InnerClassHierarchi
import
org.springframework.boot.configurationsample.specific.InnerClassProperties
;
import
org.springframework.boot.configurationsample.specific.InnerClassProperties
;
import
org.springframework.boot.configurationsample.specific.InnerClassRootConfig
;
import
org.springframework.boot.configurationsample.specific.InnerClassRootConfig
;
import
org.springframework.boot.configurationsample.specific.InvalidAccessorProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidAccessorProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidDefaultValueCharacterProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidDefaultValueFloatingPointProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidDefaultValueNumberProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidDoubleRegistrationProperties
;
import
org.springframework.boot.configurationsample.specific.InvalidDoubleRegistrationProperties
;
import
org.springframework.boot.configurationsample.specific.SimplePojo
;
import
org.springframework.boot.configurationsample.specific.SimplePojo
;
import
org.springframework.boot.configurationsample.specific.StaticAccessor
;
import
org.springframework.boot.configurationsample.specific.StaticAccessor
;
...
@@ -385,4 +388,26 @@ public class ConfigurationMetadataAnnotationProcessorTests
...
@@ -385,4 +388,26 @@ public class ConfigurationMetadataAnnotationProcessorTests
.
withMessageContaining
(
"Compilation failed"
);
.
withMessageContaining
(
"Compilation failed"
);
}
}
@Test
public
void
constructorParameterPropertyWithInvalidDefaultValueOnNumber
()
{
assertThatIllegalStateException
()
.
isThrownBy
(()
->
compile
(
InvalidDefaultValueNumberProperties
.
class
))
.
withMessageContaining
(
"Compilation failed"
);
}
@Test
public
void
constructorParameterPropertyWithInvalidDefaultValueOnFloatingPoint
()
{
assertThatIllegalStateException
()
.
isThrownBy
(
()
->
compile
(
InvalidDefaultValueFloatingPointProperties
.
class
))
.
withMessageContaining
(
"Compilation failed"
);
}
@Test
public
void
constructorParameterPropertyWithInvalidDefaultValueOnCharacter
()
{
assertThatIllegalStateException
()
.
isThrownBy
(()
->
compile
(
InvalidDefaultValueCharacterProperties
.
class
))
.
withMessageContaining
(
"Compilation failed"
);
}
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptorTests.java
0 → 100644
View file @
3125f424
This diff is collapsed.
Click to expand it.
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ImmutablePropertiesMetadataGenerationTests.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
org.junit.Test
;
import
org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata
;
import
org.springframework.boot.configurationprocessor.metadata.Metadata
;
import
org.springframework.boot.configurationsample.immutable.ImmutableSimpleProperties
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Metadata generation tests for immutable properties.
*
* @author Stephane Nicoll
*/
public
class
ImmutablePropertiesMetadataGenerationTests
extends
AbstractMetadataGenerationTests
{
@Test
public
void
immutableSimpleProperties
()
{
ConfigurationMetadata
metadata
=
compile
(
ImmutableSimpleProperties
.
class
);
assertThat
(
metadata
).
has
(
Metadata
.
withGroup
(
"immutable"
)
.
fromSource
(
ImmutableSimpleProperties
.
class
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"immutable.the-name"
,
String
.
class
)
.
fromSource
(
ImmutableSimpleProperties
.
class
)
.
withDescription
(
"The name of this simple properties."
)
.
withDefaultValue
(
"boot"
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"immutable.flag"
,
Boolean
.
class
)
.
withDefaultValue
(
false
).
fromSource
(
ImmutableSimpleProperties
.
class
)
.
withDescription
(
"A simple flag."
).
withDeprecation
(
null
,
null
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"immutable.comparator"
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"immutable.counter"
));
assertThat
(
metadata
.
getItems
()).
hasSize
(
5
);
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironmentFactory.java
View file @
3125f424
...
@@ -36,6 +36,7 @@ class MetadataGenerationEnvironmentFactory
...
@@ -36,6 +36,7 @@ class MetadataGenerationEnvironmentFactory
TestConfigurationMetadataAnnotationProcessor
.
CONFIGURATION_PROPERTIES_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
CONFIGURATION_PROPERTIES_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
NESTED_CONFIGURATION_PROPERTY_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
NESTED_CONFIGURATION_PROPERTY_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
DEFAULT_VALUE_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
ENDPOINT_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
ENDPOINT_ANNOTATION
,
TestConfigurationMetadataAnnotationProcessor
.
READ_OPERATION_ANNOTATION
);
TestConfigurationMetadataAnnotationProcessor
.
READ_OPERATION_ANNOTATION
);
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolverTests.java
View file @
3125f424
...
@@ -34,6 +34,7 @@ import org.junit.rules.TemporaryFolder;
...
@@ -34,6 +34,7 @@ import org.junit.rules.TemporaryFolder;
import
org.springframework.boot.configurationprocessor.metadata.ItemMetadata
;
import
org.springframework.boot.configurationprocessor.metadata.ItemMetadata
;
import
org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester
;
import
org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester
;
import
org.springframework.boot.configurationprocessor.test.TestableAnnotationProcessor
;
import
org.springframework.boot.configurationprocessor.test.TestableAnnotationProcessor
;
import
org.springframework.boot.configurationsample.immutable.ImmutableSimpleProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokExplicitProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokExplicitProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokSimpleDataProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokSimpleDataProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokSimpleProperties
;
import
org.springframework.boot.configurationsample.lombok.LombokSimpleProperties
;
...
@@ -41,6 +42,7 @@ import org.springframework.boot.configurationsample.simple.HierarchicalPropertie
...
@@ -41,6 +42,7 @@ import org.springframework.boot.configurationsample.simple.HierarchicalPropertie
import
org.springframework.boot.configurationsample.simple.HierarchicalPropertiesGrandparent
;
import
org.springframework.boot.configurationsample.simple.HierarchicalPropertiesGrandparent
;
import
org.springframework.boot.configurationsample.simple.HierarchicalPropertiesParent
;
import
org.springframework.boot.configurationsample.simple.HierarchicalPropertiesParent
;
import
org.springframework.boot.configurationsample.simple.SimpleProperties
;
import
org.springframework.boot.configurationsample.simple.SimpleProperties
;
import
org.springframework.boot.configurationsample.specific.TwoConstructorsExample
;
import
org.springframework.boot.testsupport.compiler.TestCompiler
;
import
org.springframework.boot.testsupport.compiler.TestCompiler
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
@@ -100,6 +102,21 @@ public class PropertyDescriptorResolverTests {
...
@@ -100,6 +102,21 @@ public class PropertyDescriptorResolverTests {
"description"
,
"counter"
,
"number"
,
"items"
)));
"description"
,
"counter"
,
"number"
,
"items"
)));
}
}
@Test
public
void
propertiesWithConstructorParameters
()
throws
IOException
{
process
(
ImmutableSimpleProperties
.
class
,
propertyNames
((
stream
)
->
assertThat
(
stream
).
containsExactly
(
"theName"
,
"flag"
,
"comparator"
,
"counter"
)));
}
@Test
public
void
propertiesWithSeveralConstructors
()
throws
IOException
{
process
(
TwoConstructorsExample
.
class
,
propertyNames
((
stream
)
->
assertThat
(
stream
).
containsExactly
(
"name"
)));
process
(
TwoConstructorsExample
.
class
,
properties
((
stream
)
->
assertThat
(
stream
)
.
element
(
0
).
isInstanceOf
(
JavaBeanPropertyDescriptor
.
class
)));
}
private
BiConsumer
<
TypeElement
,
MetadataGenerationEnvironment
>
properties
(
private
BiConsumer
<
TypeElement
,
MetadataGenerationEnvironment
>
properties
(
Consumer
<
Stream
<
PropertyDescriptor
<?>>>
stream
)
{
Consumer
<
Stream
<
PropertyDescriptor
<?>>>
stream
)
{
return
(
element
,
metadataEnv
)
->
{
return
(
element
,
metadataEnv
)
->
{
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/test/TestConfigurationMetadataAnnotationProcessor.java
View file @
3125f424
...
@@ -47,6 +47,8 @@ public class TestConfigurationMetadataAnnotationProcessor
...
@@ -47,6 +47,8 @@ public class TestConfigurationMetadataAnnotationProcessor
public
static
final
String
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
=
"org.springframework.boot.configurationsample.DeprecatedConfigurationProperty"
;
public
static
final
String
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
=
"org.springframework.boot.configurationsample.DeprecatedConfigurationProperty"
;
public
static
final
String
DEFAULT_VALUE_ANNOTATION
=
"org.springframework.boot.configurationsample.DefaultValue"
;
public
static
final
String
ENDPOINT_ANNOTATION
=
"org.springframework.boot.configurationsample.Endpoint"
;
public
static
final
String
ENDPOINT_ANNOTATION
=
"org.springframework.boot.configurationsample.Endpoint"
;
public
static
final
String
READ_OPERATION_ANNOTATION
=
"org.springframework.boot.configurationsample.ReadOperation"
;
public
static
final
String
READ_OPERATION_ANNOTATION
=
"org.springframework.boot.configurationsample.ReadOperation"
;
...
@@ -74,6 +76,11 @@ public class TestConfigurationMetadataAnnotationProcessor
...
@@ -74,6 +76,11 @@ public class TestConfigurationMetadataAnnotationProcessor
return
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
;
return
DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION
;
}
}
@Override
protected
String
defaultValueAnnotation
()
{
return
DEFAULT_VALUE_ANNOTATION
;
}
@Override
@Override
protected
String
endpointAnnotation
()
{
protected
String
endpointAnnotation
()
{
return
ENDPOINT_ANNOTATION
;
return
ENDPOINT_ANNOTATION
;
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/DefaultValue.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Alternative to Spring Boot's {@code @DefaultValue} for testing (removes the need for a
* dependency on the real annotation).
*
* @author Stephane Nicoll
*/
@Target
({
ElementType
.
PARAMETER
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
DefaultValue
{
String
[]
value
();
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutableCollectionProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
import
java.time.Duration
;
import
java.util.List
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Simple immutable properties with collections types and defaults.
*
* @author Stephane Nicoll
*/
public
class
ImmutableCollectionProperties
{
private
final
List
<
String
>
names
;
private
final
List
<
Boolean
>
flags
;
private
final
List
<
Duration
>
durations
;
public
ImmutableCollectionProperties
(
List
<
String
>
names
,
@DefaultValue
({
"true"
,
"false"
})
List
<
Boolean
>
flags
,
@DefaultValue
({
"10s"
,
"1m"
,
"1h"
})
List
<
Duration
>
durations
)
{
this
.
names
=
names
;
this
.
flags
=
flags
;
this
.
durations
=
durations
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutableInnerClassProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
import
org.springframework.boot.configurationsample.NestedConfigurationProperty
;
import
org.springframework.boot.configurationsample.specific.SimplePojo
;
/**
* Inner properties, in immutable format.
*
* @author Stephane Nicoll
*/
public
class
ImmutableInnerClassProperties
{
private
final
Foo
first
;
private
Foo
second
;
@NestedConfigurationProperty
private
final
SimplePojo
third
;
private
final
Fourth
fourth
;
public
ImmutableInnerClassProperties
(
Foo
first
,
Foo
second
,
SimplePojo
third
,
Fourth
fourth
)
{
this
.
first
=
first
;
this
.
second
=
second
;
this
.
third
=
third
;
this
.
fourth
=
fourth
;
}
public
Foo
getFirst
()
{
return
this
.
first
;
}
public
Foo
getTheSecond
()
{
return
this
.
second
;
}
public
void
setTheSecond
(
Foo
second
)
{
this
.
second
=
second
;
}
public
SimplePojo
getThird
()
{
return
this
.
third
;
}
public
Fourth
getFourth
()
{
return
this
.
fourth
;
}
public
static
class
Foo
{
private
String
name
;
private
final
Bar
bar
=
new
Bar
();
public
String
getName
()
{
return
this
.
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
Bar
getBar
()
{
return
this
.
bar
;
}
public
static
class
Bar
{
private
String
name
;
public
String
getName
()
{
return
this
.
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
}
}
public
enum
Fourth
{
YES
,
NO
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutablePrimitiveProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
/**
* Simple immutable properties with primitive types.
*
* @author Stephane Nicoll
*/
@SuppressWarnings
(
"unused"
)
public
class
ImmutablePrimitiveProperties
{
private
final
boolean
flag
;
private
final
byte
octet
;
private
final
char
letter
;
private
final
short
number
;
private
final
int
counter
;
private
final
long
value
;
private
final
float
percentage
;
private
final
double
ratio
;
public
ImmutablePrimitiveProperties
(
boolean
flag
,
byte
octet
,
char
letter
,
short
number
,
int
counter
,
long
value
,
float
percentage
,
double
ratio
)
{
this
.
flag
=
flag
;
this
.
octet
=
octet
;
this
.
letter
=
letter
;
this
.
number
=
number
;
this
.
counter
=
counter
;
this
.
value
=
value
;
this
.
percentage
=
percentage
;
this
.
ratio
=
ratio
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutablePrimitiveWithDefaultsProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Simple immutable properties with primitive types and defaults.
*
* @author Stephane Nicoll
*/
@SuppressWarnings
(
"unused"
)
public
class
ImmutablePrimitiveWithDefaultsProperties
{
private
final
boolean
flag
;
private
final
byte
octet
;
private
final
char
letter
;
private
final
short
number
;
private
final
int
counter
;
private
final
long
value
;
private
final
float
percentage
;
private
final
double
ratio
;
public
ImmutablePrimitiveWithDefaultsProperties
(
@DefaultValue
(
"true"
)
boolean
flag
,
@DefaultValue
(
"120"
)
byte
octet
,
@DefaultValue
(
"a"
)
char
letter
,
@DefaultValue
(
"1000"
)
short
number
,
@DefaultValue
(
"42"
)
int
counter
,
@DefaultValue
(
"2000"
)
long
value
,
@DefaultValue
(
"0.5"
)
float
percentage
,
@DefaultValue
(
"42.42"
)
double
ratio
)
{
this
.
flag
=
flag
;
this
.
octet
=
octet
;
this
.
letter
=
letter
;
this
.
number
=
number
;
this
.
counter
=
counter
;
this
.
value
=
value
;
this
.
percentage
=
percentage
;
this
.
ratio
=
ratio
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutablePrimitiveWrapperWithDefaultsProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Simple immutable properties with primitive wrapper types and defaults.
*
* @author Stephane Nicoll
*/
@SuppressWarnings
(
"unused"
)
public
class
ImmutablePrimitiveWrapperWithDefaultsProperties
{
private
final
Boolean
flag
;
private
final
Byte
octet
;
private
final
Character
letter
;
private
final
Short
number
;
private
final
Integer
counter
;
private
final
Long
value
;
private
final
Float
percentage
;
private
final
Double
ratio
;
public
ImmutablePrimitiveWrapperWithDefaultsProperties
(
@DefaultValue
(
"true"
)
Boolean
flag
,
@DefaultValue
(
"120"
)
Byte
octet
,
@DefaultValue
(
"a"
)
Character
letter
,
@DefaultValue
(
"1000"
)
Short
number
,
@DefaultValue
(
"42"
)
Integer
counter
,
@DefaultValue
(
"2000"
)
Long
value
,
@DefaultValue
(
"0.5"
)
Float
percentage
,
@DefaultValue
(
"42.42"
)
Double
ratio
)
{
this
.
flag
=
flag
;
this
.
octet
=
octet
;
this
.
letter
=
letter
;
this
.
number
=
number
;
this
.
counter
=
counter
;
this
.
value
=
value
;
this
.
percentage
=
percentage
;
this
.
ratio
=
ratio
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/immutable/ImmutableSimpleProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
immutable
;
import
java.util.Comparator
;
import
org.springframework.boot.configurationsample.ConfigurationProperties
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Simple properties, in immutable format.
*
* @author Stephane Nicoll
*/
@ConfigurationProperties
(
"immutable"
)
public
class
ImmutableSimpleProperties
{
/**
* The name of this simple properties.
*/
private
final
String
theName
;
/**
* A simple flag.
*/
private
final
boolean
flag
;
// An interface can still be injected because it might have a converter
private
final
Comparator
<?>
comparator
;
// Even if it is not exposed, we're still offering a way to bind the value via the
// constructor so it should be present in the metadata
@SuppressWarnings
(
"unused"
)
private
final
Long
counter
;
public
ImmutableSimpleProperties
(
@DefaultValue
(
"boot"
)
String
theName
,
boolean
flag
,
Comparator
<?>
comparator
,
Long
counter
)
{
this
.
theName
=
theName
;
this
.
flag
=
flag
;
this
.
comparator
=
comparator
;
this
.
counter
=
counter
;
}
public
String
getTheName
()
{
return
this
.
theName
;
}
@Deprecated
public
boolean
isFlag
()
{
return
this
.
flag
;
}
public
Comparator
<?>
getComparator
()
{
return
this
.
comparator
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/InvalidDefaultValueCharacterProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
specific
;
import
org.springframework.boot.configurationsample.ConfigurationProperties
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Demonstrates that an invalid default character value leads to a compilation failure.
*
* @author Stephane Nicoll
*/
@ConfigurationProperties
(
"test"
)
public
class
InvalidDefaultValueCharacterProperties
{
private
final
char
letter
;
public
InvalidDefaultValueCharacterProperties
(
@DefaultValue
(
"bad"
)
char
letter
)
{
this
.
letter
=
letter
;
}
public
char
getLetter
()
{
return
this
.
letter
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/InvalidDefaultValueFloatingPointProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
specific
;
import
org.springframework.boot.configurationsample.ConfigurationProperties
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Demonstrates that an invalid default floating point value leads to a compilation
* failure.
*
* @author Stephane Nicoll
*/
@ConfigurationProperties
(
"test"
)
public
class
InvalidDefaultValueFloatingPointProperties
{
private
final
Double
ratio
;
public
InvalidDefaultValueFloatingPointProperties
(
@DefaultValue
(
"55.55.33"
)
Double
ratio
)
{
this
.
ratio
=
ratio
;
}
public
Double
getRatio
()
{
return
this
.
ratio
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/InvalidDefaultValueNumberProperties.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
specific
;
import
org.springframework.boot.configurationsample.ConfigurationProperties
;
import
org.springframework.boot.configurationsample.DefaultValue
;
/**
* Demonstrates that an invalid default number value leads to a compilation failure.
*
* @author Stephane Nicoll
*/
@ConfigurationProperties
(
"test"
)
public
class
InvalidDefaultValueNumberProperties
{
private
final
int
counter
;
public
InvalidDefaultValueNumberProperties
(
@DefaultValue
(
"invalid"
)
int
counter
)
{
this
.
counter
=
counter
;
}
public
int
getCounter
()
{
return
this
.
counter
;
}
}
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/TwoConstructorsExample.java
0 → 100644
View file @
3125f424
/*
* Copyright 2012-2019 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
*
* https://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
.
specific
;
/**
* A type with more than one constructor.
*
* @author Stephane Nicoll
*/
public
class
TwoConstructorsExample
{
private
String
name
;
public
TwoConstructorsExample
()
{
}
public
TwoConstructorsExample
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getName
()
{
return
this
.
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
}
src/checkstyle/checkstyle-suppressions.xml
View file @
3125f424
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
<suppress
files=
"[\\/]src[\\/]main[\\/]java[\\/]sample[\\/]"
checks=
"ImportControl"
/>
<suppress
files=
"[\\/]src[\\/]main[\\/]java[\\/]sample[\\/]"
checks=
"ImportControl"
/>
<suppress
files=
"[\\/]src[\\/]test[\\/]java[\\/]sample[\\/]"
checks=
"ImportControl"
/>
<suppress
files=
"[\\/]src[\\/]test[\\/]java[\\/]sample[\\/]"
checks=
"ImportControl"
/>
<suppress
files=
"[\\/]src[\\/]test[\\/]java[\\/]"
checks=
"Javadoc*"
/>
<suppress
files=
"[\\/]src[\\/]test[\\/]java[\\/]"
checks=
"Javadoc*"
/>
<suppress
files=
"[\\/]src[\\/]test[\\/]java[\\/]"
checks=
"NonEmptyAtclauseDescription"
/>
<suppress
files=
"[\\/]autoconfigure[\\/]"
checks=
"JavadocType"
/>
<suppress
files=
"[\\/]autoconfigure[\\/]"
checks=
"JavadocType"
/>
<suppress
files=
"[\\/]autoconfigure[\\/]"
checks=
"JavadocVariable"
/>
<suppress
files=
"[\\/]autoconfigure[\\/]"
checks=
"JavadocVariable"
/>
<suppress
files=
"[\\/]spring-boot-docs[\\/]"
checks=
"JavadocType"
/>
<suppress
files=
"[\\/]spring-boot-docs[\\/]"
checks=
"JavadocType"
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment