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
4a8646bd
Commit
4a8646bd
authored
Nov 05, 2020
by
Stephane Nicoll
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.2.x' into 2.3.x
Closes gh-24058
parents
1e100677
59ea7c11
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
118 additions
and
26 deletions
+118
-26
PropertyDescriptorResolver.java
...ot/configurationprocessor/PropertyDescriptorResolver.java
+14
-4
TypeElementMembers.java
...ework/boot/configurationprocessor/TypeElementMembers.java
+31
-20
ConfigurationMetadataAnnotationProcessorTests.java
...cessor/ConfigurationMetadataAnnotationProcessorTests.java
+12
-1
BoxingPojo.java
...amework/boot/configurationsample/specific/BoxingPojo.java
+11
-1
DeprecatedLessPreciseTypePojo.java
...urationsample/specific/DeprecatedLessPreciseTypePojo.java
+50
-0
No files found.
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java
View file @
4a8646bd
/*
* Copyright 2012-20
19
the original author or authors.
* Copyright 2012-20
20
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.
...
...
@@ -91,10 +91,12 @@ class PropertyDescriptorResolver {
TypeElementMembers
members
)
{
// 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
,
getters
)
->
{
VariableElement
field
=
members
.
getFields
().
get
(
name
);
ExecutableElement
getter
=
findMatchingGetter
(
members
,
getters
,
field
);
TypeMirror
propertyType
=
getter
.
getReturnType
();
register
(
candidates
,
new
JavaBeanPropertyDescriptor
(
type
,
factoryMethod
,
getter
,
name
,
propertyType
,
members
.
get
Fields
().
get
(
name
),
members
.
get
PublicSetter
(
name
,
propertyType
)));
register
(
candidates
,
new
JavaBeanPropertyDescriptor
(
type
,
factoryMethod
,
getter
,
name
,
propertyType
,
field
,
members
.
getPublicSetter
(
name
,
propertyType
)));
});
// Then check for Lombok ones
members
.
getFields
().
forEach
((
name
,
field
)
->
{
...
...
@@ -107,6 +109,14 @@ class PropertyDescriptorResolver {
return
candidates
.
values
().
stream
();
}
private
ExecutableElement
findMatchingGetter
(
TypeElementMembers
members
,
List
<
ExecutableElement
>
candidates
,
VariableElement
field
)
{
if
(
candidates
.
size
()
>
1
&&
field
!=
null
)
{
return
members
.
getMatchingGetter
(
candidates
,
field
.
asType
());
}
return
candidates
.
get
(
0
);
}
private
void
register
(
Map
<
String
,
PropertyDescriptor
<?>>
candidates
,
PropertyDescriptor
<?>
descriptor
)
{
if
(!
candidates
.
containsKey
(
descriptor
.
getName
())
&&
isCandidate
(
descriptor
))
{
candidates
.
put
(
descriptor
.
getName
(),
descriptor
);
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeElementMembers.java
View file @
4a8646bd
...
...
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.function.Function
;
import
javax.lang.model.element.Element
;
import
javax.lang.model.element.ExecutableElement
;
...
...
@@ -48,7 +49,7 @@ class TypeElementMembers {
private
final
Map
<
String
,
VariableElement
>
fields
=
new
LinkedHashMap
<>();
private
final
Map
<
String
,
ExecutableElement
>
publicGetters
=
new
LinkedHashMap
<>();
private
final
Map
<
String
,
List
<
ExecutableElement
>
>
publicGetters
=
new
LinkedHashMap
<>();
private
final
Map
<
String
,
List
<
ExecutableElement
>>
publicSetters
=
new
LinkedHashMap
<>();
...
...
@@ -74,8 +75,14 @@ class TypeElementMembers {
private
void
processMethod
(
ExecutableElement
method
)
{
if
(
isPublic
(
method
))
{
String
name
=
method
.
getSimpleName
().
toString
();
if
(
isGetter
(
method
)
&&
!
this
.
publicGetters
.
containsKey
(
getAccessorName
(
name
)))
{
this
.
publicGetters
.
put
(
getAccessorName
(
name
),
method
);
if
(
isGetter
(
method
))
{
String
propertyName
=
getAccessorName
(
name
);
List
<
ExecutableElement
>
matchingGetters
=
this
.
publicGetters
.
computeIfAbsent
(
propertyName
,
(
k
)
->
new
ArrayList
<>());
TypeMirror
returnType
=
method
.
getReturnType
();
if
(
getMatchingGetter
(
matchingGetters
,
returnType
)
==
null
)
{
matchingGetters
.
add
(
method
);
}
}
else
if
(
isSetter
(
method
))
{
String
propertyName
=
getAccessorName
(
name
);
...
...
@@ -95,10 +102,19 @@ class TypeElementMembers {
&&
!
modifiers
.
contains
(
Modifier
.
STATIC
);
}
ExecutableElement
getMatchingGetter
(
List
<
ExecutableElement
>
candidates
,
TypeMirror
type
)
{
return
getMatchingAccessor
(
candidates
,
type
,
ExecutableElement:
:
getReturnType
);
}
private
ExecutableElement
getMatchingSetter
(
List
<
ExecutableElement
>
candidates
,
TypeMirror
type
)
{
return
getMatchingAccessor
(
candidates
,
type
,
(
candidate
)
->
candidate
.
getParameters
().
get
(
0
).
asType
());
}
private
ExecutableElement
getMatchingAccessor
(
List
<
ExecutableElement
>
candidates
,
TypeMirror
type
,
Function
<
ExecutableElement
,
TypeMirror
>
typeExtractor
)
{
for
(
ExecutableElement
candidate
:
candidates
)
{
TypeMirror
paramType
=
candidate
.
getParameters
().
get
(
0
).
asType
(
);
if
(
this
.
env
.
getTypeUtils
().
isSameType
(
param
Type
,
type
))
{
TypeMirror
candidateType
=
typeExtractor
.
apply
(
candidate
);
if
(
this
.
env
.
getTypeUtils
().
isSameType
(
candidate
Type
,
type
))
{
return
candidate
;
}
}
...
...
@@ -151,35 +167,30 @@ class TypeElementMembers {
return
Collections
.
unmodifiableMap
(
this
.
fields
);
}
Map
<
String
,
ExecutableElement
>
getPublicGetters
()
{
Map
<
String
,
List
<
ExecutableElement
>
>
getPublicGetters
()
{
return
Collections
.
unmodifiableMap
(
this
.
publicGetters
);
}
ExecutableElement
getPublicGetter
(
String
name
,
TypeMirror
type
)
{
ExecutableElement
candidate
=
this
.
publicGetters
.
get
(
name
);
if
(
candidate
!=
null
)
{
TypeMirror
returnType
=
candidate
.
getReturnType
();
if
(
this
.
env
.
getTypeUtils
().
isSameType
(
returnType
,
type
))
{
return
candidate
;
}
TypeMirror
alternative
=
this
.
env
.
getTypeUtils
().
getWrapperOrPrimitiveFor
(
type
);
if
(
alternative
!=
null
&&
this
.
env
.
getTypeUtils
().
isSameType
(
returnType
,
alternative
))
{
return
candidate
;
}
}
return
null
;
List
<
ExecutableElement
>
candidates
=
this
.
publicGetters
.
get
(
name
);
return
getPublicAccessor
(
candidates
,
type
,
(
specificType
)
->
getMatchingGetter
(
candidates
,
specificType
));
}
ExecutableElement
getPublicSetter
(
String
name
,
TypeMirror
type
)
{
List
<
ExecutableElement
>
candidates
=
this
.
publicSetters
.
get
(
name
);
return
getPublicAccessor
(
candidates
,
type
,
(
specificType
)
->
getMatchingSetter
(
candidates
,
specificType
));
}
private
ExecutableElement
getPublicAccessor
(
List
<
ExecutableElement
>
candidates
,
TypeMirror
type
,
Function
<
TypeMirror
,
ExecutableElement
>
matchingAccessorExtractor
)
{
if
(
candidates
!=
null
)
{
ExecutableElement
matching
=
getMatchingSetter
(
candidates
,
type
);
ExecutableElement
matching
=
matchingAccessorExtractor
.
apply
(
type
);
if
(
matching
!=
null
)
{
return
matching
;
}
TypeMirror
alternative
=
this
.
env
.
getTypeUtils
().
getWrapperOrPrimitiveFor
(
type
);
if
(
alternative
!=
null
)
{
return
getMatchingSetter
(
candidates
,
alternative
);
return
matchingAccessorExtractor
.
apply
(
alternative
);
}
}
return
null
;
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java
View file @
4a8646bd
...
...
@@ -38,6 +38,7 @@ import org.springframework.boot.configurationsample.simple.SimpleTypeProperties;
import
org.springframework.boot.configurationsample.specific.AnnotatedGetter
;
import
org.springframework.boot.configurationsample.specific.BoxingPojo
;
import
org.springframework.boot.configurationsample.specific.BuilderPojo
;
import
org.springframework.boot.configurationsample.specific.DeprecatedLessPreciseTypePojo
;
import
org.springframework.boot.configurationsample.specific.DeprecatedUnrelatedMethodPojo
;
import
org.springframework.boot.configurationsample.specific.DoubleRegistrationProperties
;
import
org.springframework.boot.configurationsample.specific.EmptyDefaultValueProperties
;
...
...
@@ -192,12 +193,22 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene
}
@Test
void
boxingOnSetter
()
{
void
deprecatedWithLessPreciseType
()
{
Class
<?>
type
=
DeprecatedLessPreciseTypePojo
.
class
;
ConfigurationMetadata
metadata
=
compile
(
type
);
assertThat
(
metadata
).
has
(
Metadata
.
withGroup
(
"not.deprecated"
).
fromSource
(
type
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"not.deprecated.flag"
,
Boolean
.
class
).
withDefaultValue
(
false
)
.
withNoDeprecation
().
fromSource
(
type
));
}
@Test
void
typBoxing
()
{
Class
<?>
type
=
BoxingPojo
.
class
;
ConfigurationMetadata
metadata
=
compile
(
type
);
assertThat
(
metadata
).
has
(
Metadata
.
withGroup
(
"boxing"
).
fromSource
(
type
));
assertThat
(
metadata
)
.
has
(
Metadata
.
withProperty
(
"boxing.flag"
,
Boolean
.
class
).
withDefaultValue
(
false
).
fromSource
(
type
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"boxing.another-flag"
,
Boolean
.
class
).
fromSource
(
type
));
assertThat
(
metadata
).
has
(
Metadata
.
withProperty
(
"boxing.counter"
,
Integer
.
class
).
fromSource
(
type
));
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/BoxingPojo.java
View file @
4a8646bd
/*
* Copyright 2012-20
19
the original author or authors.
* Copyright 2012-20
20
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.
...
...
@@ -29,6 +29,8 @@ public class BoxingPojo {
private
boolean
flag
;
private
Boolean
anotherFlag
;
private
Integer
counter
;
public
boolean
isFlag
()
{
...
...
@@ -40,6 +42,14 @@ public class BoxingPojo {
this
.
flag
=
flag
;
}
public
boolean
isAnotherFlag
()
{
return
Boolean
.
TRUE
.
equals
(
this
.
anotherFlag
);
}
public
void
setAnotherFlag
(
boolean
anotherFlag
)
{
this
.
anotherFlag
=
anotherFlag
;
}
public
Integer
getCounter
()
{
return
this
.
counter
;
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/specific/DeprecatedLessPreciseTypePojo.java
0 → 100644
View file @
4a8646bd
/*
* Copyright 2012-2020 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
;
/**
* Demonstrate that deprecating accessor with not the same type is not taken into account
* to detect the deprecated flag.
*
* @author Stephane Nicoll
*/
@ConfigurationProperties
(
"not.deprecated"
)
public
class
DeprecatedLessPreciseTypePojo
{
private
boolean
flag
;
@Deprecated
public
Boolean
getFlag
()
{
return
this
.
flag
;
}
public
boolean
isFlag
()
{
return
this
.
flag
;
}
public
void
setFlag
(
boolean
flag
)
{
this
.
flag
=
flag
;
}
@Deprecated
public
void
setFlag
(
Boolean
flag
)
{
this
.
flag
=
flag
;
}
}
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