You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ch...@apache.org on 2019/12/30 06:36:57 UTC
[servicecomb-toolkit] 01/02: [SCB-1676] nested complex properties
are not parsed and added to the component
This is an automated email from the ASF dual-hosted git repository.
chanjarster pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git
commit 638b269d34cd9e7e4e4c1fcb2177be1b63a31f3a
Author: kakulisen <18...@163.com>
AuthorDate: Mon Dec 23 11:45:44 2019 +0800
[SCB-1676] nested complex properties are not parsed and added to the component
Signed-off-by: kakulisen <18...@163.com>
---
.../generator/annotation/ModelInterceptor.java | 4 +-
.../toolkit/generator/util/ModelConverter.java | 60 ++++++-
.../servicecomb/toolkit/generator/UtilsTest.java | 197 ++++++++++++++++++++-
.../generator/MultipartFileInterceptor.java | 4 +-
4 files changed, 260 insertions(+), 5 deletions(-)
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java
index 8415e1a..c6c8954 100644
--- a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.toolkit.generator.annotation;
+import java.lang.reflect.Type;
+
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.Schema;
@@ -24,5 +26,5 @@ public interface ModelInterceptor {
int order();
- Schema process(Class<?> cls, Components components);
+ Schema process(Type cls, Components components);
}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java
index 307863d..ae3f9e4 100644
--- a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java
@@ -17,10 +17,16 @@
package org.apache.servicecomb.toolkit.generator.util;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.ServiceLoader;
import org.apache.servicecomb.toolkit.generator.annotation.ModelInterceptor;
@@ -37,6 +43,7 @@ import io.swagger.v3.core.util.PrimitiveType;
import io.swagger.v3.core.util.RefUtils;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.ArraySchema;
+import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
public class ModelConverter {
@@ -64,11 +71,11 @@ public class ModelConverter {
interceptorMgr.remove(interceptor);
}
- public static Schema getSchema(Class<?> cls) {
+ public static Schema getSchema(Type cls) {
return getSchema(cls, null);
}
- public static Schema getSchema(Class<?> cls, Components components) {
+ public static Schema getSchema(Type cls, Components components) {
for (ModelInterceptor interceptor : interceptorMgr) {
Schema schema = interceptor.process(cls, components);
@@ -77,16 +84,42 @@ public class ModelConverter {
}
}
+ if (cls instanceof Class) {
+ Map<String, Type> beanProperties = getBeanProperties((Class) cls);
+
+ Optional.ofNullable(beanProperties)
+ .ifPresent(properties -> properties.forEach((name, type) ->
+ {
+ if (type instanceof ParameterizedType) {
+ Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
+ Arrays.stream(actualTypeArguments).forEach(arg -> getSchema(arg, components));
+ }
+
+ if (type instanceof Class) {
+ getSchema(type, components);
+ }
+ })
+ );
+ }
+
Schema schema = PrimitiveType.createProperty(cls);
if (schema == null) {
schema = context
.resolve(new AnnotatedType(cls));
}
+ if (schema == null) {
+ if (cls == List.class) {
+ schema = new ArraySchema();
+ ((ArraySchema) schema).setItems(new ObjectSchema());
+ }
+ }
+
if (components == null) {
return schema;
}
+ // correct reference
Schema refSchema = schema;
if (shouldExtractRef(schema)) {
@@ -143,4 +176,27 @@ public class ModelConverter {
return mapper;
}
+
+ public static Map<String, Type> getBeanProperties(Class cls) {
+ if (cls.isPrimitive()) {
+ return null;
+ }
+ Method[] declaredMethods = cls.getDeclaredMethods();
+ Map<String, Type> beanProperties = new HashMap<>();
+
+ for (Method method : declaredMethods) {
+ if (method.getName().startsWith("get")) {
+ if (method.getReturnType() != null && method.getReturnType() != void.class) {
+ String propName = method.getName().substring(3);
+ try {
+ cls.getDeclaredMethod("set" + propName, method.getReturnType());
+ beanProperties.put(method.getName(), method.getGenericReturnType());
+ } catch (NoSuchMethodException e) {
+ continue;
+ }
+ }
+ }
+ }
+ return beanProperties;
+ }
}
diff --git a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java
index 1ef65d1..6aab6b9 100644
--- a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java
+++ b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
import java.util.List;
import org.apache.servicecomb.toolkit.generator.annotation.ModelInterceptor;
@@ -74,7 +75,7 @@ public class UtilsTest {
}
@Override
- public Schema process(Class<?> cls, Components components) {
+ public Schema process(Type cls, Components components) {
return new Schema().name("unknown");
}
};
@@ -83,6 +84,55 @@ public class UtilsTest {
schema = ModelConverter.getSchema(ParameterClass.class);
Assert.assertEquals("unknown", schema.getName());
ModelConverter.unRegisterInterceptor(mockModelInterceptor);
+
+ Components component = new Components();
+ ModelConverter.getSchema(BeanClass.class, component);
+ Assert.assertNotNull(component.getSchemas().get("Value"));
+
+ Schema beanClass = component.getSchemas().get("BeanClass");
+ Assert.assertNotNull(beanClass);
+ Schema valueRef = (Schema) beanClass.getProperties().get("value");
+ Assert.assertEquals("#/components/schemas/Value", valueRef.get$ref());
+
+ Schema intVal = (Schema) beanClass.getProperties().get("intVal");
+ Assert.assertEquals("int32", intVal.getFormat());
+ Assert.assertEquals("integer", intVal.getType());
+
+ Schema intObj = (Schema) beanClass.getProperties().get("intObj");
+ Assert.assertEquals("int32", intObj.getFormat());
+ Assert.assertEquals("integer", intObj.getType());
+
+ Schema longVal = (Schema) beanClass.getProperties().get("longVal");
+ Assert.assertEquals("int64", longVal.getFormat());
+ Assert.assertEquals("integer", longVal.getType());
+
+ Schema longObj = (Schema) beanClass.getProperties().get("longObj");
+ Assert.assertEquals("int64", longObj.getFormat());
+ Assert.assertEquals("integer", longObj.getType());
+
+ Schema doubleVal = (Schema) beanClass.getProperties().get("doubleVal");
+ Assert.assertEquals("double", doubleVal.getFormat());
+ Assert.assertEquals("number", doubleVal.getType());
+
+ Schema doubleObj = (Schema) beanClass.getProperties().get("doubleObj");
+ Assert.assertEquals("double", doubleObj.getFormat());
+ Assert.assertEquals("number", doubleObj.getType());
+
+ Schema props = (Schema) beanClass.getProperties().get("props");
+ Assert.assertEquals(ArraySchema.class, props.getClass());
+ Assert.assertEquals("array", props.getType());
+ Assert.assertEquals("string", ((ArraySchema) props).getItems().getType());
+
+ Schema numbers = (Schema) beanClass.getProperties().get("numbers");
+ Assert.assertEquals(ArraySchema.class, numbers.getClass());
+ Assert.assertEquals("array", numbers.getType());
+ Assert.assertEquals("integer", ((ArraySchema) numbers).getItems().getType());
+ Assert.assertEquals("int32", ((ArraySchema) numbers).getItems().getFormat());
+
+ Schema values = (Schema) beanClass.getProperties().get("values");
+ Assert.assertEquals(ArraySchema.class, values.getClass());
+ Assert.assertEquals("array", values.getType());
+ Assert.assertEquals("#/components/schemas/Value", ((ArraySchema) values).getItems().get$ref());
}
@Test
@@ -99,4 +149,149 @@ public class UtilsTest {
public void method(String param) {
}
}
+
+ class BeanClass {
+
+ private String name;
+
+ private int intVal;
+
+ private long longVal;
+
+ private double doubleVal;
+
+ private Integer intObj;
+
+ private Long longObj;
+
+ private Double doubleObj;
+
+ private Value value;
+
+ List<String> props;
+
+ List<Integer> numbers;
+
+ List<Value> values;
+
+ List list;
+
+ public List getList() {
+ return list;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+
+ public int getIntVal() {
+ return intVal;
+ }
+
+ public void setIntVal(int intVal) {
+ this.intVal = intVal;
+ }
+
+ public long getLongVal() {
+ return longVal;
+ }
+
+ public void setLongVal(long longVal) {
+ this.longVal = longVal;
+ }
+
+ public double getDoubleVal() {
+ return doubleVal;
+ }
+
+ public void setDoubleVal(double doubleVal) {
+ this.doubleVal = doubleVal;
+ }
+
+ public Integer getIntObj() {
+ return intObj;
+ }
+
+ public void setIntObj(Integer intObj) {
+ this.intObj = intObj;
+ }
+
+ public Long getLongObj() {
+ return longObj;
+ }
+
+ public void setLongObj(Long longObj) {
+ this.longObj = longObj;
+ }
+
+ public Double getDoubleObj() {
+ return doubleObj;
+ }
+
+ public void setDoubleObj(Double doubleObj) {
+ this.doubleObj = doubleObj;
+ }
+
+ public List<Value> getValues() {
+ return values;
+ }
+
+ public void setValues(List<Value> values) {
+ this.values = values;
+ }
+
+ public List<Integer> getNumbers() {
+ return numbers;
+ }
+
+ public void setNumbers(List<Integer> numbers) {
+ this.numbers = numbers;
+ }
+
+ public List<String> getProps() {
+ return props;
+ }
+
+ public void setProps(List<String> props) {
+ this.props = props;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Value getValue() {
+ return value;
+ }
+
+ public void setValue(Value value) {
+ this.value = value;
+ }
+ }
+
+ class Value {
+ private String prop1;
+
+ private String prop2;
+
+ public String getProp1() {
+ return prop1;
+ }
+
+ public void setProp1(String prop1) {
+ this.prop1 = prop1;
+ }
+
+ public String getProp2() {
+ return prop2;
+ }
+
+ public void setProp2(String prop2) {
+ this.prop2 = prop2;
+ }
+ }
}
diff --git a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/MultipartFileInterceptor.java b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/MultipartFileInterceptor.java
index 4857143..a5c2a92 100644
--- a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/MultipartFileInterceptor.java
+++ b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/MultipartFileInterceptor.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.toolkit.generator;
+import java.lang.reflect.Type;
+
import org.apache.servicecomb.toolkit.generator.annotation.ModelInterceptor;
import org.apache.servicecomb.toolkit.generator.util.ModelConverter;
import org.springframework.web.multipart.MultipartFile;
@@ -33,7 +35,7 @@ public class MultipartFileInterceptor implements ModelInterceptor {
}
@Override
- public Schema process(Class<?> cls, Components components) {
+ public Schema process(Type cls, Components components) {
if (!MultipartFile.class.equals(cls)) {
return null;