Closed
Bug 223435
Opened 21 years ago
Closed 21 years ago
Automatic conversion of JS functions into Java interfaces
Categories
(Rhino Graveyard :: Core, enhancement)
Rhino Graveyard
Core
Tracking
(Not tracked)
RESOLVED
FIXED
1.5R5
People
(Reporter: igor, Assigned: igor)
Details
Attachments
(3 files, 2 obsolete files)
51.17 KB,
patch
|
Details | Diff | Splinter Review | |
3.44 KB,
patch
|
Details | Diff | Splinter Review | |
5.16 KB,
patch
|
Details | Diff | Splinter Review |
It would be nice if Rhino would automatically create JavaAdapter from JavaScript object when calling Java methods if corresponding Java parameter is interface. For example, currently to add an action listener to Swing button SwingApplication.js example uses: button.addActionListener(new ActionListener({ actionPerformed : function() { numClicks += 1; label.setText(labelPrefix + numClicks); } })); But it would be much simpler to write just button.addActionListener({ actionPerformed : function() { numClicks += 1; label.setText(labelPrefix + numClicks); } }); which would create the adapter wrapper automatically and similarly it would be possible to replace frame.addWindowListener(new WindowAdapter({ windowClosing : function() { java.lang.System.exit(0); } }) ); by frame.addWindowListener({ windowClosing : function() { java.lang.System.exit(0); } }); Yet another usability extension would be to allow to pass JS function where corresponding Java type is an interface with a single method. With this extension the first example becomes simply: button.addActionListener(function() { numClicks += 1; label.setText(labelPrefix + numClicks); }); Moreover, with such extension one would get automatic proper binding for DOM event listeners. Java bindings for DOM states that event listener should implement EventHandler interface which contains single handleEvent method while DOM bindings for ECMAScript accepts arbitrary function.
Assignee | ||
Comment 1•21 years ago
|
||
Patch implements the first proposal: it automatically creates adapter objects when calling Java methods and when corresponding argument type is interface.
Assignee | ||
Comment 2•21 years ago
|
||
Automatic creation of wrapper objects is dangerous feature since the wrapper object is not available to JS so if one would register a listener through: var listener = { windowClosing : function() { java.lang.System.exit(0); } }; frame.addWindowListener(listener); then frame.removeWindowListener(listener); would not work since a new wrapper for the listener object would be created. The proper implementation should somehow store the wrapper so it would be reused and frame.removeWindowListener(listener) would work. Under JDK 1.2 WeakHash can be used to store the mapping but it would make dependence on JDK 1.2 too heavy when MS JVM still should be accounted for. (In fact, I know one case when Rhino is used with JDK 1.1.8 for Solaris since later JDK needs to much memory...) For single-method interface to function map such implementation is possible under restriction that only BaseFunction instances would be allowed in such usage so BaseFunction can store the wrapping. Since all usable cases for the automatic conversion involves BaseFunction, this is not a serious restriction. For this reasons the new patch does not have any support for automatic wrapping of generic JS object but just implements Java interface to JS function mapping. The patch does not create the standard adapter to take advantage of the fact that the glue object passed to Java method is not visible to JS. It allows not to create NativeJavaObject for the glue itself that the standard Java adapter would do. Since the glue need to support only interfaces, the patch uses special IFGlue class as a base for all generated code to minimize amount of generated code. In addition, patch adds optimization to the current adapter code to remove calling Context.enter/Context.exit when converting Java to JS arguments for each non-primitive type since the conversion can be done when Context instance is obtained for calling the function itself.
Assignee | ||
Updated•21 years ago
|
Attachment #133959 -
Attachment is obsolete: true
Assignee | ||
Comment 3•21 years ago
|
||
To allow to write: var t = java.lang.Thread(function f() { .... } ) to mean to create a thread that will call f() in its run method and not create Thread named by f.toString() the patch update makes conversion function->interface to weight 1 if interface contains single method.
Attachment #134210 -
Attachment is obsolete: true
Assignee | ||
Comment 4•21 years ago
|
||
Changing the title: Automatic conversion of JS object into JavaAdapter extending/implementing arbitrary Java class would be sugar that is very easy to misuse. My initial intention was to have something that allow to simplify JS implementation of event listening code in JS and the committed part took care about common case of interfaces with single method. But in the rest of useful cases event listening interfaces would have multiple methods with exactly the same signature like WindowListener, MouseListener etc. tand it is sufficient to provide sugar only for this case. Thus the idea would be allow to pass JS function to Java method not only when corresponding Java type is an interface with single method but also for interfaces with several methods with exactly the same signature. To distinguish between methods in JS the glue code would append method name as the last parameter. Since the signature for all methods are the same, the position of this last parameter would be the same as well and one could write: frame.addWindowListener(function(event, methodName) { if (methodName == "windowClosing") { java.lang.System.exit(0); } });
Summary: Automatic creation of JavaAdapter instances → Automatic conversion of JS functions into Java interfaces
Assignee | ||
Comment 5•21 years ago
|
||
The patch changes the current glue code to pass the name of the called interface method as the last parameter to JS function. This is useful for debugging, for example, even without extending the conversion to interfaces with multiple methods with the same signature.
Assignee | ||
Comment 6•21 years ago
|
||
The patch checks if all additional interface methods have the same signature, then the conversion is allowed and the initial JS function will be called for each method.
Assignee | ||
Comment 7•21 years ago
|
||
I committed the last patches which allows to mark bug as fixed
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Target Milestone: --- → 1.5R5
You need to log in
before you can comment on or make changes to this bug.
Description
•