package io.swagger.model.override; import io.swagger.converter.ModelConverter; import io.swagger.converter.ModelConverterContext; import io.swagger.converter.ModelConverters; import io.swagger.matchers.SerializationMatchers; import io.swagger.models.Model; import io.swagger.models.ModelImpl; import io.swagger.models.properties.Property; import io.swagger.models.properties.RefProperty; import com.google.common.collect.Sets; import org.testng.annotations.Test; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; public class SnakeCaseConverterTest { @Test(description = "it should change naming style") public void testConvert() { // add the custom converter final SnakeCaseConverter snakeCaseConverter = new SnakeCaseConverter(); final ModelConverters converters = new ModelConverters(); converters.addConverter(snakeCaseConverter); final Map<String, Model> models = converters.readAll(SnakeCaseModel.class); final String json = "{" + " \"bar\":{" + " \"type\":\"object\"," + " \"properties\":{" + " \"foo\":{" + " \"type\":\"string\"" + " }" + " }" + " }," + " \"snake_case_model\":{" + " \"type\":\"object\"," + " \"properties\":{" + " \"bar\":{" + " \"$ref\":\"#/definitions/bar\"" + " }," + " \"title\":{" + " \"type\":\"string\"" + " }" + " }," + " \"xml\":{" + " \"name\":\"snakeCaseModel\"" + " }" + " }" + "}"; SerializationMatchers.assertEqualsToJson(models, json); } @XmlRootElement(name = "snakeCaseModel") class SnakeCaseModel { public Bar bar = null; public String title = null; } /** * simple converter to rename models and field names into snake_case */ class SnakeCaseConverter implements ModelConverter { final Set<String> primitives = Sets.newHashSet("string", "integer", "number", "boolean", "long"); @Override public Property resolveProperty(Type type, ModelConverterContext context, Annotation[] annotations, Iterator<ModelConverter> chain) { if (chain.hasNext()) { final ModelConverter converter = chain.next(); return converter.resolveProperty(type, context, annotations, chain); } return null; } @Override public Model resolve(Type type, ModelConverterContext context, Iterator<ModelConverter> chain) { if (chain.hasNext()) { final ModelConverter converter = chain.next(); final Model model = converter.resolve(type, context, chain); if (model != null) { final Map<String, Property> properties = model.getProperties(); final Map<String, Property> updatedProperties = new LinkedHashMap<String, Property>(); for (String key : properties.keySet()) { String convertedKey = toSnakeCase(key); Property prop = properties.get(key); if (prop instanceof RefProperty) { RefProperty ref = (RefProperty) prop; ref.set$ref(toSnakeCase(ref.getSimpleRef())); } updatedProperties.put(convertedKey, prop); } model.getProperties().clear(); model.setProperties(updatedProperties); if (model instanceof ModelImpl) { ModelImpl impl = (ModelImpl) model; String prevName = impl.getName(); impl.setName(toSnakeCase(impl.getName())); context.defineModel(impl.getName(), impl, type, prevName); } return model; } } return null; } private String toSnakeCase(String str) { String o = str.replaceAll("[A-Z\\d]", "_"+ "$0").toLowerCase(); if (o.startsWith("_")) { return o.substring(1); } else { return o; } } } class Bar { public String foo = null; } }