From 901d48c803be0cc2b024e7c3a0da12dbb6d329a9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Feb 2018 17:19:12 +0100 Subject: [PATCH] Support for ResolvableType.getType().getTypeName() on Java 8 Issue: SPR-16535 (cherry picked from commit 6663d0f) --- .../springframework/core/ResolvableType.java | 18 +++++ .../core/ResolvableTypeTests.java | 65 +++++++++---------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index c50d35f7a24..155236d50a3 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -34,6 +34,7 @@ import java.util.Map; import org.springframework.core.SerializableTypeWrapper.FieldTypeProvider; import org.springframework.core.SerializableTypeWrapper.MethodParameterTypeProvider; import org.springframework.core.SerializableTypeWrapper.TypeProvider; +import org.springframework.lang.UsesJava8; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; @@ -1454,6 +1455,23 @@ public class ResolvableType implements Serializable { this.typeArguments = typeArguments; } + @Override // on Java 8 + @UsesJava8 + public String getTypeName() { + StringBuilder result = new StringBuilder(this.rawType.getTypeName()); + if (this.typeArguments.length > 0) { + result.append('<'); + for (int i = 0; i < this.typeArguments.length; i++) { + if (i > 0) { + result.append(", "); + } + result.append(this.typeArguments[i].getTypeName()); + } + result.append('>'); + } + return result.toString(); + } + @Override public Type getOwnerType() { return null; diff --git a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java index ab903fc6d79..68e5af3b8c7 100644 --- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java +++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -42,7 +42,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.Callable; -import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -927,16 +926,6 @@ public class ResolvableTypeTests { assertThat(ResolvableType.forClass(classType).getSuperType().getSource(), equalTo((Object) classType.getGenericSuperclass())); } - private void assertFieldToStringValue(String field, String expected) throws Exception { - ResolvableType type = ResolvableType.forField(Fields.class.getField(field)); - assertThat("field " + field + " toString", type.toString(), equalTo(expected)); - } - - private void assertTypedFieldToStringValue(String field, String expected) throws Exception { - ResolvableType type = ResolvableType.forField(Fields.class.getField(field), TypedFields.class); - assertThat("field " + field + " toString", type.toString(), equalTo(expected)); - } - @Test public void resolveFromOuterClass() throws Exception { Field field = EnclosedInParameterizedType.InnerTyped.class.getField("field"); @@ -954,7 +943,6 @@ public class ResolvableTypeTests { assertThat(type.asCollection().getGeneric().getGeneric().resolve(), equalTo((Type) String.class)); } - @Test public void isAssignableFromMustNotBeNull() throws Exception { this.thrown.expect(IllegalArgumentException.class); @@ -1189,18 +1177,17 @@ public class ResolvableTypeTests { assertThat(forFieldDirect, not(equalTo(forFieldWithImplementation))); } - @SuppressWarnings("unused") - private HashMap> myMap; - @Test public void javaDocSample() throws Exception { ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap")); + assertThat(t.toString(), equalTo("java.util.HashMap>")); + assertThat(t.getType().getTypeName(), equalTo("java.util.HashMap>")); assertThat(t.getSuperType().toString(), equalTo("java.util.AbstractMap>")); assertThat(t.asMap().toString(), equalTo("java.util.Map>")); - assertThat(t.getGeneric(0).resolve(), equalTo((Class)Integer.class)); - assertThat(t.getGeneric(1).resolve(), equalTo((Class)List.class)); + assertThat(t.getGeneric(0).resolve(), equalTo(Integer.class)); + assertThat(t.getGeneric(1).resolve(), equalTo(List.class)); assertThat(t.getGeneric(1).toString(), equalTo("java.util.List")); - assertThat(t.resolveGeneric(1, 0), equalTo((Class) String.class)); + assertThat(t.resolveGeneric(1, 0), equalTo(String.class)); } @Test @@ -1208,6 +1195,7 @@ public class ResolvableTypeTests { ResolvableType elementType = ResolvableType.forClassWithGenerics(Map.class, Integer.class, String.class); ResolvableType listType = ResolvableType.forClassWithGenerics(List.class, elementType); assertThat(listType.toString(), equalTo("java.util.List>")); + assertThat(listType.getType().getTypeName(), equalTo("java.util.List>")); } @Test @@ -1228,7 +1216,7 @@ public class ResolvableTypeTests { ResolvableType elementType = ResolvableType.forField(Fields.class.getField("stringList")); ResolvableType type = ResolvableType.forArrayComponent(elementType); assertThat(type.toString(), equalTo("java.util.List[]")); - assertThat(type.resolve(), equalTo((Class) List[].class)); + assertThat(type.resolve(), equalTo(List[].class)); } @Test @@ -1248,14 +1236,14 @@ public class ResolvableTypeTests { @Test public void canResolveVoid() throws Exception { ResolvableType type = ResolvableType.forClass(void.class); - assertThat(type.resolve(), equalTo((Class) void.class)); + assertThat(type.resolve(), equalTo(void.class)); } @Test public void narrow() throws Exception { ResolvableType type = ResolvableType.forField(Fields.class.getField("stringList")); ResolvableType narrow = ResolvableType.forType(ArrayList.class, type); - assertThat(narrow.getGeneric().resolve(), equalTo((Class) String.class)); + assertThat(narrow.getGeneric().resolve(), equalTo(String.class)); } @Test @@ -1330,23 +1318,30 @@ public class ResolvableTypeTests { ResolvableType read = (ResolvableType) ois.readObject(); assertThat(read, equalTo(type)); assertThat(read.getType(), equalTo(type.getType())); - assertThat(read.resolve(), equalTo((Class) type.resolve())); + assertThat(read.resolve(), equalTo(type.resolve())); return read; } - private static AssertAssignbleMatcher assertAssignable(final ResolvableType type, final ResolvableType... fromTypes) { - return new AssertAssignbleMatcher() { - @Override - public void equalTo(boolean... values) { - for (int i = 0; i < fromTypes.length; i++) { - assertThat(stringDesc(type) + " isAssignableFrom " + stringDesc(fromTypes[i]), - type.isAssignableFrom(fromTypes[i]), Matchers.equalTo(values[i])); - } + private void assertFieldToStringValue(String field, String expected) throws Exception { + ResolvableType type = ResolvableType.forField(Fields.class.getField(field)); + assertThat("field " + field + " toString", type.toString(), equalTo(expected)); + } + + private void assertTypedFieldToStringValue(String field, String expected) throws Exception { + ResolvableType type = ResolvableType.forField(Fields.class.getField(field), TypedFields.class); + assertThat("field " + field + " toString", type.toString(), equalTo(expected)); + } + + private AssertAssignbleMatcher assertAssignable(final ResolvableType type, final ResolvableType... fromTypes) { + return values -> { + for (int i = 0; i < fromTypes.length; i++) { + assertThat(stringDesc(type) + " isAssignableFrom " + stringDesc(fromTypes[i]), + type.isAssignableFrom(fromTypes[i]), equalTo(values[i])); } }; } - private static String stringDesc(ResolvableType type) { + private String stringDesc(ResolvableType type) { if (type == ResolvableType.NONE) { return "NONE"; } @@ -1357,7 +1352,11 @@ public class ResolvableTypeTests { } - private static interface AssertAssignbleMatcher { + @SuppressWarnings("unused") + private HashMap> myMap; + + + private interface AssertAssignbleMatcher { void equalTo(boolean... values); }