How to invoke Xtend code from Java? - java

I have a code generator, which takes a syntax tree and converts it into a source file (text).
Basically, it traverses through all nodes of the tree, maps the node to text and appends the resulting texts to a StringBuilder.
Now I want the node to text mappers to be implemented using Xtend like this:
public class NodeXMapper
{
private XtendRunner xtendRunner = ...;
public String map(final NodeX aNode)
{
return xtendRunner.runScript("def String map(NodeX aNode) {
''' «aNode.fieldX» - «aNode.fieldY» '''
}", aNode);
}
}
xtendRunner.runScript(String aScript, final Object... aParams) is a method, which passes the parameters aParams to Xtend script aScript and returns the result.
How can I implement that method?
Update 1: Here I found this piece of code, which seems to run Xtend code in Java:
// setup
XtendFacade f = XtendFacade.create("my::path::MyExtensionFile");
// use
f.call("sayHello",new Object[]{"World"});
But I can't find XtendFacade class in the Type hiearchy view of Eclipse.

The interpreter you found was for the old Xtend1 language, which is not what you are looking for.
The new Xtend you are referring to is compiled, so there is no interpreter.
However, you could build an interpreted expression language using Xbase. See the documentation and Github for an example on how to do that. Then you could run the interpreter of your expression language from Java.

Related

Calling methods between groovy scripts with correct parameters

I just started learning about groovy and trying to transpose my java code to groovy scripts. Usually java allows you have a class with only methods that you can call from other classes. I wanted to translate that to groovy. I have in one file - lets call it File1- a method like this:
def retrieveData(String name){
// do something
}
and in the second file, File2, I call File1 like this:
def file1Class = this.class.classLoader.parseClass(new File("../File1.groovy"))
and then try to call the method in File1 like this:
def data = file1Class.retrieveData("String")
but it keeps giving me this error - MissingMethodException:
groovy.lang.MissingMethodException: No signature of method: static File1.retrieveData() is applicable for argument types: (java.lang.String) values: [String] Possible solutions: retrieveData(java.lang.String)
so it does recognize that I am sending in the correct number of parameters and even the correct object, but it isn't running the method as it should?
Is there something I am missing? I tried to remove the object definition from the method - in other words - like this:
def retrieveData(name){
// do something
}
but that didn't work either. I am clueless about what the next step would be. Can anyone please help push me in the right direction? I would greatly appreciate it.
See the answer provided in this StackOverflow reponse.
Use the GroovyScriptEngine class. What does the GroovyScriptEngine do? From the docs:
Specific script engine able to reload modified scripts as well as
dealing properly with dependent scripts.
See the example below.
def script = new GroovyScriptEngine( '.' ).with {
loadScriptByName( '..\File1.groovy' )
}
this.metaClass.mixin script
retrieveData()
Note how we use the loadScriptByNamemethod to
Get the class of the scriptName in question, so that you can
instantiate Groovy objects with caching and reloading.
This will allow you to access Groovy objects from files however you please.

Creating a Java Object in Scala

I have a Java class "Listings". I use this in my Java MapReduce job as below:
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
Listings le = new Listings(value.toString());
...
}
I want to run the same job on Spark. So, I am writing this in Scala now. I imported the Java class:
import src.main.java.lists.Listings
I want to create a Listings object in Scala. I am doing this:
val file_le = sc.textFile("file// Path to file")
Listings lists = new Listings(file_le)
I get an error:
value lists is not a member of object src.main.java.lists.Listings
What is the right way to do this?
Based on what you've said, I think you may be forgetting the differences between Scala syntax and Java syntax.
Try this:
val lists: Listings = new Listings(SomeString)
Please note that specifying the type in Scala is completely optional. Also, use a var if you're going to be changing the value of lists.
The way you have it, Scala is trying to interpret it by its ability to call methods/access values of an object without the '.', so you're actually telling Scala this:
Listings.lists = new Listings(SomeString)

Clojure RT/Compiler: How to Iterate through forms?

I am working on a Java project that has some Clojure involved. I know how to run compile and run clojure code:
public static void main(String[] args) throws Exception {
RT.init();
runCode();
}
public static Object runCode() {
String str = "(ns my-ns)" +
"(defn add [a b] (+ a b))" +
"(println (add 1 2))";
Compiler.load(new StringReader(str));
/* I know how to invoke it: */
Var foo = RT.var("my-ns", "add");
return foo.invoke(1,2);
}
What would be very useful at the point is to have a way to iterate over forms in Java, and in some sense "analyze" the compiler output. Basic things I want to know is:
What is the text source of a form?
What function is being called in a form.
What arguments are being passed to the function (forms are ok)
Be able to do this on top level forms, or drill in as needed.
Is there a way to do this using the clojure compiler, or runtime (or other Java classes in Clojure?) I see such compiler methods as analyze, for example:
Expr target = analyze(C.EXPRESSION, RT.second(form));
Though its not clear to me yet how form was constructed, and there are no Javadoc :-). Do I need to go The Compiler Source and figure out how it works?

Get declared methods in order they appear in source code

