Rhino - Passing a javascript object to java - java

Im quite new to Rhino and my question is around how to achieve the following,
Say I have a javascript object that follows something like the following that I can consume within java.
var myObject = new Object();
myObject.string1 = "Hello";
myObject.string2 = "World";
myObject.int1 = 1;
But how do I consume this within java if its dynamic. For .e.g. if you decide to add few more members dynamically to this object within javascript. Is this doable ? My guess is the class defined within java will have to take all the possible members into account to do this ?
Hopefully I have explained what im trying to achieve correctly.

JavaScript objects, when you access them in Java, are all essentially the same class: ScriptableObject which implements the Scriptable interface (GitHub source). There are a few other classes for functions and other specialized objects.
The Scriptable interface includes methods like get, has, and put that correspond roughly to myObject.string1, myObject.hasOwnProperty("string1"), and myObject.string1 = "Hello" in JavaScript. The ScriptableObject class adds some other useful methods for defining properties, etc.

Consider using a library like GSON for converting a javascript object to JAVA.
https://code.google.com/p/google-gson/
you can convert a javascript object to JSON using JSON.stringify
and then use GSON or another such library to generate a Java object.

Related

Best way to wrap Java classes into Python

I have a Java library and I have to build a Python wrapper to it.
I am using py4j, and it's pretty easy to get any instance and any class, complete with method.
The problem is that the type of an object doesn't correspond to its class.
From python:
>>> gw = JavaGateway()
>>> a_circle = gw.jvm.com.geometry.Circle(15)
>>> a_circle.getDiameter()
30
>>> type(a_circle)
<class 'py4j.java_gateway.JavaObject'>
This is almost ok for basic usage, but what if I want to create custom constructors? Should I subclass the JavaObject class? Or it's better to create my classes from scratch and for every method and constructor invoke the corresponding Java method?
Any suggestion for a good way to achieve it? Should i try something different than py4j?
Thank you!
EDIT: for example, I have to wrap a Java class that has 3 methods, one of those methods takes an array as parameter, so I have to inject some code in order to convert.
class Service:
def __init__(self, javaService):
'''
Create a new instance of Service, assigning Java methods as attributes.
Accepts a working instance of Service from Java
This constructor is not meant to be called by the user.
'''
self.subscribe = javaService.subscribe
self.unsubscribe = javaService.unsubscribe
def publish(values):
'''
Wraps the java implementation of this method, converting the list of value from a Python iterable to a Java list.
'''
global java_gateway
parameterValues = ListConverter().convert(values, java_gateway._gateway_client)
return javaService.publish(values)
self.publish = publish
This works, but I am doing only when it is necessary. If the class just works directly, I am not writing anything to wrap it.

How to share an object state between java and prolog with JPL?

I want to create an object in java:
MyObject obj = new MyObject ();
and I want to pass it to prolog with a jpl query.
How can I accomplish java to prolog object passing?
I know that I could use jpl_new in a prolog file like this:
execMethod :-
jpl_new('my_package.MyObject', [], Object),
jpl_call(Object, myMethod, [], _ ).
But, I want to avoid the jpl_new call and just use the jpl_call with the java object obj.
And converserly,
How can I accomplish prolog to java object passing?
I mean passing to java, objects created with a jpl_new call.
In other words, I want to share an object state between java and prolog.
To access a Prolog knowledge base from within Java, you can use JPL Queries. Let's look at a simple, trivial example below:
% Knowledge base (Prolog)
foo(x,bar).
all_foo(X,Y) :- foo(X,Y).
In java, we could then write:
String query = "all_foo(x,Y)";
System.out.println("First solution: " + Query.oneSolution(query).get("Y"));
which would return 'bar' as answer in Y.
Vice versa -as you showed in your question- JPL can be used when we want to access Java functionality from within a Prolog file.
Firstly, looking at the docs of jpl_call/4, we see that its first arguments can be:
a type, class object or classname (for static methods of the denoted class, or for static or instance methods of java.lang.Class)
a class instance or array (for static or instance methods)
So you are free in how to pass your class information to jpl_call/4 to execute certain methods.
Subsequently, you can access your Java model rather than executing logic by using jpl_get/3. An example below is shown where we bind the Prolog variable Colour to a reference of a field of a Java car object held in the static final .colour field of the example.class.car class.
jpl_get('example.class.car', colour, Colour)
More generally:
jpl_get(+Class_or_Object, +Field, -Datum)
Hope this helped.
Good luck!

How to cast variables in python with jcc

In java it is possible to cast an object onto a class.
An good example is found here
Object aSentenceObject = "This is just a regular sentence";
String aSentenceString = (String)aSentenceObject;
I have a program that needs to integrate some java with python. I am trying to do this via the JCC library. The problem that I am encountering is that with JCC, all of the java classes are loaded into the imported library that I created with JCC. So I can create an instance of the base class by passing the necessary argument to the constructor of the java class.
obj = javaLibrary.BaseClass('foo')
However, in my code I need to be able to cast this object onto a a more “specific” type of Object.
How can I accomplish this in python with JCC? It seems like it may be impossible because python is dynamically typed, but that is why I am asking this question.
All comments above valid, but to be specific for your case:
casted_obj = Object.cast_(obj)

Programmatically constructing Java code?

I am working on a module where I have to convert a set of logical representations and other data into Java source code.
I would like to be able to first convert them to an intermediary representation of Java elements (classes, methods, etc), and then convert this intermediary representation to an actual String/textfile.
for example, I would like to just be able to construct an element like this:
JavaClass myClass = new JavaClass("MyClass", "MyParent", new String[] {"MyInterface", "MySecondInterface"});
and then have the toString() method of myClass output something like:
class MyClass extends MyParent implements MyInterface, MySecondInterface { }
and so on and so forth for variables, methods, statements etc - preferably with formatting. The example is oversimplified just for the sake of demonstration - in reality I would prefer a representation that at least resembles an abstract syntax tree.
I have looked at the com.sun.org.apache.bcel.* package, but since it is meant for bytecode it does not help much here. Transformation frameworks (such as Recoder) also do not seem to be what I am looking for.
Can anyone recommend a framework I can use for this?
You could use a template engine like freemarker. Write a 'class' template and use freemarker to put in your data. Really simple to use. Freemarker support everything you need like interation, conditions, ...
You should look into Javassist. It has a really simple API for creating classes on the fly.

How to convert a Java object to key-value pair without using reflection

Is it possible to convert a plain Java Object with the usual getXXX and setXXX methods for its fields to a key-value pair, like Map<String, Object>?
I need to to this without relying on Java reflection, so it can be used with a Java-To-Javascript compiler like GWT.
GWT comes with a mechanism called Deferred Binding as a replacement for reflection. While normally you only use this API by calling GWT.create(Class<?>), it can also be used to write code generators that are invoked during the GWT compile process (i.e. the Java-to-Javascript translation).
You could use this to create a code generator that will output for any of your POJO classes
a helper class which would contain the toMap() and fromMap() methods. GWT offers an API that is kind of similar to Java's reflection API with classes like JClassType, JMethod, etc. These can be used to query classes (that you want to generate code for) for their getters and setters and generate the above-mentioned methods accordingly.
Your client code would then basically look like this:
Pojo1 pojo1 = ...;
// Pojo1Transformer is the class that is generated for your domain class Pojo1
Pojo1Transformer pojo1Transformer = GWT.create(Pojo1Transformer.class);
Map<String, Object> pojo1AsMap = pojo1Transformer.toMap(pojo1);
...
pojo1AsMap.put(Pojo1Transformer.NAME, "New Name");
Pojo1 changed = pojo1Transformer.fromMap(pojo1AsMap);
I've done this before by using a MapSerialisation interface:
interface MapSerialisation {
Map<String, Object> toMap();
void fromMap(Map<String, Object>);
}
Implement that on each of your model objects and use that for translation.
Another method I've used is Google Collections' Transformers, and having model transformation functions to convert between a Java object and a structure that Javascript would like.
I'd probably be tempted to use Jackson to serialise into JSON though.
Reflection is the most logical way to do this, some might argue that Class GetMethods / Fields are not technically reflection altogether.
One way to do this is to implement toHash() function where you could explicitly create a Hashtable / Map of your Object.

Categories

Resources