Currently there doesn't seem to be any support for the swagger v2 discriminator attribute when reading an entity. I think the expectation would be that we first read in the discriminator field, then read the rest of the object based on this field. Not sure where best to put this but have been playing around with some custom JsonDeserializers.
Representing the Test Steps from https://www.runscope.com/docs/api/steps, I have Step/RequestStep/ConditionStep/PauseStep. I found two options so far which are below. Both seem roughly equivalent in terms of complexity and code size.
Option 1
The addition of a custom deserializer:
public class StepDeserializer extends JsonDeserializer<Step> {
public StepDeserializer() {
super();
}
@Override
public Step deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
String stepType = node.get("step_type").asText();
StepTypeEnum stepTypeEnum = StepTypeEnum.valueOf(stepType);
Class<? extends Step> valueType = null;
switch (stepTypeEnum) {
case condition:
valueType = ConditionStep.class;
break;
case pause:
valueType = PauseStep.class;
break;
case request:
valueType = RequestStep.class;
break;
}
if (valueType != null) {
return mapper.treeToValue(node, valueType);
} else {
throw new JsonParseException("Enumeration value of " + stepType + " not recognised",
jp.getCurrentLocation());
}
}
}
Then this JsonDeserializer can be added to the generation in two ways I think.
Either to the static initialization in JsonUtil:
SimpleModule module = new SimpleModule();
module.addDeserializer(Step.class, new StepDeserializer());
mapper.registerModule(module);
Or to Step itself (this gives stack overflow, need to work out how to stop subclasses from using the same deserializer perhaps):
@ApiModel(description = "")
@JsonDeserialize(using = StepDeserializer.class)
public class Step {
Option 2
These annotations on Step itself:
@JsonTypeInfo(use = Id.CUSTOM, property = "step_type", include = As.PROPERTY)
@JsonTypeIdResolver(StepTypeIdResolver.class)
And then this custom type resolver, can't see a way to do it with the built in resolvers:
public class StepTypeIdResolver implements TypeIdResolver {
private JavaType mBaseType;
@Override
public void init(JavaType baseType) {
mBaseType = baseType;
}
@Override
public String idFromValue(Object value) {
return idFromValueAndType(value, value.getClass());
}
@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
if (RequestStep.class.equals(suggestedType)) {
return Step.StepTypeEnum.request.toString();
} else if (ConditionStep.class.equals(suggestedType)) {
return Step.StepTypeEnum.condition.toString();
} else if (PauseStep.class.equals(suggestedType)) {
return Step.StepTypeEnum.pause.toString();
}
return String.valueOf(value);
}
@Override
public String idFromBaseType() {
return idFromValueAndType(null, mBaseType.getRawClass());
}
@Override
public JavaType typeFromId(String id) {
Class<? extends Step> clazz = null;
if (StepTypeEnum.request.toString().equals(id)) {
clazz = RequestStep.class;
} else if (StepTypeEnum.condition.toString().equals(id)) {
clazz = ConditionStep.class;
} else if (StepTypeEnum.pause.toString().equals(id)) {
clazz = PauseStep.class;
}
return TypeFactory.defaultInstance().constructSpecializedType(mBaseType, clazz);
}
@Override
public JsonTypeInfo.Id getMechanism() {
return Id.CUSTOM;
}
}
Currently there doesn't seem to be any support for the swagger v2 discriminator attribute when reading an entity. I think the expectation would be that we first read in the discriminator field, then read the rest of the object based on this field. Not sure where best to put this but have been playing around with some custom JsonDeserializers.
Representing the Test Steps from https://www.runscope.com/docs/api/steps, I have Step/RequestStep/ConditionStep/PauseStep. I found two options so far which are below. Both seem roughly equivalent in terms of complexity and code size.
Option 1
The addition of a custom deserializer:
Then this JsonDeserializer can be added to the generation in two ways I think.
Either to the static initialization in JsonUtil:
Or to Step itself (this gives stack overflow, need to work out how to stop subclasses from using the same deserializer perhaps):
Option 2
These annotations on Step itself:
And then this custom type resolver, can't see a way to do it with the built in resolvers: