This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch weak-contract-type in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit 875ae6e8349b52928b2209ffc17be8f704d5336c Author: wujimin <[email protected]> AuthorDate: Fri Jun 28 00:49:43 2019 +0800 [SCB-1328][WIP][WEAK] restore old Converter code, and replace all dynamic class to Object.class --- .../swagger/converter/AbstractConverter.java | 55 ++++++ .../servicecomb/swagger/converter/Converter.java | 33 ++++ .../swagger/converter/ConverterMgr.java | 171 ++++++++++++++++++ .../converter/model/AbstractModelConverter.java | 30 ++++ .../converter/model/ArrayModelConverter.java | 39 ++++ .../converter/model/ModelImplConverter.java | 48 +++++ .../swagger/converter/model/RefModelConverter.java | 30 ++++ .../property/AbstractPropertyConverter.java | 30 ++++ .../converter/property/ArrayPropertyConverter.java | 51 ++++++ .../converter/property/MapPropertyConverter.java | 43 +++++ .../property/ObjectPropertyConverter.java | 30 ++++ .../converter/property/RefPropertyConverter.java | 30 ++++ .../property/StringPropertyConverter.java | 50 ++++++ .../property/SwaggerParamCollectionFormat.java | 102 +++++++++++ .../swagger/extend/ModelResolverExt.java | 8 +- .../property/SwaggerParamCollectionFormatTest.java | 200 +++++++++++++++++++++ 16 files changed, 944 insertions(+), 6 deletions(-) diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/AbstractConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/AbstractConverter.java new file mode 100644 index 0000000..90ad109 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/AbstractConverter.java @@ -0,0 +1,55 @@ +/* + * 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.swagger.converter; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.swagger.SwaggerUtils; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import io.swagger.models.Swagger; + +public abstract class AbstractConverter implements Converter { + protected abstract Map<String, Object> findVendorExtensions(Object def); + + protected abstract JavaType doConvert(Swagger swagger, Object def); + + protected JavaType convertRef(Swagger swagger, String ref) { + Object def = swagger.getDefinitions().get(ref); + return ConverterMgr.findJavaType(swagger, def); + } + + @Override + public JavaType convert(Swagger swagger, Object def) { + Map<String, Object> vendorExtensions = findVendorExtensions(def); + String canonical = SwaggerUtils.getClassName(vendorExtensions); + if (StringUtils.isEmpty(canonical)) { + return doConvert(swagger, def); + } + + try { + return TypeFactory.defaultInstance().constructFromCanonical(canonical); + } catch (Throwable e) { + // type not exist + return OBJECT_JAVA_TYPE; + } + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/Converter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/Converter.java new file mode 100644 index 0000000..94d61d0 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/Converter.java @@ -0,0 +1,33 @@ +/* + * 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.swagger.converter; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import io.swagger.models.Swagger; + +public interface Converter { + static final JavaType OBJECT_JAVA_TYPE = TypeFactory.defaultInstance().constructType(Object.class); + + static final JavaType STRING_JAVA_TYPE = TypeFactory.defaultInstance().constructType(String.class); + + // def can be property or model + // def can not be null + JavaType convert(Swagger swagger, Object def); +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java new file mode 100644 index 0000000..0d96aed --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java @@ -0,0 +1,171 @@ +/* + * 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.swagger.converter; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.Part; + +import org.apache.servicecomb.swagger.converter.model.ArrayModelConverter; +import org.apache.servicecomb.swagger.converter.model.ModelImplConverter; +import org.apache.servicecomb.swagger.converter.model.RefModelConverter; +import org.apache.servicecomb.swagger.converter.property.ArrayPropertyConverter; +import org.apache.servicecomb.swagger.converter.property.MapPropertyConverter; +import org.apache.servicecomb.swagger.converter.property.ObjectPropertyConverter; +import org.apache.servicecomb.swagger.converter.property.RefPropertyConverter; +import org.apache.servicecomb.swagger.converter.property.StringPropertyConverter; +import org.apache.servicecomb.swagger.extend.property.ByteProperty; +import org.apache.servicecomb.swagger.extend.property.ShortProperty; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import io.swagger.models.ArrayModel; +import io.swagger.models.ModelImpl; +import io.swagger.models.RefModel; +import io.swagger.models.Swagger; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.BaseIntegerProperty; +import io.swagger.models.properties.BooleanProperty; +import io.swagger.models.properties.ByteArrayProperty; +import io.swagger.models.properties.DateProperty; +import io.swagger.models.properties.DateTimeProperty; +import io.swagger.models.properties.DecimalProperty; +import io.swagger.models.properties.DoubleProperty; +import io.swagger.models.properties.FileProperty; +import io.swagger.models.properties.FloatProperty; +import io.swagger.models.properties.IntegerProperty; +import io.swagger.models.properties.LongProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.ObjectProperty; +import io.swagger.models.properties.Property; +import io.swagger.models.properties.RefProperty; +import io.swagger.models.properties.StringProperty; + +public final class ConverterMgr { + private static final JavaType VOID_JAVA_TYPE = TypeFactory.defaultInstance().constructType(Void.class); + + private static final Map<Class<? extends Property>, JavaType> PROPERTY_MAP = new HashMap<>(); + + // key is "type.format" of standard swagger data type + // value is related java class + private static final Map<String, JavaType> TYPE_FORMAT_MAP = new HashMap<>(); + + private static Map<Class<?>, Converter> converterMap = new HashMap<>(); + + static { + initPropertyMap(); + initTypeFormatMap(); + initConverters(); + } + + private static String genTypeFormatKey(String type, String format) { + return type + ":" + format; + } + + private ConverterMgr() { + + } + + private static void initTypeFormatMap() { + try { + for (Entry<Class<? extends Property>, JavaType> entry : PROPERTY_MAP.entrySet()) { + Property property = entry.getKey().newInstance(); + String key = genTypeFormatKey(property.getType(), property.getFormat()); + TYPE_FORMAT_MAP.put(key, entry.getValue()); + } + } catch (Throwable e) { + throw new Error(e); + } + } + + private static void initPropertyMap() { + PROPERTY_MAP.put(BooleanProperty.class, TypeFactory.defaultInstance().constructType(Boolean.class)); + + PROPERTY_MAP.put(FloatProperty.class, TypeFactory.defaultInstance().constructType(Float.class)); + PROPERTY_MAP.put(DoubleProperty.class, TypeFactory.defaultInstance().constructType(Double.class)); + PROPERTY_MAP.put(DecimalProperty.class, TypeFactory.defaultInstance().constructType(BigDecimal.class)); + + PROPERTY_MAP.put(ByteProperty.class, TypeFactory.defaultInstance().constructType(Byte.class)); + PROPERTY_MAP.put(ShortProperty.class, TypeFactory.defaultInstance().constructType(Short.class)); + PROPERTY_MAP.put(IntegerProperty.class, TypeFactory.defaultInstance().constructType(Integer.class)); + PROPERTY_MAP.put(BaseIntegerProperty.class, TypeFactory.defaultInstance().constructType(Integer.class)); + PROPERTY_MAP.put(LongProperty.class, TypeFactory.defaultInstance().constructType(Long.class)); + + // stringProperty include enum scenes, not always be string type + // if convert by StringPropertyConverter, can support enum scenes + PROPERTY_MAP.put(StringProperty.class, TypeFactory.defaultInstance().constructType(String.class)); + + PROPERTY_MAP.put(DateProperty.class, TypeFactory.defaultInstance().constructType(LocalDate.class)); + PROPERTY_MAP.put(DateTimeProperty.class, TypeFactory.defaultInstance().constructType(Date.class)); + + PROPERTY_MAP.put(ByteArrayProperty.class, TypeFactory.defaultInstance().constructType(byte[].class)); + + PROPERTY_MAP.put(FileProperty.class, TypeFactory.defaultInstance().constructType(Part.class)); + } + + private static void initConverters() { + // inner converters + for (Class<? extends Property> propertyCls : PROPERTY_MAP.keySet()) { + addInnerConverter(propertyCls); + } + + converterMap.put(RefProperty.class, new RefPropertyConverter()); + converterMap.put(ArrayProperty.class, new ArrayPropertyConverter()); + converterMap.put(MapProperty.class, new MapPropertyConverter()); + converterMap.put(StringProperty.class, new StringPropertyConverter()); + converterMap.put(ObjectProperty.class, new ObjectPropertyConverter()); + + converterMap.put(ModelImpl.class, new ModelImplConverter()); + converterMap.put(RefModel.class, new RefModelConverter()); + converterMap.put(ArrayModel.class, new ArrayModelConverter()); + } + + private static void addInnerConverter(Class<? extends Property> propertyCls) { + JavaType javaType = PROPERTY_MAP.get(propertyCls); + if (javaType == null) { + throw new Error("not support inner property class: " + propertyCls.getName()); + } + + converterMap.put(propertyCls, (swagger, def) -> javaType); + } + + public static JavaType findJavaType(String type, String format) { + String key = genTypeFormatKey(type, format); + return TYPE_FORMAT_MAP.get(key); + } + + // def is null means void scene + // def can be model or property + public static JavaType findJavaType(Swagger swagger, Object def) { + if (def == null) { + return VOID_JAVA_TYPE; + } + Converter converter = converterMap.get(def.getClass()); + if (converter == null) { + throw new Error("not support def type: " + def.getClass()); + } + + return converter.convert(swagger, def); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/AbstractModelConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/AbstractModelConverter.java new file mode 100644 index 0000000..336f54f --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/AbstractModelConverter.java @@ -0,0 +1,30 @@ +/* + * 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.swagger.converter.model; + +import java.util.Map; + +import org.apache.servicecomb.swagger.converter.AbstractConverter; + +import io.swagger.models.Model; + +public abstract class AbstractModelConverter extends AbstractConverter { + protected Map<String, Object> findVendorExtensions(Object def) { + return ((Model) def).getVendorExtensions(); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ArrayModelConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ArrayModelConverter.java new file mode 100644 index 0000000..0ef81bd --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ArrayModelConverter.java @@ -0,0 +1,39 @@ +/* + * 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.swagger.converter.model; + +import org.apache.servicecomb.swagger.converter.property.ArrayPropertyConverter; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.ArrayModel; +import io.swagger.models.Swagger; + +public class ArrayModelConverter extends AbstractModelConverter { + @Override + public JavaType doConvert(Swagger swagger, Object model) { + ArrayModel arrayModel = (ArrayModel) model; + + if (arrayModel.getItems() != null) { + return ArrayPropertyConverter.findJavaType(swagger, arrayModel.getItems(), false); + } + + // don't know when will this happen. + throw new IllegalStateException("not support null array model items."); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java new file mode 100644 index 0000000..9c0290b --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java @@ -0,0 +1,48 @@ +/* + * 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.swagger.converter.model; + +import org.apache.servicecomb.swagger.converter.ConverterMgr; +import org.apache.servicecomb.swagger.converter.property.MapPropertyConverter; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.ModelImpl; +import io.swagger.models.Swagger; + +public class ModelImplConverter extends AbstractModelConverter { + @Override + public JavaType doConvert(Swagger swagger, Object model) { + ModelImpl modelImpl = (ModelImpl) model; + + JavaType javaType = ConverterMgr.findJavaType(modelImpl.getType(), modelImpl.getFormat()); + if (javaType != null) { + return javaType; + } + + if (modelImpl.getReference() != null) { + return convertRef(swagger, modelImpl.getReference()); + } + + if (modelImpl.getAdditionalProperties() != null) { + return MapPropertyConverter.findJavaType(swagger, modelImpl.getAdditionalProperties()); + } + + return OBJECT_JAVA_TYPE; + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/RefModelConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/RefModelConverter.java new file mode 100644 index 0000000..d9e4169 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/RefModelConverter.java @@ -0,0 +1,30 @@ +/* + * 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.swagger.converter.model; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.RefModel; +import io.swagger.models.Swagger; + +public class RefModelConverter extends AbstractModelConverter { + @Override + public JavaType doConvert(Swagger swagger, Object refModel) { + return convertRef(swagger, ((RefModel) refModel).getSimpleRef()); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/AbstractPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/AbstractPropertyConverter.java new file mode 100644 index 0000000..0998fc3 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/AbstractPropertyConverter.java @@ -0,0 +1,30 @@ +/* + * 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.swagger.converter.property; + +import java.util.Map; + +import org.apache.servicecomb.swagger.converter.AbstractConverter; + +import io.swagger.models.properties.Property; + +public abstract class AbstractPropertyConverter extends AbstractConverter { + protected Map<String, Object> findVendorExtensions(Object def) { + return ((Property) def).getVendorExtensions(); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ArrayPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ArrayPropertyConverter.java new file mode 100644 index 0000000..aab2ad5 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ArrayPropertyConverter.java @@ -0,0 +1,51 @@ +/* + * 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.swagger.converter.property; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.apache.servicecomb.swagger.converter.ConverterMgr; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import io.swagger.models.Swagger; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.Property; + +public class ArrayPropertyConverter extends AbstractPropertyConverter { + public static JavaType findJavaType(Swagger swagger, Property itemProperty, Boolean uniqueItems) { + JavaType itemJavaType = ConverterMgr.findJavaType(swagger, itemProperty); + + @SuppressWarnings("rawtypes") + Class<? extends Collection> collectionClass = List.class; + if (Boolean.TRUE.equals(uniqueItems)) { + collectionClass = Set.class; + } + return TypeFactory.defaultInstance().constructCollectionType(collectionClass, itemJavaType); + } + + @Override + public JavaType doConvert(Swagger swagger, Object property) { + ArrayProperty arrayProperty = (ArrayProperty) property; + + return findJavaType(swagger, arrayProperty.getItems(), arrayProperty.getUniqueItems()); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/MapPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/MapPropertyConverter.java new file mode 100644 index 0000000..ee8baa0 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/MapPropertyConverter.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.servicecomb.swagger.converter.property; + +import java.util.Map; + +import org.apache.servicecomb.swagger.converter.ConverterMgr; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import io.swagger.models.Swagger; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.Property; + +public class MapPropertyConverter extends AbstractPropertyConverter { + @Override + public JavaType doConvert(Swagger swagger, Object property) { + MapProperty mapProperty = (MapProperty) property; + Property valueProperty = mapProperty.getAdditionalProperties(); + return findJavaType(swagger, valueProperty); + } + + public static JavaType findJavaType(Swagger swagger, Property valueProperty) { + JavaType valueJavaType = ConverterMgr.findJavaType(swagger, valueProperty); + return TypeFactory.defaultInstance().constructMapType(Map.class, STRING_JAVA_TYPE, valueJavaType); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java new file mode 100644 index 0000000..4a15b47 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java @@ -0,0 +1,30 @@ +/* + * 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.swagger.converter.property; + +import org.apache.servicecomb.swagger.converter.Converter; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.Swagger; + +public class ObjectPropertyConverter implements Converter { + @Override + public JavaType convert(Swagger swagger, Object def) { + return OBJECT_JAVA_TYPE; + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/RefPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/RefPropertyConverter.java new file mode 100644 index 0000000..0cb9287 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/RefPropertyConverter.java @@ -0,0 +1,30 @@ +/* + * 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.swagger.converter.property; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.Swagger; +import io.swagger.models.properties.RefProperty; + +public class RefPropertyConverter extends AbstractPropertyConverter { + @Override + public JavaType doConvert(Swagger swagger, Object refProperty) { + return convertRef(swagger, ((RefProperty) refProperty).getSimpleRef()); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/StringPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/StringPropertyConverter.java new file mode 100644 index 0000000..1f02155 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/StringPropertyConverter.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.swagger.converter.property; + +import java.util.List; + +import org.apache.servicecomb.swagger.converter.ConverterMgr; + +import com.fasterxml.jackson.databind.JavaType; + +import io.swagger.models.Swagger; +import io.swagger.models.properties.StringProperty; + +public class StringPropertyConverter extends AbstractPropertyConverter { + + public static boolean isEnum(StringProperty stringProperty) { + return isEnum(stringProperty.getEnum()); + } + + public static boolean isEnum(List<String> enums) { + return enums != null && !enums.isEmpty(); + } + + @Override + public JavaType doConvert(Swagger swagger, Object property) { + StringProperty stringProperty = (StringProperty) property; + + List<String> enums = stringProperty.getEnum(); + if (!isEnum(enums)) { + return ConverterMgr.findJavaType(stringProperty.getType(), stringProperty.getFormat()); + } + + return OBJECT_JAVA_TYPE; + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormat.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormat.java new file mode 100644 index 0000000..3ae7aaa --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormat.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.servicecomb.swagger.converter.property; + +import java.util.Collection; + +public enum SwaggerParamCollectionFormat { + CSV("csv", ","), + SSV("ssv", " "), + TSV("tsv", "\t"), + PIPES("pipes", "|") { + @Override + public String[] splitParam(String rawParam) { + if (null == rawParam) { + return new String[0]; + } + return rawParam.split("\\|", -1); + } + }, + MULTI("multi", null) { + /** + * In fact, {@link SwaggerParamCollectionFormat#MULTI#splitParam(String)} of {@link SwaggerParamCollectionFormat#MULTI} + * should never be invoked. We just override this method to ensure it does not throw exception. + */ + @Override + public String[] splitParam(String rawParam) { + if (null == rawParam) { + return new String[0]; + } + return new String[] {rawParam}; + } + }; + + final private String collectionFormat; + + final private String separator; + + SwaggerParamCollectionFormat(String collectionFormat, String separator) { + this.collectionFormat = collectionFormat; + this.separator = separator; + } + + public String getCollectionFormat() { + return collectionFormat; + } + + public String getSeparator() { + return separator; + } + + public String[] splitParam(String rawParam) { + if (null == rawParam) { + return new String[0]; + } + return rawParam.split(separator, -1); + } + + /** + * Join params with {@link #separator}. + * Null element will be ignored since {@code null} cannot be described in query array param. + * + * @return joined params, or return {@code null} if {@code params} is null or all elements of {@code params} are null. + */ + public String joinParam(Collection<?> params) { + if (null == params || params.isEmpty()) { + return null; + } + + StringBuilder paramBuilder = new StringBuilder(); + int nullCount = 0; + for (Object param : params) { + if (param == null) { + nullCount++; + continue; + } + + paramBuilder.append(param).append(separator); + } + if (nullCount == params.size()) { + return null; + } + + paramBuilder.setLength(paramBuilder.length() - 1); + + return paramBuilder.toString(); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java index 95bc749..aa89b8c 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java @@ -23,13 +23,13 @@ import java.lang.reflect.Type; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; +import org.apache.servicecomb.swagger.converter.property.StringPropertyConverter; import org.apache.servicecomb.swagger.extend.module.EnumModuleExt; import org.apache.servicecomb.swagger.extend.property.creator.ByteArrayPropertyCreator; import org.apache.servicecomb.swagger.extend.property.creator.BytePropertyCreator; @@ -157,14 +157,10 @@ public class ModelResolverExt extends ModelResolver { Property property = super.resolveProperty(propType, context, annotations, next); if (StringProperty.class.isInstance(property)) { - if (isEnum(((StringProperty) property).getEnum())) { + if (StringPropertyConverter.isEnum((StringProperty) property)) { setType(propType, property.getVendorExtensions()); } } return property; } - - private boolean isEnum(List<String> enums) { - return enums != null && !enums.isEmpty(); - } } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormatTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormatTest.java new file mode 100644 index 0000000..5b42cd5 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/converter/property/SwaggerParamCollectionFormatTest.java @@ -0,0 +1,200 @@ +/* + * 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.swagger.converter.property; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +public class SwaggerParamCollectionFormatTest { + @Test + public void splitParamNormal() { + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam("a,b,c"), + Matchers.arrayContaining("a", "b", "c")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam("10 11 12"), + Matchers.arrayContaining("10", "11", "12")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam("a\tb\tc"), + Matchers.arrayContaining("a", "b", "c")); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam("a|b|c"), + Matchers.arrayContaining("a", "b", "c")); + } + + @Test + public void splitParamMulti() { + Assert.assertThat(SwaggerParamCollectionFormat.MULTI.splitParam("a,b,c"), + Matchers.arrayContaining("a,b,c")); + } + + @Test + public void splitParam_SingleElement() { + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam("a"), + Matchers.arrayContaining("a")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam("a"), + Matchers.arrayContaining("a")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam("a"), + Matchers.arrayContaining("a")); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam("a"), + Matchers.arrayContaining("a")); + Assert.assertThat(SwaggerParamCollectionFormat.MULTI.splitParam("a"), + Matchers.arrayContaining("a")); + } + + @Test + public void splitParam_NullElement() { + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam(null), + Matchers.emptyArray()); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam(null), + Matchers.emptyArray()); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam(null), + Matchers.emptyArray()); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam(null), + Matchers.emptyArray()); + Assert.assertThat(SwaggerParamCollectionFormat.MULTI.splitParam(null), + Matchers.emptyArray()); + } + + @Test + public void splitParam_BlankElement() { + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam(""), + Matchers.arrayContaining("")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam(""), + Matchers.arrayContaining("")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam(""), + Matchers.arrayContaining("")); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam(""), + Matchers.arrayContaining("")); + Assert.assertThat(SwaggerParamCollectionFormat.MULTI.splitParam(""), + Matchers.arrayContaining("")); + + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam("a,,b"), + Matchers.arrayContaining("a", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam("a b"), + Matchers.arrayContaining("a", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam("a\t\tb"), + Matchers.arrayContaining("a", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam("a||b"), + Matchers.arrayContaining("a", "", "b")); + + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam("a,,"), + Matchers.arrayContaining("a", "", "")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam("a "), + Matchers.arrayContaining("a", "", "")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam("a\t\t"), + Matchers.arrayContaining("a", "", "")); + String[] actual = SwaggerParamCollectionFormat.PIPES.splitParam("a||"); + Assert.assertThat(Arrays.toString(actual), actual, + Matchers.arrayContaining("a", "", "")); + + Assert.assertThat(SwaggerParamCollectionFormat.CSV.splitParam(",,b"), + Matchers.arrayContaining("", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.SSV.splitParam(" b"), + Matchers.arrayContaining("", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.TSV.splitParam("\t\tb"), + Matchers.arrayContaining("", "", "b")); + Assert.assertThat(SwaggerParamCollectionFormat.PIPES.splitParam("||b"), + Matchers.arrayContaining("", "", "b")); + } + + @Test + public void joinNormal() { + List<String> params = Arrays.asList("a", "b", "c"); + assertEquals("a,b,c", SwaggerParamCollectionFormat.CSV.joinParam(params)); + assertEquals("a b c", SwaggerParamCollectionFormat.SSV.joinParam(params)); + assertEquals("a\tb\tc", SwaggerParamCollectionFormat.TSV.joinParam(params)); + assertEquals("a|b|c", SwaggerParamCollectionFormat.PIPES.joinParam(params)); + } + + @Test + public void join_SingleElement() { + List<String> params = Collections.singletonList("a"); + assertEquals("a", SwaggerParamCollectionFormat.CSV.joinParam(params)); + assertEquals("a", SwaggerParamCollectionFormat.SSV.joinParam(params)); + assertEquals("a", SwaggerParamCollectionFormat.TSV.joinParam(params)); + assertEquals("a", SwaggerParamCollectionFormat.PIPES.joinParam(params)); + } + + @Test + public void join_EmptyArray() { + Assert.assertNull(SwaggerParamCollectionFormat.CSV.joinParam(Collections.EMPTY_LIST)); + } + + @Test + public void join_NullAndBlankElement() { + Assert.assertNull(SwaggerParamCollectionFormat.CSV.joinParam(Collections.singletonList(null))); + + assertEquals("", SwaggerParamCollectionFormat.CSV.joinParam(Collections.singleton(""))); + assertEquals("a,,b,c", SwaggerParamCollectionFormat.CSV.joinParam(Arrays.asList("a", "", "b", "c"))); + assertEquals("a b c", SwaggerParamCollectionFormat.SSV.joinParam(Arrays.asList("a", "", "b", "c"))); + assertEquals("a\t\tb\tc", SwaggerParamCollectionFormat.TSV.joinParam(Arrays.asList("a", "", "b", "c"))); + assertEquals("a||b|c", SwaggerParamCollectionFormat.PIPES.joinParam(Arrays.asList("a", "", "b", "c"))); + + assertEquals("a,b,,c", + SwaggerParamCollectionFormat.CSV + .joinParam(Arrays.asList(null, "a", null, "b", null, "", null, null, "c", null))); + assertEquals("a b c", + SwaggerParamCollectionFormat.SSV + .joinParam(Arrays.asList(null, "a", null, "b", null, "", null, null, "c", null))); + assertEquals("a\tb\t\tc", + SwaggerParamCollectionFormat.TSV + .joinParam(Arrays.asList(null, "a", null, "b", null, "", null, null, "c", null))); + assertEquals("a|b||c", + SwaggerParamCollectionFormat.PIPES + .joinParam(Arrays.asList(null, "a", null, "b", null, "", null, null, "c", null))); + + assertEquals("a,b,,c", + SwaggerParamCollectionFormat.CSV + .joinParam(Arrays.asList(null, null, "a", null, "b", null, "", null, null, "c", null, null))); + assertEquals("a b c", + SwaggerParamCollectionFormat.SSV + .joinParam(Arrays.asList(null, null, "a", null, "b", null, "", null, null, "c", null, null))); + assertEquals("a\tb\t\tc", + SwaggerParamCollectionFormat.TSV + .joinParam(Arrays.asList(null, null, "a", null, "b", null, "", null, null, "c", null, null))); + assertEquals("a|b||c", + SwaggerParamCollectionFormat.PIPES + .joinParam(Arrays.asList(null, null, "a", null, "b", null, "", null, null, "c", null, null))); + } + + @Test + public void join_NullArray() { + assertNull(SwaggerParamCollectionFormat.CSV.joinParam(null)); + } + + /** + * In fact, the {@link SwaggerParamCollectionFormat#joinParam(Collection)} of {@link SwaggerParamCollectionFormat#MULTI} + * should never be invoked. + * This test is just for ensuring the method does not throw exception. + */ + @Test + public void joinMulti() { + SwaggerParamCollectionFormat.MULTI.joinParam(Arrays.asList("a", "b", "c")); + SwaggerParamCollectionFormat.MULTI.joinParam(Collections.singletonList("a")); + assertNull(SwaggerParamCollectionFormat.MULTI.joinParam(new ArrayList<String>())); + assertNull(SwaggerParamCollectionFormat.MULTI.joinParam(Collections.singleton(null))); + assertNull(SwaggerParamCollectionFormat.MULTI.joinParam(null)); + } +} \ No newline at end of file
