sábado, 30 de janeiro de 2010

Invocação de funções e métodos do Python no Java (JSR-223)

Funções e métodos definidos no python podem ser invocados através da interface javax.script.Invocable. No Jython, essa interface é implementada também na mesma classe que implementa as interfaces javax.script.ScriptEngine e javax.script.Compilable. Portanto, é só chamar a fábrica de ScriptEngine para o python e obtendo uma instância de javax.script.ScriptEngine, fazer uma coerção para javax.script.Invocable. Abaixo temos dois exemplos para invocação de função definida no código fonte python no Java.

Observação: Se a função / método invocado não existirem no código python executado, será lançada um exceção java.lang.NoSuchMethodException indicando que não existe a função / método invocado.


Primeiro exemplo - Invocando função python que foi executado pelo método "eval" de javax.script.ScriptEngine
--------------------------------------------------------------------------------
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class PythonInvocableTest {

/**
* @param args
* @throws
*/
public static void main(String[] args) {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager
.getEngineByName("python");

if (scriptEngine != null) {

try {
scriptEngine
.eval("def imprimeTest(str): \n return str + u' Método invocado!' ");
} catch (ScriptException e) {
e.printStackTrace();
}

if (scriptEngine instanceof Invocable) {
Invocable invocable = (Invocable) scriptEngine;

Object object = null;

try {
object = invocable.invokeFunction("imprimeTest",
"oi jython!!");

} catch (ScriptException e1) {
e1.printStackTrace();

} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}

if (object instanceof String) {
String str = (String) object;
System.out.println("Retorno do método: " + str);
}
}
}

System.out.println("Terminado com sucesso!!");
}
}

--------------------------------------------------------------------------------


Segundo exemplo - Invocando função python que foi executado pelo método "eval" de javax.script.Compilable
--------------------------------------------------------------------------------
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class PythonInvocableTest2 {

/**
* @param args
*/
public static void main(String[] args) {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager
.getEngineByName("python");

if (scriptEngine != null) {

if (scriptEngine instanceof Compilable) {
Compilable compilable = (Compilable) scriptEngine;

CompiledScript compiledScript = null;

try {
compiledScript = compilable
.compile("def imprimeTest(str): \n return str + u' Método invocado!'");

} catch (ScriptException e) {
e.printStackTrace();
}

if (compiledScript != null) {

try {
compiledScript.eval();

} catch (ScriptException e) {
e.printStackTrace();
}
}
}

if (scriptEngine instanceof Invocable) {
Invocable invocable = (Invocable) scriptEngine;

Object object = null;

try {
object = invocable.invokeFunction("imprimeTest",
"oi jython!!");

} catch (ScriptException e1) {
e1.printStackTrace();

} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}

if (object instanceof String) {
String str = (String) object;
System.out.println("Retorno do método: " + str);
}
}
}

System.out.println("Terminado com sucesso!!");
}
}

--------------------------------------------------------------------------------


Terceiro exemplo - Invocando método da classe "A" definido no código python usando um objeto python.
--------------------------------------------------------------------------------
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class PythonInvocableTest3 {

/**
* @param args
*/
public static void main(String[] args) {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager
.getEngineByName("python");

if (scriptEngine != null) {

try {
scriptEngine
.eval("class A:\n def imprimeTest(self, str): \n return str + u' Método invocado!' + unicode(self.__class__()) \na = A()");
} catch (ScriptException e) {
e.printStackTrace();
}

if (scriptEngine instanceof Invocable) {
Invocable invocable = (Invocable) scriptEngine;

Object objectPython = scriptEngine.get("a");

Object object = null;

try {
object = invocable.invokeMethod(objectPython,
"imprimeTest", "oi jython!!");

} catch (ScriptException e1) {
e1.printStackTrace();

} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}

if (object instanceof String) {
String str = (String) object;
System.out.println("Retorno do método: " + str);
}
}
}

System.out.println("Terminado com sucesso!!");
}
}

--------------------------------------------------------------------------------

2 comentários: