modelgroup: Things that you define for all models and model elements (DTO, DCO, TABLEFOR)

Tip: with alt/opt-RETURN you can import inner class/enum names statically. This can make your Chassis DSL much shorter and more readable!

For a more complete nameAndWhereto { ... } see DSL block delegation showcase

modelgroup { … }

    modelgroup("groupName") {            /** @see com.hoffi.chassis.dsl.modelgroup.DslModelgroup */
        nameAndWhereto {                 /** @see com.hoffi.chassis.dsl.whereto.IDslApiNameAndWheretoOnSubElements */
            classPrefix("Simple")
            packageName("entity")
            dtoNameAndWhereto {
                classPostfix("Dto")
                packageName("dto")
            }
            tableNameAndWhereto {
                classPostfix("Table")
                packageName("table")
            }
        }
        /** @see com.hoffi.chassis.dsl.modelgroupIDslApiKindClassObjectOrInterface */
        constructorVisibility = IDslApiConstructorVisibility.VISIBILITY.PROTECTED
        /** @see com.hoffi.chassis.dsl.modelgroup.IDslApiGatherPropertiesModelAndModelSubelementsCommon */
        propertiesOfSuperclasses /* do not extend superclasses/superinterfaces, but gather their properties */
        propertiesOf(MODELREFENUM.MODEL "modelgroupName" withModelName "modelName", GatherPropertiesEnum.PROPERTIES_AND_SUPERCLASS_PROPERTIES)

Things set on a modelgroup { ... } (eventually depending on the strategy) are considered to be defined for all containing models and submodels and therefore can be omitted in them respectively.

model

On defining property’s also see model properties)

    modelgroup {
        model("modelName") {
            nameAndWhereto { /* see above */ }
            extends {
                replaceSuperclass = false
                replaceSuperInterfaces = false
                + (MODELREFENUM.DTO inModelgroup "modelgroupName" withModelName "persistentDTOname")
                - "modelName"   // unary minus ==> interface ; as no modelgroup is given, it is assumed that "this" modelgroup contains a model with this name
                - "otherModel"
                // minusAssign("ref:name|other:string") // not implemented yet
                // minusAssign()                        // not implemented yet
                // not()                                // not implemented yet
                // rem("...")                           // not implemented yet
            }
            /** @see com.hoffi.chassis.dsl.modelgroup.IDslApiGatherPropertiesModelAndModelSubelementsCommon */
            propertiesOfSuperclasses /* do not extend superclasses/superinterfaces, but gather their properties */
            propertiesOf(MODELREFENUM.MODEL "modelgroupName" withModelName "modelName", GatherPropertiesEnum.PROPERTIES_AND_SUPERCLASS_PROPERTIES)
            property("thePropName1", TYP.STRING, ..., Tag.CONSTRUCTOR, Tag.DEFAULT_INITIALIZER, Tag.HASH_MEMBER, Tag.TO_STRING_MEMBER, Tag.PRIMARY)
            property("thePropName2", Dummy::class, ..., Tag.CONSTRUCTOR, Tag.DEFAULT_INITIALIZER, Tag.HASH_MEMBER, Tag.TO_STRING_MEMBER)
            property("thePropName3", ClassName("packageName", "ClassName"))
            property("someModelObject", DTO of "otherModelgroup", mutable)
        }
    }

A model is the named “outer” definition of a thing that can have multiple “incarnations”.

E.g. a model “Entity” can be

  • a kotlin class in form of a DTO (Data Transfer Object)
  • a kotlin class in form of a DCO (Data Compute Object)
  • the DB representation of a DTO (TableFor(DTO))
  • the DB representation of a DCO (TableFor(DC0))
  • … (if more model subelements are defined)

Things set on a model { ... } (eventually depending on the strategy) are considered to be defined for all containing models and submodels and therefore can be omitted in them respectively.
This is particularly useful for defining properties that all subelements have.

dto

model subelements are things that “really” get code generated for.

    modelgroup {
        model("name") {
            dto {
                /** everything that a model has */
                // plus e.g. props that only a dto has
                property("dtoSpecificProp", TYP.STRING, mutable, Tag.CONSTRUCTOR, Tag.DEFAULT_INITIALIZER)
 
                //propertiesOf( (MODEL inModelgroup PERSISTENTGROUP withModelName PERSISTENT__PERSISTENT) )
                
                See(IDslApiInitializer::class)
                // REPLACE, APPEND, MODIFY the initializer of a defined property
                initializer("dtoSpecificProp", APPEND, "/* some dto specific comment */")
                initializer("prio", APPEND, "/* some dto prio comment */")
                // add/remove a property from `toString()` method
                addToStringMembers("dtoSpecificProp", "createdAt")
                removeToStringMembers("prio")
            }
        }
}

dco

    modelgroup {
        model("name") {
            dco {
                /* same as dto { ... } */
            }
        }
    }

tableFor

    modelgroup {
        model("name") {
            tableFor(MODELREFENUM.DTO) { // generate a table for the DTO of this model("name")
                /* also all a dto/dco { ... } has, but you mainly won't need those */
                initializer("name", APPEND, ".uniqueIndex()") // setting an index on the table column
                // PRIMARY KEY already had been set on property via Tag.PRIMARY
            }
        }
    }
crud

the Chassis DSL node crud { ... } specifies which persistence/DB operations should be generated for which model subelements.

    modelgroup {
        model("name") {
            tableFor(MODELREFENUM.DTO) {
                crud {
                    // generate a crud operations for the DTO of this model("name")
                    See(IDslApiOuterCrudBlock::class)
                    STANDARD FOR DTO // just a helper
                    +DTO // unary plus means "mutual with itself
                    CRUDALL FOR DTO // just a helper
                    //
                    READ.viaAllVariants FOR DTO // only select methods but all variants of them (byJoin/bySelect)
                    CREATE FOR DTO // only insert
 
                    prefixed("somePrefix") {
                        // create the same methods that would be generated directly in `crud { ... }` node
                        // but prefix them with the given prefix
                        // and apply the depp or shallow Restrictions to them
                        See(IDslApiPrefixedCrudScopeBlock::class)
                        (READ.viaAllVariants FOR DTO) deepRestrictions {
                            IGNORE propName "someModelObject"
                            IGNORE("someModelObject", "prefix1")
                        }
                        (CREATE FOR DTO) deepRestrictions {
                            IGNORE propName "subentitys"
                            IGNORE("subentitys", "someModelObject", "prefix2")
                        }
                    }
 
                }
            }
        }
    }

filler

Fillers are static methods that take to submodel objects and fill the one from the other.

That means all the props that have the same name and same type will (recursively) copied over to the other.

As target as well as source you also can specify modelsubelements that are outside the current model node or even outside the current modelgroup.

The Logic for CopyBoundrys are the same as for crud { ... } above.

As crud { ... } operations use filler { ... } defined stuff under the hood,
if a crud needs a filler, it will synthetically create it (meaning you do NOT have to define it here redundantly)

    modelgroup {
        model("name") {}
            filler {
                See(IDslApiOuterFillerBlock::class)
                +DTO // DTO filled by a DTO
                DTO mutual TABLE
                DTO mutual TABLE
                DTO from TABLE
                TABLE from DTO
                DTO from (DTO of ENTITY__SUBENTITY) // TODO check if this corresponding virtual Filler is also created because of (next line)
                (DTO of ENTITY__SUBENTITY) from TABLE
                //(DTO inModelgroup PERSISTENTGROUP withModelName PERSISTENT__PERSISTENT) from DTO
                prefixed("withoutModels") {
                    See(IDslApiPrefixedCrudScopeBlock::class)
                    (DTO mutual TABLE) shallowRestrictions {
                        IGNORE propName "someModelObject"
                        IGNORE("dtoSpecificProp", "someObject", "aLocalDateTime")
                        IGNORE("someModelObject") // vararg
                        copyBoundry(IGNORE, "someModelObject") // vararg extended form
                    }
                    (DTO mutual TABLE) deepRestrictions {
                        IGNORE propName "subentitys"
                        IGNORE("subentitys") // vararg
                        copyBoundry(IGNORE, "subentitys") // vararg extended form
                        IGNORE model (DTO of ENTITY__SUBENTITY) onlyIf COLLECTIONTYP.COLLECTION
                    }
                    FOR((TABLE from DTO), (DTO from TABLE)) deepRestrictions {
                        IGNORE propName "subentitys"
                        IGNORE("subentitys") // vararg
                    }
                    +DTO deepRestrictions {
                    //FOR DTO {
                        copyBoundry(IGNORE, "subentitys", "someModelObject")
                    }
                    FOR(+DTO, +DTO) deepRestrictions {
                        copyBoundry(IGNORE, "subentitys", "someModelObject")
                    }
                }
            }
        }

there are a number of generated functions for each filler:

e.g.: object FillerEntityDto for model(“Entity”) dto classPostfix “Dto” mutual filler from/to itself:

fun cloneDeep(EntityDto): EntityDto
fun cloneShallowlgnoreModels(EntityDto): EntityDto
fun cloneShallowTakeSameModels(EntityDto): EntityDto
fun cloneWithNewModels(EntityDto): EntityDto
fun copyDeepinto(EntityDto, EntityDto): EntityDto
fun copyShallowAndTakeSameModelslnto(EntityDto, EntityDto): EntityDto
fun copyShallowIgnoreModelsInto(EntityDto, EntityDto): EntityDto
fun copyShallowWithNewModelslnto(EntityDto, EntityDto): EntityDto

for all prefixed("some") restrictions { ... } above’s set of filler functions will be generated.


back to root