Use proper format for TypeReference
This commit updates BasicJsonWriter to handle TypeReferences and generate an appropriate format for a class name. Specifically, an inner class should be separated by a dollar sign, not a dot. Closes gh-28312
This commit is contained in:
parent
c8a7a187a2
commit
069aab37cd
|
|
@ -23,6 +23,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.springframework.aot.hint.TypeReference;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Very basic json writer for the purposes of translating runtime hints to native
|
* Very basic json writer for the purposes of translating runtime hints to native
|
||||||
* configuration.
|
* configuration.
|
||||||
|
|
@ -129,6 +132,9 @@ class BasicJsonWriter {
|
||||||
else if (value instanceof List<?> list) {
|
else if (value instanceof List<?> list) {
|
||||||
writeArray(list, false);
|
writeArray(list, false);
|
||||||
}
|
}
|
||||||
|
else if (value instanceof TypeReference typeReference) {
|
||||||
|
this.writer.print(quote(toName(typeReference)));
|
||||||
|
}
|
||||||
else if (value instanceof CharSequence string) {
|
else if (value instanceof CharSequence string) {
|
||||||
this.writer.print(quote(escape(string)));
|
this.writer.print(quote(escape(string)));
|
||||||
}
|
}
|
||||||
|
|
@ -144,6 +150,22 @@ class BasicJsonWriter {
|
||||||
return "\"" + name + "\"";
|
return "\"" + name + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toName(TypeReference typeReference) {
|
||||||
|
StringBuilder names = new StringBuilder();
|
||||||
|
buildName(typeReference, names);
|
||||||
|
return typeReference.getPackageName() + "." + names;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildName(@Nullable TypeReference type, StringBuilder sb) {
|
||||||
|
if (type == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String typeName = (type.getEnclosingType() != null) ? "$" + type.getSimpleName() : type.getSimpleName();
|
||||||
|
sb.insert(0, typeName);
|
||||||
|
buildName(type.getEnclosingType(), sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String escape(CharSequence input) {
|
private static String escape(CharSequence input) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
input.chars().forEach(c -> {
|
input.chars().forEach(c -> {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class JavaSerializationHintsWriter {
|
||||||
|
|
||||||
private Map<String, Object> toAttributes(TypeReference typeReference) {
|
private Map<String, Object> toAttributes(TypeReference typeReference) {
|
||||||
LinkedHashMap<String, Object> attributes = new LinkedHashMap<>();
|
LinkedHashMap<String, Object> attributes = new LinkedHashMap<>();
|
||||||
attributes.put("name", typeReference.getCanonicalName());
|
attributes.put("name", typeReference);
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class ReflectionHintsWriter {
|
||||||
|
|
||||||
private Map<String, Object> toAttributes(TypeHint hint) {
|
private Map<String, Object> toAttributes(TypeHint hint) {
|
||||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||||
attributes.put("name", hint.getType().getCanonicalName());
|
attributes.put("name", hint.getType());
|
||||||
handleCondition(attributes, hint);
|
handleCondition(attributes, hint);
|
||||||
handleCategories(attributes, hint.getMemberCategories());
|
handleCategories(attributes, hint.getMemberCategories());
|
||||||
handleFields(attributes, hint.fields());
|
handleFields(attributes, hint.fields());
|
||||||
|
|
@ -63,7 +63,7 @@ class ReflectionHintsWriter {
|
||||||
private void handleCondition(Map<String, Object> attributes, TypeHint hint) {
|
private void handleCondition(Map<String, Object> attributes, TypeHint hint) {
|
||||||
if (hint.getReachableType() != null) {
|
if (hint.getReachableType() != null) {
|
||||||
Map<String, Object> conditionAttributes = new LinkedHashMap<>();
|
Map<String, Object> conditionAttributes = new LinkedHashMap<>();
|
||||||
conditionAttributes.put("typeReachable", hint.getReachableType().getCanonicalName());
|
conditionAttributes.put("typeReachable", hint.getReachableType());
|
||||||
attributes.put("condition", conditionAttributes);
|
attributes.put("condition", conditionAttributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.aot.hint.TypeReference;
|
||||||
|
import org.springframework.aot.nativex.BasicJsonWriterTests.Nested.Inner;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,49 +139,66 @@ class BasicJsonWriterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeDoubleQuote() {
|
void writeWithEscapeDoubleQuote() {
|
||||||
assertEscapedValue("foo\"bar", "foo\\\"bar");
|
assertStringAttribute("foo\"bar", "foo\\\"bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeBackslash() {
|
void writeWithEscapeBackslash() {
|
||||||
assertEscapedValue("foo\"bar", "foo\\\"bar");
|
assertStringAttribute("foo\"bar", "foo\\\"bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeBackspace() {
|
void writeWithEscapeBackspace() {
|
||||||
assertEscapedValue("foo\bbar", "foo\\bbar");
|
assertStringAttribute("foo\bbar", "foo\\bbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeFormFeed() {
|
void writeWithEscapeFormFeed() {
|
||||||
assertEscapedValue("foo\fbar", "foo\\fbar");
|
assertStringAttribute("foo\fbar", "foo\\fbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeNewline() {
|
void writeWithEscapeNewline() {
|
||||||
assertEscapedValue("foo\nbar", "foo\\nbar");
|
assertStringAttribute("foo\nbar", "foo\\nbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeCarriageReturn() {
|
void writeWithEscapeCarriageReturn() {
|
||||||
assertEscapedValue("foo\rbar", "foo\\rbar");
|
assertStringAttribute("foo\rbar", "foo\\rbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeTab() {
|
void writeWithEscapeTab() {
|
||||||
assertEscapedValue("foo\tbar", "foo\\tbar");
|
assertStringAttribute("foo\tbar", "foo\\tbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeWithEscapeUnicode() {
|
void writeWithEscapeUnicode() {
|
||||||
assertEscapedValue("foo\u001Fbar", "foo\\u001fbar");
|
assertStringAttribute("foo\u001Fbar", "foo\\u001fbar");
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertEscapedValue(String value, String expectedEscapedValue) {
|
@Test
|
||||||
|
void writeWithTypeReferenceForSimpleClass() {
|
||||||
|
assertStringAttribute(TypeReference.of(String.class), "java.lang.String");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeWithTypeReferenceForInnerClass() {
|
||||||
|
assertStringAttribute(TypeReference.of(Nested.class),
|
||||||
|
"org.springframework.aot.nativex.BasicJsonWriterTests$Nested");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeWithTypeReferenceForDoubleInnerClass() {
|
||||||
|
assertStringAttribute(TypeReference.of(Inner.class),
|
||||||
|
"org.springframework.aot.nativex.BasicJsonWriterTests$Nested$Inner");
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertStringAttribute(Object value, String expectedValue) {
|
||||||
Map<String, Object> attributes = new LinkedHashMap<>();
|
Map<String, Object> attributes = new LinkedHashMap<>();
|
||||||
attributes.put("test", value);
|
attributes.put("test", value);
|
||||||
this.json.writeObject(attributes);
|
this.json.writeObject(attributes);
|
||||||
assertThat(out.toString()).contains("\"test\": \"" + expectedEscapedValue + "\"");
|
assertThat(out.toString()).contains("\"test\": \"" + expectedValue + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LinkedHashMap<String, Object> orderedMap(String key, Object value) {
|
private static LinkedHashMap<String, Object> orderedMap(String key, Object value) {
|
||||||
|
|
@ -187,4 +207,12 @@ class BasicJsonWriterTests {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Nested {
|
||||||
|
|
||||||
|
static class Inner {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue