Search in sources :

Example 1 with JCase

use of com.sun.codemodel.JCase in project rest.li by linkedin.

the class JavaDataTemplateGenerator method generateRecordFieldAccessors.

private void generateRecordFieldAccessors(JDefinedClass templateClass, RecordTemplateSpec.Field field, JClass type, JVar schemaFieldVar, JVar fieldVar) {
    final RecordDataSchema.Field schemaField = field.getSchemaField();
    final DataSchema fieldSchema = schemaField.getType();
    final String capitalizedName = CodeUtil.capitalize(schemaField.getName());
    final JExpression mapRef = JExpr._super().ref("_map");
    final JExpression fieldNameExpr = JExpr.lit(schemaField.getName());
    final String fieldFieldName = "FIELD_" + capitalizedName;
    final JFieldVar fieldField = templateClass.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, RecordDataSchema.Field.class, fieldFieldName);
    fieldField.init(schemaFieldVar.invoke("getField").arg(schemaField.getName()));
    // Generate default field if applicable
    final String defaultFieldName = "DEFAULT_" + capitalizedName;
    final JFieldVar defaultField;
    if (field.getSchemaField().getDefault() != null) {
        defaultField = templateClass.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, type, defaultFieldName);
        templateClass.init().assign(defaultField, getCoerceOutputExpression(fieldField.invoke("getDefault"), schemaField.getType(), type, field.getCustomInfo()));
    } else {
        defaultField = null;
    }
    // Generate has method.
    final JMethod has = templateClass.method(JMod.PUBLIC, getCodeModel().BOOLEAN, "has" + capitalizedName);
    addAccessorDoc(templateClass, has, schemaField, "Existence checker");
    setDeprecatedAnnotationAndJavadoc(has, schemaField);
    final JBlock hasBody = has.body();
    final JBlock hasInstanceVarBody = hasBody._if(fieldVar.ne(JExpr._null()))._then();
    hasInstanceVarBody._return(JExpr.lit(true));
    hasBody._return(mapRef.invoke("containsKey").arg(fieldNameExpr));
    if (_recordFieldRemove) {
        // Generate remove method.
        final String removeName = "remove" + capitalizedName;
        final JMethod remove = templateClass.method(JMod.PUBLIC, getCodeModel().VOID, removeName);
        addAccessorDoc(templateClass, remove, schemaField, "Remover");
        setDeprecatedAnnotationAndJavadoc(remove, schemaField);
        final JBlock removeBody = remove.body();
        removeBody.add(mapRef.invoke("remove").arg(fieldNameExpr));
    }
    final String getterName = JavaCodeUtil.getGetterName(getCodeModel(), type, capitalizedName);
    if (_recordFieldAccessorWithMode) {
        // Getter method with mode.
        final JMethod getterWithMode = templateClass.method(JMod.PUBLIC, type, getterName);
        addAccessorDoc(templateClass, getterWithMode, schemaField, "Getter");
        setDeprecatedAnnotationAndJavadoc(getterWithMode, schemaField);
        JVar modeParam = getterWithMode.param(_getModeClass, "mode");
        final JBlock getterWithModeBody = getterWithMode.body();
        // If it is an optional field with no default, just call out to the getter without mode.
        if (field.getSchemaField().getOptional() && defaultField == null) {
            getterWithModeBody._return(JExpr.invoke(getterName));
        } else {
            JSwitch modeSwitch = getterWithModeBody._switch(modeParam);
            JCase strictCase = modeSwitch._case(JExpr.ref("STRICT"));
            // If there is no default defined, call the getter without mode, else fall through to default.
            if (defaultField == null) {
                strictCase.body()._return(JExpr.invoke(getterName));
            }
            JCase defaultCase = modeSwitch._case(JExpr.ref("DEFAULT"));
            if (defaultField != null) {
                // If there is a default, then default is the same as strict, else we should fall through to null.
                defaultCase.body()._return(JExpr.invoke(getterName));
            }
            JCase nullCase = modeSwitch._case(JExpr.ref("NULL"));
            JConditional nullCaseConditional = nullCase.body()._if(fieldVar.ne(JExpr._null()));
            nullCaseConditional._then()._return(fieldVar);
            JBlock nullCaseConditionalElse = nullCaseConditional._else();
            JVar rawValueVar = nullCaseConditionalElse.decl(_objectClass, "__rawValue", mapRef.invoke("get").arg(fieldNameExpr));
            nullCaseConditionalElse.assign(fieldVar, getCoerceOutputExpression(rawValueVar, fieldSchema, type, field.getCustomInfo()));
            nullCaseConditionalElse._return(fieldVar);
            getterWithModeBody._throw(JExpr._new(getCodeModel().ref(IllegalStateException.class)).arg(JExpr.lit("Unknown mode ").plus(modeParam)));
        }
    }
    // Getter method without mode.
    final JMethod getterWithoutMode = templateClass.method(JMod.PUBLIC, type, getterName);
    addAccessorDoc(templateClass, getterWithoutMode, schemaField, "Getter");
    setDeprecatedAnnotationAndJavadoc(getterWithoutMode, schemaField);
    JCommentPart returnComment = getterWithoutMode.javadoc().addReturn();
    if (schemaField.getOptional()) {
        getterWithoutMode.annotate(Nullable.class);
        returnComment.add("Optional field. Always check for null.");
    } else {
        getterWithoutMode.annotate(Nonnull.class);
        returnComment.add("Required field. Could be null for partial record.");
    }
    final JBlock getterWithoutModeBody = getterWithoutMode.body();
    JConditional getterWithoutModeBodyConditional = getterWithoutModeBody._if(fieldVar.ne(JExpr._null()));
    getterWithoutModeBodyConditional._then()._return(fieldVar);
    JBlock getterWithoutModeBodyConditionalElse = getterWithoutModeBodyConditional._else();
    JVar rawValueVar = getterWithoutModeBodyConditionalElse.decl(_objectClass, "__rawValue", mapRef.invoke("get").arg(fieldNameExpr));
    if (schemaField.getDefault() != null) {
        getterWithoutModeBodyConditionalElse._if(rawValueVar.eq(JExpr._null()))._then()._return(defaultField);
    } else if (!schemaField.getOptional()) {
        getterWithoutModeBodyConditionalElse._if(rawValueVar.eq(JExpr._null()))._then()._throw(JExpr._new(getCodeModel().ref(RequiredFieldNotPresentException.class)).arg(fieldNameExpr));
    }
    getterWithoutModeBodyConditionalElse.assign(fieldVar, getCoerceOutputExpression(rawValueVar, fieldSchema, type, field.getCustomInfo()));
    getterWithoutModeBodyConditionalElse._return(fieldVar);
    final String setterName = "set" + capitalizedName;
    if (_recordFieldAccessorWithMode) {
        // Setter method with mode
        final JMethod setterWithMode = templateClass.method(JMod.PUBLIC, templateClass, setterName);
        addAccessorDoc(templateClass, setterWithMode, schemaField, "Setter");
        setDeprecatedAnnotationAndJavadoc(setterWithMode, schemaField);
        JVar param = setterWithMode.param(type, "value");
        JVar modeParam = setterWithMode.param(_setModeClass, "mode");
        JSwitch modeSwitch = setterWithMode.body()._switch(modeParam);
        JCase disallowNullCase = modeSwitch._case(JExpr.ref("DISALLOW_NULL"));
        disallowNullCase.body()._return(JExpr.invoke(setterName).arg(param));
        // Generate remove optional if null, only for required fields. Optional fields will fall through to
        // remove if null, which is the same behavior for them.
        JCase removeOptionalIfNullCase = modeSwitch._case(JExpr.ref("REMOVE_OPTIONAL_IF_NULL"));
        if (!schemaField.getOptional()) {
            JConditional paramIsNull = removeOptionalIfNullCase.body()._if(param.eq(JExpr._null()));
            paramIsNull._then()._throw(JExpr._new(getCodeModel().ref(IllegalArgumentException.class)).arg(JExpr.lit("Cannot remove mandatory field " + schemaField.getName() + " of " + templateClass.fullName())));
            paramIsNull._else().add(_checkedUtilClass.staticInvoke("putWithoutChecking").arg(mapRef).arg(fieldNameExpr).arg(getCoerceInputExpression(param, fieldSchema, field.getCustomInfo())));
            paramIsNull._else().assign(fieldVar, param);
            removeOptionalIfNullCase.body()._break();
        }
        JCase removeIfNullCase = modeSwitch._case(JExpr.ref("REMOVE_IF_NULL"));
        JConditional paramIsNull = removeIfNullCase.body()._if(param.eq(JExpr._null()));
        paramIsNull._then().invoke("remove" + capitalizedName);
        paramIsNull._else().add(_checkedUtilClass.staticInvoke("putWithoutChecking").arg(mapRef).arg(fieldNameExpr).arg(getCoerceInputExpression(param, fieldSchema, field.getCustomInfo())));
        paramIsNull._else().assign(fieldVar, param);
        removeIfNullCase.body()._break();
        JCase ignoreNullCase = modeSwitch._case(JExpr.ref("IGNORE_NULL"));
        JConditional paramIsNotNull = ignoreNullCase.body()._if(param.ne(JExpr._null()));
        paramIsNotNull._then().add(_checkedUtilClass.staticInvoke("putWithoutChecking").arg(mapRef).arg(fieldNameExpr).arg(getCoerceInputExpression(param, fieldSchema, field.getCustomInfo())));
        paramIsNotNull._then().assign(fieldVar, param);
        ignoreNullCase.body()._break();
        setterWithMode.body()._return(JExpr._this());
    }
    // Setter method without mode
    final JMethod setter = templateClass.method(JMod.PUBLIC, templateClass, setterName);
    addAccessorDoc(templateClass, setter, schemaField, "Setter");
    setDeprecatedAnnotationAndJavadoc(setter, schemaField);
    JVar param = setter.param(type, "value");
    param.annotate(Nonnull.class);
    JCommentPart paramDoc = setter.javadoc().addParam(param);
    paramDoc.add("Must not be null. For more control, use setters with mode instead.");
    JConditional paramIsNull = setter.body()._if(param.eq(JExpr._null()));
    paramIsNull._then()._throw(JExpr._new(getCodeModel().ref(NullPointerException.class)).arg(JExpr.lit("Cannot set field " + schemaField.getName() + " of " + templateClass.fullName() + " to null")));
    paramIsNull._else().add(_checkedUtilClass.staticInvoke("putWithoutChecking").arg(mapRef).arg(fieldNameExpr).arg(getCoerceInputExpression(param, fieldSchema, field.getCustomInfo())));
    paramIsNull._else().assign(fieldVar, param);
    setter.body()._return(JExpr._this());
    // Setter method without mode for unboxified type
    if (!type.unboxify().equals(type)) {
        final JMethod unboxifySetter = templateClass.method(JMod.PUBLIC, templateClass, setterName);
        addAccessorDoc(templateClass, unboxifySetter, schemaField, "Setter");
        setDeprecatedAnnotationAndJavadoc(unboxifySetter, schemaField);
        param = unboxifySetter.param(type.unboxify(), "value");
        unboxifySetter.body().add(_checkedUtilClass.staticInvoke("putWithoutChecking").arg(mapRef).arg(fieldNameExpr).arg(getCoerceInputExpression(param, fieldSchema, field.getCustomInfo())));
        unboxifySetter.body().assign(fieldVar, param);
        unboxifySetter.body()._return(JExpr._this());
    }
}
Also used : JCase(com.sun.codemodel.JCase) JCommentPart(com.sun.codemodel.JCommentPart) ByteString(com.linkedin.data.ByteString) JExpression(com.sun.codemodel.JExpression) EnumDataSchema(com.linkedin.data.schema.EnumDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) MapDataSchema(com.linkedin.data.schema.MapDataSchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) JSwitch(com.sun.codemodel.JSwitch) JFieldVar(com.sun.codemodel.JFieldVar) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) JBlock(com.sun.codemodel.JBlock) JConditional(com.sun.codemodel.JConditional) JMethod(com.sun.codemodel.JMethod) JVar(com.sun.codemodel.JVar)

