This projects contains tools which allow idiomatic other language API shims to be generated from Java APIs.
A code generator consist of an MVEL template declared in a codegen.json descriptor:
{
  "name": "Groovy",
  "generators": [ {
    "kind": "class",
    "fileName": "'groovy/' + fqn.replace('io.vertx', 'io.vertx.groovy').replace('.', '/') + '.groovy'",
    "templateFileName": "vertx-groovy/template/groovy.templ"
  } ]
}
fileNameis an MVEL expression for the file name, returning null skips the generation.templateFileNameis the name of the MVEL template to applykind: there are several kinds of generators for different use casesclass: applied on each API classespackage: applied on each Java packagemodule: applied on each declared module, a module uniquely identifies an APIdataObject: applied on each data object classproxy: applied on each proxy class
There can be as many generators as you like.
By default the processor will only validate the source API against the Codegen rules and will not perform code
generation. Code generation will occur when the processor outputDirectory option is configured:
<pluginManagement>
  <plugins>
    <!-- Configure the execution of the compiler to execute the codegen processor -->
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>${project.build.sourceEncoding}</encoding>
      </configuration>
      <executions>
        <execution>
          <id>default-compile</id>
          <configuration>
            <annotationProcessors>
              <annotationProcessor>io.vertx.codegen.CodeGenProcessor</annotationProcessor>
            </annotationProcessors>
            <compilerArgs>
              <arg>-AoutputDirectory=${project.basedir}/src/main</arg>
            </compilerArgs>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</pluginManagement>
In order for code generation to work effectively, certain constraints are put on the Java interfaces.
The constraints are
- The API must be described as a set of Java interfaces, classes are not permitted
 - Default methods are not permitted
 - Nested interfaces are not permitted
 - All interfaces to have generation performed on them must be annotated with the 
io.vertx.codegen.annotations.VertxGenannotation - Fluent methods (methods which return a reference to this) must be annotated with the 
io.vertx.codegen.annotations.Fluentannotation - Data object classes (classes which provide data (e.g. configuration) to methods) must be annotated with the 
io.vertx.codegen.annotations.DataObjectannotation - Data object classes must provide a constructor which takes a single 
io.vertx.core.json.JsonObjectparameter. - Methods where the return value must be cached in the API shim must be annotated with the 
io.vertx.codegen.annotations.CacheReturnannotation - Only certain types are allowed as parameter or return value types for any API methods (defined below).
 
We define the following set B of basic types:
- any primitive type
 - any boxed primitive type
 java.lang.String
We define J as the set of types io.vertx.core.json.JsonObject and io.vertx.core.json.JsonArray
We define V as the set of user defined API types which are defined in its own interface and annotated with @VertxGen
The following set P of types are permitted as parameters to any API method:
- the set 
B java.lang.Object- the set 
V - the set 
J - any data object class annotated with 
@DataObject - type 
java.util.List<C>orjava.util.Set<C>whereCcontains- the set 
B - the set 
V - the set 
J 
 - the set 
 - type 
java.util.Map<String, C>whereCcontains- the set 
B - the set 
J - the set 
V 
 - the set 
 - any Enum class
 - the exact 
java.lang.Throwableclass, for instancejava.lang.Exceptionis not supported io.vertx.java.core.Handler<io.vertx.java.core.AsyncResult<HA>>whereHAcontains- the set 
B - the set 
V - the set 
J java.lang.Voidjava.lang.Throwable- any data object class annotated with 
@DataObject - type 
java.util.List<C>orjava.util.Set<C>whereCcontains- the set 
B - the set 
V - the set 
J 
 - the set 
 
- the set 
 io.vertx.java.core.Handler<H>whereHcontains- the set 
HA java.lang.Throwable
- the set 
 
The following set R of types are permitted as return types from any API method:
- void
 - the set 
B - the set 
V - the set 
J - any Enum class
 - any 
java.lang.Throwable - any data object class annotated with 
@DataObject - type 
java.util.List<C>orjava.util.Set<C>whereCcontains- the set 
B - the set 
J - the set 
V - any data object class annotated with 
@DataObject 
 - the set 
 - type 
java.util.Map<String, C>whereCcontains- the set 
B - the set 
J 
 - the set 
 
