ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Dynamic Groovy Script Executor

Groovy

Goal -- WPM

Ready
Exercise Algorithm Area
1import groovy.lang.GroovyShell
2import groovy.lang.Binding
3import java.util.Map
4import java.util.HashMap
5
6class DynamicScriptExecutor {
7
8private GroovyShell shell
9private Binding binding
10
11/**
12* Initializes the executor with a set of global variables.
13* @param globalVariables A map of variable names to their values.
14*/
15DynamicScriptExecutor(Map<String, Object> globalVariables = [:]) {
16binding = new Binding()
17globalVariables.each {
18key, value -> binding.setVariable(key, value)
19}
20shell = new GroovyShell(binding)
21}
22
23/**
24* Executes a given Groovy script string.
25* @param script The Groovy script to execute.
26* @return A map containing 'output' (stdout) and 'result' (return value of the script).
27* Returns null if the script is null or empty.
28*/
29Map<String, Object> executeScript(String script) {
30if (script == null || script.trim().isEmpty()) {
31println "Warning: Script is null or empty."
32return null
33}
34
35// Capture stdout
36ByteArrayOutputStream baos = new ByteArrayOutputStream()
37PrintStream ps = new PrintStream(baos)
38PrintStream originalOut = System.out
39System.setOut(ps)
40
41Object result = null
42try {
43result = shell.evaluate(script)
44} catch (Exception e) {
45println "Error executing script: ${e.getMessage()}"
46e.printStackTrace(ps) // Print stack trace to our stream
47} finally {
48// Restore stdout
49System.out = originalOut
50ps.close()
51}
52
53String output = baos.toString()
54Map<String, Object> executionResult = new HashMap<>()
55executionResult.put("output", output)
56executionResult.put("result", result)
57
58return executionResult
59}
60
61/**
62* Adds or updates a variable in the script's binding.
63* @param name The name of the variable.
64* @param value The value of the variable.
65*/
66void setVariable(String name, Object value) {
67binding.setVariable(name, value)
68}
69
70/**
71* Gets the current value of a variable from the binding.
72* @param name The name of the variable.
73* @return The value of the variable, or null if not found.
74*/
75Object getVariable(String name) {
76return binding.getVariable(name)
77}
78
79/**
80* Main method for demonstration.
81*/
82static void main(String[] args) {
83// Initialize with some global variables
84Map<String, Object> initialGlobals = [
85"appName": "MyDynamicApp",
86"version": 1.5
87]
88DynamicScriptExecutor executor = new DynamicScriptExecutor(initialGlobals)
89
90// Script 1: Simple script with print statements
91String script1 = """
92println "Running script 1 for app: ${appName}"
93def message = "Hello from dynamic script!"
94println message
95message
96"""
97Map<String, Object> result1 = executor.executeScript(script1)
98println "--- Script 1 Results ---"
99println "Output:\n${result1.output}"
100println "Result: ${result1.result}"
101println "------------------------\n"
102
103// Script 2: Script with an error
104String script2 = """
105println "Running script 2 with an error..."
106def x = 10 / 0 // Division by zero
107x
108"""
109Map<String, Object> result2 = executor.executeScript(script2)
110println "--- Script 2 Results ---"
111println "Output:\n${result2.output}"
112println "Result: ${result2.result}"
113println "------------------------\n"
114
115// Script 3: Script that uses a dynamically set variable
116executor.setVariable("dynamicVar", "This is dynamic!")
117String script3 = """
118println "Script 3 using dynamicVar: ${dynamicVar}"
119dynamicVar.length()
120"""
121Map<String, Object> result3 = executor.executeScript(script3)
122println "--- Script 3 Results ---"
123println "Output:\n${result3.output}"
124println "Result: ${result3.result}"
125println "------------------------\n"
126
127// Script 4: Empty script test
128String script4 = ""
129Map<String, Object> result4 = executor.executeScript(script4)
130println "--- Script 4 Results ---"
131println "Output:\n${result4?.output ?: 'N/A'}"
132println "Result: ${result4?.result ?: 'N/A'}"
133println "------------------------\n"
134}
135}
Algorithm description viewbox

Dynamic Groovy Script Executor

Algorithm description:

This Groovy class, `DynamicScriptExecutor`, allows for the execution of arbitrary Groovy code provided as strings. It leverages Groovy's `GroovyShell` and `Binding` classes to manage the execution environment and variables. The system captures standard output from the executed scripts and also returns the script's final evaluated result. It includes robust error handling for exceptions during script execution and handles null or empty script inputs gracefully.

Algorithm explanation:

The `DynamicScriptExecutor` class initializes a `GroovyShell` with a `Binding` object. This `Binding` can be pre-populated with global variables accessible to any script executed. The `executeScript` method takes a script string, redirects `System.out` to a `ByteArrayOutputStream` to capture printed output, and then uses `shell.evaluate(script)` to run the code. Any exceptions thrown during evaluation are caught, their messages and stack traces are printed to the captured output stream, and `System.out` is restored. The method returns a map containing the captured `output` and the script's `result`. The `setVariable` and `getVariable` methods allow for dynamic manipulation of the script's execution context. The time complexity depends heavily on the complexity of the executed script, but the overhead of the executor itself is minimal. Space complexity is primarily determined by the size of the captured output and the complexity of the script's internal state.

Pseudocode:

CLASS DynamicScriptExecutor:
  shell = GroovyShell instance
  binding = Binding instance

  CONSTRUCTOR(globalVariables):
    binding = new Binding()
    FOR EACH key, value IN globalVariables:
      binding.setVariable(key, value)
    END FOR
    shell = new GroovyShell(binding)
  END CONSTRUCTOR

  FUNCTION executeScript(script):
    IF script is null OR empty THEN
      PRINT "Warning: Script is null or empty."
      RETURN null
    END IF

    // Capture stdout
    baos = new ByteArrayOutputStream()
    ps = new PrintStream(baos)
    originalOut = System.out
    System.setOut(ps)

    result = null
    TRY:
      result = shell.evaluate(script)
    CATCH Exception e:
      PRINT "Error executing script: ${e.getMessage()}"
      e.printStackTrace(ps)
    FINALLY:
      System.out = originalOut
      ps.close()
    END TRY

    output = baos.toString()
    executionResult = new map
    executionResult["output"] = output
    executionResult["result"] = result

    RETURN executionResult
  END FUNCTION

  FUNCTION setVariable(name, value):
    binding.setVariable(name, value)
  END FUNCTION

  FUNCTION getVariable(name):
    RETURN binding.getVariable(name)
  END FUNCTION

  FUNCTION main(args):
    // ... (demonstration code) ...
  END FUNCTION
END CLASS