users@jersey.java.net

Re: [Jersey] generate wadl including source comments

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Wed, 18 Jun 2008 09:35:33 +0200

Hi,

now I have a first working version committed in the branch [1]. What is
included:

- Added a maven-wadlplugin that provides a doclet that generates
  a so called resourcedoc: some xml file containing javadoc and more
  meta information (like xsd-element references) about your resource
  classes
- The maven-wadl-plugin also can generate a wadl file that reads the
  resourcedoc.xml and uses this meta information to create doc and other
  elements in the wadl file
- The jersey WadlResource tries to read a resourcedoc.xml from the
  classpath and in this case also creates a wadl file including
  documentation/comments (-> request
  http://localhost/api/application.wadl to retrieve the wadl resource).
  * There's just one issue: The UriInfo seems not to be initialized,
    therefore the baseUri might not be initialized

An example of additionally supported javadoc tags that can be used:

    /**
     * Creates a new User.
     *
     * @param createUserRequest the entity with user data
     *
     * @request.representation.qname {http://www.example.com/api}createUserRequest
     * @request.representation.example {_at_link Examples#CREATE_USER_REQUEST_EXAMPLE}
     *
     * @response.param {_at_name Location}
     * {_at_style header}
     * {@type {http://www.w3.org/2001/XMLSchema}anyURI}
     * {_at_doc The URI where the user has been created.}
     *
     * @response.representation.500.qname {http://www.example.com/api}error
     * @response.representation.500.mediaType application/xml
     * @response.representation.500.example {_at_link Examples#ERROR_EXAMPLE}
     *
     * @response.representation.400.qname {http://www.example.com/api}messages
     * @response.representation.400.mediaType application/xml
     * @response.representation.400.example {_at_link Examples#MESSAGES_EXAMPLE}
     *
     * @response.representation.201.qname {http://www.example.com/api}user
     * @response.representation.201.mediaType application/xml
     * @response.representation.201.example {_at_link Examples#GET_USER_EXAMPLE}
     *
     * @return Returns the user that has been created.
     */
    @POST
    @ConsumeMime( { "application/xml" } )
    @ProduceMime({ "application/xml" })
    public Response createUser( CreateUserRequest createUserRequest ) {
        ...
    }

The representation.qname {http://www.example.com/api}createUserRequest
sets the element attribute of a representation. What's missing right
now, is the specification of grammars for the WADL (see below for more
TODOs).

The {_at_link Examples#CREATE_USER_REQUEST_EXAMPLE} is followed, read and
marshalled to xml, that is added as a <doc /> element to the
representation. All other things should be self descriptive.


An example how to configure it's own (app) pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <configuration>
    
        <encoding>UTF-8</encoding>
        <verbose>false</verbose>
        <show>public</show>
        <subpackages>path.to.resources</subpackages>

        <doclet>com.sun.jersey.wadl.resourcedoc.ResourceDoclet</doclet>
        <docletArtifacts>
            <docletArtifact>
                <groupId>com.sun.jersey</groupId>
                <artifactId>maven-wadl-plugin</artifactId>
                <version>0.8-ea-SNAPSHOT</version>
            </docletArtifact>
            <!--
                Also specify jersey as doclet artifact as the ResourceDoclet
                uses classes provided by jersey to generate the resourcedoc.
             -->
            <docletArtifact>
                <groupId>com.sun.jersey</groupId>
                <artifactId>jersey</artifactId>
                <version>0.8-ea-SNAPSHOT</version>
            </docletArtifact>
        </docletArtifacts>
        <!--
            The resourcedoc.xml is also read by the WadlResource.java that
            provides the application.wadl for your jersey app. So this should
            not be changed
        -->
        <additionalparam>-output ${project.build.outputDirectory}/resourcedoc.xml</additionalparam>
        
    </configuration>
</plugin>

<plugin>
    <groupId>com.sun.jersey</groupId>
    <artifactId>maven-wadl-plugin</artifactId>
    <version>0.8-ea-SNAPSHOT</version>
    <executions>
        <execution>
            <id>generate-wadl</id>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    
    <configuration>
        
        <resourceDocFile>
            ${project.build.outputDirectory}/resourcedoc.xml
        </resourceDocFile>
    
        <wadlFile>${project.build.outputDirectory}/application.wadl</wadlFile>
        <baseUri>http://www.example.com/api</baseUri>
        <packagesResourceConfig>
            <param>path.to.resources</param>
        </packagesResourceConfig>
        <dependencies>
            <!--
                Additional dependencies for resolving ClassNotFoundExceptons
                can be added here
            -->
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.3</version>
            </dependency>
        </dependencies>
    </configuration>
</plugin>


To generate just the resourcedoc.xml run
# mvn javadoc:javadoc

To generate the wadl using the resourcedoc run
# mvn javadoc:javadoc com.sun.jersey:maven-wadl-plugin:generate


TODOs:
- The WadlMethodFactory (OPTIONS support) does not use the
  resourcedoc
- The grammars must be set on the generated wadl so that referenced
  xsd-elements can be resolved
- The ResourceDoclet must allow to hook into the resourcedoc generation,
  so that users can read their specific javadoc tags (like e.g.
  @security.ssl)
- The maven-wadl-plugin (GenerateWadlMojo) must allow to hook into the
  wadl generation, so that application specific information can be used
  to pimp the generated wadl
- Jersey must allow to specify these wadl-hooks so that these can also
  be used at runtime


This was the first start, feedback welcome. If you want to test this
stuff you have to switch to the branch [1] and build jersey by yourself
(e.g. change the artifact version to some 0.8-wadl-SNAPSHOT).


Cheers,
Martin


[1] https://jersey.dev.java.net/svn/jersey/branches/wadl-generator-improvements


On Tue, 2008-06-10 at 10:06 +0200, Martin Grotzke wrote:
> Hi,
>
> I want to improve the generation of wadl so that resource and method
> comments are added to the related wadl-elements.
>
> The idea is basically that of Seth Call: Create some xml-representation
> of the javadoc so that this information can be read when the wadl is
> generated.
>
> Additionally we want to be able to add examples for representations, so
> that it's easy for readers of the doc to get an idea of in/out data.
> My idea is to create a taglet like "@request.representation.example".
> Are there any suggestions / other requirements concerning this that I
> should/could take into consideration?
>
> Also we want to reference schema elements in our representations.
>
> I would prefer do improve the existing jersey WadlGenerator that writing
> our own.
> @jersey-devs: Is this also s.th. that you would prefer?
>
> I would start with a maven-plugin so that testing cycles are as short as
> possible. Then I would create the taglets/doclets, create the required
> javadoc-xml file and afterwards extend the WadlGenerator.
>
> Shall changes be done in the trunk, or would you prefer to keep this in
> a branch?
>
> Cheers,
> Martin
>
>