编译用户在运行时输入了groovy脚本 [英] Compiling user entered groovy script at run time

查看:150
本文介绍了编译用户在运行时输入了groovy脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class CostCalculator {

字符串名称
字符串groovyScript

静态约束= {
groovyScript:static validateScript = {String script,def obj->
boolean status = true
try {
def shell = new GroovyShell()
def data = shell.parse(script)
data.run()
)catch(Throwable e){
e.printStackTrace()
status = false
}
if(!status){
returndomain.script.compilation .errors
} else {
return true
}
}
}

}



上面代码中的问题是它运行代码,如果有任何异常,它会在运行时抛出它。


$
$ b


  1. groovy代码应该编译而不是运行(代码可能包含数据库级更新)和抛出异常。

  2. groovy代码应该静态编译,例如,如果我们在脚本中缺少一些属性,那么它必须通知。

可能是scr例子ipt:

  void addCost(int x,int y,String itemName){
double cost = x * y + originalCost
Item item = SoldItem.findByItemName(itemName)
item.price + = cost
}


解决方案

我会建议您将groovy脚本放入类中。 方法 addCost(),所以我只是说将这个方法包装在一个类中。例如:

 字符串gScript =
类CostCalculatorScript {
void addCost(int x,int y,String itemName){
double cost = x * y + originalCost
Item item = SoldItem.findByItemName(itemName)
item.price + = cost
}
}
$ b

现在使用GroovyClassLoader加载和分析这个脚本。

  ClassLoader gcl = new GroovyClassLoader()
class clazz = gcl.parseClass(gScript)

验证加载的类与您在脚本中指定的名称相同。

  assert clazz.simpleName =='CostCalculatorScript'



<现在你想要的解决方案看起来像静态编译。您可以将 @ groovy.transform.CompileStatic 注释添加到您的类中。但是有了这个注解,问题在于你不能使用grails或def关键字的动态查找器。



但是如果你仍然需要这个功能,那么你应该使用 @ grails.compiler.GrailsCompileStatic 注解,在Grails 2.4中可用。


Have a scenario as below where I need to validate the groovy script for correctness.

class CostCalculator{

String name
String groovyScript

static constraints = {
groovyScript:static validateScript = {String script ,def obj->
        boolean status = true
        try {
            def shell = new GroovyShell()
            def data = shell.parse(script)
            data.run()
        }catch (Throwable e){
            e.printStackTrace()
            status = false
        }
        if(!status){
            return "domain.script.compilation.errors"
        }else{
            return true
        }
    }
}

}

Problem in above code is that it runs the code and if there is any exception it throws it at runtime.

There are few things to consider:

  1. groovy code should compile rather than running(As code might contain db level updates) and throwing exception.
  2. groovy code should compile statically i.e. for example if we have some property missing in script, then it must get notified.

below could be example script:

void addCost(int x, int y,String itemName){
double cost = x*y + originalCost
Item item = SoldItem.findByItemName(itemName)
item.price += cost
}

解决方案

I would recommend to put your groovy script in a class.

In the example you have method addCost(), so I would say just wrap this method in a class. ex:

String gScript = """
class CostCalculatorScript{
    void addCost(int x, int y,String itemName){
        double cost = x*y + originalCost
        Item item = SoldItem.findByItemName(itemName)
        item.price += cost
    }
}

"""

Now load and parse this script using GroovyClassLoader.

ClassLoader gcl = new GroovyClassLoader()
Class clazz = gcl.parseClass(gScript)

Verify that the loaded class have the same name as you have specified in your script.

assert clazz.simpleName == 'CostCalculatorScript'

Now the kind of solution you want does seem like static compilation. You can add the @groovy.transform.CompileStatic annotation to your class. But with this annotation the problem is that you can't use the dynamic finders of grails or the def keyword.

But if you still want that functionality then you should use @grails.compiler.GrailsCompileStatic annotation which is available in Grails 2.4.

这篇关于编译用户在运行时输入了groovy脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