Search in sources :

Example 36 with JFieldVar

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;
}
Also used : JFieldVar(com.sun.codemodel.JFieldVar) Schema(org.jsonschema2pojo.Schema) JType(com.sun.codemodel.JType)

Example 37 with JFieldVar

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;
}
Also used : JFieldVar(com.sun.codemodel.JFieldVar) JClass(com.sun.codemodel.JClass)

Example 38 with JFieldVar

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;
}
Also used : JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) JDefinedClass(com.sun.codemodel.JDefinedClass) JTypeVar(com.sun.codemodel.JTypeVar) JFieldVar(com.sun.codemodel.JFieldVar) JClass(com.sun.codemodel.JClass) JBlock(com.sun.codemodel.JBlock) JMethod(com.sun.codemodel.JMethod) JVar(com.sun.codemodel.JVar)

Example 39 with JFieldVar

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);
}
Also used : JFieldVar(com.sun.codemodel.JFieldVar) JClass(com.sun.codemodel.JClass) JBlock(com.sun.codemodel.JBlock) JInvocation(com.sun.codemodel.JInvocation) JConditional(com.sun.codemodel.JConditional) JMethod(com.sun.codemodel.JMethod) JVar(com.sun.codemodel.JVar)

Example 40 with JFieldVar

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());
}
Also used : JFieldVar(com.sun.codemodel.JFieldVar) Test(org.junit.Test)

Aggregations

JFieldVar (com.sun.codemodel.JFieldVar)74 JMethod (com.sun.codemodel.JMethod)33 JVar (com.sun.codemodel.JVar)28 JClass (com.sun.codemodel.JClass)24 Test (org.junit.Test)24 JBlock (com.sun.codemodel.JBlock)21 JInvocation (com.sun.codemodel.JInvocation)19 JDefinedClass (com.sun.codemodel.JDefinedClass)16 Random (java.util.Random)12 ByteString (com.linkedin.data.ByteString)10 HashMap (java.util.HashMap)10 JsonNode (com.fasterxml.jackson.databind.JsonNode)9 JExpression (com.sun.codemodel.JExpression)9 JConditional (com.sun.codemodel.JConditional)8 JType (com.sun.codemodel.JType)8 ArrayList (java.util.ArrayList)7 Map (java.util.Map)6 JFieldRef (com.sun.codemodel.JFieldRef)5 JCodeModel (com.sun.codemodel.JCodeModel)3 JPackage (com.sun.codemodel.JPackage)3