Annotation Interface Owner


@Target({FIELD,METHOD}) @Retention(RUNTIME) @WriteAccess(MANUAL) @MutuallyExclusive({"root","transitive"}) @Documented public @interface Owner

Designates a field or method as owner field or method.

Owners are automatically set when an instance of the containing class is first to another DSL-Object, either as value of a field or as member of a collection.

Fields


 given:
 @DSL
 class Foo {
   Bar bar
 }

 @DSL
 class Bar {
   @Owner Foo container
 }

 when:
 instance = Foo.Create.With {
   bar {}
 }

 then:
 instance.bar.container.is(instance)
 

A dsl hierarchy can have any number of Owner fields. When the object is added to another object, any owner field of that object that:

  • is not set
  • has a type that the container object is derived from (i.e., the object is a legal value for that field)

will be set to the owner value.

This means that if an object that already has an existing owner is reused, the owner is not overridden, but silently ignored. I.e., the first object that an object is assigned to is the actual owner.

Closure field

If the annotated field is of type Closure, the Closure itself will be executed in the owner phase.

Methods

Can also be used to annotate a single parameter method. All matching methods are also called when the object is added to another object. Other as with fields, these methods are called multiple times, if applicable.


 given:
 @DSL
 class Foo {
   @Key String name
   Bar bar
 }

 @DSL
 class Bar {
   String containerName
   @Owner void container(Foo foo) {
       containerName = foo.name
   }
 }

 when:
 instance = Foo.Create.With("bla") {
   bar {}
 }

 then:
 instance.bar.containerName == "bla"
 

Transitive Owners

If the attribute transitive is set, not only the direct container is considered as ancestor, but instead the closest ancestor of the given type (i.e., a grandparent instead of a direct parent). This works for fields as well as methods.

Root Owners

If the attribute root is set, the ultimate top level object is set, if the type matcher. This works for fields as well as methods.

Converter

If the attribute converter is set, the converter is executed against the owner object and the result of the closure is assigned to the field or method. In that case, the single parameter of the closure is used as the owner type to match.

  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Class<? extends groovy.lang.Closure<Object>>
    If set, the field or method matches the closure parameter.
    boolean
    If set to true, the owner is set to root object, if matching.
    boolean
    If set to true, the owner is set to the first ancestor of the given type.
  • Element Details

    • transitive

      boolean transitive
      If set to true, the owner is set to the first ancestor of the given type.
      Default:
      false
    • root

      boolean root
      If set to true, the owner is set to root object, if matching.
      Default:
      false
    • converter

      Class<? extends groovy.lang.Closure<Object>> converter
      If set, the field or method matches the closure parameter. When set, the converter is executed against the owner object, and the result of the closure is assigned to the field or method.
      Default:
      com.blackbuild.klum.ast.NoClosure.class