martes, noviembre 11, 2014

groovy dinámico

Los closures en groovy son muy utilizados, pero transformar metodos a closures no tanto, hay muchas ventajas como poder pasarlos como parametros de funciones o como valores en un mapa, para esto se ocupa el operador (.&)

13   def dynamicMethods = [[regex:"hasPermission(.*)", method:this.&hasPermission],
14   [regex:"create(.*)Permission", method:this.&createPermission]]


En este caso estamos convirtiendo el método hasPermission() y createPermission() en un closure y pasandoselo a un mapa, el metodo puede ser llamado como se muestra en la línea 21.

17   def methodMissing(String name, args) {
18   | def method = dynamicMethods.find { name =~ it.regex}
19   | if(method) {
20   | | def match = name =~ method.regex
21   | | return method.method(match[0][1], * args)
22   | } else
23   | | throw new MissingMethodException(name, DemoDynamic , args)
24   }
25 
26 }

Ocupando una expresión regular y methodMissing podemos mandar a llamar dinámicamente el método que vive en el mapa.

32 assert demo.hasPermissionHgmiguel("write")
33 assert !demo.hasPermissionOtros("write")

Dejo un Gist como ejemplo de lo que quiero explicar:
class DemoDynamic {
Map<String, List<String>> permissions = [:]
Boolean hasPermission(String name, String permission){
permission in permissions?."$name"
}
Map createPermission(String name, List<String> permissions) {
this.permissions?."$name" = permissions
this.permissions
}
def dynamicMethods = [[regex:"hasPermission(.*)", method:this.&hasPermission],
[regex:"create(.*)Permission", method:this.&createPermission]]
def methodMissing(String name, args) {
def method = dynamicMethods.find { name =~ it.regex}
if(method) {
def match = name =~ method.regex
return method.method(match[0][1], * args)
} else
throw new MissingMethodException(name, DemoDynamic , args)
}
}
demo = new DemoDynamic()
demo.createHgmiguelPermission(["write","read"])
demo.createOtrosPermission(["read"])
assert demo.hasPermissionHgmiguel("write")
assert !demo.hasPermissionOtros("write")

No hay comentarios.: