How to model collection of similarly typed objects?

I’ve begun experimenting with the new modelling API and I’m looking for advice on the best way to model a collection. I’m using Gradle 2.8.

I would like to model a collection of “things” like:

model {
    things {
        thingOne {
            ...
        }
        thingTwo {
            ...
        }
    }
}

In this case all of my things are of the same type.

Thanks, Chris

Yes, in this case “things” would be a ModelMap<Thing>.

https://docs.gradle.org/current/javadoc/org/gradle/model/ModelMap.html

Thanks for the pointer @mark_vieira.
Does your answer change if I intended on having the names of thingOne and thingTwo be defined by the user? Looking at ManagedModelMapIntegrationTest it seems that the things need to be created by the @Model.

Here’s what I tried:

@Managed
interface Thing extends Named {
    void setAttrib( String attrib )
    String getAttrib()
}
class Rules extends RuleSource {
    @Model void things( ModelMap<Thing> things ) {}
    @Mutate void doSomething( ModelMap<Task> tasks, ModelMap<Thing> things ) {
        println 'doing something'
    }
}
apply plugin: Rules
model {
    things {
        thingOne {
            attrib = 'one'
        }
    }
}

which fails with:

> The following model rules could not be applied due to unbound inputs and/or subjects:
    model.things > named(thingOne)
      subject:
        - things.thingOne Thing [*]
  [*] - indicates that a model item could not be found for the path or type.

unless I use the following instead:

@Model void things( ModelMap<Thing> things ) {
    things.create( 'thingOne' )
}

When creating a new model element via the DSL you have to specify a type.

model {
    things {
        thingOne(Thing) {
            attrib = 'one'
        }
    }
}

Perfect, I got it working, thank you for the help.

I had tried specifying a type earlier but it didn’t work because I forgot to include the type’s package (doh!).

model {
    things {
        thingOne(the.package.Thing) {
            attrib = 'one'
        }
    }
}

Without the type being properly specified you get an error that may not be too clear.

> Exception thrown while executing model rule: model.things
   > Attempt to read a write only view of model of type 'java.lang.Object' given to rule 'model.things'

Thanks again, this is fun stuff and I look forward to seeing it progress.