in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java [217:375]
private JsonMap getSchema(ClassMeta<?> eType, String attrName, String[] pNames, boolean exampleAdded, boolean descriptionAdded, JsonSchemaBeanPropertyMeta jsbpm) throws BeanRecursionException, SerializeException {
if (ctx.isIgnoredType(eType))
return null;
JsonMap out = new JsonMap();
if (eType == null)
eType = object();
ClassMeta<?> aType; // The actual type (will be null if recursion occurs)
ClassMeta<?> sType; // The serialized type
ObjectSwap objectSwap = eType.getSwap(this);
aType = push(attrName, eType, null);
sType = eType.getSerializedClassMeta(this);
String type = null, format = null;
Object example = null, description = null;
boolean useDef = isUseBeanDefs() && sType.isBean() && pNames == null;
if (useDef) {
exampleAdded = false;
descriptionAdded = false;
}
if (useDef && defs.containsKey(getBeanDefId(sType))) {
pop();
return new JsonMap().append("$ref", getBeanDefUri(sType));
}
JsonSchemaClassMeta jscm = null;
ClassMeta objectSwapCM = objectSwap == null ? null : getClassMeta(objectSwap.getClass());
if (objectSwapCM != null && objectSwapCM.hasAnnotation(Schema.class))
jscm = getJsonSchemaClassMeta(objectSwapCM);
if (jscm == null)
jscm = getJsonSchemaClassMeta(sType);
TypeCategory tc = null;
if (sType.isNumber()) {
tc = NUMBER;
if (sType.isDecimal()) {
type = "number";
if (sType.isFloat()) {
format = "float";
} else if (sType.isDouble()) {
format = "double";
}
} else {
type = "integer";
if (sType.isShort()) {
format = "int16";
} else if (sType.isInteger()) {
format = "int32";
} else if (sType.isLong()) {
format = "int64";
}
}
} else if (sType.isBoolean()) {
tc = BOOLEAN;
type = "boolean";
} else if (sType.isMap()) {
tc = MAP;
type = "object";
} else if (sType.isBean()) {
tc = BEAN;
type = "object";
} else if (sType.isCollection()) {
tc = COLLECTION;
type = "array";
} else if (sType.isArray()) {
tc = ARRAY;
type = "array";
} else if (sType.isEnum()) {
tc = ENUM;
type = "string";
} else if (sType.isCharSequence() || sType.isChar()) {
tc = STRING;
type = "string";
} else if (sType.isUri()) {
tc = STRING;
type = "string";
format = "uri";
} else {
tc = STRING;
type = "string";
}
// Add info from @Schema on bean property.
if (jsbpm != null) {
out.append(jsbpm.getSchema());
}
out.append(jscm.getSchema());
Predicate<String> ne = StringUtils::isNotEmpty;
out.appendIfAbsentIf(ne, "type", type);
out.appendIfAbsentIf(ne, "format", format);
if (aType != null) {
example = getExample(sType, tc, exampleAdded);
description = getDescription(sType, tc, descriptionAdded);
exampleAdded |= example != null;
descriptionAdded |= description != null;
if (tc == BEAN) {
JsonMap properties = new JsonMap();
BeanMeta bm = getBeanMeta(sType.getInnerClass());
if (pNames != null)
bm = new BeanMetaFiltered(bm, pNames);
for (Iterator<BeanPropertyMeta> i = bm.getPropertyMetas().iterator(); i.hasNext();) {
BeanPropertyMeta p = i.next();
if (p.canRead())
properties.put(p.getName(), getSchema(p.getClassMeta(), p.getName(), p.getProperties(), exampleAdded, descriptionAdded, getJsonSchemaBeanPropertyMeta(p)));
}
out.put("properties", properties);
} else if (tc == COLLECTION) {
ClassMeta et = sType.getElementType();
if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
out.put("uniqueItems", true);
out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));
} else if (tc == ARRAY) {
ClassMeta et = sType.getElementType();
if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
out.put("uniqueItems", true);
out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));
} else if (tc == ENUM) {
out.put("enum", getEnums(sType));
} else if (tc == MAP) {
JsonMap om = getSchema(sType.getValueType(), "additionalProperties", null, exampleAdded, descriptionAdded, null);
if (! om.isEmpty())
out.put("additionalProperties", om);
}
}
out.append(jscm.getSchema());
Predicate<Object> neo = ObjectUtils::isNotEmpty;
out.appendIfAbsentIf(neo, "description", description);
out.appendIfAbsentIf(neo, "example", example);
if (useDef) {
defs.put(getBeanDefId(sType), out);
out = JsonMap.of("$ref", getBeanDefUri(sType));
}
pop();
return out;
}