AnnotatedDocServicePlugin implements DocServicePlugin { @VisibleForTesting static TypeSignature toTypeSignature(Type type) { requireNonNull(type, "type"); if (type == Void.class || type == void.class) { return VOID; } if (type == Boolean.class || type == boolean.class) { return BOOLEAN; } if (type == Byte.class || type == byte.class) { return BYTE; } if (type == Short.class || type == short.class) { return SHORT; } if (type == Integer.class || type == int.class) { return INT; } if (type == Long.class || type == long.class) { return LONG; } if (type == Float.class || type == float.class) { return FLOAT; } if (type == Double.class || type == double.class) { return DOUBLE; } if (type == String.class) { return STRING; } if (type == byte[].class || type == Byte[].class) { return BINARY; } if (type instanceof ParameterizedType) { final ParameterizedType parameterizedType = (ParameterizedType) type; final Class<?> rawType = (Class<?>) parameterizedType.getRawType(); if (List.class.isAssignableFrom(rawType)) { return TypeSignature.ofList(toTypeSignature(parameterizedType.getActualTypeArguments()[0])); } if (Set.class.isAssignableFrom(rawType)) { return TypeSignature.ofSet(toTypeSignature(parameterizedType.getActualTypeArguments()[0])); } if (Map.class.isAssignableFrom(rawType)) { final TypeSignature key = toTypeSignature(parameterizedType.getActualTypeArguments()[0]); final TypeSignature value = toTypeSignature(parameterizedType.getActualTypeArguments()[1]); return TypeSignature.ofMap(key, value); } final List<TypeSignature> actualTypes = Stream.of(parameterizedType.getActualTypeArguments()) .map(AnnotatedDocServicePlugin::toTypeSignature) .collect(toImmutableList()); return TypeSignature.ofContainer(rawType.getSimpleName(), actualTypes); } if (type instanceof WildcardType) { return TypeSignature.ofUnresolved(""); } if (type instanceof TypeVariable) { return TypeSignature.ofBase(type.getTypeName()); } if (type instanceof GenericArrayType) { return TypeSignature.ofList(toTypeSignature(((GenericArrayType) type).getGenericComponentType())); } if (!(type instanceof Class)) { return TypeSignature.ofBase(type.getTypeName()); } final Class<?> clazz = (Class<?>) type; if (clazz.isArray()) { return TypeSignature.ofList(toTypeSignature(clazz.getComponentType())); } return TypeSignature.ofBase(clazz.getSimpleName()); }  @Override String name(); @Override Set<Class<? extends Service<?, ?>>> supportedServiceTypes(); @Override ServiceSpecification generateSpecification(Set<ServiceConfig> serviceConfigs,
                                                      DocServiceFilter filter); @Override Set<Class<?>> supportedExampleRequestTypes(); @Override @Nullable String serializeExampleRequest(String serviceName, String methodName,
                                          Object exampleRequest);  }
@Test void testToTypeSignature() throws Exception { assertThat(toTypeSignature(Void.class)).isEqualTo(TypeSignature.ofBase("void")); assertThat(toTypeSignature(void.class)).isEqualTo(TypeSignature.ofBase("void")); assertThat(toTypeSignature(Boolean.class)).isEqualTo(TypeSignature.ofBase("boolean")); assertThat(toTypeSignature(boolean.class)).isEqualTo(TypeSignature.ofBase("boolean")); assertThat(toTypeSignature(Byte.class)).isEqualTo(TypeSignature.ofBase("byte")); assertThat(toTypeSignature(byte.class)).isEqualTo(TypeSignature.ofBase("byte")); assertThat(toTypeSignature(Short.class)).isEqualTo(TypeSignature.ofBase("short")); assertThat(toTypeSignature(short.class)).isEqualTo(TypeSignature.ofBase("short")); assertThat(toTypeSignature(Integer.class)).isEqualTo(TypeSignature.ofBase("int")); assertThat(toTypeSignature(int.class)).isEqualTo(TypeSignature.ofBase("int")); assertThat(toTypeSignature(Long.class)).isEqualTo(TypeSignature.ofBase("long")); assertThat(toTypeSignature(long.class)).isEqualTo(TypeSignature.ofBase("long")); assertThat(toTypeSignature(Float.class)).isEqualTo(TypeSignature.ofBase("float")); assertThat(toTypeSignature(float.class)).isEqualTo(TypeSignature.ofBase("float")); assertThat(toTypeSignature(Double.class)).isEqualTo(TypeSignature.ofBase("double")); assertThat(toTypeSignature(double.class)).isEqualTo(TypeSignature.ofBase("double")); assertThat(toTypeSignature(String.class)).isEqualTo(TypeSignature.ofBase("string")); assertThat(toTypeSignature(Byte[].class)).isEqualTo(TypeSignature.ofBase("binary")); assertThat(toTypeSignature(byte[].class)).isEqualTo(TypeSignature.ofBase("binary")); assertThat(toTypeSignature(int[].class)).isEqualTo(TypeSignature.ofList(TypeSignature.ofBase("int"))); final TypeSignature typeVariable = toTypeSignature(FieldContainer.class.getDeclaredField("typeVariable") .getGenericType()); assertThat(typeVariable).isEqualTo(TypeSignature.ofBase("T")); final TypeSignature list = toTypeSignature(FieldContainer.class.getDeclaredField("list") .getGenericType()); assertThat(list).isEqualTo(TypeSignature.ofList(TypeSignature.ofBase("string"))); final TypeSignature set = toTypeSignature(FieldContainer.class.getDeclaredField("set") .getGenericType()); assertThat(set).isEqualTo(TypeSignature.ofSet(TypeSignature.ofBase("float"))); final TypeSignature map = toTypeSignature(FieldContainer.class.getDeclaredField("map") .getGenericType()); assertThat(map).isEqualTo(TypeSignature.ofMap(TypeSignature.ofBase("long"), TypeSignature.ofUnresolved(""))); final TypeSignature future = toTypeSignature(FieldContainer.class.getDeclaredField("future") .getGenericType()); assertThat(future).isEqualTo(TypeSignature.ofContainer("CompletableFuture", TypeSignature.ofBase("double"))); final TypeSignature typeVariableFuture = toTypeSignature(FieldContainer.class.getDeclaredField("typeVariableFuture").getGenericType()); assertThat(typeVariableFuture).isEqualTo(TypeSignature.ofContainer("CompletableFuture", TypeSignature.ofBase("T"))); final TypeSignature genericArray = toTypeSignature(FieldContainer.class.getDeclaredField("genericArray").getGenericType()); assertThat(genericArray).isEqualTo( TypeSignature.ofList(TypeSignature.ofList(TypeSignature.ofBase("string")))); final TypeSignature biFunction = toTypeSignature(FieldContainer.class.getDeclaredField("biFunction").getGenericType()); assertThat(biFunction).isEqualTo(TypeSignature.ofContainer("BiFunction", TypeSignature.ofBase("JsonNode"), TypeSignature.ofUnresolved(""), TypeSignature.ofBase("string"))); assertThat(toTypeSignature(FieldContainer.class)).isEqualTo(TypeSignature.ofBase("FieldContainer")); }