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

liubao pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new b4845a2  [SCB-922] collect Getter/Setter from pojo
b4845a2 is described below

commit b4845a22711ee0ab8c0b8b4a2c07ca9aab81fd25
Author: wujimin <wuji...@huawei.com>
AuthorDate: Tue Sep 18 16:38:17 2018 +0800

    [SCB-922] collect Getter/Setter from pojo
---
 .../main/resources/META-INF/spring/cse.bean.xml    |   2 +-
 .../common/utils/LambdaMetafactoryUtils.java       |  16 ++-
 .../foundation/common/utils/bean/Getter.java       |   2 +-
 .../utils/bean/{Getter.java => MapGetter.java}     |  16 ++-
 .../utils/bean/{Getter.java => MapSetter.java}     |  16 ++-
 .../foundation/common/utils/bean/Setter.java       |   2 +-
 foundations/foundation-protobuf/pom.xml            |  21 ++++
 .../protobuf/internal/bean/BeanDescriptor.java     | 111 +++++++++++++++++
 .../internal/bean/BeanDescriptorManager.java       |  50 ++++++++
 .../protobuf/internal/bean/BeanFactory.java        | 104 ++++++++++++++++
 .../protobuf/internal/bean/PropertyDescriptor.java |  75 +++++++++++
 .../internal/bean/TestBeanDescriptorManager.java   | 137 +++++++++++++++++++++
 pom.xml                                            |   2 +
 13 files changed, 545 insertions(+), 9 deletions(-)

diff --git a/core/src/main/resources/META-INF/spring/cse.bean.xml 
b/core/src/main/resources/META-INF/spring/cse.bean.xml
index b24ab13..092187c 100644
--- a/core/src/main/resources/META-INF/spring/cse.bean.xml
+++ b/core/src/main/resources/META-INF/spring/cse.bean.xml
@@ -20,7 +20,7 @@
   xmlns:context="http://www.springframework.org/schema/context";
   xsi:schemaLocation="
                http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
-               http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd";>
+               http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd";>
   <context:annotation-config/>
   <!-- <context:spring-configured /> -->
   <context:component-scan 
