I have a situation where I need to determine eligiblity for for one object to "ride" another. The rules for the vehicles are wildly confusing, and I would like to be able to change them without restarting or recompiling my project.
This works but basically makes my security friends convulse and speak in tongues:
class SweetRider{
String stuff
BigDecimal someNumber
BigDecimal anotherNumber
}
class SweetVehicle{
static hasMany=[constraintLinkers:VehicleConstraintLinker]
String vehicleName
Boolean canIRideIt(SweetRider checkRider){
def checkList = VehicleConstraintLinker.findAllByVehicle(this)
checkList.each{
def theClosureObject = it.closureConstraint
def iThinkINeedAShell = new GroovyShell()
def checkerThing = iThinkINeedAShell.evaluate(theClosureObject.closureText)
def result = checkerThing(checkRider)
return result
}
}
}
class VehicleConstraintLinker{
static belongsTo = [closureConstraint:ConstraintByClosure, vehicle:SweetVehicle]
}
class ConstraintByClosure{
String humanReadable
String closureText
static hasMany = [vehicleLinkers:VehicleConstraintLinker]
}
So if I want to add the rule that you are only eligible for a certain vehicle if your "stuff" is "peggy" or "waffles" and your someNumber is greater than your anotherNumber all I have to do is this:
Make a new ConstraintByClosure with humanReadable = "peggy waffle some#>" (thats the human readable explanation) and then add this string as the closureText
{
checkRider->if(
["peggy","waffles"].contains(checkRider.stuff) &&
checkRider.someNumber > checkRider.anotherNumber ) {
return true
}
else {
return false
}
}
Then I just make a VehicleConstraintLinker to link it up and voila.
My question is this: Is there any way to restrict what the GroovyShell can do? Can I make it unable to change any files, globals or database data? Is this sufficient?