Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

VJET/JSRReference

Purpose

The purpose is the document how the VJET JS or Java to JS is transformed into a Java API using a reference based programming model.

What is a JSR

A JSR (JavaScript Reference) is a Java type that serves as a reference to the following types:

  • VJET JavaScript Authored in multiple languages
    • JavaScript language
    • Java language
  • Native Types
    • JavaScript Native Types
    • DOM types

Java APIs to Access JavaScript

JSR provides access to JavaScript and provides Java APIs for public

  • Functions
  • Methods
  • Properties
  • Function References
  • Type References

Java code can access JavaScript references using Java. JavaScript developers can develop a definition neutral JavaScript Reference API. Developers can choose to use JavaScript authored in JavaScript language or in the Java language. JSRs are part of a larger technology set, V4, which supports the development of web pages and applications using Java.


Resource Access

JSRs provide a resource reference for any JavaScript resource backing the type. This is used for ensuring that when executing the JavaScript that all the definitions have loaded in the runtime. Resource Specs can be added to view specs. Please see the V4 resource pattern documentation for more information.


APIs Public Access Required

Methods, nested classes, and properties that are public will have generated JSR apis. All others will not be generated in JSR.


JSR Creation Options

VJET JS to JSR

VJET JS to Jsr is the entry point for JavaScript developers to work with Java developers. The JSR generated from the VJET JS source file is not meant to be edited by hand. The name of a JSR is composed of the name of the type it represents, appended with ‘Jsr’. For example, VJET JavaScript type named MyClass (.js) will generate a JSR named MyClassJsr.java. Generated java files should always be generated and never checked into source control. To handle this case the generated JSR contains a Java 5 annotation: @org.eclipse.vjet.resource.utils.CodeGen("JsrGenerator")


There are 3 ways this can be done:

  1. Eclipse plugin – right click V4-> Js reference generation -
  2. Java main program - org.eclipse.vjet.jstojava.codegen.JsToJavaGen
  3. ANT task - org.eclipse.vjet.jstojava.prebuild.JsLibPreBuildTask

//Note for eBay this task has been integrated into the Build3 and Build2 systems.


VJET Java to JSR

JSRs can also be generated from Java files. This provides the capability for JavaScript code to be authored in Java or JavaScript code without having consumer change their code if the signature doesn't change. The JSR generated from the Java source file is not meant to be edited by hand. The name of a JSR is composed of the name of the Java type it represents, appended with ‘Jsr’. For example, Java type named MyClass.java will generate a JSR named MyClassJsr.java. Generated java files should always be generated and never checked into source control. To handle this case the generated JSR contains a Java 5 annotation: @org.eclipse.vjet.resource.utils.CodeGen("JsrGenerator")


There are 3 ways this can be done:

  1. Eclipse plug-in – right click V4-> Java 2 Js Generation
  2. Java main program - org.eclipse.vjet.javatojs.cli.Java2Vjo
  3. ANT task - org.eclipse.vjet.javatojs.prebuild.J2JsBuildTask

Hand coded Jsr

JSRs can also be generated by hand. For example if the original api authored by the JavaScript developer doesn't handle a specific case such as using a JavaScript type or DOM type but there is a more appropriate Java type that should be used a custom Jsr can be created.

When to not use Jsr

JSRs should not be used when writing JavaScript definitions using Java. Native java proxies should be used when trying to access native JavaScript code from a Java 2 Js definition.


VJET Types map to Jsr generated types

A JSR definition preserves all aspects of the original type definition, including inheritance, interface implementations, and dependencies. For example, if a JavaScript definition inherits from another type, the JSR will extend from the super class; if a JavaScript definition implements an interface, the JSR will specify the implemented interface. Please refer to the Appendix Xxx for more information.


Below is the list of fundamental VJO types that are supported.


Java Related types

  1. CType - a java class extending JsObj is generated
  2. IType – a java interface is generated
  3. EType – a java class extending JsEnum is generated
  4. Static Inner Type – a nested java class will be created for each public nested class.
  5. Instance Inner Type
  6. Anonymous Type

Js Types with no equivalent Java type

  1. MType – a java class is generated since java doesn't support mixin natively. This type answers to let you know it isMixin and provides access to resource backing mixin.
  2. OType – a java class with nested java classes is generated.

Js Functions

The following diagram shows the relationships for the Java Script Reference model for JavaScript Functions,

Vjet jsrreference jsfunction.png

Functions with No Arguments

If a method takes no arguments, a single function reference is generated. The reference preserves all modifier information from the original definition, in this case, a void return type, and public access.


JS code JSR Java API
 //> public void warn();
warn:function(){}
public JsFunc<Void> warn() {}
Java authored Js code
public void warn(){}

Functions with arguments

If a method takes one or more arguments, two function references are generated:

  • A reference that accepts the given argument type
JS code JSR Java API
//> public String foo(String s);
 
foo:function(s){}
public JsFunc<String> foo(String s)


Java authored Js code
public void warn(String s){}
  • A reference that accepts a value binding


JS code JSR Java API
//> public String foo(String s);
 
