This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.0-metadata-refactor
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 33d31c4b779af79079eef24d163b378b79a45582
Author: ken.lj <[email protected]>
AuthorDate: Thu Nov 4 22:29:21 2021 +0800

    add new files
---
 .../definition/MethodDefinitionBuilder.java        |  78 +++++++++
 .../definition/ServiceDefinitionBuilder.java       | 126 ++++++++++++++
 .../metadata/definition/TypeDefinitionBuilder.java |  87 ++++++++++
 .../definition/builder/ArrayTypeBuilder.java       |  56 +++++++
 .../definition/builder/CollectionTypeBuilder.java  |  83 ++++++++++
 .../definition/builder/DefaultTypeBuilder.java     |  65 ++++++++
 .../definition/builder/EnumTypeBuilder.java        |  69 ++++++++
 .../definition/builder/MapTypeBuilder.java         |  87 ++++++++++
 .../metadata/definition/builder/TypeBuilder.java   |  42 +++++
 .../definition/model/FullServiceDefinition.java    |  43 +++++
 .../definition/model/MethodDefinition.java         | 117 +++++++++++++
 .../definition/model/ServiceDefinition.java        | 136 +++++++++++++++
 .../metadata/definition/model/TypeDefinition.java  | 183 +++++++++++++++++++++
 .../dubbo/metadata/definition/util/ClassUtils.java | 164 ++++++++++++++++++
 .../definition/util/JaketConfigurationUtils.java   | 102 ++++++++++++
 15 files changed, 1438 insertions(+)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java
new file mode 100644
index 0000000..e7c18e6
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition;
+
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link MethodDefinition} Builder based on Java Reflection
+ *
+ * @since 2.7.6
+ */
+public class MethodDefinitionBuilder {
+
+    private final TypeDefinitionBuilder builder;
+
+    public MethodDefinitionBuilder(TypeDefinitionBuilder builder) {
+        this.builder = builder;
+    }
+
+    public MethodDefinitionBuilder() {
+        this.builder = new TypeDefinitionBuilder();
+    }
+
+    /**
+     * Build the instance of {@link MethodDefinition}
+     *
+     * @param method {@link Method}
+     * @return non-null
+     */
+    public MethodDefinition build(Method method) {
+
+        MethodDefinition md = new MethodDefinition();
+        md.setName(method.getName());
+
+        // Process the parameters
+        Class<?>[] paramTypes = method.getParameterTypes();
+        Type[] genericParamTypes = method.getGenericParameterTypes();
+
+        int paramSize = paramTypes.length;
+        String[] parameterTypes = new String[paramSize];
+        List<TypeDefinition> parameters = new ArrayList<>(paramSize);
+        for (int i = 0; i < paramSize; i++) {
+            TypeDefinition parameter = builder.build(genericParamTypes[i], 
paramTypes[i]);
+            parameterTypes[i] = parameter.getType();
+            parameters.add(parameter);
+        }
+
+        md.setParameterTypes(parameterTypes);
+        md.setParameters(parameters);
+
+        // Process return type.
+        TypeDefinition td = builder.build(method.getGenericReturnType(), 
method.getReturnType());
+        md.setReturnType(td.getType());
+
+        return md;
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
new file mode 100755
index 0000000..cfdec72
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition;
+
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+import org.apache.dubbo.metadata.definition.util.ClassUtils;
+
+import com.google.gson.Gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 2015/1/27.
+ */
+public final class ServiceDefinitionBuilder {
+
+    /**
+     * Describe a Java interface in {@link ServiceDefinition}.
+     *
+     * @return Service description
+     */
+    public static ServiceDefinition build(final Class<?> interfaceClass) {
+        ServiceDefinition sd = new ServiceDefinition();
+        build(sd, interfaceClass);
+        return sd;
+    }
+
+    public static FullServiceDefinition buildFullDefinition(final Class<?> 
interfaceClass) {
+        FullServiceDefinition sd = new FullServiceDefinition();
+        build(sd, interfaceClass);
+        return sd;
+    }
+
+    public static FullServiceDefinition buildFullDefinition(final Class<?> 
interfaceClass, Map<String, String> params) {
+        FullServiceDefinition sd = new FullServiceDefinition();
+        build(sd, interfaceClass);
+        sd.setParameters(params);
+        return sd;
+    }
+
+    public static <T extends ServiceDefinition> void build(T sd, final 
Class<?> interfaceClass) {
+        sd.setCanonicalName(interfaceClass.getCanonicalName());
+        sd.setCodeSource(ClassUtils.getCodeSource(interfaceClass));
+        Annotation[] classAnnotations = interfaceClass.getAnnotations();
+        sd.setAnnotations(annotationToStringList(classAnnotations));
+
+        TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
+        List<Method> methods = 
ClassUtils.getPublicNonStaticMethods(interfaceClass);
+        for (Method method : methods) {
+            MethodDefinition md = new MethodDefinition();
+            md.setName(method.getName());
+
+            Annotation[] methodAnnotations = method.getAnnotations();
+            md.setAnnotations(annotationToStringList(methodAnnotations));
+
+            // Process parameter types.
+            Class<?>[] paramTypes = method.getParameterTypes();
+            Type[] genericParamTypes = method.getGenericParameterTypes();
+
+            String[] parameterTypes = new String[paramTypes.length];
+            for (int i = 0; i < paramTypes.length; i++) {
+                TypeDefinition td = builder.build(genericParamTypes[i], 
paramTypes[i]);
+                parameterTypes[i] = td.getType();
+            }
+            md.setParameterTypes(parameterTypes);
+
+            // Process return type.
+            TypeDefinition td = builder.build(method.getGenericReturnType(), 
method.getReturnType());
+            md.setReturnType(td.getType());
+
+            sd.getMethods().add(md);
+        }
+
+        sd.setTypes(builder.getTypeDefinitions());
+    }
+
+    private static List<String> annotationToStringList(Annotation[] 
annotations) {
+        if (annotations == null) {
+            return Collections.emptyList();
+        }
+        List<String> list = new ArrayList<>();
+        for (Annotation annotation : annotations) {
+            list.add(annotation.toString());
+        }
+        return list;
+    }
+
+    /**
+     * Describe a Java interface in Json schema.
+     *
+     * @return Service description
+     */
+    public static String schema(final Class<?> clazz) {
+        ServiceDefinition sd = build(clazz);
+        Gson gson = new Gson();
+        return gson.toJson(sd);
+    }
+
+    private ServiceDefinitionBuilder() {
+    }
+}
+
+
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
new file mode 100755
index 0000000..b2758e3
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * 2015/1/27.
+ */
+public class TypeDefinitionBuilder {
+    private static final Logger logger = 
LoggerFactory.getLogger(TypeDefinitionBuilder.class);
+    static final List<TypeBuilder> BUILDERS;
+
+    static {
+        ExtensionLoader<TypeBuilder> extensionLoader = 
ExtensionLoader.getExtensionLoader(TypeBuilder.class);
+        Set<TypeBuilder> tbs = 
extensionLoader.getSupportedExtensionInstances();
+        BUILDERS = new ArrayList<>(tbs);
+    }
+
+    public static TypeDefinition build(Type type, Class<?> clazz, Map<String, 
TypeDefinition> typeCache) {
+        TypeBuilder builder = getGenericTypeBuilder(clazz);
+        TypeDefinition td;
+
+        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);
+        } else {
+            td = DefaultTypeBuilder.build(clazz, typeCache);
+        }
+        return td;
+    }
+
+    private static TypeBuilder getGenericTypeBuilder(Class<?> clazz) {
+        for (TypeBuilder builder : BUILDERS) {
+            try {
+                if (builder.accept(clazz)) {
+                    return builder;
+                }
+            } catch (NoClassDefFoundError cnfe) {
+                //ignore
+                logger.info("Throw classNotFound (" + cnfe.getMessage() + ") 
in " + builder.getClass());
+            }
+        }
+        return null;
+    }
+
+    private Map<String, TypeDefinition> typeCache = new HashMap<>();
+
+    public TypeDefinition build(Type type, Class<?> clazz) {
+        return build(type, clazz, typeCache);
+    }
+
+    public List<TypeDefinition> getTypeDefinitions() {
+        return new ArrayList<>(typeCache.values());
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
new file mode 100755
index 0000000..78cc7a5
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.builder;
+
+import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * 2015/1/27.
+ */
+public class ArrayTypeBuilder implements TypeBuilder {
+
+    @Override
+    public boolean accept(Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+        return clazz.isArray();
+    }
+
+    @Override
+    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 array.
+        Class<?> componentType = clazz.getComponentType();
+        TypeDefinition itemTd = TypeDefinitionBuilder.build(componentType, 
componentType, typeCache);
+        if (itemTd != null) {
+            td.getItems().add(itemTd.getType());
+        }
+        return td;
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
new file mode 100755
index 0000000..6c6ee11
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 2015/1/27.
+ */
+public class CollectionTypeBuilder implements TypeBuilder {
+
+    @Override
+    public boolean accept(Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+        return Collection.class.isAssignableFrom(clazz);
+    }
+
+    @Override
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, 
TypeDefinition> typeCache) {
+        if (!(type instanceof ParameterizedType)) {
+            return new TypeDefinition(clazz.getCanonicalName());
+        }
+
+        ParameterizedType parameterizedType = (ParameterizedType) type;
+        Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
+        if (actualTypeArgs == null || actualTypeArgs.length != 1) {
+            throw new IllegalArgumentException(MessageFormat.format(
+                    "[ServiceDefinitionBuilder] Collection type [{0}] with 
unexpected amount of arguments [{1}]."
+                            + Arrays.toString(actualTypeArgs),
+                    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();
+            itemTd = TypeDefinitionBuilder.build(actualType, rawType, 
typeCache);
+        } else if (actualType instanceof Class<?>) {
+            Class<?> actualClass = (Class<?>) actualType;
+            itemTd = TypeDefinitionBuilder.build(null, actualClass, typeCache);
+        }
+        if (itemTd != null) {
+            td.getItems().add(itemTd.getType());
+        }
+
+        return td;
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
new file mode 100755
index 0000000..4ac52a4
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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 org.apache.dubbo.metadata.definition.util.JaketConfigurationUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 2015/1/27.
+ */
+public final class DefaultTypeBuilder {
+
+    public static TypeDefinition build(Class<?> clazz, Map<String, 
TypeDefinition> typeCache) {
+        final String canonicalName = clazz.getCanonicalName();
+
+        // Try to get a cached definition
+        TypeDefinition td = typeCache.get(canonicalName);
+        if (td != null) {
+            return td;
+        }
+        td = new TypeDefinition(canonicalName);
+        typeCache.put(canonicalName, td);
+
+        // Primitive type
+        if (!JaketConfigurationUtils.needAnalyzing(clazz)) {
+            return td;
+        }
+
+        // Custom type
+        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.getType());
+        }
+
+        return td;
+    }
+
+    private DefaultTypeBuilder() {
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
new file mode 100755
index 0000000..1f5d52a
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+import java.lang.reflect.Type;
+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(Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+        return clazz.isEnum();
+    }
+
+    @Override
+    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");
+            methodValues.setAccessible(true);
+            Object[] values = (Object[]) methodValues.invoke(clazz, new 
Object[0]);
+            int length = values.length;
+            for (int i = 0; i < length; i++) {
+                Object value = values[i];
+                td.getEnums().add(value.toString());
+            }
+            return td;
+        } catch (Throwable t) {
+            logger.error("There is an error while process class " + clazz, t);
+        }
+        return td;
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
new file mode 100755
index 0000000..121198c
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Map;
+
+import static org.apache.dubbo.common.utils.TypeUtils.getRawClass;
+import static org.apache.dubbo.common.utils.TypeUtils.isClass;
+import static org.apache.dubbo.common.utils.TypeUtils.isParameterizedType;
+
+/**
+ * 2015/1/27.
+ */
+public class MapTypeBuilder implements TypeBuilder {
+
+    @Override
+    public boolean accept(Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+        return Map.class.isAssignableFrom(clazz);
+    }
+
+    @Override
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, 
TypeDefinition> typeCache) {
+        if (!(type instanceof ParameterizedType)) {
+            return new TypeDefinition(clazz.getCanonicalName());
+        }
+
+        ParameterizedType parameterizedType = (ParameterizedType) type;
+        Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
+        int actualTypeArgsLength = actualTypeArgs == null ? 0 : 
actualTypeArgs.length;
+
+        if (actualTypeArgsLength != 2) {
+            throw new IllegalArgumentException(MessageFormat.format(
+                    "[ServiceDefinitionBuilder] Map type [{0}] with unexpected 
amount of arguments [{1}]."
+                            + Arrays.toString(actualTypeArgs), type, 
actualTypeArgs));
+        }
+
+        String mapType = 
ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
+
+        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];
+            TypeDefinition item = null;
+            Class<?> rawType = getRawClass(actualType);
+            if (isParameterizedType(actualType)) {
+                // Nested collection or map.
+                item = TypeDefinitionBuilder.build(actualType, rawType, 
typeCache);
+            } else if (isClass(actualType)) {
+                item = TypeDefinitionBuilder.build(null, rawType, typeCache);
+            }
+            if (item != null) {
+                td.getItems().add(item.getType());
+            }
+        }
+        return td;
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
new file mode 100755
index 0000000..050de3c
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.builder;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * 2015/1/27.
+ */
+@SPI
+public interface TypeBuilder extends Prioritized {
+
+    /**
+     * Whether the build accept the class passed in.
+     */
+    boolean accept(Class<?> clazz);
+
+    /**
+     * Build type definition with the type or class.
+     */
+    TypeDefinition build(Type type, Class<?> clazz, Map<String, 
TypeDefinition> typeCache);
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java
new file mode 100644
index 0000000..fbebcf1
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.model;
+
+import java.util.Map;
+
+/**
+ * 2018/10/25
+ */
+public class FullServiceDefinition extends ServiceDefinition {
+
+    private Map<String, String> parameters;
+
+    public Map<String, String> getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(Map<String, String> parameters) {
+        this.parameters = parameters;
+    }
+
+    @Override
+    public String toString() {
+        return "FullServiceDefinition{" +
+                "parameters=" + parameters +
+                "} " + super.toString();
+    }
+
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
new file mode 100755
index 0000000..305bfc3
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static 
org.apache.dubbo.metadata.definition.model.TypeDefinition.formatType;
+import static 
org.apache.dubbo.metadata.definition.model.TypeDefinition.formatTypes;
+
+/**
+ * 2015/1/27.
+ */
+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;
+
+    private List<String> annotations;
+
+    public String getName() {
+        return name;
+    }
+
+    public List<TypeDefinition> getParameters() {
+        if (parameters == null) {
+            parameters = new ArrayList<>();
+        }
+        return parameters;
+    }
+
+    public String[] getParameterTypes() {
+        return parameterTypes;
+    }
+
+    public String getReturnType() {
+        return returnType;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setParameters(List<TypeDefinition> parameters) {
+        this.parameters = parameters;
+    }
+
+    public void setParameterTypes(String[] parameterTypes) {
+        this.parameterTypes = formatTypes(parameterTypes);
+    }
+
+    public void setReturnType(String returnType) {
+        this.returnType = formatType(returnType);
+    }
+
+    public List<String> getAnnotations() {
+        if (annotations == null) {
+            annotations = Collections.emptyList();
+        }
+        return annotations;
+    }
+
+    public void setAnnotations(List<String> annotations) {
+        this.annotations = annotations;
+    }
+
+    @Override
+    public String toString() {
+        return "MethodDefinition [name=" + name + ", parameterTypes=" + 
Arrays.toString(parameterTypes)
+                + ", returnType=" + returnType + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof MethodDefinition)) {
+            return false;
+        }
+        MethodDefinition that = (MethodDefinition) o;
+        return Objects.equals(getName(), that.getName()) &&
+                Arrays.equals(getParameterTypes(), that.getParameterTypes()) &&
+                Objects.equals(getReturnType(), that.getReturnType());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getName(), getReturnType(), 
Arrays.toString(getParameterTypes()));
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
new file mode 100755
index 0000000..a16eb6a
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 2015/1/27.
+ */
+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;
+
+    /**
+     * the definitions of annotations
+     */
+    private List<String> annotations;
+
+    public String getCanonicalName() {
+        return canonicalName;
+    }
+
+    public String getCodeSource() {
+        return codeSource;
+    }
+
+    public List<MethodDefinition> getMethods() {
+        if (methods == null) {
+            methods = new ArrayList<>();
+        }
+        return methods;
+    }
+
+    public List<TypeDefinition> getTypes() {
+        if (types == null) {
+            types = new ArrayList<>();
+        }
+        return types;
+    }
+
+    public String getUniqueId() {
+        return canonicalName + "@" + codeSource;
+    }
+
+    public void setCanonicalName(String canonicalName) {
+        this.canonicalName = canonicalName;
+    }
+
+    public void setCodeSource(String codeSource) {
+        this.codeSource = codeSource;
+    }
+
+    public void setMethods(List<MethodDefinition> methods) {
+        this.methods = methods;
+    }
+
+    public void setTypes(List<TypeDefinition> types) {
+        this.types = types;
+    }
+
+    public List<String> getAnnotations() {
+        if (annotations == null) {
+            annotations = Collections.emptyList();
+        }
+        return annotations;
+    }
+
+    public void setAnnotations(List<String> annotations) {
+        this.annotations = annotations;
+    }
+
+    @Override
+    public String toString() {
+        return "ServiceDefinition [canonicalName=" + canonicalName + ", 
codeSource=" + codeSource + ", methods="
+                + methods + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ServiceDefinition)) {
+            return false;
+        }
+        ServiceDefinition that = (ServiceDefinition) o;
+        return Objects.equals(getCanonicalName(), that.getCanonicalName()) &&
+                Objects.equals(getCodeSource(), that.getCodeSource()) &&
+                Objects.equals(getMethods(), that.getMethods()) &&
+                Objects.equals(getTypes(), that.getTypes());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getCanonicalName(), getCodeSource(), getMethods(), 
getTypes());
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
new file mode 100755
index 0000000..6dd0f06
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.apache.dubbo.common.utils.StringUtils.replace;
+
+/**
+ * 2015/1/27.
+ */
+public class TypeDefinition implements Serializable {
+
+    /**
+     * 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<String> items;
+
+    /**
+     * the enum's value
+     * <p>
+     * If this type is not enum, enums is null or empty
+     */
+    @SerializedName("enum")
+    private List<String> enums;
+
+    /**
+     * the key is property name,
+     * the value is property's type name
+     */
+    private Map<String, String> properties;
+
+    public TypeDefinition() {
+    }
+
+    public TypeDefinition(String type) {
+        this.setType(type);
+    }
+
+    /**
+     * Format the {@link String} array presenting Java types
+     *
+     * @param types the strings presenting Java types
+     * @return new String array of Java types after be formatted
+     * @since 2.7.9
+     */
+    public static String[] formatTypes(String[] types) {
+        String[] newTypes = new String[types.length];
+        for (int i = 0; i < types.length; i++) {
+            newTypes[i] = formatType(types[i]);
+        }
+        return newTypes;
+    }
+
+    /**
+     * Format the {@link String} presenting Java type
+     *
+     * @param type the String presenting type
+     * @return new String presenting Java type after be formatted
+     * @since 2.7.9
+     */
+    public static String formatType(String type) {
+        if (isGenericType(type)) {
+            return formatGenericType(type);
+        }
+        return type;
+    }
+
+    /**
+     * Replacing <code>", "</code> to <code>","</code> will not change the 
semantic of
+     * {@link ParameterizedType#toString()}
+     *
+     * @param type
+     * @return formatted type
+     * @see sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
+     */
+    private static String formatGenericType(String type) {
+        return replace(type, ", ", ",");
+    }
+
+    private static boolean isGenericType(String type) {
+        return type.contains("<") && type.contains(">");
+    }
+
+    public List<String> getEnums() {
+        if (enums == null) {
+            enums = new ArrayList<>();
+        }
+        return enums;
+    }
+
+    public List<String> getItems() {
+        if (items == null) {
+            items = new ArrayList<>();
+        }
+        return items;
+    }
+
+    public Map<String, String> getProperties() {
+        if (properties == null) {
+            properties = new HashMap<>();
+        }
+        return properties;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setEnums(List<String> enums) {
+        this.enums = enums;
+    }
+
+    public void setItems(List<String> items) {
+        this.items = items;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    public void setType(String type) {
+        this.type = formatType(type);
+    }
+
+    @Override
+    public String toString() {
+        return "TypeDefinition [type=" + type + ", properties=" + properties + 
"]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof TypeDefinition)) {
+            return false;
+        }
+        TypeDefinition that = (TypeDefinition) o;
+        return Objects.equals(getType(), that.getType()) &&
+                Objects.equals(getItems(), that.getItems()) &&
+                Objects.equals(getEnums(), that.getEnums()) &&
+                Objects.equals(getProperties(), that.getProperties());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getType(), getItems(), getEnums(), 
getProperties());
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
new file mode 100755
index 0000000..c6f13d5
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.util;
+
+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;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 2015/1/27.
+ */
+public final class ClassUtils {
+
+    /**
+     * Get the code source file or class path of the Class passed in.
+     *
+     * @param clazz
+     * @return Jar file name or class path.
+     */
+    public static String getCodeSource(Class<?> clazz) {
+        ProtectionDomain protectionDomain = clazz.getProtectionDomain();
+        if (protectionDomain == null || protectionDomain.getCodeSource() == 
null) {
+            return null;
+        }
+
+        CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
+        URL location = codeSource.getLocation();
+        if (location == null) {
+            return null;
+        }
+
+        String path = location.toExternalForm();
+
+        if (path.endsWith(".jar") && path.contains("/")) {
+            return path.substring(path.lastIndexOf('/') + 1);
+        }
+        return path;
+    }
+
+    /**
+     * Get all non-static fields of the Class passed in or its super classes.
+     * <p>
+     *
+     * @param clazz Class to parse.
+     * @return field list
+     */
+    public static List<Field> getNonStaticFields(final Class<?> clazz) {
+        List<Field> result = new ArrayList<>();
+        Class<?> target = clazz;
+        while (target != null) {
+            if (JaketConfigurationUtils.isExcludedType(target)) {
+                break;
+            }
+
+            Field[] fields = target.getDeclaredFields();
+            for (Field field : fields) {
+                int modifiers = field.getModifiers();
+                if (Modifier.isStatic(modifiers) || 
Modifier.isTransient(modifiers)) {
+                    continue;
+                }
+
+                result.add(field);
+            }
+            target = target.getSuperclass();
+        }
+
+        return result;
+    }
+
+    /**
+     * Get all public, non-static methods of the Class passed in.
+     * <p>
+     *
+     * @param clazz Class to parse.
+     * @return methods list
+     */
+    public static List<Method> getPublicNonStaticMethods(final Class<?> clazz) 
{
+        List<Method> result = new ArrayList<Method>();
+
+        Method[] methods = clazz.getMethods();
+        for (Method method : methods) {
+            int mod = method.getModifiers();
+            if (Modifier.isPublic(mod) && !Modifier.isStatic(mod)) {
+                result.add(method);
+            }
+        }
+        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);
+            }
+
+            sb.append('.');
+
+            if (ownerType instanceof ParameterizedType) {
+                // 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() {
+    }
+}
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java
new file mode 100755
index 0000000..a21de3f
--- /dev/null
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.definition.util;
+
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * 2015/1/27.
+ */
+public class JaketConfigurationUtils {
+
+    private static final String CONFIGURATION_FILE = "jaket.properties";
+
+    private static String[] includedInterfacePackages;
+    private static String[] includedTypePackages;
+    private static String[] closedTypes;
+
+    static {
+        Properties props = new Properties();
+        InputStream inStream = 
JaketConfigurationUtils.class.getClassLoader().getResourceAsStream(CONFIGURATION_FILE);
+        try {
+            props.load(inStream);
+            String value = (String) props.get("included_interface_packages");
+            if (StringUtils.isNotEmpty(value)) {
+                includedInterfacePackages = value.split(",");
+            }
+
+            value = props.getProperty("included_type_packages");
+            if (StringUtils.isNotEmpty(value)) {
+                includedTypePackages = value.split(",");
+            }
+
+            value = props.getProperty("closed_types");
+            if (StringUtils.isNotEmpty(value)) {
+                closedTypes = value.split(",");
+            }
+
+        } catch (Throwable e) {
+            // Ignore it.
+        }
+    }
+
+    public static boolean isExcludedInterface(Class<?> clazz) {
+        if (includedInterfacePackages == null || 
includedInterfacePackages.length == 0) {
+            return false;
+        }
+
+        for (String packagePrefix : includedInterfacePackages) {
+            if (clazz.getCanonicalName().startsWith(packagePrefix)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static boolean isExcludedType(Class<?> clazz) {
+        if (includedTypePackages == null || includedTypePackages.length == 0) {
+            return false;
+        }
+
+        for (String packagePrefix : includedTypePackages) {
+            if (clazz.getCanonicalName().startsWith(packagePrefix)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static boolean needAnalyzing(Class<?> clazz) {
+        String canonicalName = clazz.getCanonicalName();
+
+        if (closedTypes != null && closedTypes.length > 0) {
+            for (String type : closedTypes) {
+                if (canonicalName.startsWith(type)) {
+                    return false;
+                }
+            }
+        }
+
+        return !isExcludedType(clazz);
+    }
+
+}

Reply via email to