Cool.  Any examples out there in the ether?  

That said, I do think an interface-based approach would be more desirable since 
it does not force a specific class hierarchy (e.g. must extend JSObject), which 
could be very problematic in many cases (including ours).

-----Original Message-----
From: Attila Szegedi [mailto:attila.szeg...@oracle.com] 
Sent: Tuesday, October 22, 2013 12:51 PM
To: Rick Bullotta
Cc: A. Sundararajan; nashorn-dev@openjdk.java.net
Subject: Re: Docs/examples for JSAdapter

You should be able to use your own subclasses of 
jdk.nashorn.api.scripting.JSObject for this purpose.

Attila.

On Oct 22, 2013, at 6:46 PM, Rick Bullotta <rick.bullo...@thingworx.com> wrote:

> Yuck.  Looks like we'll be sticking with Rhino for a while then. 
> 
> I would STRONGLY recommend adding the ability of a Java class developer to 
> implement an interface that provides the functionality I described in my 
> response to Jim.  It is just plain wrong to push complexity to the end user 
> when it can easily be solved in the framework/platform.  To implement that 
> should be rather trivial, to be honest.
> 
> 
> -----Original Message-----
> From: nashorn-dev-boun...@openjdk.java.net 
> [mailto:nashorn-dev-boun...@openjdk.java.net] On Behalf Of A. Sundararajan
> Sent: Tuesday, October 22, 2013 12:33 PM
> To: nashorn-dev@openjdk.java.net
> Subject: Re: Docs/examples for JSAdapter
> 
> No. Nashorn uses wrapperless Java objects. Java objects are exposed to 
> scripts "as is" - no wrapping as 'script objects' as in Rhino.
> 
> It is possible to implement Java interfaces in script (just like it was in 
> Rhino).
> 
> -Sundar
> 
> On Tuesday 22 October 2013 09:32 PM, Rick Bullotta wrote:
>> In Rhino, you register custom adapters in a "wrap factory" that tells the 
>> script engine to use these adapters for accessing instances of those 
>> classes/types.  What's the analog in Nashorn?  Can custom types implement 
>> interfaces that Nashorn will use?
>> 
>> From: Jim Laskey (Oracle) [mailto:james.las...@oracle.com]
>> Sent: Tuesday, October 22, 2013 11:52 AM
>> To: Rick Bullotta
>> Cc: nashorn-dev@openjdk.java.net
>> Subject: Re: Docs/examples for JSAdapter
>> 
>> In general the Nashorn docs start here. 
>> https://wiki.openjdk.java.net/display/Nashorn/Nashorn+Documentation, but as 
>> you point out, we seem to be lacking JSAdapter details.  I should start an 
>> FAQ.
>> 
>>> From the javadoc (cd make; ant javadoc # ./dist/javadoc/index.html)
>> 
>> 
>> *         public final class NativeJSAdapter
>> 
>> *         extends 
>> ScriptObject<file:///\\Volumes\Elephant\Projects\nashorn~jdk8\nashorn\dist\javadoc\jdk\nashorn\internal\runtime\ScriptObject.html>
>> This class is the implementation of the Nashorn-specific global object named 
>> JSAdapter. It can be thought of as the 
>> Proxy<http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html?is-external=true>
>>  equivalent for JavaScript. NativeJSAdapter calls specially named JavaScript 
>> methods on an adaptee object when property access/update/call/new/delete is 
>> attempted on it. Example:
>> 
>>     var y = {
>> 
>>                 __get__    : function (name) { ... }
>> 
>>                 __has__    : function (name) { ... }
>> 
>>                 __put__    : function (name, value) {...}
>> 
>>                 __call__   : function (name, arg1, arg2) {...}
>> 
>>                 __new__    : function (arg1, arg2) {...}
>> 
>>                 __delete__ : function (name) { ... }
>> 
>>                 __getIds__ : function () { ... }
>> 
>>             };
>> 
>> 
>> 
>>     var x = new JSAdapter(y);
>> 
>> 
>> 
>>     x.i;                        // calls y.__get__
>> 
>>     x.foo();                    // calls y.__call__
>> 
>>     new x();                    // calls y.__new__
>> 
>>     i in x;                     // calls y.__has__
>> 
>>     x.p = 10;                   // calls y.__put__
>> 
>>     delete x.p;                 // calls y.__delete__
>> 
>>     for (i in x) { print(i); }  // calls y.__getIds__
>> 
>> 
>> 
>> JavaScript caller of adapter object is isolated from the fact that the 
>> property access/mutation/deletion are really calls to JavaScript methods on 
>> adaptee.
>> 
>> JSAdapter constructor can optionally receive an "overrides" object. 
>> Properties of overrides object is copied to JSAdapter instance. When user 
>> accessed property is one of these, then adaptee's methods like __get__, 
>> __put__ etc. are not called for those. This can be used to make certain 
>> "preferred" properties that can be accessed in the usual/faster way avoiding 
>> proxy mechanism. Example:
>> 
>>      var x = new JSAdapter({ foo: 444, bar: 6546 }) {
>> 
>>           __get__: function(name) { return name; }
>> 
>>       };
>> 
>> 
>> 
>>      x.foo;           // 444 directly retrieved without __get__ call
>> 
>>      x.bar = 'hello'; // "bar" directly set without __put__ call
>> 
>>      x.prop           // calls __get__("prop") as 'prop' is not overridden
>> 
>> 
>> It is possible to pass a specific prototype for JSAdapter instance by 
>> passing three arguments to JSAdapter constructor. So exact signature of 
>> JSAdapter constructor is as follows:
>> 
>>      JSAdapter([proto], [overrides], adaptee);
>> 
>> 
>> Both proto and overrides are optional - but adaptee is not. When proto is 
>> not passed JSAdapter.prototype is used.
>> *
>> As well as the test ./test/script/basic/jsadapter.js
>> 
>> var obj = new JSAdapter() {
>>     __get__: function(name) {
>>         print("getter called for '" + name + "'"); return name;
>>     },
>> 
>>     __put__: function(name, value) {
>>         print("setter called for '" + name + "' with " + value);
>>     },
>> 
>>     __call__: function(name, arg1, arg2) {
>>         print("method '" + name + "' called with " + arg1 + ", " + arg2);
>>     },
>> 
>>     __new__: function(arg1, arg2) {
>>         print("new with " + arg1 + ", " + arg2);
>>     },
>> 
>>     __getIds__: function() {
>>         print("__getIds__ called");
>>         return [ "foo", "bar" ];
>>     },
>> 
>>     __getValues__: function() {
>>         print("__getValues__ called");
>>         return [ "fooval", "barval" ];
>>     },
>> 
>>     __has__: function(name) {
>>         print("__has__ called with '" + name + "'");
>>         return name == "js";
>>     },
>> 
>>     __delete__: function(name) {
>>         print("__delete__ called with '" + name + "'");
>>         return true;
>>     }
>> };
>> 
>> // calls __get__
>> print(obj.foo);
>> 
>> // calls __put__
>> obj.foo = 33;
>> 
>> // calls __call__
>> obj.func("hello", "world");
>> 
>> // calls __new__
>> new obj("hey!", "it works!");
>> 
>> for (i in obj) {
>>     print(i);
>> }
>> 
>> for each (i in obj) {
>>     print(i);
>> }
>> 
>> var x = "foo" in obj;
>> print(x);
>> 
>> var y = "js" in obj;
>> print(y);
>> 
>> print(delete obj.prop);
>> 
>> print(obj["js"]);
>> obj["js"] = "javascript";
>> print(obj["javascript"]);
>> Hope that helps.  Is there a specific question?
>> 
>> Cheers,
>> 
>> -- Jim
>> 
>> On 2013-10-22, at 11:50 AM, Rick Bullotta 
>> <rick.bullo...@thingworx.com<mailto:rick.bullo...@thingworx.com>> wrote:
>> 
>> 
>> Hi, all.
>> 
>> I've been searching everywhere for any form of documentation or substantive 
>> examples as to how JSAdapter works in Nashorn, as it is an essential piece 
>> of the puzzle for many of us who will naturally be migrating from Rhino.
>> 
>> Can anyone provide and additional info?
>> 
>> Thanks,
>> 
>> Rick
>> ThingWorx
>> 
> 

Reply via email to