Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Info
titleGroovy Plugin Available

There is now a Struts 2 Groovy plugin that largely superceded this page: http://cwiki.apache.org/S2PLUGINS/groovy-plugin.html

GroovyResult - Groovy scripts as a view

...

Here's the code of the actual GroovyResult. This is a verbose version, with a lot of error checking.

  • source code
    Code Block
    java
    java
    titleGroovyResult.java
    
    public class GroovyResult implements Result {
    
    	public final static String GROOVY_DIR_NAME = "groovy";
    
    	private final static Logger logger = Logger.getLogger(GroovyResult.class);
    	//our groovy source file name
    	private String file;
    	//a groovy shell
    	private GroovyShell shell;
    	//our parsed script
    	private Script script;
    	//the outputstream that will replace the 'out' in our groovy stream
    	private OutputStream out;
    	//directory containing groovy scripts
    	private String scriptDirectory;
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
    	 */
    	public void execute(ActionInvocation inv) {
    
    		//check the scriptDirectory - if it doesn't exists, use the default one
    		//WEBAPP + Groovy files directory
    		if (scriptDirectory == null) {
    			//not pretty, but this allows us to get the app root directory
    			String base = ServletActionContext.getServletContext().getRealPath(
    					"/");
    			//if for some reason (.war, apache connector, ..) we can't get the
    			// base path
    			if (base == null) {
    				logger
    						.warn("Could not translate the virtual path \"/\" to set the default groovy script directory");
    				return;
    			}
    			scriptDirectory = base + GROOVY_DIR_NAME;
    			//issue a warning that this directory should NOT be world readable
    			// !!
    			logger
    					.warn("Please make sure your script directory is NOT world readable !");
    		}
    
    		// first of all, make sure our groovy file exists, is readable, and is
    		// an actual file
    
    		File groovyFile = new File(scriptDirectory, file);
    		if (!groovyFile.exists()) {
    			//log an error and return
    			logger.warn("Could not find destination groovy file: "
    					+ groovyFile.getAbsolutePath());
    			return;
    		}
    		if (!groovyFile.isFile()) {
    			//log an error and return
    			logger.warn("Destination is not a file: "
    					+ groovyFile.getAbsolutePath());
    			return;
    		}
    		if (!groovyFile.canRead()) {
    			//log an error and return
    			logger.warn("Can not read file: " + groovyFile.getAbsolutePath());
    			return;
    		}
    
    		if (logger.isDebugEnabled())
    			logger.debug("File " + groovyFile.getPath()
    					+ " found, going to parse it ..");
    
    		/*
    		 * Here we create a Binding object which we populate with the webwork
    		 * stack
    		 */
    		Binding binding = new Binding();
    
    		binding.setVariable("context", ActionContext.getContext());
    
    		/*
    		 * We replace the standard OutputStream with our own, in this case the
    		 * OutputStream from our httpResponse
    		 */
    		try {
    			//the out will be stored in an OutputStream
    			out = ServletActionContext.getResponse().getOutputStream();
    		} catch (IOException e1) {
    			logger.error("Could not open outputstream", e1);
    		}
    		if (out != null){
    			binding.setVariable("out", out);
    		}
    		else {
    			logger
    					.warn("OutputStream not available, using default System.out instead");
    			binding.setVariable("out", System.out);
    		}
    
    		//create a new shell to parse and run our groovy file
    		shell = new GroovyShell(binding);
    		try {
    			//try to parse the script - the returned script could be cached for
    			//performance improvent
    			script = shell.parse(groovyFile);
    		} catch (CompilationFailedException e) {
    			logger.error("Could not parse groovy script", e);
    			return;
    		} catch (IOException e) {
    			logger.error("Error reading groovy script", e);
    			return;
    		}
    		//the binding is set, now run the script
    		Object result = script.run();
    
    		if (logger.isDebugEnabled()) {
    			logger.debug("Script " + groovyFile.getName()
    					+ " executed, and returned: " + result);
    		}
    		try {
    			out.flush();
    		} catch (IOException e2) {
    			logger.error("Could not flush the outputstream", e2);
    		}
    	}
    
    	/**
    	 * @return Returns the script.
    	 */
    	public Script getScript() {
    		return script;
    	}
    	/**
    	 * @param file
    	 *            The file to set.
    	 */
    	public void setFile(String file) {
    		this.file = file;
    	}
    	/**
    	 * @param out
    	 *            The out to set.
    	 */
    	public void setOut(OutputStream out) {
    		this.out = out;
    	}
    

Explanation

The first part of the result is little more than:

  • determining the script directory - defaults to MYWEBAPP/groovy/
  • checking the file - make sure it exists, is readable, ..
    Note

    Make sure the groovy scripts directory is not world readable !

Code Block
java
java
titleThe groovy part
Binding binding = new Binding();
binding.setVariable("context", ActionContext.getContext());

...