<commit_before>package org.neo4j.util.shell.apps.extra;

import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.neo4j.util.shell.AppCommandParser;
import org.neo4j.util.shell.Output;
import org.neo4j.util.shell.Session;
import org.neo4j.util.shell.ShellException;

public class GshExecutor
{
	public static final String PATH_STRING = "GSH_PATH";
	public static final String BINDING_CLASS = "groovy.lang.Binding";
	public static final String ENGINE_CLASS = "groovy.util.GroovyScriptEngine";
	
	public void execute( String line, Session session, Output out )
		throws ShellException
	{
		this.ensureGroovyIsInClasspath();
		if ( line == null || line.trim().length() == 0 )
		{
			throw new ShellException( "Need to supply groovy scripts" );
		}
		
		List<String> pathList = this.getEnvPaths( session );
		Object groovyScriptEngine = this.newGroovyScriptEngine(
			pathList.toArray( new String[ pathList.size() ] ) );
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put( "out", out );
		properties.put( "session", session );
		this.runGroovyScripts( groovyScriptEngine, properties, line );
	}

	private void runGroovyScripts( Object groovyScriptEngine,
		Map<String, Object> properties, String line ) throws ShellException
	{
		ArgReader reader = new ArgReader(
			AppCommandParser.tokenizeStringWithQuotes( line ) );
		HashMap<String, Object> hashMap =
			( HashMap<String, Object> ) properties;
		while ( reader.hasNext() )
		{
			String arg = reader.next();
			if ( arg.startsWith( "--" ) )
			{
				String[] scriptArgs = getScriptArgs( reader );
				String scriptName = arg.substring( 2 );
				Map<String, Object> props =
					( Map<String, Object> ) hashMap.clone();
				props.put( "args", scriptArgs );
				this.runGroovyScript( groovyScriptEngine, scriptName,
					this.newGroovyBinding( props ) );
			}
		}
	}
	
	private void runGroovyScript( Object groovyScriptEngine,
		String scriptName, Object groovyBinding ) throws ShellException
	{
		try
		{
			Method runMethod = groovyScriptEngine.getClass().getMethod(
				"run", String.class, groovyBinding.getClass() );
			runMethod.invoke( groovyScriptEngine, scriptName + ".groovy",
				groovyBinding );
		}
		catch ( Exception e )
		{
			throw new ShellException( "Groovy exception: " +
				this.findProperMessage( e ), e );
		}
	}
	
	private String findProperMessage( Throwable e )
	{
		String message = e.getMessage();
		if ( ( message == null || message.length() == 0 ) &&
			e.getCause() != null )
		{
			message = this.findProperMessage( e.getCause() );
		}
		return message;
	}
	<commit_msg>Fixed an issue where the real groovy stacktrace (compilation/runtime error) wouldn't be displayed in the client... the reason was that the nested exception groovy.lang.*Exception couldn't be found on the clients classpath when the object was about to be deserialized by the client. The fix is that the nested exception isn't passed on, but instead the most descriptive message.<commit_after>package org.neo4j.util.shell.apps.extra;

import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.neo4j.util.shell.AppCommandParser;
import org.neo4j.util.shell.Output;
import org.neo4j.util.shell.Session;
import org.neo4j.util.shell.ShellException;

public class GshExecutor
{
	public static final String PATH_STRING = "GSH_PATH";
	public static final String BINDING_CLASS = "groovy.lang.Binding";
	public static final String ENGINE_CLASS = "groovy.util.GroovyScriptEngine";
	
	public void execute( String line, Session session, Output out )
		throws ShellException
	{
		this.ensureGroovyIsInClasspath();
		if ( line == null || line.trim().length() == 0 )
		{
			throw new ShellException( "Need to supply groovy scripts" );
		}
		
		List<String> pathList = this.getEnvPaths( session );
		Object groovyScriptEngine = this.newGroovyScriptEngine(
			pathList.toArray( new String[ pathList.size() ] ) );
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put( "out", out );
		properties.put( "session", session );
		this.runGroovyScripts( groovyScriptEngine, properties, line );
	}

	private void runGroovyScripts( Object groovyScriptEngine,
		Map<String, Object> properties, String line ) throws ShellException
	{
		ArgReader reader = new ArgReader(
			AppCommandParser.tokenizeStringWithQuotes( line ) );
		HashMap<String, Object> hashMap =
			( HashMap<String, Object> ) properties;
		while ( reader.hasNext() )
		{
			String arg = reader.next();
			if ( arg.startsWith( "--" ) )
			{
				String[] scriptArgs = getScriptArgs( reader );
				String scriptName = arg.substring( 2 );
				Map<String, Object> props =
					( Map<String, Object> ) hashMap.clone();
				props.put( "args", scriptArgs );
				this.runGroovyScript( groovyScriptEngine, scriptName,
					this.newGroovyBinding( props ) );
			}
		}
	}
	
	private void runGroovyScript( Object groovyScriptEngine,
		String scriptName, Object groovyBinding ) throws ShellException
	{
		try
		{
			Method runMethod = groovyScriptEngine.getClass().getMethod(
				"run", String.class, groovyBinding.getClass() );
			runMethod.invoke( groovyScriptEngine, scriptName + ".groovy",
				groovyBinding );
		}
		catch ( Exception e )
		{
			// Don't pass the exception on because the client most certainly
			// doesn't have groovy in the classpath.
			throw new ShellException( "Groovy exception: " +
				this.findProperMessage( e ) );
		}
	}
	
	private String findProperMessage( Throwable e )
	{
		String message = e.getMessage();
		if ( e.getCause() != null )
		{
			message = this.findProperMessage( e.getCause() );
		}
		return message;
	}
	
{'fraction_non_alphanumeric': 0.11204293861120429, 'fraction_numerical': 0.0025159342502515934, 'mean_word_length': 4.167244367417678, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6644440', 'n_tokens_mistral': 2081, 'n_tokens_neox': 1812, 'n_words': 480}