Skip to content

Instantly share code, notes, and snippets.

@int128
Last active August 29, 2015 14:05
Show Gist options
  • Save int128/e20570487e4d497934a9 to your computer and use it in GitHub Desktop.
Save int128/e20570487e4d497934a9 to your computer and use it in GitHub Desktop.
named object collection
class Catcher {
final Map<String, Closure> nameAndClosure = [:]
def methodMissing(String name, args) {
assert args.length == 1
assert args[0] instanceof Closure
nameAndClosure.put(name, args[0])
}
}
def remotes(Closure c) {
def catcher = new Catcher()
catcher.with(c)
catcher.nameAndClosure
}
remotes {
webServer {
role 'serversA'
host = 'web'
user = 'webuser'
}
appServer {
host = 'app'
user = 'appuser'
}
}
class NamedObjectCollection<T> implements Collection<T> {
private final Map<String, T> map = [:]
@Delegate
private final Collection<T> list = map.values()
@Override
boolean add(T o) {
map.put(o.name, o)
}
T get(String name) {
map[name]
}
void set(String name, T o) {
assert name == o.name
add(o)
}
}
@groovy.transform.Immutable
class Remote {
String name
int x
List<String> roles = []
}
trait RoleAccessor {
static interface KeyAccessor {
Collection<Remote> get(String name)
}
final KeyAccessor role = [get: { name -> role(name) }] as KeyAccessor
Collection<Remote> role(String name) {
findAll { remote -> remote.roles.contains(name) }
}
}
class Remotes extends NamedObjectCollection<Remote> implements RoleAccessor {
}
def remotes = new Remotes()
remotes.add(new Remote(name: 'hoge', x: 1, roles: ['web']))
remotes.fuga = new Remote(name: 'fuga', x: 2)
println remotes
println remotes.role('web')
println remotes.role.web
println remotes.role('db')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment