Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ public Model resolve(JavaType type, ModelConverterContext context, Iterator<Mode
annotations = annotationList.toArray(new Annotation[annotationList.size()]);

ApiModelProperty mp = member.getAnnotation(ApiModelProperty.class);

if(mp != null && mp.readOnly()) {
isReadOnly = mp.readOnly();
}
Expand Down Expand Up @@ -650,15 +650,22 @@ private boolean resolveSubtypes(ModelImpl model, BeanDescription bean, ModelConv
int count = 0;
final Class<?> beanClass = bean.getClassInfo().getAnnotated();
for (NamedType subtype : types) {
if (!beanClass.isAssignableFrom(subtype.getType())) {
final Class<?> subtypeType = subtype.getType();
if (!beanClass.isAssignableFrom(subtypeType)) {
continue;
}

final Model subtypeModel = context.resolve(subtype.getType());
final Model subtypeModel = context.resolve(subtypeType);

if (subtypeModel instanceof ModelImpl) {
final ModelImpl impl = (ModelImpl) subtypeModel;

// check if model name was inherited
if (impl.getName().equals(model.getName())) {
impl.setName(_typeNameResolver.nameForType(_mapper.constructType(subtypeType),
TypeNameResolver.Options.SKIP_API_MODEL));
}

// remove shared properties defined in the parent
final Map<String, Property> baseProps = model.getProperties();
final Map<String, Property> subtypeProps = impl.getProperties();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package io.swagger.jackson;

import com.fasterxml.jackson.databind.JavaType;
import io.swagger.annotations.ApiModel;
import io.swagger.util.PrimitiveType;

import com.fasterxml.jackson.databind.JavaType;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

/**
* Helper class used for converting well-known (property) types into
* Swagger type names.
Expand All @@ -16,30 +22,39 @@ public class TypeNameResolver {
protected TypeNameResolver() {
}

public String nameForType(JavaType type) {
public String nameForType(JavaType type, Options... options) {
return nameForType(type, options.length == 0 ? Collections.<Options>emptySet() :
EnumSet.copyOf(Arrays.asList(options)));
}

public String nameForType(JavaType type, Set<Options> options) {
if (type.hasGenericTypes()) {
return nameForGenericType(type);
return nameForGenericType(type, options);
}
final String name = findStdName(type);
return (name == null) ? nameForClass(type) : name;
return (name == null) ? nameForClass(type, options) : name;
}

protected String nameForClass(JavaType type) {
return nameForClass(type.getRawClass());
protected String nameForClass(JavaType type, Set<Options> options) {
return nameForClass(type.getRawClass(), options);
}

protected String nameForClass(Class<?> cls) {
protected String nameForClass(Class<?> cls, Set<Options> options) {
if (options.contains(Options.SKIP_API_MODEL)) {
return cls.getSimpleName();
}
final ApiModel model = cls.getAnnotation(ApiModel.class);
final String modelName = model == null ? null : StringUtils.trimToNull(model.value());
return modelName == null ? cls.getSimpleName() : modelName;
}

protected String nameForGenericType(JavaType type) {
final StringBuilder generic = new StringBuilder(nameForClass(type));
protected String nameForGenericType(JavaType type, Set<Options> options) {
final StringBuilder generic = new StringBuilder(nameForClass(type, options));
final int count = type.containedTypeCount();
for (int i = 0; i < count; ++i) {
final JavaType arg = type.containedType(i);
final String argName = PrimitiveType.fromType(arg) != null ? nameForClass(arg) : nameForType(arg);
final String argName = PrimitiveType.fromType(arg) != null ? nameForClass(arg, options) :
nameForType(arg, options);
generic.append(WordUtils.capitalize(argName));
}
return generic.toString();
Expand All @@ -48,4 +63,8 @@ protected String nameForGenericType(JavaType type) {
protected String findStdName(JavaType type) {
return PrimitiveType.getCommonName(type);
}

public enum Options {
SKIP_API_MODEL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import io.swagger.models.ModelWithNumbers;
import io.swagger.models.ModelWithTuple2;
import io.swagger.models.Person;
import io.swagger.models.composition.AbstractModelWithApiModel;
import io.swagger.models.composition.ModelWithUrlProperty;
import io.swagger.models.composition.Pet;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BaseIntegerProperty;
Expand Down Expand Up @@ -100,6 +102,19 @@ public void honorApiModelName() {
assertEquals(model, "MyModel");
}

@Test(description = "it should override an inherited model's name")
public void overrideInheritedModelName() {
final Map<String, Model> rootSchemas = readAll(AbstractModelWithApiModel.class);
assertEquals(rootSchemas.size(), 3);
assertTrue(rootSchemas.containsKey("MyProperty"));
assertTrue(rootSchemas.containsKey("ModelWithUrlProperty"));
assertTrue(rootSchemas.containsKey("ModelWithValueProperty"));

final Map<String, Model> nestedSchemas = readAll(ModelWithUrlProperty.class);
assertEquals(nestedSchemas.size(), 1);
assertTrue(nestedSchemas.containsKey("MyProperty"));
}

@Test(description = "it should maintain property names")
public void maintainPropertyNames() {
final Map<String, Model> schemas = readAll(ModelPropertyName.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.swagger.models.composition;

import io.swagger.annotations.ApiModel;

import com.fasterxml.jackson.annotation.JsonSubTypes;

@ApiModel("MyProperty")
@JsonSubTypes({@JsonSubTypes.Type(value = ModelWithUrlProperty.class), @JsonSubTypes.Type(value = ModelWithValueProperty.class)})
public abstract class AbstractModelWithApiModel {

private final String type;

protected AbstractModelWithApiModel(String type) {
this.type = type;
}

public String getType() {
return type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.swagger.models.composition;

import java.net.MalformedURLException;
import java.net.URL;

public class ModelWithUrlProperty extends AbstractModelWithApiModel {

private final URL url;

public ModelWithUrlProperty(String type, String url) {
super(type);
try {
this.url = new URL(url);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}

public URL getUrl() {
return url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.swagger.models.composition;

public class ModelWithValueProperty extends AbstractModelWithApiModel {

private final String value;

public ModelWithValueProperty(String type, String value) {
super(type);
this.value = value;
}

public String getValue() {
return value;
}
}