|
Groovy example source code file (ArithmeticShell.groovy)
The Groovy ArithmeticShell.groovy source codeimport org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.MultipleCompilationErrorsException import org.codehaus.groovy.control.customizers.ImportCustomizer import org.codehaus.groovy.control.customizers.SecureASTCustomizer import org.codehaus.groovy.control.messages.ExceptionMessage import static org.codehaus.groovy.syntax.Types.* import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.StaticMethodCallExpression import org.codehaus.groovy.ast.expr.ArgumentListExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.UnaryMinusExpression import org.codehaus.groovy.ast.expr.UnaryPlusExpression import org.codehaus.groovy.ast.expr.PrefixExpression import org.codehaus.groovy.ast.expr.PostfixExpression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.expr.ElvisOperatorExpression import org.codehaus.groovy.ast.expr.BooleanExpression import org.codehaus.groovy.ast.expr.ClassExpression /** * The arithmetic shell is similar to a GroovyShell in that it can evaluate text as * code and return a result. It is not a subclass of GroovyShell because it does not widen * the contract of GroovyShell, instead it narrows it. Using one of these shells like a * GroovyShell would result in many runtime errors. * * @author Hamlet D'Arcy (hamletdrc@gmail.com) * @author Guillaume Laforge */ class ArithmeticShell { /** * Compiles the text into a Groovy object and then executes it, returning the result. * @param text * the script to evaluate typed as a string * @throws SecurityException * most likely the script is doing something other than arithmetic * @throws IllegalStateException * if the script returns something other than a number */ Number evaluate(String text) { try { final ImportCustomizer imports = new ImportCustomizer().addStaticStars('java.lang.Math') // add static import of java.lang.Math final SecureASTCustomizer secure = new SecureASTCustomizer() secure.with { closuresAllowed = false methodDefinitionAllowed = false importsWhitelist = [] staticImportsWhitelist = [] staticStarImportsWhitelist = ['java.lang.Math'] // only java.lang.Math is allowed tokensWhitelist = [ PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, PLUS_PLUS, MINUS_MINUS, COMPARE_EQUAL, COMPARE_NOT_EQUAL, COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL, COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL, ].asImmutable() constantTypesClassesWhiteList = [ Integer, Float, Long, Double, BigDecimal, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE ].asImmutable() receiversClassesWhiteList = [ Math, Integer, Float, Double, Long, BigDecimal ].asImmutable() statementsWhitelist = [ BlockStatement, ExpressionStatement ].asImmutable() expressionsWhitelist = [ BinaryExpression, ConstantExpression, MethodCallExpression, StaticMethodCallExpression, ArgumentListExpression, PropertyExpression, UnaryMinusExpression, UnaryPlusExpression, PrefixExpression, PostfixExpression, TernaryExpression, ElvisOperatorExpression, BooleanExpression, // ClassExpression needed for processing of MethodCallExpression, PropertyExpression // and StaticMethodCallExpression ClassExpression ].asImmutable() } CompilerConfiguration config = new CompilerConfiguration() config.addCompilationCustomizers(imports, secure) GroovyClassLoader loader = new GroovyClassLoader(this.class.classLoader, config) Class clazz = loader.parseClass(text) Script script = (Script) clazz.newInstance(); Object result = script.run() if (!(result instanceof Number)) throw new IllegalStateException("Script returned a non-number: $result"); return (Number) result } catch (SecurityException ex) { throw new SecurityException("Could not evaluate script: $text", ex) } catch (MultipleCompilationErrorsException mce) { //this allows compilation errors to be seen by the user mce.errorCollector.errors.each { if (it instanceof ExceptionMessage && it.cause instanceof SecurityException) { throw it.cause } } throw mce } } } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy ArithmeticShell.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.