Example 2 with JCase

use of com.sun.codemodel.JCase in project rest.li by linkedin.

the class JavaDataTemplateGenerator method generateChangeListener.

private JClass generateChangeListener(JDefinedClass cls, Map<String, JVar> fieldMap) throws JClassAlreadyExistsException {
    final JClass changeListenerInterface = getCodeModel().ref(CheckedMap.ChangeListener.class);
    final JDefinedClass changeListenerClass = cls._class(JMod.PRIVATE | JMod.STATIC, "ChangeListener");
    changeListenerClass._implements(changeListenerInterface.narrow(String.class, Object.class));
    final JFieldVar objectRefVar = changeListenerClass.field(JMod.PRIVATE | JMod.FINAL, cls, "__objectRef");
    final JMethod constructor = changeListenerClass.constructor(JMod.PRIVATE);
    JVar refParam = constructor.param(cls, "reference");
    constructor.body().assign(objectRefVar, refParam);
    final JMethod method = changeListenerClass.method(JMod.PUBLIC, void.class, "onUnderlyingMapChanged");
    method.annotate(Override.class);
    final JVar keyParam = method.param(String.class, "key");
    method.param(_objectClass, "value");
    JSwitch keySwitch = method.body()._switch(keyParam);
    fieldMap.forEach((key, field) -> {
        JCase keyCase = keySwitch._case(JExpr.lit(key));
        keyCase.body().assign(objectRefVar.ref(field.name()), JExpr._null());
        keyCase.body()._break();
    });
    return changeListenerClass;
}
Also used : JSwitch(com.sun.codemodel.JSwitch) JDefinedClass(com.sun.codemodel.JDefinedClass) JFieldVar(com.sun.codemodel.JFieldVar) JClass(com.sun.codemodel.JClass) JCase(com.sun.codemodel.JCase) ByteString(com.linkedin.data.ByteString) CheckedMap(com.linkedin.data.collections.CheckedMap) JMethod(com.sun.codemodel.JMethod) JVar(com.sun.codemodel.JVar)

Aggregations

ByteString (com.linkedin.data.ByteString)2 JCase (com.sun.codemodel.JCase)2 JFieldVar (com.sun.codemodel.JFieldVar)2 JMethod (com.sun.codemodel.JMethod)2 JSwitch (com.sun.codemodel.JSwitch)2 JVar (com.sun.codemodel.JVar)2 CheckedMap (com.linkedin.data.collections.CheckedMap)1 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)1 DataSchema (com.linkedin.data.schema.DataSchema)1 EnumDataSchema (com.linkedin.data.schema.EnumDataSchema)1 MapDataSchema (com.linkedin.data.schema.MapDataSchema)1 NamedDataSchema (com.linkedin.data.schema.NamedDataSchema)1 RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)1 JBlock (com.sun.codemodel.JBlock)1 JClass (com.sun.codemodel.JClass)1 JCommentPart (com.sun.codemodel.JCommentPart)1 JConditional (com.sun.codemodel.JConditional)1 JDefinedClass (com.sun.codemodel.JDefinedClass)1 JExpression (com.sun.codemodel.JExpression)1