mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 16:09:21 +08:00
Merge pull request #237 from NightlyNexus/patch-1
Add Types.createJsonQualifierImplementation
This commit is contained in:
@@ -61,6 +61,11 @@ public final class Moshi {
|
|||||||
return adapter(type, Util.NO_ANNOTATIONS);
|
return adapter(type, Util.NO_ANNOTATIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> JsonAdapter<T> adapter(Type type, Class<? extends Annotation> annotationType) {
|
||||||
|
return adapter(type,
|
||||||
|
Collections.singleton(Types.createJsonQualifierImplementation(annotationType)));
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") // Factories are required to return only matching JsonAdapters.
|
@SuppressWarnings("unchecked") // Factories are required to return only matching JsonAdapters.
|
||||||
public <T> JsonAdapter<T> adapter(Type type, Set<? extends Annotation> annotations) {
|
public <T> JsonAdapter<T> adapter(Type type, Set<? extends Annotation> annotations) {
|
||||||
type = Types.canonicalize(type);
|
type = Types.canonicalize(type);
|
||||||
|
@@ -15,10 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.squareup.moshi;
|
package com.squareup.moshi;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.GenericArrayType;
|
import java.lang.reflect.GenericArrayType;
|
||||||
import java.lang.reflect.GenericDeclaration;
|
import java.lang.reflect.GenericDeclaration;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.lang.reflect.WildcardType;
|
import java.lang.reflect.WildcardType;
|
||||||
@@ -137,6 +141,39 @@ public final class Types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
static <T extends Annotation> T createJsonQualifierImplementation(final Class<T> annotationType) {
|
||||||
|
if (!annotationType.isAnnotation()) {
|
||||||
|
throw new IllegalArgumentException(annotationType + " must be an annotation.");
|
||||||
|
}
|
||||||
|
if (!annotationType.isAnnotationPresent(JsonQualifier.class)) {
|
||||||
|
throw new IllegalArgumentException(annotationType + " must have @JsonQualifier.");
|
||||||
|
}
|
||||||
|
if (annotationType.getDeclaredMethods().length != 0) {
|
||||||
|
throw new IllegalArgumentException(annotationType + " must not declare methods.");
|
||||||
|
}
|
||||||
|
return (T) Proxy.newProxyInstance(annotationType.getClassLoader(),
|
||||||
|
new Class<?>[] { annotationType }, new InvocationHandler() {
|
||||||
|
@Override public Object invoke(Object proxy, Method method, Object[] args)
|
||||||
|
throws Throwable {
|
||||||
|
String methodName = method.getName();
|
||||||
|
switch (methodName) {
|
||||||
|
case "annotationType":
|
||||||
|
return annotationType;
|
||||||
|
case "equals":
|
||||||
|
Object o = args[0];
|
||||||
|
return annotationType.isInstance(o);
|
||||||
|
case "hashCode":
|
||||||
|
return 0;
|
||||||
|
case "toString":
|
||||||
|
return "@" + annotationType.getName() + "()";
|
||||||
|
default:
|
||||||
|
return method.invoke(proxy, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static boolean equal(Object a, Object b) {
|
static boolean equal(Object a, Object b) {
|
||||||
return a == b || (a != null && a.equals(b));
|
return a == b || (a != null && a.equals(b));
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.squareup.moshi;
|
package com.squareup.moshi;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -23,6 +24,7 @@ import java.util.Map;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
@@ -143,4 +145,20 @@ public final class TypesTest {
|
|||||||
assertThat(Types.mapKeyAndValueTypes(StringIntegerMap.class, StringIntegerMap.class))
|
assertThat(Types.mapKeyAndValueTypes(StringIntegerMap.class, StringIntegerMap.class))
|
||||||
.containsExactly(String.class, Integer.class);
|
.containsExactly(String.class, Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void createJsonQualifierImplementation() throws Exception {
|
||||||
|
TestQualifier actual = Types.createJsonQualifierImplementation(TestQualifier.class);
|
||||||
|
TestQualifier expected =
|
||||||
|
(TestQualifier) TypesTest.class.getDeclaredField("unused").getAnnotations()[0];
|
||||||
|
assertThat(actual.annotationType()).isEqualTo(TestQualifier.class);
|
||||||
|
assertThat(actual).isEqualTo(expected);
|
||||||
|
assertThat(actual).isNotEqualTo(null);
|
||||||
|
assertThat(actual.hashCode()).isEqualTo(expected.hashCode());
|
||||||
|
assertThat(actual.getClass()).isNotEqualTo(TestQualifier.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestQualifier private static Object unused;
|
||||||
|
|
||||||
|
@Retention(RUNTIME) @JsonQualifier @interface TestQualifier {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user