15
15
*/
16
16
package org .springframework .data .domain ;
17
17
18
+ import java .util .LinkedHashMap ;
19
+ import java .util .Map ;
20
+
18
21
import org .springframework .util .Assert ;
19
22
import org .springframework .util .ClassUtils ;
20
23
25
28
public class Example <T > {
26
29
27
30
private final T probe ;
28
- private ObjectMatchMode objectMatchMode = ObjectMatchMode .LENIENT ;
29
- private StringMatchMode stringMatchMode = StringMatchMode .DEFAULT ;
30
- private boolean ignoreCaseEnabled = false ;
31
+
32
+ private NullHandling nullHandling = NullHandling .IGNORE_NULL ;
33
+ private StringMatcher defaultStringMatcher = StringMatcher .DEFAULT ;
34
+
35
+ private boolean ignoreCase = false ;
36
+
37
+ private Map <String , PropertySpecifier > propertySpecifiers = new LinkedHashMap <String , PropertySpecifier >();
31
38
32
39
public <S extends T > Example (S probe ) {
33
40
@@ -39,51 +46,105 @@ public T getProbe() {
39
46
return probe ;
40
47
}
41
48
42
- public ObjectMatchMode getObjectMatchMode () {
43
- return objectMatchMode ;
49
+ public NullHandling getNullHandling () {
50
+ return nullHandling ;
44
51
}
45
52
46
- public StringMatchMode getStringMatchMode () {
47
- return stringMatchMode ;
53
+ public StringMatcher getDefaultStringMatcher () {
54
+ return defaultStringMatcher ;
48
55
}
49
56
50
57
public boolean isIngnoreCaseEnabled () {
51
- return this .ignoreCaseEnabled ;
58
+ return this .ignoreCase ;
59
+ }
60
+
61
+ public boolean hasPropertySpecifier (String path ) {
62
+ return propertySpecifiers .containsKey (path );
63
+ }
64
+
65
+ public PropertySpecifier getPropertySpecifier (String propertyPath ) {
66
+ return this .propertySpecifiers .get (propertyPath );
67
+ }
68
+
69
+ public boolean hasPropertySpecifiers () {
70
+ return !this .propertySpecifiers .isEmpty ();
52
71
}
53
72
54
73
@ SuppressWarnings ("unchecked" )
55
74
public Class <? extends T > getProbeType () {
56
75
return (Class <? extends T >) ClassUtils .getUserClass (probe .getClass ());
57
76
}
58
77
59
- public static <S extends T , T > Example <T > example (S probe ) {
78
+ public static <S extends T , T > Example <T > exampleOf (S probe ) {
60
79
return new Example <T >(probe );
61
80
}
62
81
63
- public static class ExampleBuilder <T > {
82
+ public static <S extends T , T > Example <T > exampleOf (S probe , String ... ignoredProperties ) {
83
+ return new Builder <T >(probe ).ignore (ignoredProperties ).get ();
84
+ }
85
+
86
+ public static <S extends T , T > Builder <S > newExampleOf (S probe ) {
87
+ return new Builder <S >(probe );
88
+ }
89
+
90
+ public static class Builder <T > {
64
91
65
92
private Example <T > example ;
66
93
67
- public ExampleBuilder (T probe ) {
94
+ Builder (T probe ) {
68
95
example = new Example <T >(probe );
69
96
}
70
97
71
- public ExampleBuilder <T > objectMatchMode (ObjectMatchMode matchMode ) {
98
+ public Builder <T > with (NullHandling nullHandling ) {
99
+ return nullHandling (nullHandling );
100
+ }
101
+
102
+ public Builder <T > with (StringMatcher stringMatcher ) {
103
+ return stringMatcher (stringMatcher );
104
+ }
105
+
106
+ public Builder <T > with (PropertySpecifier specifier ) {
107
+ return specify (specifier );
108
+ }
109
+
110
+ public Builder <T > nullHandling (NullHandling nullHandling ) {
72
111
73
- example .objectMatchMode = matchMode == null ? ObjectMatchMode . LENIENT : matchMode ;
112
+ example .nullHandling = nullHandling == null ? NullHandling . IGNORE_NULL : nullHandling ;
74
113
return this ;
75
114
}
76
115
77
- public ExampleBuilder <T > stringMatchMode ( StringMatchMode matchMode ) {
116
+ public Builder <T > stringMatcher ( StringMatcher stringMatcher ) {
78
117
79
- example .stringMatchMode = matchMode == null ? StringMatchMode .DEFAULT : matchMode ;
118
+ example .defaultStringMatcher = stringMatcher == null ? StringMatcher .DEFAULT : stringMatcher ;
80
119
return this ;
81
120
}
82
121
83
- public ExampleBuilder <T > stringMatchMode ( StringMatchMode matchMode , boolean ignoreCase ) {
122
+ public Builder <T > stringMatcher ( StringMatcher stringMatching , boolean ignoreCase ) {
84
123
85
- example .stringMatchMode = matchMode == null ? StringMatchMode .DEFAULT : matchMode ;
86
- example .ignoreCaseEnabled = ignoreCase ;
124
+ example .defaultStringMatcher = stringMatching == null ? StringMatcher .DEFAULT : stringMatching ;
125
+ example .ignoreCase = ignoreCase ;
126
+ return this ;
127
+ }
128
+
129
+ public Builder <T > ignoreCase () {
130
+ example .ignoreCase = true ;
131
+ return this ;
132
+ }
133
+
134
+ public Builder <T > specify (PropertySpecifier ... specifiers ) {
135
+
136
+ for (PropertySpecifier specifier : specifiers ) {
137
+ example .propertySpecifiers .put (specifier .getPath (), specifier );
138
+ }
139
+ return this ;
140
+ }
141
+
142
+ public Builder <T > ignore (String ... ignoredProperties ) {
143
+
144
+ for (String ignoredProperty : ignoredProperties ) {
145
+ specify (PropertySpecifier .newPropertySpecifier (ignoredProperty )
146
+ .valueTransformer (new ExcludingValueTransformer ()).get ());
147
+ }
87
148
return this ;
88
149
}
89
150
@@ -97,23 +158,23 @@ public Example<T> get() {
97
158
*
98
159
* @author Christoph Strobl
99
160
*/
100
- public static enum ObjectMatchMode {
161
+ public static enum NullHandling {
101
162
/**
102
163
* Strict matching will use partially filled objects as reference.
103
164
*/
104
- STRICT ,
165
+ INCLUDE_NULL ,
105
166
/**
106
167
* Lenient matching will inspected nested objects and extract path if needed.
107
168
*/
108
- LENIENT
169
+ IGNORE_NULL
109
170
}
110
171
111
172
/**
112
173
* Match modes indicates treatment of {@link String} values.
113
174
*
114
175
* @author Christoph Strobl
115
176
*/
116
- public static enum StringMatchMode {
177
+ public static enum StringMatcher {
117
178
118
179
/**
119
180
* Store specific default.
@@ -141,9 +202,12 @@ public static enum StringMatchMode {
141
202
REGEX
142
203
}
143
204
144
- // TODO: add default null handling
145
- // TODO: add default String handling
146
- // TODO: add per field null handling
147
- // TODO: add per field String handling
205
+ public static class ExcludingValueTransformer implements PropertyValueTransformer {
206
+
207
+ @ Override
208
+ public Object tranform (Object source ) {
209
+ return null ;
210
+ }
211
+ }
148
212
149
213
}
0 commit comments