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
368a77f3
Commit
368a77f3
authored
Feb 24, 2020
by
Madhura Bhave
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.1.x' into 2.2.x
Closes gh-20306
parents
11b98620
09571686
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
150 additions
and
1 deletion
+150
-1
NoUnboundElementsBindHandler.java
...properties/bind/handler/NoUnboundElementsBindHandler.java
+52
-1
NoUnboundElementsBindHandlerTests.java
...rties/bind/handler/NoUnboundElementsBindHandlerTests.java
+98
-0
No files found.
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandler.java
View file @
368a77f3
...
...
@@ -43,6 +43,8 @@ public class NoUnboundElementsBindHandler extends AbstractBindHandler {
private
final
Set
<
ConfigurationPropertyName
>
boundNames
=
new
HashSet
<>();
private
final
Set
<
ConfigurationPropertyName
>
attemptedNames
=
new
HashSet
<>();
private
final
Function
<
ConfigurationPropertySource
,
Boolean
>
filter
;
NoUnboundElementsBindHandler
()
{
...
...
@@ -58,6 +60,12 @@ public class NoUnboundElementsBindHandler extends AbstractBindHandler {
this
.
filter
=
filter
;
}
@Override
public
<
T
>
Bindable
<
T
>
onStart
(
ConfigurationPropertyName
name
,
Bindable
<
T
>
target
,
BindContext
context
)
{
this
.
attemptedNames
.
add
(
name
);
return
super
.
onStart
(
name
,
target
,
context
);
}
@Override
public
Object
onSuccess
(
ConfigurationPropertyName
name
,
Bindable
<?>
target
,
BindContext
context
,
Object
result
)
{
this
.
boundNames
.
add
(
name
);
...
...
@@ -106,11 +114,54 @@ public class NoUnboundElementsBindHandler extends AbstractBindHandler {
private
boolean
isOverriddenCollectionElement
(
ConfigurationPropertyName
candidate
)
{
int
lastIndex
=
candidate
.
getNumberOfElements
()
-
1
;
if
(
candidate
.
is
NumericIndex
(
lastIndex
))
{
if
(
candidate
.
is
LastElementIndexed
(
))
{
ConfigurationPropertyName
propertyName
=
candidate
.
chop
(
lastIndex
);
return
this
.
boundNames
.
contains
(
propertyName
);
}
Indexed
indexed
=
getIndexed
(
candidate
);
if
(
indexed
!=
null
)
{
String
zeroethProperty
=
indexed
.
getName
()
+
"[0]"
;
if
(
this
.
boundNames
.
contains
(
ConfigurationPropertyName
.
of
(
zeroethProperty
)))
{
String
nestedZeroethProperty
=
zeroethProperty
+
"."
+
indexed
.
getNestedPropertyName
();
return
isCandidateValidPropertyName
(
nestedZeroethProperty
);
}
}
return
false
;
}
private
boolean
isCandidateValidPropertyName
(
String
nestedZeroethProperty
)
{
return
this
.
attemptedNames
.
contains
(
ConfigurationPropertyName
.
of
(
nestedZeroethProperty
));
}
private
Indexed
getIndexed
(
ConfigurationPropertyName
candidate
)
{
for
(
int
i
=
0
;
i
<
candidate
.
getNumberOfElements
();
i
++)
{
if
(
candidate
.
isNumericIndex
(
i
))
{
return
new
Indexed
(
candidate
.
chop
(
i
).
toString
(),
candidate
.
getElement
(
i
+
1
,
ConfigurationPropertyName
.
Form
.
UNIFORM
));
}
}
return
null
;
}
private
static
final
class
Indexed
{
private
final
String
name
;
private
final
String
nestedPropertyName
;
private
Indexed
(
String
name
,
String
nestedPropertyName
)
{
this
.
name
=
name
;
this
.
nestedPropertyName
=
nestedPropertyName
;
}
String
getName
()
{
return
this
.
name
;
}
String
getNestedPropertyName
()
{
return
this
.
nestedPropertyName
;
}
}
}
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandlerTests.java
View file @
368a77f3
...
...
@@ -131,6 +131,42 @@ class NoUnboundElementsBindHandlerTests {
.
contains
(
"The elements [example.foo[0]] were left unbound"
));
}
@Test
void
bindWhenUsingNoUnboundElementsHandlerShouldBindIfUnboundNestedCollectionProperties
()
{
MockConfigurationPropertySource
source1
=
new
MockConfigurationPropertySource
();
source1
.
put
(
"example.nested[0].string-value"
,
"bar"
);
MockConfigurationPropertySource
source2
=
new
MockConfigurationPropertySource
();
source2
.
put
(
"example.nested[0].string-value"
,
"bar"
);
source2
.
put
(
"example.nested[0].int-value"
,
"2"
);
source2
.
put
(
"example.nested[1].string-value"
,
"baz"
);
source2
.
put
(
"example.nested[1].other-nested.baz"
,
"baz"
);
this
.
sources
.
add
(
source1
);
this
.
sources
.
add
(
source2
);
this
.
binder
=
new
Binder
(
this
.
sources
);
NoUnboundElementsBindHandler
handler
=
new
NoUnboundElementsBindHandler
();
ExampleWithNestedList
bound
=
this
.
binder
.
bind
(
"example"
,
Bindable
.
of
(
ExampleWithNestedList
.
class
),
handler
)
.
get
();
assertThat
(
bound
.
getNested
().
get
(
0
).
getStringValue
()).
isEqualTo
(
"bar"
);
}
@Test
void
bindWhenUsingNoUnboundElementsHandlerAndUnboundCollectionElementsWithInvalidPropertyShouldThrowException
()
{
MockConfigurationPropertySource
source1
=
new
MockConfigurationPropertySource
();
source1
.
put
(
"example.nested[0].string-value"
,
"bar"
);
MockConfigurationPropertySource
source2
=
new
MockConfigurationPropertySource
();
source2
.
put
(
"example.nested[0].string-value"
,
"bar"
);
source2
.
put
(
"example.nested[1].int-value"
,
"1"
);
source2
.
put
(
"example.nested[1].invalid"
,
"baz"
);
this
.
sources
.
add
(
source1
);
this
.
sources
.
add
(
source2
);
this
.
binder
=
new
Binder
(
this
.
sources
);
assertThatExceptionOfType
(
BindException
.
class
)
.
isThrownBy
(()
->
this
.
binder
.
bind
(
"example"
,
Bindable
.
of
(
ExampleWithNestedList
.
class
),
new
NoUnboundElementsBindHandler
()))
.
satisfies
((
ex
)
->
assertThat
(
ex
.
getCause
().
getMessage
())
.
contains
(
"The elements [example.nested[1].invalid] were left unbound"
));
}
static
class
Example
{
private
String
foo
;
...
...
@@ -159,4 +195,66 @@ class NoUnboundElementsBindHandlerTests {
}
static
class
ExampleWithNestedList
{
private
List
<
Nested
>
nested
;
List
<
Nested
>
getNested
()
{
return
this
.
nested
;
}
void
setNested
(
List
<
Nested
>
nested
)
{
this
.
nested
=
nested
;
}
}
static
class
Nested
{
private
String
stringValue
;
private
Integer
intValue
;
private
OtherNested
otherNested
;
String
getStringValue
()
{
return
this
.
stringValue
;
}
void
setStringValue
(
String
value
)
{
this
.
stringValue
=
value
;
}
Integer
getIntValue
()
{
return
this
.
intValue
;
}
void
setIntValue
(
Integer
intValue
)
{
this
.
intValue
=
intValue
;
}
OtherNested
getOtherNested
()
{
return
this
.
otherNested
;
}
void
setOtherNested
(
OtherNested
otherNested
)
{
this
.
otherNested
=
otherNested
;
}
}
static
class
OtherNested
{
private
String
baz
;
String
getBaz
()
{
return
this
.
baz
;
}
void
setBaz
(
String
baz
)
{
this
.
baz
=
baz
;
}
}
}
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