org.jsonschema2pojo.rules.ArrayRule Maven / Gradle / Ivy
/**
* Copyright © 2010-2020 Nokia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsonschema2pojo.rules;
import java.util.List;
import java.util.Set;
import org.jsonschema2pojo.Schema;
import org.jsonschema2pojo.util.Inflector;
import com.fasterxml.jackson.databind.JsonNode;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JPackage;
import com.sun.codemodel.JType;
/**
* Applies the "type":"array" schema rule.
*
* @see http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.5
* @see http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.15
*/
public class ArrayRule implements Rule {
private final RuleFactory ruleFactory;
protected ArrayRule(RuleFactory ruleFactory) {
this.ruleFactory = ruleFactory;
}
/**
* Applies this schema rule to take the required code generation steps.
*
* When constructs of type "array" appear in the schema, these are mapped to
* Java collections in the generated POJO. If the array is marked as having
* "uniqueItems" then the resulting Java type is {@link Set}, if not, then
* the resulting Java type is {@link List}. The schema given by "items" will
* decide the generic type of the collection.
*
* If the "items" property requires newly generated types, then the type
* name will be the singular version of the nodeName (unless overridden by
* the javaType property) e.g.
*
* "fooBars" : {"type":"array", "uniqueItems":"true", "items":{type:"object"}}
* ==>
* {@code Set getFooBars(); }
*
*
* @param nodeName
* the name of the property which has type "array"
* @param node
* the schema "type" node
* @param parent
* the parent node
* @param jpackage
* the package into which newly generated types should be added
* @return the Java type associated with this array rule, either {@link Set}
* or {@link List}, narrowed by the "items" type
*/
@Override
public JClass apply(String nodeName, JsonNode node, JsonNode parent, JPackage jpackage, Schema schema) {
boolean uniqueItems = node.has("uniqueItems") && node.get("uniqueItems").asBoolean();
boolean rootSchemaIsArray = !schema.isGenerated();
JType itemType;
if (node.has("items")) {
String pathToItems;
if (schema.getId() == null || schema.getId().getFragment() == null) {
pathToItems = "#/items";
} else {
pathToItems = "#" + schema.getId().getFragment() + "/items";
}
Schema itemsSchema = ruleFactory.getSchemaStore().create(schema, pathToItems, ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
if (itemsSchema.isGenerated()) {
itemType = itemsSchema.getJavaType();
} else {
itemType = ruleFactory.getSchemaRule().apply(makeSingular(nodeName), node.get("items"), node, jpackage, itemsSchema);
itemsSchema.setJavaTypeIfEmpty(itemType);
}
} else {
itemType = jpackage.owner().ref(Object.class);
}
JClass arrayType;
if (uniqueItems) {
arrayType = jpackage.owner().ref(Set.class).narrow(itemType);
} else {
arrayType = jpackage.owner().ref(List.class).narrow(itemType);
}
if (rootSchemaIsArray) {
schema.setJavaType(arrayType);
}
return arrayType;
}
private String makeSingular(String nodeName) {
return Inflector.getInstance().singularize(nodeName);
}
}