У меня есть ситуация, когда мне нужно определить право на то, чтобы один объект «ездил» на другом. Правила для транспортных средств сильно сбивают с толку, и я хотел бы изменить их, не перезапуская и не перекомпилируя мой проект.
Это работает, но в основном заставляет моих друзей по безопасности судорожно говорить и говорить на языках:
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]
}
Так что, если я хочу добавить правило, согласно которому вы имеете право только на определенное транспортное средство, если ваш «материал» «пегги» или «вафли», а ваш someNumber больше, чем ваш anotherNumber, все, что мне нужно сделать, это:
Создайте новый ConstraintByClosure с humanReadable = "peggy waffle some #>" (это объяснение, понятное человеку), а затем добавьте эту строку как closureText
{
checkRider->if(
["peggy","waffles"].contains(checkRider.stuff) &&
checkRider.someNumber > checkRider.anotherNumber ) {
return true
}
else {
return false
}
}
Тогда я просто создаю привязку VehicleConstraintLinker, чтобы связать ее и вуаля.
Мой вопрос таков: есть ли способ ограничить то, что может делать GroovyShell? Могу ли я сделать невозможным изменение каких-либо файлов, глобальных переменных или данных базы данных? Достаточно ли этого?