static Type getGenericSuperclass(Type type) { Class<?> rawType = Types.getRawType(type); return resolve(type, rawType, rawType.getGenericSuperclass()); }
public static Class<?> getRawType(Type type) { if (type instanceof Class<?>) { // type is a normal class. return (Class<?>) type; } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; // I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but // suspects some pathological case related to nested classes exists. Type rawType = parameterizedType.getRawType(); return (Class<?>) rawType; } else if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType) type).getGenericComponentType(); return Array.newInstance(getRawType(componentType), 0).getClass(); } else if (type instanceof TypeVariable) { // We could use the variable's bounds, but that won't work if there are multiple. having a raw // type that's more general than necessary is okay. return Object.class; } else if (type instanceof WildcardType) { return getRawType(((WildcardType) type).getUpperBounds()[0]); } else { String className = type == null ? "null" : type.getClass().getName(); throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + className); } }
@Nullable @Override @SuppressWarnings("unchecked") public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { Class<?> rawType = Types.getRawType(type); if (!rawType.isEnum()) { return null; } if (annotations.size() != 1) { return null; } Annotation annotation = annotations.iterator().next(); if (!(annotation instanceof Fallback)) { return null; } Class<Enum> enumType = (Class<Enum>) rawType; Enum<?> fallback = Enum.valueOf(enumType, ((Fallback) annotation).value()); return new FallbackEnumJsonAdapter<>(enumType, fallback); } };
@Override public @Nullable JsonAdapter<?> create( Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (!annotations.isEmpty()) return null; Class<?> rawType = Types.getRawType(type); if (rawType != Map.class) return null; Type[] keyAndValue = Types.mapKeyAndValueTypes(type, rawType); return new MapJsonAdapter<>(moshi, keyAndValue[0], keyAndValue[1]).nullSafe(); } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (Types.getRawType(type) != baseType || !annotations.isEmpty()) { return null; } List<JsonAdapter<Object>> jsonAdapters = new ArrayList<>(subtypes.size()); for (int i = 0, size = subtypes.size(); i < size; i++) { jsonAdapters.add(moshi.adapter(subtypes.get(i))); } return new PolymorphicJsonAdapter(labelKey, labels, subtypes, jsonAdapters, defaultValue, defaultValueSet ).nullSafe(); }
@Override public @Nullable JsonAdapter<?> create( Type type, Set<? extends Annotation> annotations, Moshi moshi) { Class<?> rawType = Types.getRawType(type); if (!annotations.isEmpty()) return null; if (rawType == List.class || rawType == Collection.class) { return newArrayListAdapter(type, moshi).nullSafe(); } else if (rawType == Set.class) { return newLinkedHashSetAdapter(type, moshi).nullSafe(); } return null; } };
@Override public @Nullable JsonAdapter<?> create( Type type, Set<? extends Annotation> annotations, Moshi moshi) { Type elementType = Types.arrayComponentType(type); if (elementType == null) return null; if (!annotations.isEmpty()) return null; Class<?> elementClass = Types.getRawType(elementType); JsonAdapter<Object> elementAdapter = moshi.adapter(elementType); return new ArrayJsonAdapter(elementClass, elementAdapter).nullSafe(); } };
return null; Class<?> rawType = Types.getRawType(type); if (rawType.isInterface() || rawType.isEnum()) return null; if (!annotations.isEmpty()) return null;
@Override public @Nullable JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if ((type == Long.class || type == long.class) && Types.nextAnnotations(annotations, Uint64.class) != null) { return UINT64_JSON_ADAPTER; } Class<?> rawType = Types.getRawType(type); if (rawType == List.class && ((ParameterizedType) type).getActualTypeArguments()[0] == Long.class && Types.nextAnnotations(annotations, Uint64.class) != null) { return LIST_OF_UINT64_JSON_ADAPTER; } if (!annotations.isEmpty()) { return null; } if (rawType.equals(ByteString.class)) { return BYTE_STRING_JSON_ADAPTER; } if (Message.class.isAssignableFrom(rawType)) { return new MessageJsonAdapter(moshi, type); } return null; } }
public ParameterizedTypeImpl(@Nullable Type ownerType, Type rawType, Type... typeArguments) { // Require an owner type if the raw type needs it. if (rawType instanceof Class<?>) { Class<?> enclosingClass = ((Class<?>) rawType).getEnclosingClass(); if (ownerType != null) { if (enclosingClass == null || Types.getRawType(ownerType) != enclosingClass) { throw new IllegalArgumentException( "unexpected owner type for " + rawType + ": " + ownerType); } } else if (enclosingClass != null) { throw new IllegalArgumentException( "unexpected owner type for " + rawType + ": null"); } } this.ownerType = ownerType == null ? null : canonicalize(ownerType); this.rawType = canonicalize(rawType); this.typeArguments = typeArguments.clone(); for (int t = 0; t < this.typeArguments.length; t++) { if (this.typeArguments[t] == null) throw new NullPointerException(); checkNotPrimitive(this.typeArguments[t]); this.typeArguments[t] = canonicalize(this.typeArguments[t]); } }
/** Creates a field binding for each of declared field of {@code type}. */ private void createFieldBindings( Moshi moshi, Type type, Map<String, FieldBinding<?>> fieldBindings) { Class<?> rawType = Types.getRawType(type); boolean platformType = Util.isPlatformType(rawType); for (Field field : rawType.getDeclaredFields()) { if (!includeField(platformType, field.getModifiers())) continue; // Look up a type adapter for this type. Type fieldType = resolve(type, rawType, field.getGenericType()); Set<? extends Annotation> annotations = Util.jsonAnnotations(field); String fieldName = field.getName(); JsonAdapter<Object> adapter = moshi.adapter(fieldType, annotations, fieldName); // Create the binding between field and JSON. field.setAccessible(true); // Store it using the field's name. If there was already a field with this name, fail! Json jsonAnnotation = field.getAnnotation(Json.class); String name = jsonAnnotation != null ? jsonAnnotation.name() : fieldName; FieldBinding<Object> fieldBinding = new FieldBinding<>(name, field, adapter); FieldBinding<?> replaced = fieldBindings.put(name, fieldBinding); if (replaced != null) { throw new IllegalArgumentException("Conflicting fields:\n" + " " + replaced.field + "\n" + " " + fieldBinding.field); } } }
if (type == Object.class) return new ObjectJsonAdapter(moshi).nullSafe(); Class<?> rawType = Types.getRawType(type);
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (annotations.isEmpty() || annotations.size() != 1 // At this point we know that the set contains only one entry. || annotations.iterator().next().annotationType() != BirthDate.class) { return null; } Class<?> rawType = Types.getRawType(type); if (rawType != SafeCalendar.class) return null; return new BirthDateJsonAdapter().nullSafe(); } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (!annotations.isEmpty()) return null; Class<?> rawType = Types.getRawType(type); if (rawType.isEnum()) { //noinspection unchecked return new SafeEnumJsonAdapter<>((Class<? extends Enum>) rawType).nullSafe(); } return null; } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (!annotations.isEmpty()) return null; Class<?> rawType = Types.getRawType(type); if (rawType != Phone.class) return null; return new PhoneJsonAdapter().nullSafe(); } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (!annotations.isEmpty()) return null; Class<?> rawType = Types.getRawType(type); if (rawType != GeoCode.class) return null; return new GeoCodeJsonAdapter().nullSafe(); } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { if (!annotations.isEmpty()) return null; Class<?> rawType = Types.getRawType(type); if (rawType != TimeZone.class) return null; return new TimeZoneJsonAdapter().nullSafe(); } };
@Override public @Nullable JsonAdapter<?> create( Type type, Set<? extends Annotation> annotations, Moshi moshi) { Type elementType = Types.arrayComponentType(type); if (elementType == null) return null; if (!annotations.isEmpty()) return null; Class<?> elementClass = Types.getRawType(elementType); JsonAdapter<Object> elementAdapter = moshi.adapter(elementType); return new ArrayJsonAdapter(elementClass, elementAdapter).nullSafe(); } };
@Override public @Nullable JsonAdapter<?> create( Type type, Set<? extends Annotation> annotations, Moshi moshi) { Class<?> rawType = Types.getRawType(type); if (!annotations.isEmpty()) return null; if (rawType == List.class || rawType == Collection.class) { return newArrayListAdapter(type, moshi).nullSafe(); } else if (rawType == Set.class) { return newLinkedHashSetAdapter(type, moshi).nullSafe(); } return null; } };
@Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { Pair<FallbackOnNull, Set<Annotation>> nextAnnotations = nextAnnotations(annotations, FallbackOnNull.class); if (nextAnnotations == null) return null; Class<?> rawType = Types.getRawType(type); if (!FallbackOnNullJsonAdapter.PRIMITIVE_CLASSES.contains(rawType)) return null; String fallbackType = fallbackType(rawType); Object fallback = retrieveFallback(nextAnnotations.first, fallbackType); return new FallbackOnNullJsonAdapter<>(moshi.adapter(type, nextAnnotations.second), fallback, fallbackType); }