use of com.sun.codemodel.JFieldVar in project jsonschema2pojo by joelittlejohn.
the class AdditionalPropertiesRule method apply.
/**
* Applies this schema rule to take the required code generation steps.
* <p>
* If additionalProperties is specified and set to the boolean value
* <code>false</code>, this rule does not make any change to the generated
* Java type (the type does not allow additional properties).
* <p>
* If the additionalProperties node is <code>null</code> (not specified in
* the schema) or empty, then a new bean property named
* "additionalProperties", of type {@link Map}{@literal <String,Object>} is
* added to the generated type (with appropriate accessors). The accessors
* are annotated to allow unrecognised (additional) properties found in JSON
* data to be marshalled/unmarshalled from/to this map.
* <p>
* If the additionalProperties node is present and specifies a schema, then
* an "additionalProperties" map is added to the generated type. This time
* the map values will be restricted and must be instances of a newly
* generated Java type that will be created based on the
* additionalProperties schema provided. If the schema does not specify the
* javaType property, the name of the newly generated type will be derived
* from the nodeName and the suffix 'Property'.
*
* @param nodeName
* the name of the schema node for which the additionalProperties
* node applies
* @param node
* the additionalProperties node itself, found in the schema (may
* be null if not specified in the schema)
* @param jclass
* the Java type that is being generated to represent this schema
* @return the given Java type jclass
*/
@Override
public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDefinedClass jclass, Schema schema) {
if (node != null && node.isBoolean() && node.asBoolean() == false) {
// no additional properties allowed
return jclass;
}
if (!this.ruleFactory.getGenerationConfig().isIncludeAdditionalProperties()) {
// no additional properties allowed
return jclass;
}
if (!ruleFactory.getAnnotator().isAdditionalPropertiesSupported()) {
// schema allows additional properties, but serializer library can't support them
return jclass;
}
JType propertyType;
if (node != null && node.size() != 0) {
String pathToAdditionalProperties;
if (schema.getId().getFragment() == null) {
pathToAdditionalProperties = "#/additionalProperties";
} else {
pathToAdditionalProperties = "#" + schema.getId().getFragment() + "/additionalProperties";
}
Schema additionalPropertiesSchema = ruleFactory.getSchemaStore().create(schema, pathToAdditionalProperties, ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
propertyType = ruleFactory.getSchemaRule().apply(nodeName + "Property", node, parent, jclass, additionalPropertiesSchema);
additionalPropertiesSchema.setJavaTypeIfEmpty(propertyType);
} else {
propertyType = jclass.owner().ref(Object.class);
}
JFieldVar field = addAdditionalPropertiesField(jclass, propertyType);
addGetter(jclass, field);
addSetter(jclass, propertyType, field);
if (ruleFactory.getGenerationConfig().isIncludeJsr303Annotations()) {
ruleFactory.getValidRule().apply(nodeName, node, parent, field, schema);
}
if (ruleFactory.getGenerationConfig().isGenerateBuilders()) {
addBuilder(jclass, propertyType, field);
}
return jclass;
}
use of com.sun.codemodel.JFieldVar in project jsonschema2pojo by joelittlejohn.
the class AdditionalPropertiesRule method addAdditionalPropertiesField.
private JFieldVar addAdditionalPropertiesField(JDefinedClass jclass, JType propertyType) {
JClass propertiesMapType = jclass.owner().ref(Map.class);
propertiesMapType = propertiesMapType.narrow(jclass.owner().ref(String.class), propertyType.boxify());
JClass propertiesMapImplType = jclass.owner().ref(HashMap.class);
propertiesMapImplType = propertiesMapImplType.narrow(jclass.owner().ref(String.class), propertyType.boxify());
JFieldVar field = jclass.field(JMod.PRIVATE, propertiesMapType, "additionalProperties");
ruleFactory.getAnnotator().additionalPropertiesField(field, jclass, "additionalProperties");
field.init(JExpr._new(propertiesMapImplType));
return field;
}
use of com.sun.codemodel.JFieldVar in project jsonschema2pojo by joelittlejohn.
the class BuilderRule method apply.
@Override
public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDefinedClass instanceClass, Schema currentSchema) {
// Create the inner class for the builder
JDefinedClass concreteBuilderClass;
JDefinedClass builderClass;
try {
String concreteBuilderClassName = ruleFactory.getNameHelper().getBuilderClassName(instanceClass);
String builderClassName = ruleFactory.getNameHelper().getBaseBuilderClassName(instanceClass);
builderClass = instanceClass._class(JMod.ABSTRACT + JMod.PUBLIC + JMod.STATIC, builderClassName);
concreteBuilderClass = instanceClass._class(JMod.PUBLIC + JMod.STATIC, concreteBuilderClassName);
concreteBuilderClass._extends(builderClass.narrow(instanceClass));
} catch (JClassAlreadyExistsException e) {
return e.getExistingClass();
}
// Determine which base builder (if any) this builder should inherit from
JClass parentBuilderClass = null;
JClass parentClass = instanceClass._extends();
if (!(parentClass.isPrimitive() || reflectionHelper.isFinal(parentClass) || Objects.equals(parentClass.fullName(), "java.lang.Object"))) {
parentBuilderClass = reflectionHelper.getBaseBuilderClass(parentClass);
}
// Determine the generic type name and that the builder will create instances of
String builderTypeParameterName = ruleFactory.getNameHelper().getBuilderTypeParameterName(instanceClass);
JTypeVar instanceType = builderClass.generify(builderTypeParameterName, instanceClass);
// for inheriting builders we'll receive these from the superType
if (parentBuilderClass == null) {
// Create the instance variable
JFieldVar instanceField = builderClass.field(JMod.PROTECTED, instanceType, "instance");
// Create the actual "build" method
JMethod buildMethod = builderClass.method(JMod.PUBLIC, instanceType, "build");
JBlock body = buildMethod.body();
JVar result = body.decl(instanceType, "result");
body.assign(result, JExpr._this().ref(instanceField));
body.assign(JExpr._this().ref(instanceField), JExpr._null());
body._return(result);
// Create the noargs builder constructors
generateNoArgsBuilderConstructors(instanceClass, builderClass, concreteBuilderClass);
} else {
// Declare the inheritance
builderClass._extends(parentBuilderClass.narrow(parentBuilderClass.owner().ref(builderTypeParameterName)));
JMethod buildMethod = builderClass.method(JMod.PUBLIC, instanceType, "build");
buildMethod.annotate(Override.class);
JBlock body = buildMethod.body();
body._return(JExpr._super().invoke("build"));
// Create the noargs builder constructors
generateNoArgsBuilderConstructors(instanceClass, builderClass, concreteBuilderClass);
}
return builderClass;
}
use of com.sun.codemodel.JFieldVar in project jsonschema2pojo by joelittlejohn.
the class ConstructorRule method generateFieldsBuilderConstructor.
private void generateFieldsBuilderConstructor(JDefinedClass builderClass, JDefinedClass concreteBuilderClass, JDefinedClass instanceClass, JMethod instanceConstructor) {
// Locate the instance field since we'll need it to assign a value
JFieldVar instanceField = reflectionHelper.searchClassAndSuperClassesForField("instance", builderClass);
// Create a new method to be the builder constructor we're defining
JMethod builderConstructor = builderClass.constructor(JMod.PUBLIC);
builderConstructor.annotate(SuppressWarnings.class).param("value", "unchecked");
JBlock constructorBlock = builderConstructor.body();
// The builder constructor should have the exact same parameters as the instanceConstructor
for (JVar param : instanceConstructor.params()) {
builderConstructor.param(param.type(), param.name());
}
// Determine if we need to invoke the super() method for our parent builder
JClass parentClass = builderClass._extends();
if (!(parentClass.isPrimitive() || reflectionHelper.isFinal(parentClass) || Objects.equals(parentClass.fullName(), "java.lang.Object"))) {
constructorBlock.invoke("super");
}
// The constructor invocation will also need all the parameters passed through
JInvocation instanceConstructorInvocation = JExpr._new(instanceClass);
for (JVar param : instanceConstructor.params()) {
instanceConstructorInvocation.arg(param);
}
// Only initialize the instance if the object being constructed is actually this class
// if it's a subtype then ignore the instance initialization since the subclass will initialize it
constructorBlock.directStatement("// Skip initialization when called from subclass");
JInvocation comparison = JExpr._this().invoke("getClass").invoke("equals").arg(JExpr.dotclass(concreteBuilderClass));
JConditional ifNotSubclass = constructorBlock._if(comparison);
ifNotSubclass._then().assign(JExpr._this().ref(instanceField), JExpr.cast(instanceField.type(), instanceConstructorInvocation));
generateFieldsConcreteBuilderConstructor(builderClass, concreteBuilderClass, instanceConstructor);
}
use of com.sun.codemodel.JFieldVar in project jsonschema2pojo by joelittlejohn.
the class PatternRuleTest method jsrDisable.
@Test
public void jsrDisable() {
when(config.isIncludeJsr303Annotations()).thenReturn(false);
JFieldVar result = rule.apply("node", node, null, fieldVar, null);
assertSame(fieldVar, result);
verify(fieldVar, never()).annotate(patternClass);
verify(annotation, never()).param(anyString(), anyString());
}
Aggregations