Indexed access on Java objects
Opened this issue · 5 comments
Hello.
I want to use indexed/key access on Java objects which are not maps, lists or arrays. In Rhino it could be done by overriding public Object get(int index); public Object get(String key);
on wrapper objects. Is there any way to achieve same with your library? Sorry if it mentioned somewhere, but I could not find an answer.
Thank you.
Hi @anri-vin ,
Thanks for reaching out! When you say indexed/key access, do you mean that, given an instance of the following Java class:
public class MyJavaClass {
public String myString = "Hello, World!";
public int myInteger = 1337;
}
The following JavaScript code:
console.log(myJavaClassInstance["myString"]);
console.log(myJavaClassInstance.myInteger);
Would output the following to the console:
Hello, World!
1337
If so, I do not think we have a built-in feature for this; @AlexTrotsenko may be able to chime in, as he has added quite a few features along these lines in the past. If we do not have a feature for this, there are probably a few ways to implement one, but I will not be able to take charge of that at the moment.
@crahda yes it's implemented. But for encapsulation reasons it uses get/set property (as @anri-vin actually posted)
It can be replaced with
"var x = new WannabeBeanNoAnnotations(); x['i'] = 6688; x.i;"
I think we are not completely understanding each other. What I want is when I have Java class like this:
class JavaObject {
private Object[] internalArray = ...;
public Object getProperty(int index) {
return internalArray[index];
}
public void setProperty(int index, Object value) {
internalArray[index] = value;
}
}
calling JS as following
javaObject[42]; javaObject[42] = 0;
will internally call getProperty and setProperty.
@anri-vin as far as I know - this behaviour with indexed setter is not implemented. Since I have not used this one in Rhino either - it's a bit hard to tell you want should be the easiest way to achieve this (as I am not sure about exact use case).
I would start looking in the io.alicorn.v8.V8JavaClassInterceptor
api. If it's not matching your needs - then as @crahda mentioned - you can probably try implement one yourself. Normally @crahda is quite fast to reviewing PR.
Also if you are using latest version of J2V8 and thus newer V8 itself - you can likely use JS Proxy api in you app and redirect requests to the set/get methods of your object (actually Js proxy object of your Java object). I was experimenting with it in this PR, but since proxies are not supported in J2V8 4.6.0
(current target of this lib) - I skipped this change for now.
I found a solution at the moment. It's not as pretty as it can be, but it works. After injecting object to JS I execute following script for each entry in internal array (0 - is index):
v8.executeScript("Object.defineProperty(javaObject, 0, { get: function() { return this.getProperty(\"0\"); }});")