2010-11-22 29 views
2

Dans mon application, j'utilise Groovy comme langage de script. Pour faciliter les choses pour mes clients, j'ai une portée globale où je définis des classes et des constantes auxiliaires.Scoping dans les scripts groovy intégrés

Actuellement, je dois exécuter le script (qui construit la portée globale) chaque fois qu'un script utilisateur est exécuté:

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

Est-il possible de configurer cette portée globale une fois et juste dire le script intégré interprète: "Regardez ici si vous ne trouvez pas une variable"? De cette façon, je pourrais lancer le script global une fois.

Remarque: La sécurité n'est pas un problème ici, mais si vous connaissez un moyen de vous assurer que l'utilisateur ne peut pas modifier la portée globale, c'est un avantage supplémentaire.

Répondre

1

Une solution simple est d'utiliser le code de groovy.lang.GroovyShell: Vous pouvez précompiler le script comme ceci:

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); 

Ce WAS la partie coûteuse. Maintenant, utilisez InvokeHelper pour lier le code compilé à un contexte (avec des variables globales) et exécutez-le:

Binding context = new javax.script.Binding(); 
Script script = InvokerHelper.createScript(scriptClass, context); 
script.run(); 
1

de groovy.codehaus volé Shamelessly:

La solution la plus complète pour les personnes qui veulent intégrer des scripts Groovy dans leurs serveurs et ont les rechargées sur la modification est le GroovyScriptEngine. Vous initialisez le GroovyScriptEngine avec un ensemble de CLASSPATH comme des racines qui peuvent être des URL ou des noms de répertoires. Vous pouvez alors exécuter n'importe quel script Groovy dans les racines . Le GSE suivra également dépendances entre les scripts de sorte que si un script dépendant est modifié l'arbre entier sera recompilé et rechargé.

De plus, chaque fois que vous exécutez un script vous pouvez passer dans une liaison qui contient des propriétés que le script peut accéder. Toutes les propriétés définies dans le script seront également disponibles dans la liaison après l'exécution du script. Ici est un exemple simple:

/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!". 

Trouvé: here

Would quelque chose comme ça pour vous?