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

JSObjectPropertiesMap - proper usage #17

Closed
ghost opened this issue Mar 14, 2017 · 4 comments
Closed

JSObjectPropertiesMap - proper usage #17

ghost opened this issue Mar 14, 2017 · 4 comments
Labels

Comments

@ghost
Copy link

ghost commented Mar 14, 2017

It looks like this is an inner wrapper class to assist with maps. If I set a map in context as follows:

    Map<String, Object> pageContext =  new HashMap<String, Object>();
    JSObject oPageContext = new JSObject(this.jsContext, pageContext);
    jsContext.property("pageContext", oPageContext);

Is this the proper way to then reference that map in the context (after running evaluate script and associated call function):

    JSValue _pageContext = jsContext.property("pageContext");
    Map<String, Object> map = (Map<String, Object> _pageContext.toObject();

thx, appreciate the assist.

@ericwlange ericwlange added the bug label Mar 15, 2017
@ericwlange
Copy link
Member

It seems that I have mistakenly made JSObjectPropertiesMap package local. It should be public. I will fix that for the next release. Unfortunately, it will be difficult to use without reflections unless it is public.

The intent was to enable a convenient method of setting JSObject properties using the Map interface. So the correct way to use it should be:

JSValue _pageContext = jsContext.property("pageContext");
Map<String, JSValue> map = new JSObjectPropertiesMap<>(_pageContext.toObject(), JSValue.class);

I recommend using JSValue as a generic type rather than Object because not all objects can be translated into Javascript values. Or, if your object uses only one type, you can specify that type, as in: Map<String, Integer> map = new JSObjectPropertiessMap<>(_pageContext, Integer.class);

But because the class is not public, this won't work. If you really want to use it, there are two choices: (1) add public in front of the class in JSObjectPropertiesMap.java and build the library yourself, or (2) use reflections:

Class<?> cl = Class.forName("org.liquidplayer.javascript.JSObjectPropertiesMap");
Constructor<?> cons = cl.getConstructor(JSObject.class, Class.class);
Object inst = cons.newInstance(_pageContext.toObject(), JSValue.class);
Map<String, JSValue> map = (Map<String, JSValue>) inst;

You'll also need to wrap this in a try/catch block because there are several exceptions that can theoretically occur, although if your parameters are right, it should work fine.

As an aside, I had intended to just allow JSObject to always implement the Map inteface, however, in Java, I learned, an object cannot implement both Map and List!! This is because they share a single method, remove, which has different return types in each implementation! I wanted JSArray (which is also a JSObject) be able to be used as a generic List. And so I couldn't do both. So to still make this possible, JSObjectPropertiesMap is just a shadow object for some JSObject. Just a little trivia for you.

I will mark this as a bug and fix. Thanks for reporting.

@ericwlange ericwlange self-assigned this Mar 15, 2017
@ericwlange ericwlange added this to TODO in Release 0.2.2 Mar 15, 2017
@ericwlange
Copy link
Member

ericwlange commented Mar 15, 2017

@ericwlange ericwlange moved this from TODO to Completed in Release 0.2.2 Mar 15, 2017
@ghost
Copy link
Author

ghost commented Mar 15, 2017 via email

@ericwlange
Copy link
Member

This is fixed in v0.2.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Release 0.2.2
Completed
Development

No branches or pull requests

1 participant