Области применения во встроенных скриптах - PullRequest
2 голосов
/ 22 ноября 2010

В своем приложении я использую Groovy в качестве языка сценариев.Чтобы упростить работу для моих клиентов, у меня есть глобальная область, где я определяю вспомогательные классы и константы.

В настоящее время мне нужно запускать сценарий (который создает глобальную область) каждый раз, когда выполняется сценарий пользователя:

context = setupGroovy();
runScript( context, "global.groovy" ); // Can I avoid doing this step every time?
runScript( context, "user.groovy" );

Можно ли один раз настроить эту глобальную область и просто сказать встроенному интерпретатору сценария: «Посмотрите, не можете ли вы найти переменную»?Таким образом, я мог бы запустить глобальный скрипт один раз.

Примечание. Безопасность здесь не проблема, но если вы знаете способ убедиться, что пользователь не может изменить глобальную область, это дополнительный плюс.

Ответы [ 2 ]

1 голос
/ 04 января 2011

Простым решением является использование кода из groovy.lang.GroovyShell: вы можете предварительно скомпилировать скрипт следующим образом:

    GroovyCodeSource gcs = AccessController.doPrivileged( new PrivilegedAction<GroovyCodeSource>() {
        public GroovyCodeSource run() {
            return new GroovyCodeSource( scriptCode, fileName, GroovyShell.DEFAULT_CODE_BASE );
        }
    } );
    GroovyClassLoader loader = AccessController.doPrivileged( new PrivilegedAction<GroovyClassLoader>() {
        public GroovyClassLoader run() {
            return new GroovyClassLoader( parentLoader, CompilerConfiguration.DEFAULT );
        }
    } );
    Class<?> scriptClass = loader.parseClass( gcs, false );

Это была дорогая часть.Теперь используйте InvokeHelper, чтобы связать скомпилированный код с контекстом (с глобальными переменными) и запустить его:

Binding context = new javax.script.Binding();
Script script = InvokerHelper.createScript(scriptClass, context);
script.run();
1 голос
/ 22 ноября 2010

Бесстыдно похищенный из groovy.codehaus:

Самым полным решением для людей, которые хотят встраивать скрипты groovy в свои серверы и перезагружать их при модификации, является GroovyScriptEngine.Вы инициализируете GroovyScriptEngine с набором CLASSPATH, таких как корни, которые могут быть URL-адресами или именами каталогов.Затем вы можете выполнить любой скрипт Groovy внутри этих корней.GSE также будет отслеживать зависимости между сценариями, так что, если какой-либо зависимый сценарий будет изменен, все дерево будет перекомпилировано и перезагружено.

Кроме того, каждый раз, когда вы запускаете сценарий, вы можете передать Binding, содержащий свойства, которыеСкрипт может получить доступ.Любые свойства, установленные в скрипте, также будут доступны в этой привязке после запуска скрипта.Вот простой пример:

/my/groovy/script/path/hello.groovy:

output = "Hello, ${input}!"
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;

String[] roots = new String[] { "/my/groovy/script/path" };
GroovyScriptEngine gse = new GroovyScriptEngine(roots);
Binding binding = new Binding();
binding.setVariable("input", "world");
gse.run("hello.groovy", binding);
System.out.println(binding.getVariable("output"));
This will print "Hello, world!".

Найдено: здесь

Будет ли что-то подобное работать для вас?

...