Bug 534634: [Python] support import statements for EASE modules

  changed code generation to access class whenever possible
  added fixes for groovy/ruby to access static elements
  fixed jruby bootstrapper

Change-Id: I82eddffce91144fc02ae081e60819216519dac83
diff --git a/plugins/org.eclipse.ease.lang.groovy/src/org/eclipse/ease/lang/groovy/GroovyCodeFactory.java b/plugins/org.eclipse.ease.lang.groovy/src/org/eclipse/ease/lang/groovy/GroovyCodeFactory.java
index dae3367..f8ede86 100644
--- a/plugins/org.eclipse.ease.lang.groovy/src/org/eclipse/ease/lang/groovy/GroovyCodeFactory.java
+++ b/plugins/org.eclipse.ease.lang.groovy/src/org/eclipse/ease/lang/groovy/GroovyCodeFactory.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.ease.lang.groovy;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
@@ -146,6 +147,21 @@
 	}
 
 	@Override
+	protected String createFieldWrapper(IEnvironment environment, String identifier, Field field) {
+		final StringBuilder groovyCode = new StringBuilder();
+
+		groovyCode.append(field.getName());
+		groovyCode.append(" = ");
+		groovyCode.append(identifier);
+		groovyCode.append('.');
+		groovyCode.append(field.getName());
+		groovyCode.append(';');
+		groovyCode.append(StringTools.LINE_DELIMITER);
+
+		return groovyCode.toString();
+	}
+
+	@Override
 	public String createFunctionWrapper(final IEnvironment environment, final String moduleVariable, final Method method) {
 
 		final String methodId = ((EnvironmentModule) environment).registerMethod(method);
diff --git a/plugins/org.eclipse.ease.lang.javascript/src/org/eclipse/ease/lang/javascript/JavaScriptCodeFactory.java b/plugins/org.eclipse.ease.lang.javascript/src/org/eclipse/ease/lang/javascript/JavaScriptCodeFactory.java
index 4880eab..6927686 100644
--- a/plugins/org.eclipse.ease.lang.javascript/src/org/eclipse/ease/lang/javascript/JavaScriptCodeFactory.java
+++ b/plugins/org.eclipse.ease.lang.javascript/src/org/eclipse/ease/lang/javascript/JavaScriptCodeFactory.java
@@ -257,6 +257,21 @@
 		return javaScriptCode.toString();
 	}
 
+	@Override
+	protected String createFieldWrapper(IEnvironment environment, String identifier, Field field) {
+		final StringBuilder javaScriptCode = new StringBuilder();
+
+		javaScriptCode.append(field.getName());
+		javaScriptCode.append(" = ");
+		javaScriptCode.append(identifier);
+		javaScriptCode.append('.');
+		javaScriptCode.append(field.getName());
+		javaScriptCode.append(';');
+		javaScriptCode.append(StringTools.LINE_DELIMITER);
+
+		return javaScriptCode.toString();
+	}
+
 	private String buildMethodBody(List<Parameter> parameters, Method method, String classIdentifier) {
 		final StringBuilder body = new StringBuilder();
 		// insert parameter checks
diff --git a/plugins/org.eclipse.ease.lang.python/src/org/eclipse/ease/lang/python/PythonCodeFactory.java b/plugins/org.eclipse.ease.lang.python/src/org/eclipse/ease/lang/python/PythonCodeFactory.java
index 9649c36..dbb6c80 100644
--- a/plugins/org.eclipse.ease.lang.python/src/org/eclipse/ease/lang/python/PythonCodeFactory.java
+++ b/plugins/org.eclipse.ease.lang.python/src/org/eclipse/ease/lang/python/PythonCodeFactory.java
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.eclipse.ease.lang.python;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -145,6 +146,34 @@
 	}
 
 	@Override
+	protected String createFieldWrapper(IEnvironment environment, String identifier, Field field) {
+		final StringBuilder pythonCode = new StringBuilder();
+
+		pythonCode.append("import sys").append(StringTools.LINE_DELIMITER);
+
+		pythonCode.append("if \"py4j\" in sys.modules:").append(StringTools.LINE_DELIMITER);
+		pythonCode.append("    ");
+		pythonCode.append(field.getName());
+		pythonCode.append(" = py4j.java_gateway.get_field(");
+		pythonCode.append(identifier);
+		pythonCode.append(", \"");
+		pythonCode.append(field.getName());
+		pythonCode.append("\")");
+		pythonCode.append(StringTools.LINE_DELIMITER);
+
+		pythonCode.append("else:").append(StringTools.LINE_DELIMITER);
+		pythonCode.append("    ");
+		pythonCode.append(field.getName());
+		pythonCode.append(" = ");
+		pythonCode.append(identifier);
+		pythonCode.append(".");
+		pythonCode.append(field.getName());
+		pythonCode.append(StringTools.LINE_DELIMITER);
+
+		return pythonCode.toString();
+	}
+
+	@Override
 	public String createFunctionWrapper(IEnvironment environment, final String moduleVariable, final Method method) {
 
 		final StringBuilder pythonCode = new StringBuilder();
diff --git a/plugins/org.eclipse.ease.lang.ruby.jruby/src/org/eclipse/ease/lang/ruby/jruby/JRubyEnvironementBootStrapper.java b/plugins/org.eclipse.ease.lang.ruby.jruby/src/org/eclipse/ease/lang/ruby/jruby/JRubyEnvironementBootStrapper.java
index 149edb1..87dc448 100644
--- a/plugins/org.eclipse.ease.lang.ruby.jruby/src/org/eclipse/ease/lang/ruby/jruby/JRubyEnvironementBootStrapper.java
+++ b/plugins/org.eclipse.ease.lang.ruby.jruby/src/org/eclipse/ease/lang/ruby/jruby/JRubyEnvironementBootStrapper.java
@@ -22,6 +22,6 @@
 	public void createEngine(final IScriptEngine engine) {
 		// load environment module
 		engine.executeAsync("java_import org.eclipse.ease.modules.EnvironmentModule");
-		engine.executeAsync("org.eclipse.ease.modules.EnvironmentModule.new().bootstrap()");
+		engine.executeAsync("org.eclipse.ease.modules.EnvironmentModule.bootstrap()");
 	}
 }