The situation seems to be abnormal, but I was asked to build serializer that will parse an object into string by concatenating results of "get" methods. The values should appear in the same order as their "get" equivalent is declared in source code file.
So, for example, we have
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
The result should be:
"value1 - value2"
An not
"value2 - value1"
It can't be done with Class object according to the documentation. But I wonder if I can find this information in "*.class" file or is it lost? If such data exists, maybe, someone knows a ready to use tool for that purpose? If such information can't be found, please, suggest the most professional way of achieving the goal. I thought about adding some kind of custom annotations to the getters of the class that should be serialized.
If you want that you have to parse the source code, not the byte code.
There are a number of libraries that parse a source file into a node tree, my favorite is the javaparser (hosted at code.google.com), which, in a slightly modified version, is also used by spring roo.
On the usage page you can find some samples. Basically you will want to use a Visitor that listens for MethodDefinitions.
Although reflection does not anymore (as of java 7 I think) give you the methods in the order in which they appear in the source code, the class file appears to still (as of Java 8) contain the methods in the order in which they appear in the source code.
So, you can parse the class file looking for method names and then sort the methods based on the file offset in which each method was found.
If you want to do it in a less hacky way you can use Javassist, which will give you the line number of each declared method, so you can sort methods by line number.
I don't think the information is retained.
JAXB, for example, has #XmlType(propOrder="field1, field2") where you define the order of the fields when they are serialized to xml. You can implemenet something similar
Edit: This works only on concrete classes (the class to inspect has its own .class file). I changed the code below to reflect this. Until diving deeper into the ClassFileAnalyzer library to work with classes directly instead of reading them from a temporary file this limitation exists.
Following approach works for me:
Download and import following libarary ClassFileAnalyzer
Add the following two static methods (Attention! getClussDump() needs a little modification for writing out the class file to a temporary file: I removed my code here because it's very special at this point):
public static String getClassDump(Class<?> c) throws Exception {
String classFileName = c.getSimpleName() + ".class";
URL resource = c.getResource(classFileName);
if (resource == null) {
throw new RuntimeException("Works only for concreate classes!");
}
String absolutePath = ...; // write to temp file and get absolute path
ClassFile classFile = new ClassFile(absolutePath);
classFile.parse();
Info infos = new Info(classFile, absolutePath);
StringBuffer infoBuffer = infos.getInfos();
return infoBuffer.toString();
}
public static <S extends List<Method>> S sortMethodsBySourceOrder(Class<?> c, S methods) throws Exception {
String classDump = getClassDump(c);
int index = classDump.indexOf("constant_pool_count:");
final String dump = classDump.substring(index);
Collections.sort(methods, new Comparator<Method>() {
public int compare(Method o1, Method o2) {
Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator));
Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator));
return i1.compareTo(i2);
}});
return methods;
}
Now you can call the sortMethodsBySourceOrder with any List of methods (because sorting arrays is not very comfortable) and you will get the list back sorted.
It works by looking at the class dumps constant pool which in turn can be determined by the library.
Greetz,
GHad
Write your custom annotation to store ordering data, then use Method.getAnnotation(Class annotationClass)

How can I convert OO Perl to Java?

I inherited large monolithic body of OO Perl code that needs to be gradually converted to Java (per client request). I know both languages but am rusty on my Perl skills. Are there any tools (Eclipse plugins?) that you folks can recommend to ease the pain?
Does OO code use Moose? If yes, it is possible to convert class declarations automatically using introspection.
To gradually convert Perl to Java, you can include Java code into Perl program with Inline::Java.
There is Perl on JVM project, maybe it can be used to compile Perl to Java?
I'd say PLEAC is one of the greatest resources.
The inccode.com allows you to automatically convert the perl code to java code. Nevertheless the conversion of perl variables is slightly tricky due to dynamic typing in perl. The scalar variable in perl can contain the reference to any type and the real referenced type is known when the code is executed.
Translator uses VarBox class for encapsulating all predefined types: ref(HASH), ref(ARRAY) and BoxModule for encapsulating the reference to Perl Modules.
The example show perl script which call two modules to print “hello world”. The module LibConsole is instantiated in script and the module LibPrinter is accessed by calling the method in LibConsole.
#!/usr/bin/perl
use strict;
use test::LibPrinter;
use test::LibConsole;
hello_on_console( "hello world");
hello_on_printer( "hello world");
sub get_console
{
my $console = test::LibConsole->new();
return $console;
}
sub get_printer
{
##cast(module="test::LibPrinter")
my $printer = get_console()->get_printer();
return $printer;
}
sub hello_on_console
{
my ($hello) = #_;
my $console = get_console();
$console->output ($hello);
}
sub hello_on_printer
{
my ($hello) = #_;
my $printer= get_printer();
$printer->output ($hello);
}
Translator must now the types of both modules and while perl don’t define specific operators for declaring the object there’s an assumption that method named “new” return the reference to module. When the method which return reference to module is named otherwise the annotation cast(module=”{class}”) can be used to inform translator about the type of the module.
The identified type of the variable will be propagate because the translator control the conformity of types in assignments.
public class hello extends CRoutineProcess implements IInProcess
{
VarBox call ()
{
hello_on_console("hello world");
return hello_on_printer("hello world");
}
BoxModule<LibConsole> get_console ()
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(LibConsole.apply());
return varConsole;
}
BoxModule<test.LibPrinter> get_printer ()
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_console().getModule().get_printer());
return varPrinter;
}
VarBox hello_on_console (VarBox varHello)
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(get_console());
return varConsole.getModule().output(varHello);
}
VarBox hello_on_printer (VarBox varHello)
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_printer());
return varPrinter.getModule().output(varHello);
}
}
The translated code requires runtime library to be executed.

Categories