foo:function(s){} // assume this code is in props section / static
public static JsFunc<String> foo(IValueBinding<String> s)
Java authored Js code
public String foo(String s)
  • Passing a value binding allows delegation and deferring the materialization of a value to another object. In this case another Jsr property or function that returns JsFunc<String> can be passed into the warn method. For example since foo method returns JsFunc<String> it can be passed into itself.


Java JSR Usage Code Generated Js Method call code (un-optimized)
MyJsr.foo(MyJsr.foo("test"));
a.b.c.MyJsr.foo(a.b.c.MyJsr.foo("test")); 
// note that there are optimization techniques we use to shorten this.



Functions with Optional Arguments in methods (Js authored only)

Optional arguments will produce overloaded apis in JSR.

One required argument and one optional argument:

JS code JSR Java API
//>public void foo(Foo a, String? b) 
 
foo : function(a, b){}
public JsFunc<Void> foo(FooJsr a, String b)
 
public JsFunc<Void> foo(</nowiki>IValueBinding<nowiki><? extends 
FooJsr> a, IValueBinding<nowiki><String> b)
 
public JsFunc<Void> foo(FooJsr a)
 
public JsFunc<Void> foo(</nowiki>IValueBinding<? extends FooJsr> a)

Multiple Optional Arguments:

JS code JSR Java API
//>public void foo(Foo a, String? b, String? c) 
 
foo2 : function(a, b){}
public JsFunc<Void> foo2(FooJsr a, String b, String c)
 
public JsFunc<Void> foo2(IValueBinding<? extends
 FooJsr> a, IValueBinding<String> b, IValueBinding<String> c)
 
public JsFunc<Void> foo2(FooJsr a, String b)
 
public JsFunc<Void> foo2(IValueBinding<? extends 
FooJsr> a, IValueBinding<String> b)
 
public JsFunc<Void> foo2(FooJsr a)
 
public JsFunc<Void> foo2(IValueBinding<? extends FooJsr> a)

Incorrect Optional arguments

Optional arguments are only supported as the last arguments in the argument list. If the optional argument occurs before a required argument the jsr generation will assume that the optional argument is required.


JS code JSR Java API
//>public void foo(Foo? a, String b) 
foo : function(a, b){}
public JsFunc<Void> foo(FooJsr a, String b)
 
public JsFunc<Void> foo(IValueBinding<? extends FooJsr> a, IValueBinding<String> b)


Supporting Variable arguments

Variable Argument only

JS code JSR Java API
//>public void foo3(Foo ... s)
foo3 : function(s){}
public JsFunc<Void> foo3(FooJsr... p0)
 
public JsFunc<Void> foo3(IValueBinding<? extends FooJsr>... p0)
Java authored Js code
public String foo3(Foo … s)

Required argument and Variable argument

JS code JSR Java API
//>public void foo5(String z, Foo ... b) 
 
foo5 : function(z, b){
 
}
public JsFunc<Void> foo5(String z, FooJsr... b)
 
public JsFunc<Void> foo5(IValueBinding<String> z, IValueBinding<? 
extends FooJsr>... b)
Java authored Js code
public String foo3(Foo … s)

Variable Argument listed before required argument – not supported

VJET validation error will be produced and if error is ignored no method will be generated. In Java authored code java compiler will give you an error.


JS code JSR Java API
//>public void foo4(Foo ... s, String b) 
foo3 : function(s, b){}
// nothing produced

Overloaded Methods

JavaScript developers can declare overloaded methods but JavaScript can only have one function per name so the Js developer must handle the overloading in the function internally. The Java developer can author 2 independent methods rather than rely on one method. The Jsr Generation supports up to 15 overloaded signatures.

Simple overloading scenario

JS code JSR Java API
//>public void foo4(String) 
 
//>public void foo4(int) 
 
foo4 : function(){}
public JsFunc<Void> foo4(String a)
 
public JsFunc<Void> foo4(IValueBinding<String> a)
 
public JsFunc<Void> foo4(int a)
 
public JsFunc<Void> foo4(IValueBinding<Integer> a, org.eclipse.vjet.aggregator.jsref.d.D1... notUsed)
Java authored Js code
public void foo4(String a){}
 
public void foo4(int a){}

Note: the D1 class is for working around a problem with overloading and generics in Java. We use the D1 vararg to fake out the compiler. Since the generic is an erasure the compile get's confused between IValueBinding<Integer> vs IValueBinding<String>.

Hand coding a function reference

In the base JsObj there is an overloaded method called call where you can pass in the return type, method name, and arguments. If you look at the generated code you will see this simple internal call.


Original Js code JSR Hand coded Function reference
//> public String foo(String s);
 
foo:function(s){}
public JsFunc<String> foo(String s){
 
return call(String.class, "foo").with(s);
 
}
 //> public String foo2();
 
foo2:function(){}
public JsFunc<String> foo2(){
 
return call(String.class,"foo2");
 
}

If a JavaScript developer doesn't correctly declare a method you can add a call method directly. This is not recommended practice it is similar to using reflection to call a method. It is possible to get

Back to the top