You may add static factory methods in your interfaces, e.g.
interface MyInterface {
    static MyInterface newInterface(String foo) {
      return new ....
    }
}
Interfaces can extend other interfaces which also have the @VertxGen annotation.
Interfaces annotated with @VertxGen can either be concrete or abstract, such information is important
for languages not supporting multiple class inheritance like Groovy:
- interfaces annotated with 
@VertxGen(concrete = false)are meant to be extended by concrete interfaces and can inherit from abstract interfaces only. - interfaces annotated with 
@VertxGenor@VertxGen(concrete = true)are implemented directly by Vertx and can inherit at most one other concrete interface and any abstract interface 
If you do not wish a method to be used for generation you can annotate it with the @GenIgnore annotation.
Generated types must belong to a module: a java package annotated with @GenModule that defines a module, modules
cannot be nested. Such file is created in a file package-info.java.
In addition of the package name, a module must define a name used when generating languages that don't follow Java
package naming, like JavaScript or Ruby.
@GenModule(name = "vertx-unit")
package io.vertx.ext.unit;
For non Vert.x modules, the @GenModule annotation provides the groupPackageName member to define the
package of the group used for generating the generated package names (for Groovy or RxJava generation):
@GenModule(name = "acme", groupPackageName="com.acme")
package com.acme.myservice;
The group package name must be a prefix of the annotated module, it defines the naming of the generate packages o for the modules that belongs to the same group, in this case:
com.acme.groovy...for Groovy APIcom.acme.rxjava...for RxJava API
For this particular com.acme.myservice module we have:
com.acme.groovy.myservicefor Groovy APIcom.acme.rxjava.myservicefor RxJava API
NOTE: the default group name is io.vertx and should only be used by Vert.x projects or extensions.
We use MVEL templating to generate APIs.
There should be a single MVEL template for each language API that is to be generated.
The template will be called once for each interface that is annotated with @VertxGen in the Java API. One
output file (e.g. one .js file) will be created for each Java interface.
The following variables are made available to templates:
ifaceSimpleName- the simple name of the Java interfaceifaceFQCN- the fully qualified class name of the Java interfaceifacePackageName- the name of the Java package the Java interface belongs toifaceComment- the class comment from the Java interfaceconcrete- true when the interface is implemented by vert.x useful to decide the generation of a class or interface in the API shimhelper- a helper class that of typeio.vertx.codegen.Helperwhich contains useful methods for things such as converting CamelCase to underscores.methods- a list ofMethodInfoobjects describing each method in the interface.referencedTypes- a list of strings representing the set of user defined types (also annotated withVertxGen) which are referenced from the current interfacesuperTypes- a list ofTypeInforepresenting the set of user defined types which the current interface extends fromconcreteSuperTypes- subset ofsuperTypeswhich are concreteabstractSuperTypes- subset ofsuperTypeswhich are abstractmethodMap- this is a Map<String, MethodInfo> - which allows you to look up all methods with a given nameimportedTypes- this is aSet<TypeInfo>containing the types used by this class
The TypeInfo represents a Java type:
name. Generates a string of a form suitable for representing this type in source code using qualified names, for instanceio.vertx.core.Handler<io.vertx.core.buffer.Buffer>simpleName. Generates a string of a form suitable for representing this type in source code using simple names, for instanceHandler<Buffer>toString. Same asnamecollectImports(Collection<TypeInfo.Class> imports). Collect all imports required by this type
The TypeInfo.Class is a subclass of TypeInfo representing a Java class:
kind. An enum providing more information about the typeSTRING,BOXED_PRIMITIVE,PRIMITIVE: basic typesJSON_OBJECT,JSON_ARRAY: io.vertx.core.json.JsonObject and io.vertx.core.json.JsonArrayTHROWABLE: java.lang.ThrowableVOID: java.lang.VoidOBJECT: java.lang.ObjectLIST,SET: corresponding java collectionsAPI: a type annotated with @VertxGenDATA_OBJECT: a type annotations with @DataObjectHANDLER: io.vertx.core.HandlerASYNC_RESULT: io.vertx.core.AsyncResultENUM: An enumOTHER: anything else
The MethodInfo object has the following fields:
name. The name of the methodkind. The method kindHANDLER: last parameter type isio.vertx.core.Handler<T>and avoidor fluent returnFUTURE: last parameter type isio.vertx.core.Handler<io.vertx.core.AsyncResult<T>>and avoidor fluent returnINDEX_GETTER: an index getterINDEX_SETTER: an index setterOTHER: anything else
returnType. The fully qualified return type (orvoid) of the methodfluent.trueif the method is fluent (i.e. returns a reference to the interface itself for chaining calls)cacheReturn.trueif the generated API method should cache return valuecomment. Method comment.params. List ofParamInfoobjects representing the parameters of the method.staticMethod.trueif it's a static method.typeParams. The list of the type parameters declared by the method
The ParamInfo object has the following fields:
name. The name of the parametertype. The type of the parameter as aTypeInfodataObject.trueIf the parameter is a data object type.
type- theTypeInfoof the current optiondoc- theDocobjectconcrete" - true when the option is implemented by vert.x - useful to decide the generation of a class or interface in the API shimgenerateConverter- whether a converter should be generated or notinheritConverter- whether the generated converter should convert all propertiesproperties- aSet<PropertyInfo>of the available properties in this optionimportedTypes- the imported types by the optionsuperTypes- a list ofTypeInforepresenting the set of user defined types which the current interface extends fromsuperType- the supertype of this option ???
The PropertyInfo object has the following fields:
name. The name of the propertytype. The type of the property asTypeInfodoc- theDocobjectdeclared. True if the property is declared by its data object and does not override the same property from an ancestorwriterMethod. The name of the setter/adder method in JavareaderMethod. The optional name of the getter method in Javaarray. True if the property is an arrayadder. True if the property is an adder (addSomething)jsonifiable. True if the object can be converted somehow to json