private JsonMap getSchema()

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;
	}