diff --git a/plugins/org.eclipse.ease.lang.ruby/src/org/eclipse/ease/lang/ruby/RubyCodeFactory.java b/plugins/org.eclipse.ease.lang.ruby/src/org/eclipse/ease/lang/ruby/RubyCodeFactory.java
index 6b02a31..c015600 100644
--- a/plugins/org.eclipse.ease.lang.ruby/src/org/eclipse/ease/lang/ruby/RubyCodeFactory.java
+++ b/plugins/org.eclipse.ease.lang.ruby/src/org/eclipse/ease/lang/ruby/RubyCodeFactory.java
@@ -10,7 +10,9 @@
  *******************************************************************************/
 package org.eclipse.ease.lang.ruby;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,6 +38,21 @@
 	}
 
 	@Override
+	protected String createFieldWrapper(IEnvironment environment, String identifier, Field field) {
+		final StringBuilder groovyCode = new StringBuilder();
+
+		groovyCode.append(field.getName());
+		groovyCode.append(" = ");
+		groovyCode.append(field.getDeclaringClass().getName());
+		groovyCode.append("::");
+		groovyCode.append(field.getName());
+		groovyCode.append(';');
+		groovyCode.append(StringTools.LINE_DELIMITER);
+
+		return groovyCode.toString();
+	}
+
+	@Override
 	public String createFunctionWrapper(final IEnvironment environment, final String moduleVariable, final Method method) {
 
 		final String methodId = ((EnvironmentModule) environment).registerMethod(method);
@@ -62,7 +79,11 @@
 				.append(parameters.isEmpty() ? "" : ", ").append(parameterList).append(");").append(StringTools.LINE_DELIMITER);
 
 		// insert method call
-		body.append("\t").append(RESULT_NAME).append(" = ").append('$').append(moduleVariable).append('.').append(method.getName()).append('(');
+		if (Modifier.isStatic(method.getModifiers()))
+			body.append("\t").append(RESULT_NAME).append(" = ").append(method.getDeclaringClass().getName()).append('.').append(method.getName()).append('(');
+		else
+			body.append("\t").append(RESULT_NAME).append(" = ").append('$').append(moduleVariable).append('.').append(method.getName()).append('(');
+
 		body.append(parameterList);
 		body.append(");\n");
 
diff --git a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractCodeFactory.java b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractCodeFactory.java
index 9d1feb6..950b954 100644
--- a/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractCodeFactory.java
+++ b/plugins/org.eclipse.ease/src/org/eclipse/ease/AbstractCodeFactory.java
@@ -297,24 +297,11 @@
 			// create wrappers for final fields
 			for (final Field field : ModuleHelper.getFields(instance.getClass())) {
 				if (isSupportedByLanguage(field)) {
-					try {
-						final Object toBeInjected = field.get(instance);
+					final String code = createFieldWrapper(environment, identifier, field);
 
-						// only wrap if field is not already declared
-						if (!engine.hasVariable(getSaveVariableName(field.getName()))) {
-							engine.setVariable(getSaveVariableName(field.getName()), toBeInjected);
-
-						} else {
-							// see if the defined variable equals the one we want to set
-							final Object existing = engine.getVariable(getSaveVariableName(field.getName()));
-							if (((existing != null) && (!existing.equals(toBeInjected))) || ((existing == null) && (toBeInjected != null))) {
-								Logger.trace(Activator.PLUGIN_ID, ICodeFactory.TRACE_MODULE_WRAPPER, "Skipped wrapping of field \"" + field.getName()
-										+ "\" (module \"" + instance.getClass().getName() + "\") as variable is already declared.");
-							}
-						}
-
-					} catch (final IllegalArgumentException | IllegalAccessException e) {
-						Logger.error(Activator.PLUGIN_ID, "Could not wrap field \"" + field.getName() + " \" of module \"" + instance.getClass() + "\".", e);
+					if ((code != null) && !code.isEmpty()) {
+						scriptCode.append(code);
+						scriptCode.append('\n');
 					}
 				}
 			}
@@ -389,7 +376,7 @@
 	protected abstract Object getLanguageIdentifier();
 
 	/**
-	 * Create code for a wrapper function in the global namespace of the script engine.
+	 * Create code for a method wrapper function in the global namespace of the script engine.
 	 *
 	 * @param environment
 	 *            environment instance
@@ -402,6 +389,19 @@
 	protected abstract String createFunctionWrapper(IEnvironment environment, String identifier, Method method);
 
 	/**
+	 * Create code for a field wrapper function in the global namespace of the script engine.
+	 *
+	 * @param environment
+	 *            environment instance
+	 * @param identifier
+	 *            function name to be used
+	 * @param field
+	 *            field to refer to
+	 * @return script code to be injected into the script engine
+	 */
+	protected abstract String createFieldWrapper(IEnvironment environment, String identifier, Field field);
+
+	/**
 	 * Convert a given name to a script language safe name. To make sure it is safe we check against a list of given keywords. We then append '_' until the
 	 * value is save.
 	 *