[Dubbo-7029] new format ServiceDefinition (#7029)
This commit is contained in:
parent
c4815f5602
commit
7580232b4a
|
|
@ -55,6 +55,7 @@ public interface EventListener<E extends Event> extends java.util.EventListener,
|
|||
* {@link Integer#MIN_VALUE} indicates the highest priority. The default value is {@link Integer#MAX_VALUE}.
|
||||
* The comparison rule , refer to {@link #compareTo}.
|
||||
*/
|
||||
@Override
|
||||
default int getPriority() {
|
||||
return NORMAL_PRIORITY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ public class PrioritizedTest {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public class DefaultCharSequence implements CharSequence, Prioritized {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return MAX_PRIORITY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ public class GenericServiceTest {
|
|||
|
||||
FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(DemoService.class);
|
||||
MethodDefinition methodDefinition = getMethod("complexCompute", fullServiceDefinition.getMethods());
|
||||
Map mapObject = createComplexObject(fullServiceDefinition,var1, var2, l, var3, var4, testEnum);
|
||||
Map mapObject = createComplexObject(fullServiceDefinition, var1, var2, l, var3, var4, testEnum);
|
||||
ComplexObject complexObject = map2bean(mapObject);
|
||||
|
||||
Invoker<GenericService> invoker = protocol.refer(GenericService.class, url);
|
||||
|
|
@ -172,32 +172,32 @@ public class GenericServiceTest {
|
|||
TypeDefinition inner2TypeDefinition = null;
|
||||
TypeDefinition inner3TypeDefinition = null;
|
||||
for (TypeDefinition typeDefinition : typeDefinitions) {
|
||||
if (typeDefinition.getType().equals(ComplexObject.class.getName())) {
|
||||
if (typeDefinition.getType().equals(ComplexObject.class.getCanonicalName())) {
|
||||
topTypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getCanonicalName())) {
|
||||
innerTypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().contains(ComplexObject.InnerObject2.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject2.class.getCanonicalName())) {
|
||||
inner2TypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getCanonicalName())) {
|
||||
inner3TypeDefinition = typeDefinition;
|
||||
}
|
||||
}
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("v").getType(), "long");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("maps").getType(), "java.util.Map<java.lang.String,java.lang.String>");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject").getType(), "org.apache.dubbo.service.ComplexObject$InnerObject");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("intList").getType(), "java.util.List<java.lang.Integer>");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("strArrays").getType(), "java.lang.String[]");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject3").getType(), "org.apache.dubbo.service.ComplexObject.InnerObject3[]");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("testEnum").getType(), "org.apache.dubbo.service.ComplexObject.TestEnum");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject2").getType(), "java.util.List<org.apache.dubbo.service.ComplexObject$InnerObject2>");
|
||||
Assertions.assertEquals("long", topTypeDefinition.getProperties().get("v"));
|
||||
Assertions.assertEquals("java.util.Map<java.lang.String,java.lang.String>", topTypeDefinition.getProperties().get("maps"));
|
||||
Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.InnerObject", topTypeDefinition.getProperties().get("innerObject"));
|
||||
Assertions.assertEquals("java.util.List<java.lang.Integer>", topTypeDefinition.getProperties().get("intList"));
|
||||
Assertions.assertEquals("java.lang.String[]", topTypeDefinition.getProperties().get("strArrays"));
|
||||
Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.InnerObject3[]", topTypeDefinition.getProperties().get("innerObject3"));
|
||||
Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.TestEnum", topTypeDefinition.getProperties().get("testEnum"));
|
||||
Assertions.assertEquals("java.util.List<org.apache.dubbo.service.ComplexObject.InnerObject2>", topTypeDefinition.getProperties().get("innerObject2"));
|
||||
|
||||
Assertions.assertSame(innerTypeDefinition.getProperties().get("innerA").getType(), "java.lang.String");
|
||||
Assertions.assertSame(innerTypeDefinition.getProperties().get("innerB").getType(), "int");
|
||||
Assertions.assertSame("java.lang.String", innerTypeDefinition.getProperties().get("innerA"));
|
||||
Assertions.assertSame("int", innerTypeDefinition.getProperties().get("innerB"));
|
||||
|
||||
Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerA2").getType(), "java.lang.String");
|
||||
Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerB2").getType(), "int");
|
||||
Assertions.assertSame("java.lang.String", inner2TypeDefinition.getProperties().get("innerA2"));
|
||||
Assertions.assertSame("int", inner2TypeDefinition.getProperties().get("innerB2"));
|
||||
|
||||
Assertions.assertSame(inner3TypeDefinition.getProperties().get("innerA3").getType(), "java.lang.String");
|
||||
Assertions.assertSame("java.lang.String", inner3TypeDefinition.getProperties().get("innerA3"));
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("v", l);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.metadata.definition;
|
|||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
|
@ -30,7 +31,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.utils.ClassUtils.isSimpleType;
|
||||
|
||||
/**
|
||||
* 2015/1/27.
|
||||
|
|
@ -45,18 +45,17 @@ public class TypeDefinitionBuilder {
|
|||
BUILDERS = new ArrayList<>(tbs);
|
||||
}
|
||||
|
||||
public static TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public static TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
TypeBuilder builder = getGenericTypeBuilder(type, clazz);
|
||||
TypeDefinition td;
|
||||
if (builder != null) {
|
||||
|
||||
if (clazz.isPrimitive() || ClassUtils.isSimpleType(clazz)) { // changed since 2.7.6
|
||||
td = new TypeDefinition(clazz.getCanonicalName());
|
||||
typeCache.put(clazz.getCanonicalName(), td);
|
||||
} else if (builder != null) {
|
||||
td = builder.build(type, clazz, typeCache);
|
||||
td.setTypeBuilderName(builder.getClass().getName());
|
||||
} else {
|
||||
td = DefaultTypeBuilder.build(clazz, typeCache);
|
||||
td.setTypeBuilderName(DefaultTypeBuilder.class.getName());
|
||||
}
|
||||
if (isSimpleType(clazz)) { // changed since 2.7.6
|
||||
td.setProperties(null);
|
||||
}
|
||||
return td;
|
||||
}
|
||||
|
|
@ -75,7 +74,7 @@ public class TypeDefinitionBuilder {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Map<Class<?>, TypeDefinition> typeCache = new HashMap<>();
|
||||
private Map<String, TypeDefinition> typeCache = new HashMap<>();
|
||||
|
||||
public TypeDefinition build(Type type, Class<?> clazz) {
|
||||
return build(type, clazz, typeCache);
|
||||
|
|
|
|||
|
|
@ -36,13 +36,21 @@ public class ArrayTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
final String canonicalName = clazz.getCanonicalName();
|
||||
TypeDefinition td = typeCache.get(canonicalName);
|
||||
if (td != null) {
|
||||
return td;
|
||||
}
|
||||
td = new TypeDefinition(canonicalName);
|
||||
typeCache.put(canonicalName, td);
|
||||
// Process the component type of an array.
|
||||
Class<?> componentType = clazz.getComponentType();
|
||||
TypeDefinitionBuilder.build(componentType, componentType, typeCache);
|
||||
|
||||
final String canonicalName = clazz.getCanonicalName();
|
||||
return new TypeDefinition(canonicalName);
|
||||
TypeDefinition itemTd = TypeDefinitionBuilder.build(componentType, componentType, typeCache);
|
||||
if (itemTd != null) {
|
||||
td.getItems().add(itemTd.getType());
|
||||
}
|
||||
return td;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.definition.builder;
|
|||
|
||||
import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
import org.apache.dubbo.metadata.definition.util.ClassUtils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
|
@ -40,9 +41,9 @@ public class CollectionTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
return new TypeDefinition(clazz.getName());
|
||||
return new TypeDefinition(clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
|
|
@ -54,17 +55,29 @@ public class CollectionTypeBuilder implements TypeBuilder {
|
|||
type, actualTypeArgs));
|
||||
}
|
||||
|
||||
String colType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
|
||||
TypeDefinition td = typeCache.get(colType);
|
||||
if (td != null) {
|
||||
return td;
|
||||
}
|
||||
td = new TypeDefinition(colType);
|
||||
typeCache.put(colType, td);
|
||||
|
||||
Type actualType = actualTypeArgs[0];
|
||||
TypeDefinition itemTd = null;
|
||||
if (actualType instanceof ParameterizedType) {
|
||||
// Nested collection or map.
|
||||
Class<?> rawType = (Class<?>) ((ParameterizedType) actualType).getRawType();
|
||||
TypeDefinitionBuilder.build(actualType, rawType, typeCache);
|
||||
itemTd = TypeDefinitionBuilder.build(actualType, rawType, typeCache);
|
||||
} else if (actualType instanceof Class<?>) {
|
||||
Class<?> actualClass = (Class<?>) actualType;
|
||||
TypeDefinitionBuilder.build(null, actualClass, typeCache);
|
||||
itemTd = TypeDefinitionBuilder.build(null, actualClass, typeCache);
|
||||
}
|
||||
if (itemTd != null) {
|
||||
td.getItems().add(itemTd.getType());
|
||||
}
|
||||
|
||||
return new TypeDefinition(type.toString());
|
||||
return td;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,15 +31,16 @@ import java.util.Map;
|
|||
*/
|
||||
public final class DefaultTypeBuilder {
|
||||
|
||||
public static TypeDefinition build(Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
// final String canonicalName = clazz.getCanonicalName();
|
||||
final String name = clazz.getName();
|
||||
public static TypeDefinition build(Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
final String canonicalName = clazz.getCanonicalName();
|
||||
|
||||
TypeDefinition td = new TypeDefinition(name);
|
||||
// Try to get a cached definition
|
||||
if (typeCache.containsKey(clazz)) {
|
||||
return typeCache.get(clazz);
|
||||
TypeDefinition td = typeCache.get(canonicalName);
|
||||
if (td != null) {
|
||||
return td;
|
||||
}
|
||||
td = new TypeDefinition(canonicalName);
|
||||
typeCache.put(canonicalName, td);
|
||||
|
||||
// Primitive type
|
||||
if (!JaketConfigurationUtils.needAnalyzing(clazz)) {
|
||||
|
|
@ -47,21 +48,15 @@ public final class DefaultTypeBuilder {
|
|||
}
|
||||
|
||||
// Custom type
|
||||
TypeDefinition ref = new TypeDefinition(name);
|
||||
ref.set$ref(name);
|
||||
typeCache.put(clazz, ref);
|
||||
|
||||
List<Field> fields = ClassUtils.getNonStaticFields(clazz);
|
||||
for (Field field : fields) {
|
||||
String fieldName = field.getName();
|
||||
Class<?> fieldClass = field.getType();
|
||||
Type fieldType = field.getGenericType();
|
||||
|
||||
TypeDefinition fieldTd = TypeDefinitionBuilder.build(fieldType, fieldClass, typeCache);
|
||||
td.getProperties().put(fieldName, fieldTd);
|
||||
td.getProperties().put(fieldName, fieldTd.getType());
|
||||
}
|
||||
|
||||
typeCache.put(clazz, td);
|
||||
return td;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.definition.builder;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -26,6 +29,7 @@ import java.util.Map;
|
|||
* 2015/1/27.
|
||||
*/
|
||||
public class EnumTypeBuilder implements TypeBuilder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TypeDefinitionBuilder.class);
|
||||
|
||||
@Override
|
||||
public boolean accept(Type type, Class<?> clazz) {
|
||||
|
|
@ -36,8 +40,15 @@ public class EnumTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
TypeDefinition td = new TypeDefinition(clazz.getCanonicalName());
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
String canonicalName = clazz.getCanonicalName();
|
||||
|
||||
TypeDefinition td = typeCache.get(canonicalName);
|
||||
if (td != null) {
|
||||
return td;
|
||||
}
|
||||
td = new TypeDefinition(canonicalName);
|
||||
typeCache.put(canonicalName, td);
|
||||
|
||||
try {
|
||||
Method methodValues = clazz.getDeclaredMethod("values");
|
||||
|
|
@ -47,12 +58,11 @@ public class EnumTypeBuilder implements TypeBuilder {
|
|||
Object value = values[i];
|
||||
td.getEnums().add(value.toString());
|
||||
}
|
||||
return td;
|
||||
} catch (Throwable t) {
|
||||
td.setId("-1");
|
||||
logger.error("There is an error while process class " + clazz, t);
|
||||
}
|
||||
|
||||
typeCache.put(clazz, td);
|
||||
return td;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.definition.builder;
|
|||
|
||||
import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
import org.apache.dubbo.metadata.definition.util.ClassUtils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
|
@ -44,9 +45,9 @@ public class MapTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
return new TypeDefinition(clazz.getName());
|
||||
return new TypeDefinition(clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
|
|
@ -65,9 +66,15 @@ public class MapTypeBuilder implements TypeBuilder {
|
|||
* {@link ParameterizedType#toString()}
|
||||
* @see sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
|
||||
*/
|
||||
String mapType = replace(type.toString(), ", ", ",");
|
||||
String mapType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
|
||||
mapType = replace(mapType, ", ", ",");
|
||||
|
||||
TypeDefinition typeDefinition = new TypeDefinition(mapType);
|
||||
TypeDefinition td = typeCache.get(mapType);
|
||||
if (td != null) {
|
||||
return td;
|
||||
}
|
||||
td = new TypeDefinition(mapType);
|
||||
typeCache.put(mapType, td);
|
||||
|
||||
for (int i = 0; i < actualTypeArgsLength; i++) {
|
||||
Type actualType = actualTypeArgs[i];
|
||||
|
|
@ -79,9 +86,10 @@ public class MapTypeBuilder implements TypeBuilder {
|
|||
} else if (isClass(actualType)) {
|
||||
item = TypeDefinitionBuilder.build(null, rawType, typeCache);
|
||||
}
|
||||
typeDefinition.getItems().add(item);
|
||||
if (item != null) {
|
||||
td.getItems().add(item.getType());
|
||||
}
|
||||
}
|
||||
|
||||
return typeDefinition;
|
||||
return td;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ public interface TypeBuilder extends Prioritized {
|
|||
/**
|
||||
* Build type definition with the type or class.
|
||||
*/
|
||||
TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache);
|
||||
TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ public class MethodDefinition implements Serializable {
|
|||
private String name;
|
||||
private String[] parameterTypes;
|
||||
private String returnType;
|
||||
|
||||
/**
|
||||
* @deprecated please use parameterTypes,
|
||||
* and find TypeDefinition in org.apache.dubbo.metadata.definition.model.ServiceDefinition#types
|
||||
*/
|
||||
@Deprecated
|
||||
private List<TypeDefinition> parameters;
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -84,14 +90,11 @@ public class MethodDefinition implements Serializable {
|
|||
MethodDefinition that = (MethodDefinition) o;
|
||||
return Objects.equals(getName(), that.getName()) &&
|
||||
Arrays.equals(getParameterTypes(), that.getParameterTypes()) &&
|
||||
Objects.equals(getReturnType(), that.getReturnType()) &&
|
||||
Objects.equals(getParameters(), that.getParameters());
|
||||
Objects.equals(getReturnType(), that.getReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(getName(), getReturnType(), getParameters());
|
||||
result = 31 * result + Arrays.hashCode(getParameterTypes());
|
||||
return result;
|
||||
return Objects.hash(getName(), getReturnType(), getParameterTypes());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.definition.model;
|
||||
|
||||
import org.apache.dubbo.metadata.definition.util.ClassUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -26,9 +28,25 @@ import java.util.Objects;
|
|||
*/
|
||||
public class ServiceDefinition implements Serializable {
|
||||
|
||||
/**
|
||||
* the canonical name of interface
|
||||
*
|
||||
* @see Class#getCanonicalName()
|
||||
*/
|
||||
private String canonicalName;
|
||||
|
||||
/**
|
||||
* the location of class file
|
||||
*
|
||||
* @see ClassUtils#getCodeSource(Class)
|
||||
*/
|
||||
private String codeSource;
|
||||
|
||||
private List<MethodDefinition> methods;
|
||||
|
||||
/**
|
||||
* the definitions of type
|
||||
*/
|
||||
private List<TypeDefinition> types;
|
||||
|
||||
public String getCanonicalName() {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.apache.dubbo.metadata.definition.model;
|
|||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -30,15 +32,35 @@ import java.util.Objects;
|
|||
*/
|
||||
public class TypeDefinition implements Serializable {
|
||||
|
||||
private String id;
|
||||
/**
|
||||
* the name of type
|
||||
*
|
||||
* @see Class#getCanonicalName()
|
||||
* @see org.apache.dubbo.metadata.definition.util.ClassUtils#getCanonicalNameForParameterizedType(ParameterizedType)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* the items(generic parameter) of Map/List(ParameterizedType)
|
||||
* <p>
|
||||
* if this type is not ParameterizedType, the items is null or empty
|
||||
*/
|
||||
@SerializedName("items")
|
||||
private List<TypeDefinition> items;
|
||||
private List<String> items;
|
||||
|
||||
/**
|
||||
* the enum's value
|
||||
* <p>
|
||||
* If this type is not enum, enums is null or empty
|
||||
*/
|
||||
@SerializedName("enum")
|
||||
private List<String> enums;
|
||||
private String $ref;
|
||||
private Map<String, TypeDefinition> properties;
|
||||
private String typeBuilderName;
|
||||
|
||||
/**
|
||||
* the key is property name,
|
||||
* the value is property's type name
|
||||
*/
|
||||
private Map<String, String> properties;
|
||||
|
||||
public TypeDefinition() {
|
||||
}
|
||||
|
|
@ -47,29 +69,21 @@ public class TypeDefinition implements Serializable {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public String get$ref() {
|
||||
return $ref;
|
||||
}
|
||||
|
||||
public List<String> getEnums() {
|
||||
if (enums == null) {
|
||||
enums = new ArrayList<String>();
|
||||
enums = new ArrayList<>();
|
||||
}
|
||||
return enums;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<TypeDefinition> getItems() {
|
||||
public List<String> getItems() {
|
||||
if (items == null) {
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public Map<String, TypeDefinition> getProperties() {
|
||||
public Map<String, String> getProperties() {
|
||||
if (properties == null) {
|
||||
properties = new HashMap<>();
|
||||
}
|
||||
|
|
@ -80,27 +94,15 @@ public class TypeDefinition implements Serializable {
|
|||
return type;
|
||||
}
|
||||
|
||||
public String getTypeBuilderName() {
|
||||
return typeBuilderName;
|
||||
}
|
||||
|
||||
public void set$ref(String $ref) {
|
||||
this.$ref = $ref;
|
||||
}
|
||||
|
||||
public void setEnums(List<String> enums) {
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setItems(List<TypeDefinition> items) {
|
||||
public void setItems(List<String> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, TypeDefinition> properties) {
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
|
@ -108,13 +110,9 @@ public class TypeDefinition implements Serializable {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public void setTypeBuilderName(String typeBuilderName) {
|
||||
this.typeBuilderName = typeBuilderName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TypeDefinition [id=" + id + ", type=" + type + ", properties=" + properties + ", $ref=" + $ref + "]";
|
||||
return "TypeDefinition [type=" + type + ", properties=" + properties + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -126,16 +124,14 @@ public class TypeDefinition implements Serializable {
|
|||
return false;
|
||||
}
|
||||
TypeDefinition that = (TypeDefinition) o;
|
||||
return Objects.equals(getId(), that.getId()) &&
|
||||
Objects.equals(getType(), that.getType()) &&
|
||||
return Objects.equals(getType(), that.getType()) &&
|
||||
Objects.equals(getItems(), that.getItems()) &&
|
||||
Objects.equals(getEnums(), that.getEnums()) &&
|
||||
Objects.equals(get$ref(), that.get$ref()) &&
|
||||
Objects.equals(getProperties(), that.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId(), getType(), getItems(), getEnums(), get$ref(), getProperties());
|
||||
return Objects.hash(getType(), getItems(), getEnums(), getProperties());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.definition.util;
|
||||
|
||||
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
import java.security.ProtectionDomain;
|
||||
|
|
@ -106,6 +110,57 @@ public final class ClassUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static String getCanonicalNameForParameterizedType(ParameterizedType parameterizedType) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Type ownerType = parameterizedType.getOwnerType();
|
||||
Class<?> rawType = (Class) parameterizedType.getRawType();
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
|
||||
if (ownerType != null) {
|
||||
if (ownerType instanceof Class) {
|
||||
sb.append(((Class) ownerType).getName());
|
||||
} else {
|
||||
sb.append(ownerType.toString());
|
||||
}
|
||||
|
||||
sb.append(".");
|
||||
|
||||
if (ownerType instanceof ParameterizedTypeImpl) {
|
||||
// Find simple name of nested type by removing the
|
||||
// shared prefix with owner.
|
||||
sb.append(rawType.getName().replace(((Class) ((ParameterizedType) ownerType).getRawType()).getName() + "$",
|
||||
""));
|
||||
} else {
|
||||
sb.append(rawType.getSimpleName());
|
||||
}
|
||||
} else {
|
||||
sb.append(rawType.getCanonicalName());
|
||||
}
|
||||
|
||||
if (actualTypeArguments != null &&
|
||||
actualTypeArguments.length > 0) {
|
||||
sb.append("<");
|
||||
boolean first = true;
|
||||
for (Type t : actualTypeArguments) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
}
|
||||
if (t instanceof Class) {
|
||||
Class c = (Class) t;
|
||||
sb.append(c.getCanonicalName());
|
||||
} else if (t instanceof ParameterizedType) {
|
||||
sb.append(getCanonicalNameForParameterizedType((ParameterizedType) t));
|
||||
} else {
|
||||
sb.append(t.toString());
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
sb.append(">");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private ClassUtils() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParam
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return MIN_PRIORITY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.definition;
|
||||
|
||||
import org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.MapTypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.common.ClassExtendsMap;
|
||||
import org.apache.dubbo.metadata.definition.common.ColorEnum;
|
||||
import org.apache.dubbo.metadata.definition.common.OuterClass;
|
||||
|
|
@ -40,6 +36,7 @@ import org.junit.jupiter.api.Test;
|
|||
public class MetadataTest {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testInnerClassType() {
|
||||
|
|
@ -47,10 +44,9 @@ public class MetadataTest {
|
|||
TypeDefinition td = builder.build(OuterClass.InnerClass.class, OuterClass.InnerClass.class);
|
||||
System.out.println(">> testInnerClassType: " + new Gson().toJson(td));
|
||||
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.OuterClass$InnerClass", td.getType());
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.OuterClass.InnerClass", td.getType());
|
||||
Assertions.assertEquals(1, td.getProperties().size());
|
||||
Assertions.assertNotNull(td.getProperties().get("name"));
|
||||
Assertions.assertEquals(DefaultTypeBuilder.class.getName(), td.getTypeBuilderName());
|
||||
ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
|
||||
System.out.println(">> testInnerClassType: " + new Gson().toJson(sd));
|
||||
|
||||
|
|
@ -58,7 +54,7 @@ public class MetadataTest {
|
|||
Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
|
||||
boolean containsType = false;
|
||||
for (TypeDefinition type : sd.getTypes()) {
|
||||
if (type.getType().equals("org.apache.dubbo.metadata.definition.common.OuterClass$InnerClass")) {
|
||||
if (type.getType().equals("org.apache.dubbo.metadata.definition.common.OuterClass.InnerClass")) {
|
||||
containsType = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -76,10 +72,8 @@ public class MetadataTest {
|
|||
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ResultWithRawCollections", td.getType());
|
||||
Assertions.assertEquals(2, td.getProperties().size());
|
||||
Assertions.assertEquals("java.util.Map", td.getProperties().get("map").getType());
|
||||
Assertions.assertEquals(MapTypeBuilder.class.getName(), td.getProperties().get("map").getTypeBuilderName());
|
||||
Assertions.assertEquals("java.util.List", td.getProperties().get("list").getType());
|
||||
Assertions.assertEquals(CollectionTypeBuilder.class.getName(), td.getProperties().get("list").getTypeBuilderName());
|
||||
Assertions.assertEquals("java.util.Map", td.getProperties().get("map"));
|
||||
Assertions.assertEquals("java.util.List", td.getProperties().get("list"));
|
||||
|
||||
ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
|
||||
System.out.println(">> testRawMap: " + new Gson().toJson(sd));
|
||||
|
|
@ -103,7 +97,6 @@ public class MetadataTest {
|
|||
System.out.println(">> testEnum: " + new Gson().toJson(td));
|
||||
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ColorEnum", td.getType());
|
||||
Assertions.assertEquals(EnumTypeBuilder.class.getName(), td.getTypeBuilderName());
|
||||
Assertions.assertEquals(3, td.getEnums().size());
|
||||
Assertions.assertTrue(td.getEnums().contains("RED"));
|
||||
Assertions.assertTrue(td.getEnums().contains("YELLOW"));
|
||||
|
|
@ -131,7 +124,6 @@ public class MetadataTest {
|
|||
System.out.println(">> testExtendsMap: " + new Gson().toJson(td));
|
||||
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ClassExtendsMap", td.getType());
|
||||
Assertions.assertEquals(MapTypeBuilder.class.getName(), td.getTypeBuilderName());
|
||||
Assertions.assertEquals(0, td.getProperties().size());
|
||||
|
||||
ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import org.apache.dubbo.metadata.definition.model.MethodDefinition;
|
|||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
import org.apache.dubbo.metadata.definition.service.ComplexObject;
|
||||
import org.apache.dubbo.metadata.definition.service.DemoService;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -58,41 +57,44 @@ public class ServiceDefinitionBuilderTest {
|
|||
String[].class.getCanonicalName(), "java.util.List<java.lang.Integer>", ComplexObject.TestEnum.class.getCanonicalName()}));
|
||||
Assertions.assertEquals(findComplexObject.getReturnType(), ComplexObject.class.getCanonicalName());
|
||||
|
||||
|
||||
List<TypeDefinition> typeDefinitions = fullServiceDefinition.getTypes();
|
||||
|
||||
TypeDefinition topTypeDefinition = null;
|
||||
TypeDefinition innerTypeDefinition = null;
|
||||
TypeDefinition inner2TypeDefinition = null;
|
||||
TypeDefinition inner3TypeDefinition = null;
|
||||
TypeDefinition listTypeDefinition = null;
|
||||
for (TypeDefinition typeDefinition : typeDefinitions) {
|
||||
if (typeDefinition.getType().equals(ComplexObject.class.getName())) {
|
||||
if (typeDefinition.getType().equals(ComplexObject.class.getCanonicalName())) {
|
||||
topTypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getCanonicalName())) {
|
||||
innerTypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().contains(ComplexObject.InnerObject2.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject2.class.getCanonicalName())) {
|
||||
inner2TypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getName())) {
|
||||
} else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getCanonicalName())) {
|
||||
inner3TypeDefinition = typeDefinition;
|
||||
} else if (typeDefinition.getType().equals("java.util.List<java.lang.Integer>")) {
|
||||
listTypeDefinition = typeDefinition;
|
||||
}
|
||||
}
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("v").getType(), "long");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("maps").getType(), "java.util.Map<java.lang.String,java.lang.String>");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject").getType(), ComplexObject.InnerObject.class.getName());
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("intList").getType(), "java.util.List<java.lang.Integer>");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("strArrays").getType(), "java.lang.String[]");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject3").getType(), "org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject3[]");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("testEnum").getType(), "org.apache.dubbo.metadata.definition.service.ComplexObject.TestEnum");
|
||||
Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject2").getType(), "java.util.Set<org.apache.dubbo.metadata.definition.service.ComplexObject$InnerObject2>");
|
||||
Assertions.assertEquals("long", topTypeDefinition.getProperties().get("v"));
|
||||
Assertions.assertEquals("java.util.Map<java.lang.String,java.lang.String>", topTypeDefinition.getProperties().get("maps"));
|
||||
Assertions.assertEquals(ComplexObject.InnerObject.class.getCanonicalName(), topTypeDefinition.getProperties().get("innerObject"));
|
||||
Assertions.assertEquals("java.util.List<java.lang.Integer>", topTypeDefinition.getProperties().get("intList"));
|
||||
Assertions.assertEquals("java.lang.String[]", topTypeDefinition.getProperties().get("strArrays"));
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject3[]", topTypeDefinition.getProperties().get("innerObject3"));
|
||||
Assertions.assertEquals("org.apache.dubbo.metadata.definition.service.ComplexObject.TestEnum", topTypeDefinition.getProperties().get("testEnum"));
|
||||
Assertions.assertEquals("java.util.Set<org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject2>", topTypeDefinition.getProperties().get("innerObject2"));
|
||||
|
||||
Assertions.assertSame(innerTypeDefinition.getProperties().get("innerA").getType(), "java.lang.String");
|
||||
Assertions.assertSame(innerTypeDefinition.getProperties().get("innerB").getType(), "int");
|
||||
Assertions.assertSame("java.lang.String", innerTypeDefinition.getProperties().get("innerA"));
|
||||
Assertions.assertSame("int", innerTypeDefinition.getProperties().get("innerB"));
|
||||
|
||||
Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerA2").getType(), "java.lang.String");
|
||||
Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerB2").getType(), "int");
|
||||
Assertions.assertSame("java.lang.String", inner2TypeDefinition.getProperties().get("innerA2"));
|
||||
Assertions.assertSame("int", inner2TypeDefinition.getProperties().get("innerB2"));
|
||||
|
||||
Assertions.assertSame(inner3TypeDefinition.getProperties().get("innerA3").getType(), "java.lang.String");
|
||||
Assertions.assertSame("java.lang.String", inner3TypeDefinition.getProperties().get("innerA3"));
|
||||
|
||||
Assertions.assertEquals(Integer.class.getCanonicalName(), listTypeDefinition.getItems().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.Map;
|
|||
*/
|
||||
public class Test3TypeBuilder implements TypeBuilder {
|
||||
// it is smaller than the implements of TypeBuilder
|
||||
@Override
|
||||
public int getPriority(){
|
||||
return 10;
|
||||
}
|
||||
|
|
@ -37,7 +38,7 @@ public class Test3TypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.Map;
|
|||
*/
|
||||
public class TestTypeBuilder implements TypeBuilder {
|
||||
// it is smaller than the implements of TypeBuilder
|
||||
@Override
|
||||
public int getPriority(){
|
||||
return -3;
|
||||
}
|
||||
|
|
@ -37,7 +38,7 @@ public class TestTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,17 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.definition.protobuf;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Descriptors;
|
||||
import com.google.protobuf.GeneratedMessageV3;
|
||||
import com.google.protobuf.ProtocolStringList;
|
||||
import com.google.protobuf.UnknownFieldSet;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
|
|
@ -36,7 +36,7 @@ import java.util.Map;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ProtobufTypeBuilder implements TypeBuilder {
|
||||
public class ProtobufTypeBuilder implements TypeBuilder, Prioritized {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private static final Pattern MAP_PATTERN = Pattern.compile("^java\\.util\\.Map<(\\S+), (\\S+)>$");
|
||||
private static final Pattern LIST_PATTERN = Pattern.compile("^java\\.util\\.List<(\\S+)>$");
|
||||
|
|
@ -55,6 +55,11 @@ public class ProtobufTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Type type, Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
|
|
@ -65,11 +70,16 @@ public class ProtobufTypeBuilder implements TypeBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
|
||||
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
|
||||
String canonicalName = clazz.getCanonicalName();
|
||||
TypeDefinition typeDefinition = typeCache.get(canonicalName);
|
||||
if (typeDefinition != null) {
|
||||
return typeDefinition;
|
||||
}
|
||||
try {
|
||||
GeneratedMessageV3.Builder builder = getMessageBuilder(clazz);
|
||||
typeDefinition = buildProtobufTypeDefinition(clazz, builder, typeCache);
|
||||
typeCache.put(canonicalName, typeDefinition);
|
||||
} catch (Exception e) {
|
||||
logger.info("TypeDefinition build failed.", e);
|
||||
}
|
||||
|
|
@ -82,48 +92,50 @@ public class ProtobufTypeBuilder implements TypeBuilder {
|
|||
return (GeneratedMessageV3.Builder) method.invoke(null, null);
|
||||
}
|
||||
|
||||
private TypeDefinition buildProtobufTypeDefinition(Class<?> clazz, GeneratedMessageV3.Builder builder, Map<Class<?>, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
|
||||
private TypeDefinition buildProtobufTypeDefinition(Class<?> clazz, GeneratedMessageV3.Builder builder, Map<String, TypeDefinition> typeCache) {
|
||||
String canonicalName = clazz.getCanonicalName();
|
||||
TypeDefinition td = new TypeDefinition(canonicalName);
|
||||
if (builder == null) {
|
||||
return typeDefinition;
|
||||
return td;
|
||||
}
|
||||
|
||||
Map<String, TypeDefinition> properties = new HashMap<>();
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
Method[] methods = builder.getClass().getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
String methodName = method.getName();
|
||||
|
||||
if (isSimplePropertySettingMethod(method)) {
|
||||
// property of custom type or primitive type
|
||||
properties.put(generateSimpleFiledName(methodName), TypeDefinitionBuilder.build(method.getGenericParameterTypes()[0], method.getParameterTypes()[0], typeCache));
|
||||
TypeDefinition fieldTd = TypeDefinitionBuilder.build(method.getGenericParameterTypes()[0], method.getParameterTypes()[0], typeCache);
|
||||
properties.put(generateSimpleFiledName(methodName), fieldTd.getType());
|
||||
} else if (isMapPropertySettingMethod(method)) {
|
||||
// property of map
|
||||
Type type = method.getGenericParameterTypes()[0];
|
||||
String fieldName = generateMapFieldName(methodName);
|
||||
validateMapType(fieldName, type.toString());
|
||||
properties.put(fieldName, TypeDefinitionBuilder.build(type, method.getParameterTypes()[0], typeCache));
|
||||
TypeDefinition fieldTd = TypeDefinitionBuilder.build(type, method.getParameterTypes()[0], typeCache);
|
||||
properties.put(fieldName, fieldTd.getType());
|
||||
} else if (isListPropertyGettingMethod(method)) {
|
||||
// property of list
|
||||
Type type = method.getGenericReturnType();
|
||||
String fieldName = generateListFieldName(methodName);
|
||||
TypeDefinition td;
|
||||
TypeDefinition fieldTd;
|
||||
if (ProtocolStringList.class.isAssignableFrom(method.getReturnType())) {
|
||||
// property defined as "repeated string" transform to ProtocolStringList,
|
||||
// should be build as List<String>.
|
||||
td = TypeDefinitionBuilder.build(STRING_LIST_TYPE, List.class, typeCache);
|
||||
fieldTd = TypeDefinitionBuilder.build(STRING_LIST_TYPE, List.class, typeCache);
|
||||
} else {
|
||||
// property without generic type should not be build ex method return List
|
||||
if (!LIST_PATTERN.matcher(type.toString()).matches()) {
|
||||
continue;
|
||||
}
|
||||
td = TypeDefinitionBuilder.build(type, method.getReturnType(), typeCache);
|
||||
fieldTd = TypeDefinitionBuilder.build(type, method.getReturnType(), typeCache);
|
||||
}
|
||||
properties.put(fieldName, td);
|
||||
properties.put(fieldName, fieldTd.getType());
|
||||
}
|
||||
}
|
||||
typeDefinition.setProperties(properties);
|
||||
typeCache.put(clazz, typeDefinition);
|
||||
return typeDefinition;
|
||||
td.setProperties(properties);
|
||||
return td;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
|
|||
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
import org.apache.dubbo.metadata.definition.protobuf.model.ServiceInterface;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
|
@ -39,6 +39,7 @@ public class ProtobufTypeBuilderTest {
|
|||
// TEST Pb Service metaData builder
|
||||
FullServiceDefinition serviceDefinition = ServiceDefinitionBuilder.buildFullDefinition(ServiceInterface.class);
|
||||
MethodDefinition methodDefinition = serviceDefinition.getMethods().get(0);
|
||||
List<TypeDefinition> types = serviceDefinition.getTypes();
|
||||
String parameterName = methodDefinition.getParameterTypes()[0];
|
||||
TypeDefinition typeDefinition = null;
|
||||
for (TypeDefinition type : serviceDefinition.getTypes()) {
|
||||
|
|
@ -47,27 +48,41 @@ public class ProtobufTypeBuilderTest {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Map<String, TypeDefinition> propertiesMap = typeDefinition.getProperties();
|
||||
Map<String, String> propertiesMap = typeDefinition.getProperties();
|
||||
assertThat(propertiesMap.size(), is(11));
|
||||
assertThat(propertiesMap.containsKey("money"), is(true));
|
||||
assertThat(propertiesMap.get("money").getType(), equalTo("double"));
|
||||
assertThat(getTypeName(propertiesMap.get("money"), types), equalTo("double"));
|
||||
assertThat(propertiesMap.containsKey("cash"), is(true));
|
||||
assertThat(propertiesMap.get("cash").getType(), equalTo("float"));
|
||||
assertThat(getTypeName(propertiesMap.get("cash"), types), equalTo("float"));
|
||||
assertThat(propertiesMap.containsKey("age"), is(true));
|
||||
assertThat(propertiesMap.get("age").getType(), equalTo("int"));
|
||||
assertThat(getTypeName(propertiesMap.get("age"), types), equalTo("int"));
|
||||
assertThat(propertiesMap.containsKey("num"), is(true));
|
||||
assertThat(propertiesMap.get("num").getType(), equalTo("long"));
|
||||
assertThat(getTypeName(propertiesMap.get("num"), types), equalTo("long"));
|
||||
assertThat(propertiesMap.containsKey("sex"), is(true));
|
||||
assertThat(propertiesMap.get("sex").getType(), equalTo("boolean"));
|
||||
assertThat(getTypeName(propertiesMap.get("sex"), types), equalTo("boolean"));
|
||||
assertThat(propertiesMap.containsKey("name"), is(true));
|
||||
assertThat(propertiesMap.get("name").getType(), equalTo("java.lang.String"));
|
||||
assertThat(getTypeName(propertiesMap.get("name"), types), equalTo("java.lang.String"));
|
||||
assertThat(propertiesMap.containsKey("msg"), is(true));
|
||||
assertThat(propertiesMap.get("msg").getType(), equalTo("com.google.protobuf.ByteString"));
|
||||
assertThat(getTypeName(propertiesMap.get("msg"), types),
|
||||
equalTo("com.google.protobuf.ByteString"));
|
||||
assertThat(propertiesMap.containsKey("phone"), is(true));
|
||||
assertThat(propertiesMap.get("phone").getType(), equalTo("java.util.List<org.apache.dubbo.metadata.definition.protobuf.model.GooglePB$PhoneNumber>"));
|
||||
assertThat(getTypeName(propertiesMap.get("phone"), types),
|
||||
equalTo("java.util.List<org.apache.dubbo.metadata.definition.protobuf.model.GooglePB.PhoneNumber>"));
|
||||
assertThat(propertiesMap.containsKey("doubleMap"), is(true));
|
||||
assertThat(propertiesMap.get("doubleMap").getType(), equalTo("java.util.Map<java.lang.String,org.apache.dubbo.metadata.definition.protobuf.model.GooglePB$PhoneNumber>"));
|
||||
assertThat(propertiesMap.get("bytesList").getType(), equalTo("java.util.List<com.google.protobuf.ByteString>"));
|
||||
assertThat(propertiesMap.get("bytesMap").getType(), equalTo("java.util.Map<java.lang.String,com.google.protobuf.ByteString>"));
|
||||
assertThat(getTypeName(propertiesMap.get("doubleMap"), types),
|
||||
equalTo("java.util.Map<java.lang.String,org.apache.dubbo.metadata.definition.protobuf.model.GooglePB.PhoneNumber>"));
|
||||
assertThat(getTypeName(propertiesMap.get("bytesList"), types),
|
||||
equalTo("java.util.List<com.google.protobuf.ByteString>"));
|
||||
assertThat(getTypeName(propertiesMap.get("bytesMap"), types),
|
||||
equalTo("java.util.Map<java.lang.String,com.google.protobuf.ByteString>"));
|
||||
}
|
||||
|
||||
private static String getTypeName(String type, List<TypeDefinition> types) {
|
||||
for (TypeDefinition typeDefinition : types) {
|
||||
if (type.equals(typeDefinition.getType())) {
|
||||
return typeDefinition.getType();
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,15 +22,16 @@ import javax.annotation.processing.ProcessingEnvironment;
|
|||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isArrayType;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for Java {@link Array}
|
||||
* {@link TypeBuilder} for Java {@link Array}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
public class ArrayTypeDefinitionBuilder implements TypeDefinitionBuilder<ArrayType> {
|
||||
public class ArrayTypeDefinitionBuilder implements TypeBuilder<ArrayType> {
|
||||
|
||||
@Override
|
||||
public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
|
||||
|
|
@ -38,9 +39,13 @@ public class ArrayTypeDefinitionBuilder implements TypeDefinitionBuilder<ArrayTy
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, ArrayType type, TypeDefinition typeDefinition) {
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, ArrayType type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(type.toString());
|
||||
TypeMirror componentType = type.getComponentType();
|
||||
typeDefinition.getItems().add(TypeDefinitionBuilder.build(processingEnv, componentType));
|
||||
TypeDefinition subTypeDefinition = TypeDefinitionBuilder.build(processingEnv, componentType, typeCache);
|
||||
typeDefinition.getItems()
|
||||
.add(subTypeDefinition.getType());
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@ import javax.lang.model.type.TypeMirror;
|
|||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for Java {@link Collection}
|
||||
* {@link TypeBuilder} for Java {@link Collection}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
|
|
@ -45,13 +46,17 @@ public class CollectionTypeDefinitionBuilder implements DeclaredTypeDefinitionBu
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
|
||||
String typeName = type.toString();
|
||||
TypeDefinition typeDefinition = new TypeDefinition(typeName);
|
||||
// Generic Type arguments
|
||||
type.getTypeArguments()
|
||||
.stream()
|
||||
.map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
|
||||
.map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument, typeCache)) // build the TypeDefinition from typeArgument
|
||||
.filter(Objects::nonNull)
|
||||
.map(TypeDefinition::getType)
|
||||
.forEach(typeDefinition.getItems()::add); // Add into the declared TypeDefinition
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import javax.lang.model.type.TypeMirror;
|
|||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofDeclaredType;
|
||||
|
||||
/**
|
||||
* An interface of {@link TypeDefinitionBuilder} for {@link DeclaredType}
|
||||
* An interface of {@link TypeBuilder} for {@link DeclaredType}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
public interface DeclaredTypeDefinitionBuilder extends TypeDefinitionBuilder<DeclaredType> {
|
||||
public interface DeclaredTypeDefinitionBuilder extends TypeBuilder<DeclaredType> {
|
||||
|
||||
@Override
|
||||
default boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ import javax.lang.model.element.Element;
|
|||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getDeclaredFields;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isEnumType;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for Java {@link Enum}
|
||||
* {@link TypeBuilder} for Java {@link Enum}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
|
|
@ -40,12 +42,14 @@ public class EnumTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(type.toString());
|
||||
getDeclaredFields(type, FieldUtils::isEnumMemberField)
|
||||
.stream()
|
||||
.map(Element::getSimpleName)
|
||||
.map(Name::toString)
|
||||
.forEach(typeDefinition.getEnums()::add);
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,12 +22,14 @@ import javax.annotation.processing.ProcessingEnvironment;
|
|||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getNonStaticFields;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getType;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isClassType;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for General Object
|
||||
* {@link TypeBuilder} for General Object
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
|
|
@ -39,23 +41,26 @@ public class GeneralTypeDefinitionBuilder implements DeclaredTypeDefinitionBuild
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
|
||||
|
||||
String typeName = type.toString();
|
||||
|
||||
TypeElement typeElement = getType(processingEnv, typeName);
|
||||
|
||||
buildProperties(processingEnv, typeElement, typeDefinition);
|
||||
return buildProperties(processingEnv, typeElement, typeCache);
|
||||
}
|
||||
|
||||
protected void buildProperties(ProcessingEnvironment processingEnv, TypeElement type, TypeDefinition definition) {
|
||||
protected TypeDefinition buildProperties(ProcessingEnvironment processingEnv, TypeElement type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition definition = new TypeDefinition(type.toString());
|
||||
getNonStaticFields(type).forEach(field -> {
|
||||
String fieldName = field.getSimpleName().toString();
|
||||
TypeDefinition propertyType = TypeDefinitionBuilder.build(processingEnv, field);
|
||||
TypeDefinition propertyType = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
|
||||
if (propertyType != null) {
|
||||
definition.getProperties().put(fieldName, propertyType);
|
||||
typeCache.put(propertyType.getType(), propertyType);
|
||||
definition.getProperties().put(fieldName, propertyType.getType());
|
||||
}
|
||||
});
|
||||
return definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for Java {@link Map}
|
||||
* {@link TypeBuilder} for Java {@link Map}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
|
|
@ -45,14 +45,16 @@ public class MapTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(type.toString());
|
||||
// Generic Type arguments
|
||||
type.getTypeArguments()
|
||||
.stream()
|
||||
.map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
|
||||
.map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument, typeCache)) // build the TypeDefinition from typeArgument
|
||||
.filter(Objects::nonNull)
|
||||
.map(TypeDefinition::getType)
|
||||
.forEach(typeDefinition.getItems()::add); // Add into the declared TypeDefinition
|
||||
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
|||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getMethodName;
|
||||
|
|
@ -36,18 +37,18 @@ import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.g
|
|||
*/
|
||||
public interface MethodDefinitionBuilder {
|
||||
|
||||
static MethodDefinition build(ProcessingEnvironment processingEnv, ExecutableElement method) {
|
||||
static MethodDefinition build(ProcessingEnvironment processingEnv, ExecutableElement method, Map<String, TypeDefinition> typeCache) {
|
||||
MethodDefinition methodDefinition = new MethodDefinition();
|
||||
methodDefinition.setName(getMethodName(method));
|
||||
methodDefinition.setReturnType(getReturnType(method));
|
||||
methodDefinition.setParameterTypes(getMethodParameterTypes(method));
|
||||
methodDefinition.setParameters(getMethodParameters(processingEnv, method));
|
||||
methodDefinition.setParameters(getMethodParameters(processingEnv, method, typeCache));
|
||||
return methodDefinition;
|
||||
}
|
||||
|
||||
static List<TypeDefinition> getMethodParameters(ProcessingEnvironment processingEnv, ExecutableElement method) {
|
||||
static List<TypeDefinition> getMethodParameters(ProcessingEnvironment processingEnv, ExecutableElement method, Map<String, TypeDefinition> typeCache) {
|
||||
return method.getParameters().stream()
|
||||
.map(element -> TypeDefinitionBuilder.build(processingEnv, element))
|
||||
.map(element -> TypeDefinitionBuilder.build(processingEnv, element, typeCache))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,16 @@ import javax.annotation.processing.ProcessingEnvironment;
|
|||
import javax.lang.model.type.PrimitiveType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isPrimitiveType;
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for Java {@link PrimitiveType primitve type}
|
||||
* {@link TypeBuilder} for Java {@link PrimitiveType primitve type}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
public class PrimitiveTypeDefinitionBuilder implements TypeDefinitionBuilder<PrimitiveType> {
|
||||
public class PrimitiveTypeDefinitionBuilder implements TypeBuilder<PrimitiveType> {
|
||||
|
||||
@Override
|
||||
public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
|
||||
|
|
@ -37,8 +39,9 @@ public class PrimitiveTypeDefinitionBuilder implements TypeDefinitionBuilder<Pri
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, PrimitiveType type, TypeDefinition typeDefinition) {
|
||||
// DO NOTHING
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, PrimitiveType type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = new TypeDefinition(type.toString());
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,10 +17,15 @@
|
|||
package org.apache.dubbo.metadata.annotation.processing.builder;
|
||||
|
||||
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getPublicNonStaticMethods;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getResourceName;
|
||||
|
|
@ -38,19 +43,21 @@ public interface ServiceDefinitionBuilder {
|
|||
serviceDefinition.setCanonicalName(type.toString());
|
||||
serviceDefinition.setCodeSource(getResourceName(type.toString()));
|
||||
|
||||
Map<String, TypeDefinition> types = new HashMap<>();
|
||||
|
||||
// Get all super types and interface excluding the specified type
|
||||
// and then the result will be added into ServiceDefinition#getTypes()
|
||||
getHierarchicalTypes(type.asType(), Object.class)
|
||||
.stream()
|
||||
.map(t -> TypeDefinitionBuilder.build(processingEnv, t))
|
||||
.forEach(serviceDefinition.getTypes()::add);
|
||||
.forEach(t -> TypeDefinitionBuilder.build(processingEnv, t, types));
|
||||
|
||||
// Get all declared methods that will be added into ServiceDefinition#getMethods()
|
||||
getPublicNonStaticMethods(type, Object.class)
|
||||
.stream()
|
||||
.map(method -> MethodDefinitionBuilder.build(processingEnv, method))
|
||||
.map(method -> MethodDefinitionBuilder.build(processingEnv, method, types))
|
||||
.forEach(serviceDefinition.getMethods()::add);
|
||||
|
||||
serviceDefinition.setTypes(new ArrayList<>(types.values()));
|
||||
|
||||
return serviceDefinition;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,13 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
|||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isSimpleType;
|
||||
|
||||
|
||||
/**
|
||||
* {@link TypeDefinitionBuilder} for {@link TypeUtils#SIMPLE_TYPES Java Simple Type}
|
||||
* {@link TypeBuilder} for {@link TypeUtils#SIMPLE_TYPES Java Simple Type}
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
|
|
@ -38,8 +40,9 @@ public class SimpleTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
|
||||
// DO NOTHING
|
||||
public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition td = new TypeDefinition(type.toString());
|
||||
return td;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package org.apache.dubbo.metadata.annotation.processing.builder;
|
||||
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.util.Map;
|
||||
|
||||
@SPI
|
||||
public interface TypeBuilder<T extends TypeMirror> extends Prioritized {
|
||||
|
||||
/**
|
||||
* Test the specified {@link TypeMirror type} is accepted or not
|
||||
*
|
||||
* @param processingEnv {@link ProcessingEnvironment}
|
||||
* @param type {@link TypeMirror type}
|
||||
* @return <code>true</code> if accepted
|
||||
*/
|
||||
boolean accept(ProcessingEnvironment processingEnv, TypeMirror type);
|
||||
|
||||
/**
|
||||
* Build the instance of {@link TypeDefinition}
|
||||
*
|
||||
* @param processingEnv {@link ProcessingEnvironment}
|
||||
* @param type {@link T type}
|
||||
* @return an instance of {@link TypeDefinition}
|
||||
*/
|
||||
TypeDefinition build(ProcessingEnvironment processingEnv, T type, Map<String, TypeDefinition> typeCache);
|
||||
}
|
||||
|
|
@ -16,13 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.metadata.annotation.processing.builder;
|
||||
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
import org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
|
||||
|
|
@ -31,28 +32,8 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
|
|||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
@SPI
|
||||
public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized {
|
||||
|
||||
/**
|
||||
* Test the specified {@link TypeMirror type} is accepted or not
|
||||
*
|
||||
* @param processingEnv {@link ProcessingEnvironment}
|
||||
* @param type {@link TypeMirror type}
|
||||
* @return <code>true</code> if accepted
|
||||
*/
|
||||
boolean accept(ProcessingEnvironment processingEnv, TypeMirror type);
|
||||
|
||||
/**
|
||||
* Build the instance of {@link TypeDefinition}
|
||||
*
|
||||
* @param processingEnv {@link ProcessingEnvironment}
|
||||
* @param type {@link T type}
|
||||
* @param typeDefinition {@link TypeDefinition} to be built
|
||||
* @return an instance of {@link TypeDefinition}
|
||||
*/
|
||||
void build(ProcessingEnvironment processingEnv, T type, TypeDefinition typeDefinition);
|
||||
|
||||
/**
|
||||
* Build the instance of {@link TypeDefinition} from the specified {@link Element element}
|
||||
*
|
||||
|
|
@ -60,8 +41,8 @@ public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized
|
|||
* @param element {@link Element source element}
|
||||
* @return non-null
|
||||
*/
|
||||
static TypeDefinition build(ProcessingEnvironment processingEnv, Element element) {
|
||||
TypeDefinition typeDefinition = build(processingEnv, element.asType());
|
||||
static TypeDefinition build(ProcessingEnvironment processingEnv, Element element, Map<String, TypeDefinition> typeCache) {
|
||||
TypeDefinition typeDefinition = build(processingEnv, element.asType(), typeCache);
|
||||
// Comment this code for the compatibility
|
||||
// typeDefinition.set$ref(element.toString());
|
||||
return typeDefinition;
|
||||
|
|
@ -74,23 +55,23 @@ public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized
|
|||
* @param type {@link TypeMirror type}
|
||||
* @return non-null
|
||||
*/
|
||||
static TypeDefinition build(ProcessingEnvironment processingEnv, TypeMirror type) {
|
||||
String typeName = type.toString();
|
||||
TypeDefinition typeDefinition = new TypeDefinition(typeName);
|
||||
|
||||
static TypeDefinition build(ProcessingEnvironment processingEnv, TypeMirror type, Map<String, TypeDefinition> typeCache) {
|
||||
// Build by all instances of TypeDefinitionBuilder that were loaded By Java SPI
|
||||
|
||||
getExtensionLoader(TypeDefinitionBuilder.class)
|
||||
TypeDefinition typeDefinition = getExtensionLoader(TypeBuilder.class)
|
||||
.getSupportedExtensionInstances()
|
||||
.stream()
|
||||
// load(TypeDefinitionBuilder.class, TypeDefinitionBuilder.class.getClassLoader())
|
||||
.filter(builder -> builder.accept(processingEnv, type))
|
||||
.findFirst()
|
||||
.ifPresent(builder -> {
|
||||
builder.build(processingEnv, type, typeDefinition);
|
||||
.map(builder -> {
|
||||
return builder.build(processingEnv, type, typeCache);
|
||||
// typeDefinition.setTypeBuilderName(builder.getClass().getName());
|
||||
});
|
||||
}).orElse(null);
|
||||
|
||||
if (typeDefinition != null) {
|
||||
typeCache.put(typeDefinition.getType(), typeDefinition);
|
||||
}
|
||||
return typeDefinition;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest
|
|||
|
||||
protected MethodDefinition resolveMethodDefinition(ProcessingEnvironment processingEnv, TypeElement serviceType,
|
||||
ExecutableElement method) {
|
||||
return build(processingEnv, method);
|
||||
return build(processingEnv, method, new HashMap<>());
|
||||
}
|
||||
|
||||
protected void processAnnotatedMethodParameters(ExecutableElement method, TypeElement type,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParam
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return MIN_PRIORITY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import javax.annotation.processing.ProcessingEnvironment;
|
|||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -108,10 +110,12 @@ public class ArrayTypeDefinitionBuilderTest extends AbstractAnnotationProcessing
|
|||
}
|
||||
|
||||
static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
|
||||
String expectedType, String compositeType, TypeDefinitionBuilder builder,
|
||||
String expectedType, String compositeType, TypeBuilder builder,
|
||||
BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
|
||||
TypeDefinition subTypeDefinition = typeDefinition.getItems().get(0);
|
||||
Map<String, TypeDefinition> typeCache = new HashMap<>();
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
|
||||
String subTypeName = typeDefinition.getItems().get(0);
|
||||
TypeDefinition subTypeDefinition = typeCache.get(subTypeName);
|
||||
assertEquals(expectedType, typeDefinition.getType());
|
||||
// assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
|
||||
assertEquals(compositeType, subTypeDefinition.getType());
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder.build;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
|
@ -58,7 +59,8 @@ public class EnumTypeDefinitionBuilderTest extends AbstractAnnotationProcessingT
|
|||
@Test
|
||||
public void testBuild() {
|
||||
TypeElement typeElement = getType(Color.class);
|
||||
TypeDefinition typeDefinition = build(processingEnv, typeElement);
|
||||
Map<String, TypeDefinition> typeCache = new HashMap<>();
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, typeElement, typeCache);
|
||||
assertEquals(Color.class.getName(), typeDefinition.getType());
|
||||
assertEquals(asList("RED", "YELLOW", "BLUE"), typeDefinition.getEnums());
|
||||
// assertEquals(typeDefinition.getTypeBuilderName(), builder.getClass().getName());
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
|
|||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -61,11 +63,11 @@ public class MapTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTe
|
|||
protected void beforeEach() {
|
||||
builder = new MapTypeDefinitionBuilder();
|
||||
TypeElement testType = getType(MapTypeModel.class);
|
||||
stringsField = findField( testType, "strings");
|
||||
colorsField = findField( testType, "colors");
|
||||
primitiveTypeModelsField = findField( testType, "primitiveTypeModels");
|
||||
modelsField = findField( testType, "models");
|
||||
modelArraysField = findField( testType, "modelArrays");
|
||||
stringsField = findField(testType, "strings");
|
||||
colorsField = findField(testType, "colors");
|
||||
primitiveTypeModelsField = findField(testType, "primitiveTypeModels");
|
||||
modelsField = findField(testType, "models");
|
||||
modelArraysField = findField(testType, "modelArrays");
|
||||
|
||||
assertEquals("strings", stringsField.getSimpleName().toString());
|
||||
assertEquals("colors", colorsField.getSimpleName().toString());
|
||||
|
|
@ -119,11 +121,14 @@ public class MapTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTe
|
|||
|
||||
static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
|
||||
String expectedType, String keyType, String valueType,
|
||||
TypeDefinitionBuilder builder,
|
||||
TypeBuilder builder,
|
||||
BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
|
||||
TypeDefinition keyTypeDefinition = typeDefinition.getItems().get(0);
|
||||
TypeDefinition valueTypeDefinition = typeDefinition.getItems().get(1);
|
||||
Map<String, TypeDefinition> typeCache = new HashMap<>();
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
|
||||
String keyTypeName = typeDefinition.getItems().get(0);
|
||||
TypeDefinition keyTypeDefinition = typeCache.get(keyTypeName);
|
||||
String valueTypeName = typeDefinition.getItems().get(1);
|
||||
TypeDefinition valueTypeDefinition = typeCache.get(valueTypeName);
|
||||
assertEquals(expectedType, typeDefinition.getType());
|
||||
// assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
|
||||
assertEquals(keyType, keyTypeDefinition.getType());
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
|
|||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
|
||||
|
|
@ -113,18 +115,18 @@ public class PrimitiveTypeDefinitionBuilderTest extends AbstractAnnotationProces
|
|||
buildAndAssertTypeDefinition(processingEnv, dField, builder);
|
||||
}
|
||||
|
||||
static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field, TypeDefinitionBuilder builder) {
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
|
||||
static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field, TypeBuilder builder) {
|
||||
Map<String, TypeDefinition> typeCache = new HashMap<>();
|
||||
TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
|
||||
assertBasicTypeDefinition(typeDefinition, field.asType().toString(), builder);
|
||||
// assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
|
||||
}
|
||||
|
||||
static void assertBasicTypeDefinition(TypeDefinition typeDefinition, String type, TypeDefinitionBuilder builder) {
|
||||
static void assertBasicTypeDefinition(TypeDefinition typeDefinition, String type, TypeBuilder builder) {
|
||||
assertEquals(type, typeDefinition.getType());
|
||||
// assertEquals(builder.getClass().getName(), typeDefinition.getTypeBuilderName());
|
||||
assertTrue(typeDefinition.getProperties().isEmpty());
|
||||
assertTrue(typeDefinition.getItems().isEmpty());
|
||||
assertTrue(typeDefinition.getEnums().isEmpty());
|
||||
assertNull(typeDefinition.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ package org.apache.dubbo.metadata.annotation.processing.builder;
|
|||
|
||||
import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
|
||||
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
|
||||
import org.apache.dubbo.metadata.tools.TestServiceImpl;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.metadata.annotation.processing.builder.ServiceDefinitionBuilder.build;
|
||||
|
|
@ -49,16 +52,32 @@ public class ServiceDefinitionBuilderTest extends AbstractAnnotationProcessingTe
|
|||
ServiceDefinition serviceDefinition = build(processingEnv, getType(TestServiceImpl.class));
|
||||
assertEquals(TestServiceImpl.class.getTypeName(), serviceDefinition.getCanonicalName());
|
||||
assertEquals("org/apache/dubbo/metadata/tools/TestServiceImpl.class", serviceDefinition.getCodeSource());
|
||||
|
||||
// types
|
||||
int i = 0;
|
||||
assertEquals("org.apache.dubbo.metadata.tools.TestServiceImpl", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("org.apache.dubbo.metadata.tools.GenericTestService", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("org.apache.dubbo.metadata.tools.DefaultTestService", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("org.apache.dubbo.metadata.tools.TestService", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("java.lang.AutoCloseable", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("java.io.Serializable", serviceDefinition.getTypes().get(i++).getType());
|
||||
assertEquals("java.util.EventListener", serviceDefinition.getTypes().get(i++).getType());
|
||||
List<String> typeNames = Arrays.asList(
|
||||
"org.apache.dubbo.metadata.tools.TestServiceImpl",
|
||||
"org.apache.dubbo.metadata.tools.GenericTestService",
|
||||
"org.apache.dubbo.metadata.tools.DefaultTestService",
|
||||
"org.apache.dubbo.metadata.tools.TestService",
|
||||
"java.lang.AutoCloseable",
|
||||
"java.io.Serializable",
|
||||
"java.util.EventListener"
|
||||
);
|
||||
for (String typeName : typeNames) {
|
||||
String gotTypeName = getTypeName(typeName, serviceDefinition.getTypes());
|
||||
assertEquals(typeName, gotTypeName);
|
||||
}
|
||||
|
||||
// methods
|
||||
assertEquals(14, serviceDefinition.getMethods().size());
|
||||
}
|
||||
|
||||
private static String getTypeName(String type, List<TypeDefinition> types) {
|
||||
for (TypeDefinition typeDefinition : types) {
|
||||
if (type.equals(typeDefinition.getType())) {
|
||||
return typeDefinition.getType();
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue