Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indexed access on Java objects #30

Open
anri-vin opened this issue Nov 26, 2018 · 5 comments
Open

Indexed access on Java objects #30

anri-vin opened this issue Nov 26, 2018 · 5 comments

Comments

@anri-vin
Copy link

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.

@caer
Copy link
Member

caer commented Nov 26, 2018

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.

@AlexTrotsenko
Copy link
Contributor

@crahda yes it's implemented. But for encapsulation reasons it uses get/set property (as @anri-vin actually posted)

Check https://github.com/AlexTrotsenko/v8-adapter/blob/870e306dbb0b5d6194a2edceff64ee4d25bad4c5/src/test/java/io/alicorn/v8/V8JavaAdapterTest.java#L615

It can be replaced with

"var x = new WannabeBeanNoAnnotations(); x['i'] = 6688; x.i;"

@anri-vin
Copy link
Author

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.

@AlexTrotsenko
Copy link
Contributor

@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.

@anri-vin
Copy link
Author

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\"); }});")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants