Skip to content

Commit 388f7bf

Browse files
committed
Make DefaultValueStyler extensible
The `style(Object)` method in DefaultValueStyler delegates to several internal methods. Prior to this commit those methods were private, which prevented users from extending DefaultValueStyler without rewriting most of the functionality. This commit addresses this by making those methods protected so that DefaultValueStyler can be extended. In addition, this commit introduces protected methods for styling null, strings, classes, methods, and objects that are not covered by any of the other style*() methods. Closes gh-29380
1 parent 7f4dbdb commit 388f7bf

File tree

1 file changed

+114
-35
lines changed

1 file changed

+114
-35
lines changed

spring-core/src/main/java/org/springframework/core/style/DefaultValueStyler.java

Lines changed: 114 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*
3737
* @author Keith Donald
3838
* @author Juergen Hoeller
39+
* @author Sam Brannen
3940
* @since 1.2.2
4041
*/
4142
public class DefaultValueStyler implements ValueStyler {
@@ -53,86 +54,164 @@ public class DefaultValueStyler implements ValueStyler {
5354
@Override
5455
public String style(@Nullable Object value) {
5556
if (value == null) {
56-
return NULL;
57+
return styleNull();
5758
}
58-
else if (value instanceof String) {
59-
return "\'" + value + "\'";
59+
else if (value instanceof String str) {
60+
return styleString(str);
6061
}
6162
else if (value instanceof Class<?> clazz) {
62-
return ClassUtils.getShortName(clazz);
63+
return styleClass(clazz);
6364
}
6465
else if (value instanceof Method method) {
65-
return method.getName() + "@" + ClassUtils.getShortName(method.getDeclaringClass());
66+
return styleMethod(method);
6667
}
6768
else if (value instanceof Map<?, ?> map) {
68-
return style(map);
69+
return styleMap(map);
6970
}
7071
else if (value instanceof Map.Entry<?, ?> entry) {
71-
return style(entry);
72+
return styleMapEntry(entry);
7273
}
7374
else if (value instanceof Collection<?> collection) {
74-
return style(collection);
75+
return styleCollection(collection);
7576
}
7677
else if (value.getClass().isArray()) {
7778
return styleArray(ObjectUtils.toObjectArray(value));
7879
}
7980
else {
80-
return String.valueOf(value);
81+
return styleObject(value);
8182
}
8283
}
8384

84-
private <K, V> String style(Map<K, V> value) {
85-
if (value.isEmpty()) {
85+
/**
86+
* Generate a styled version of {@code null}.
87+
* <p>The default implementation returns {@code "[null]"}.
88+
* @return a styled version of {@code null}
89+
* @since 6.0
90+
*/
91+
protected String styleNull() {
92+
return NULL;
93+
}
94+
95+
/**
96+
* Generate a styled version of the supplied {@link String}.
97+
* <p>The default implementation returns the supplied string wrapped in
98+
* single quotes.
99+
* @return a styled version of the supplied string
100+
* @since 6.0
101+
*/
102+
protected String styleString(String str) {
103+
return "\'" + str + "\'";
104+
}
105+
106+
/**
107+
* Generate a styled version of the supplied {@link Class}.
108+
* <p>The default implementation delegates to {@link ClassUtils#getShortName(Class)}.
109+
* @return a styled version of the supplied class
110+
* @since 6.0
111+
*/
112+
protected String styleClass(Class<?> clazz) {
113+
return ClassUtils.getShortName(clazz);
114+
}
115+
116+
/**
117+
* Generate a styled version of the supplied {@link Method}.
118+
* <p>The default implementation returns the method's {@linkplain Method#getName()
119+
* name} and the {@linkplain ClassUtils#getShortName(Class) short name} of the
120+
* method's {@linkplain Method#getDeclaringClass() declaring class}, separated by
121+
* the {@code "@"} symbol.
122+
* @return a styled version of the supplied method
123+
* @since 6.0
124+
*/
125+
protected String styleMethod(Method method) {
126+
return method.getName() + "@" + ClassUtils.getShortName(method.getDeclaringClass());
127+
}
128+
129+
/**
130+
* Generate a styled version of the supplied {@link Map}.
131+
* @return a styled version of the supplied map
132+
* @since 6.0
133+
*/
134+
protected <K, V> String styleMap(Map<K, V> map) {
135+
if (map.isEmpty()) {
86136
return EMPTY_MAP;
87137
}
88138

89139
StringJoiner result = new StringJoiner(", ", "[", "]");
90-
for (Map.Entry<K, V> entry : value.entrySet()) {
91-
result.add(style(entry));
140+
for (Map.Entry<K, V> entry : map.entrySet()) {
141+
result.add(styleMapEntry(entry));
92142
}
93143
return MAP + result;
94144
}
95145

96-
private String style(Map.Entry<?, ?> value) {
97-
return style(value.getKey()) + " -> " + style(value.getValue());
146+
/**
147+
* Generate a styled version of the supplied {@link Map.Entry}.
148+
* @return a styled version of the supplied map entry
149+
* @since 6.0
150+
*/
151+
protected String styleMapEntry(Map.Entry<?, ?> entry) {
152+
return style(entry.getKey()) + " -> " + style(entry.getValue());
98153
}
99154

100-
private String style(Collection<?> value) {
101-
String collectionType = getCollectionTypeString(value);
155+
/**
156+
* Generate a styled version of the supplied {@link Collection}.
157+
* @return a styled version of the supplied collection
158+
* @since 6.0
159+
*/
160+
protected String styleCollection(Collection<?> collection) {
161+
String collectionType = getCollectionTypeString(collection);
102162

103-
if (value.isEmpty()) {
163+
if (collection.isEmpty()) {
104164
return collectionType + EMPTY;
105165
}
106166

107167
StringJoiner result = new StringJoiner(", ", "[", "]");
108-
for (Object o : value) {
109-
result.add(style(o));
168+
for (Object element : collection) {
169+
result.add(style(element));
110170
}
111171
return collectionType + result;
112172
}
113173

114-
private String getCollectionTypeString(Collection<?> value) {
115-
if (value instanceof List) {
116-
return LIST;
117-
}
118-
else if (value instanceof Set) {
119-
return SET;
120-
}
121-
else {
122-
return COLLECTION;
123-
}
124-
}
125-
126-
private String styleArray(Object[] array) {
174+
/**
175+
* Generate a styled version of the supplied array.
176+
* @return a styled version of the supplied array
177+
* @since 6.0
178+
*/
179+
protected String styleArray(Object[] array) {
127180
if (array.length == 0) {
128181
return ARRAY + '<' + ClassUtils.getShortName(array.getClass().getComponentType()) + '>' + EMPTY;
129182
}
130183

131184
StringJoiner result = new StringJoiner(", ", "[", "]");
132-
for (Object o : array) {
133-
result.add(style(o));
185+
for (Object element : array) {
186+
result.add(style(element));
134187
}
135188
return ARRAY + '<' + ClassUtils.getShortName(array.getClass().getComponentType()) + '>' + result;
136189
}
137190

191+
/**
192+
* Generate a styled version of the supplied {@link Object}.
193+
* <p>This method is only invoked by {@link #style(Object)} as a fallback,
194+
* if none of the other {@code style*()} methods is suitable for the object's
195+
* type.
196+
* <p>The default implementation delegates to {@link String#valueOf(Object)}.
197+
* @return a styled version of the supplied object
198+
* @since 6.0
199+
*/
200+
protected String styleObject(Object obj) {
201+
return String.valueOf(obj);
202+
}
203+
204+
205+
private static String getCollectionTypeString(Collection<?> collection) {
206+
if (collection instanceof List) {
207+
return LIST;
208+
}
209+
else if (collection instanceof Set) {
210+
return SET;
211+
}
212+
else {
213+
return COLLECTION;
214+
}
215+
}
216+
138217
}

0 commit comments

Comments
 (0)