base-package="${scb-scan-package:org.apache.servicecomb}"/>
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
index e6bfa73..3e85787 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
@@ -93,7 +93,13 @@ public final class LambdaMetafactoryUtils {
   // slower than reflect directly
   public static Getter createGetter(Field field) {
     field.setAccessible(true);
-    return instance -> field.get(instance);
+    return instance -> {
+      try {
+        return field.get(instance);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      }
+    };
   }
 
   public static Setter createSetter(Method setMethod) throws Throwable {
@@ -103,6 +109,12 @@ public final class LambdaMetafactoryUtils {
   // slower than reflect directly
   public static Setter createSetter(Field field) {
     field.setAccessible(true);
-    return (instance, value) -> field.set(instance, value);
+    return (instance, value) -> {
+      try {
+        field.set(instance, value);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      }
+    };
   }
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
index 1404f47..15ea1d9 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
@@ -17,5 +17,5 @@
 package org.apache.servicecomb.foundation.common.utils.bean;
 
 public interface Getter {
-  Object get(Object instance) throws Throwable;
+  Object get(Object instance);
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapGetter.java
similarity index 74%
copy from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
copy to 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapGetter.java
index 1404f47..0766e99 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapGetter.java
@@ -16,6 +16,18 @@
  */
 package org.apache.servicecomb.foundation.common.utils.bean;
 
-public interface Getter {
-  Object get(Object instance) throws Throwable;
+import java.util.Map;
+
+public class MapGetter implements Getter {
+  private Object key;
+
+  public MapGetter(Object key) {
+    this.key = key;
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public Object get(Object instance) {
+    return ((Map<Object, Object>) instance).get(key);
+  }
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapSetter.java
similarity index 74%
copy from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
copy to 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapSetter.java
index 1404f47..216a051 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapSetter.java
@@ -16,6 +16,18 @@
  */
 package org.apache.servicecomb.foundation.common.utils.bean;
 
-public interface Getter {
-  Object get(Object instance) throws Throwable;
+import java.util.Map;
+
+public class MapSetter implements Setter {
+  private Object key;
+
+  public MapSetter(Object key) {
+    this.key = key;
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void set(Object instance, Object value) {
+    ((Map<Object, Object>) instance).put(key, value);
+  }
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Setter.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Setter.java
index eb1c1c9..c612b69 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Setter.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Setter.java
@@ -17,5 +17,5 @@
 package org.apache.servicecomb.foundation.common.utils.bean;
 
 public interface Setter {
-  void set(Object instance, Object value) throws Throwable;
+  void set(Object instance, Object value);
 }
diff --git a/foundations/foundation-protobuf/pom.xml 
b/foundations/foundation-protobuf/pom.xml
index 9087a0f..8eaa4e5 100644
--- a/foundations/foundation-protobuf/pom.xml
+++ b/foundations/foundation-protobuf/pom.xml
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
 <project xmlns="http://maven.apache.org/POM/4.0.0";
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
@@ -13,6 +30,10 @@
 
   <dependencies>
     <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-common</artifactId>
+    </dependency>
+    <dependency>
       <groupId>io.protostuff</groupId>
       <artifactId>protostuff-parser</artifactId>
     </dependency>
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptor.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptor.java
new file mode 100644
index 0000000..868d151
--- /dev/null
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptor.java
@@ -0,0 +1,111 @@
+/*
+ * 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.servicecomb.foundation.protobuf.internal.bean;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;
+import org.apache.servicecomb.foundation.common.utils.bean.Getter;
+import org.apache.servicecomb.foundation.common.utils.bean.Setter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
+
+public class BeanDescriptor {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(BeanDescriptor.class);
+
+  private JavaType javaType;
+
+  private BeanFactory factory;
+
+  private Map<String, PropertyDescriptor> propertyDescriptors = new 
HashMap<>();
+
+  public JavaType getJavaType() {
+    return javaType;
+  }
+
+  public BeanFactory getFactory() {
+    return factory;
+  }
+
+  public Map<String, PropertyDescriptor> getPropertyDescriptors() {
+    return propertyDescriptors;
+  }
+
+  public void init(SerializationConfig serializationConfig, JavaType javaType) 
{
+    this.javaType = javaType;
+
+    this.factory = BeanFactory.createFactory(javaType);
+
+    BeanDescription beanDescription = serializationConfig.introspect(javaType);
+    for (BeanPropertyDefinition propertyDefinition : 
beanDescription.findProperties()) {
+      PropertyDescriptor propertyDescriptor = new PropertyDescriptor();
+      propertyDescriptor.setName(propertyDefinition.getName());
+      propertyDescriptor.setJavaType(propertyDefinition.getPrimaryType());
+      
propertyDescriptor.setFactory(BeanFactory.createFactory(propertyDefinition.getPrimaryType()));
+
+      try {
+        propertyDescriptor.setGetter(initGetter(propertyDefinition));
+      } catch (Throwable e) {
+        LOGGER.error("failed to init getter for field {}:{}", 
javaType.getRawClass().getName(),
+            propertyDefinition.getName(), e);
+      }
+
+      try {
+        propertyDescriptor.setSetter(initSetter(propertyDefinition));
+      } catch (Throwable e) {
+        LOGGER.error("failed to init setter for field {}:{}", 
javaType.getRawClass().getName(),
+            propertyDefinition.getName(), e);
+      }
+
+      propertyDescriptors.put(propertyDefinition.getName(), 
propertyDescriptor);
+    }
+  }
+
+  protected Getter initGetter(BeanPropertyDefinition propertyDefinition) 
throws Throwable {
+    if (propertyDefinition.hasGetter()) {
+      return 
LambdaMetafactoryUtils.createGetter(propertyDefinition.getGetter().getAnnotated());
+    }
+
+    if (propertyDefinition.hasField() && 
propertyDefinition.getField().isPublic()) {
+      return 
LambdaMetafactoryUtils.createGetter(propertyDefinition.getField().getAnnotated());
+    }
+
+    return null;
+  }
+
+  protected Setter initSetter(BeanPropertyDefinition propertyDefinition) 
throws Throwable {
+    if (propertyDefinition.hasSetter()) {
+      return 
LambdaMetafactoryUtils.createSetter(propertyDefinition.getSetter().getAnnotated());
+    }
+
+    if (propertyDefinition.hasField() && 
propertyDefinition.getField().isPublic()) {
+      return 
LambdaMetafactoryUtils.createSetter(propertyDefinition.getField().getAnnotated());
+    }
+
+    return null;
+  }
+
+  public Object create() {
+    return factory.create();
+  }
+}
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptorManager.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptorManager.java
new file mode 100644
index 0000000..58945b0
--- /dev/null
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptorManager.java
@@ -0,0 +1,50 @@
+/*
+ * 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.servicecomb.foundation.protobuf.internal.bean;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+public class BeanDescriptorManager {
+  private SerializationConfig serializationConfig;
+
+  private Map<Type, BeanDescriptor> beanDescriptors = new 
ConcurrentHashMapEx<>();
+
+  public BeanDescriptorManager(SerializationConfig serializationConfig) {
+    this.serializationConfig = serializationConfig;
+  }
+
+  public BeanDescriptor getOrCreateBeanDescriptor(Type type) {
+    return beanDescriptors.computeIfAbsent(type, this::createBeanDescriptor);
+  }
+
+  protected BeanDescriptor createBeanDescriptor(Type type) {
+    return 
createBeanDescriptor(TypeFactory.defaultInstance().constructType(type));
+  }
+
+  protected BeanDescriptor createBeanDescriptor(JavaType javaType) {
+    BeanDescriptor beanDescriptor = new BeanDescriptor();
+    beanDescriptor.init(serializationConfig, javaType);
+    return beanDescriptor;
+  }
+}
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanFactory.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanFactory.java
new file mode 100644
index 0000000..24594ac
--- /dev/null
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanFactory.java
@@ -0,0 +1,104 @@
+/*
+ * 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.servicecomb.foundation.protobuf.internal.bean;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+import io.protostuff.compiler.model.Field;
+
+public interface BeanFactory {
+  static BeanFactory createFactory(Field field) {
+    // map also is repeated, so must determine first
+    if (field.isMap()) {
+      return BeanFactory::mapFactory;
+    }
+
+    if (field.isRepeated()) {
+      return BeanFactory::listFactory;
+    }
+    
+    if (field.getType().isScalar()) {
+      // no need a factory
+      return null;
+    }
+
+    return BeanFactory::mapFactory;
+  }
+
+  static BeanFactory createFactory(JavaType javaType) {
+    if (javaType.isPrimitive()) {
+      // no need a factory
+      return null;
+    }
+
+    if (List.class.isAssignableFrom(javaType.getRawClass())) {
+      return BeanFactory::listFactory;
+    }
+
+    if (Set.class.isAssignableFrom(javaType.getRawClass())) {
+      return BeanFactory::setFactory;
+    }
+
+    if (Map.class.isAssignableFrom(javaType.getRawClass())) {
+      return BeanFactory::mapFactory;
+    }
+
+    return new ConstructorFactory(javaType);
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> T listFactory() {
+    return (T) new ArrayList<>();
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> T setFactory() {
+    return (T) new LinkedHashSet<>();
+  }
+
+  @SuppressWarnings("unchecked")
+  static <T> T mapFactory() {
+    return (T) new LinkedHashMap<>();
+  }
+
+  class ConstructorFactory implements BeanFactory {
+    private final JavaType javaType;
+
+    public ConstructorFactory(JavaType javaType) {
+      this.javaType = javaType;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T create() {
+      try {
+        return (T) javaType.getRawClass().newInstance();
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  <T> T create();
+}
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyDescriptor.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyDescriptor.java
new file mode 100644
index 0000000..4fb6a8f
--- /dev/null
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.servicecomb.foundation.protobuf.internal.bean;
+
+import org.apache.servicecomb.foundation.common.utils.bean.Getter;
+import org.apache.servicecomb.foundation.common.utils.bean.Setter;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class PropertyDescriptor {
+  private String name;
+
+  private JavaType javaType;
+
+  private Getter getter;
+
+  private Setter setter;
+
+  // not available for primitive types
+  private BeanFactory factory;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public JavaType getJavaType() {
+    return javaType;
+  }
+
+  public void setJavaType(JavaType javaType) {
+    this.javaType = javaType;
+  }
+
+  public Getter getGetter() {
+    return getter;
+  }
+
+  public void setGetter(Getter getter) {
+    this.getter = getter;
+  }
+
+  public Setter getSetter() {
+    return setter;
+  }
+
+  public void setSetter(Setter setter) {
+    this.setter = setter;
+  }
+
+  public BeanFactory getFactory() {
+    return factory;
+  }
+
+  public void setFactory(BeanFactory factory) {
+    this.factory = factory;
+  }
+}
diff --git 
a/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/bean/TestBeanDescriptorManager.java
 
b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/bean/TestBeanDescriptorManager.java
new file mode 100644
index 0000000..dff8e42
--- /dev/null
+++ 
b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/bean/TestBeanDescriptorManager.java
@@ -0,0 +1,137 @@
+/*
+ * 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.servicecomb.foundation.protobuf.internal.bean;
+
+import java.lang.reflect.Method;
+
+import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class TestBeanDescriptorManager {
+  public static class Model {
+    private int both;
+
+    private int onlyGet;
+
+    private int onlySet;
+
+    public int direct;
+
+    public int getBoth() {
+      return both;
+    }
+
+    public void setBoth(int both) {
+      this.both = both;
+    }
+
+    public int getOnlyGet() {
+      return onlyGet;
+    }
+
+    public void onlyGet(int value) {
+      this.onlyGet = value;
+    }
+
+    public void setOnlySet(int onlySet) {
+      this.onlySet = onlySet;
+    }
+
+    public int onlySet() {
+      return onlySet;
+    }
+  }
+
+  public static class CustomGeneric<T> {
+    private T value;
+
+    public T getValue() {
+      return value;
+    }
+
+    public void setValue(T value) {
+      this.value = value;
+    }
+  }
+
+  public static class GenericSchema {
+    public CustomGeneric<Model> genericMethod(CustomGeneric<String> input) {
+      return null;
+    }
+  }
+
+  static ObjectMapper mapper = new ObjectMapper();
+
+  static BeanDescriptorManager beanDescriptorManager = new 
BeanDescriptorManager(mapper.getSerializationConfig());
+
+  static BeanDescriptor beanDescriptor = 
beanDescriptorManager.getOrCreateBeanDescriptor(Model.class);
+
+  Model model = new Model();
+
+  @Test
+  public void generic() {
+    Method method = ReflectUtils.findMethod(GenericSchema.class, 
"genericMethod");
+    BeanDescriptor beanDescriptor = beanDescriptorManager
+        .getOrCreateBeanDescriptor(method.getGenericParameterTypes()[0]);
+
+    Assert.assertEquals(String.class, 
beanDescriptor.getPropertyDescriptors().get("value").getJavaType().getRawClass());
+  }
+
+  @Test
+  public void getOrCreate() {
+    Assert.assertSame(beanDescriptor, 
beanDescriptorManager.getOrCreateBeanDescriptor(Model.class));
+    Assert.assertSame(Model.class, beanDescriptor.getJavaType().getRawClass());
+  }
+
+  @Test
+  public void both() throws Throwable {
+    PropertyDescriptor propertyDescriptor = 
beanDescriptor.getPropertyDescriptors().get("both");
+    propertyDescriptor.getSetter().set(model, 1);
+    Assert.assertEquals(1, propertyDescriptor.getGetter().get(model));
+    Assert.assertEquals(1, model.getBoth());
+  }
+
+  @Test
+  public void onlyGet() throws Throwable {
+    PropertyDescriptor propertyDescriptor = 
beanDescriptor.getPropertyDescriptors().get("onlyGet");
+    Assert.assertNull(propertyDescriptor.getSetter());
+
+    model.onlyGet(1);
+    Assert.assertEquals(1, propertyDescriptor.getGetter().get(model));
+    Assert.assertEquals(1, model.getOnlyGet());
+  }
+
+  @Test
+  public void onlySet() throws Throwable {
+    PropertyDescriptor propertyDescriptor = 
beanDescriptor.getPropertyDescriptors().get("onlySet");
+    Assert.assertNull(propertyDescriptor.getGetter());
+
+    propertyDescriptor.getSetter().set(model, 1);
+    Assert.assertEquals(1, model.onlySet());
+  }
+
+  @Test
+  public void direct() throws Throwable {
+    PropertyDescriptor propertyDescriptor = 
beanDescriptor.getPropertyDescriptors().get("direct");
+    propertyDescriptor.getSetter().set(model, 1);
+    Assert.assertEquals(1, propertyDescriptor.getGetter().get(model));
+    Assert.assertEquals(1, model.direct);
+  }
+}
diff --git a/pom.xml b/pom.xml
index d161bd4..1aedd7e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -162,6 +162,8 @@
             <!-- Skip the source files which are forked from vertx -->
             <exclude>**/io/vertx/ext/web/impl/MimeTypesUtils.java</exclude>
             
<exclude>**/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java</exclude>
+            <!--Skip protobuf generated file-->
+            
<exclude>**/java/org/apache/servicecomb/foundation/protobuf/internal/model/ProtobufRoot.java</exclude>
           </excludes>
         </configuration>
       </plugin>

Reply via email to