# RESTEasy WADL Grammar Support

RESTEasy has added WADL grammar support by this PR:

 

 

- [RESTEASY-1695 Add GRAMMARS into RESTEasy WADL by liweinan · Pull Request #1649 · resteasy/Resteasy · GitHub](https://github.com/resteasy/Resteasy/pull/1649)

 

 

The major change is that `ResteasyWadlGrammar` is added into `ResteasyWadlWriter`:

 

 

 

In addition, the `ResteasyWadlWriter` is rewritten now, and all the static methods are now instance methods. It means users need to create an instance of `ResteasyWadlWriter` and put it into per-deployment scope.

 

 

To avoid people to write the boilerplate code, the `ResteasyWadlDefaultResource` can be used for deployment, and it can be put into the `getSingleton()` method of `Application` class:

 

 

```java

@Provider

@ApplicationPath("/")

public class WadlTestApplication extends Application {

   public static Set<Class<?>> classes = new HashSet<Class<?>>();

   public static Set<Object> singletons = new HashSet<Object>();

...

   @Override

   public Set<Object> getSingletons() {

   ...

         ResteasyWadlDefaultResource defaultResource = new ResteasyWadlDefaultResource();

         singletons.add(defaultResource);

      }

      return singletons;

   }

}

```

 

 

And then the URL `/application.xml` is enabled by the methods inside `ResteasyWadlDefaultResource`.

 

 

To enable the WADL Grammar support, users need to create an instance of `ResteasyWadlGrammar` and put it into the instance of `ResteasyWadlWriter`.

 

 

The recommended way is to use it with `ResteasyWadlDefaultResource`. Here is an example:

 

 

```java

ResteasyWadlDefaultResource defaultResource = new ResteasyWadlDefaultResource();

 

 

ResteasyWadlWriter.ResteasyWadlGrammar wadlGrammar = new ResteasyWadlWriter.ResteasyWadlGrammar();

wadlGrammar.enableSchemaGeneration();

 

 

defaultResource.getWadlWriter().setWadlGrammar(wadlGrammar);

```

 

 

As the code shown above, we have created an instance of `ResteasyWadlGrammar`, and it’s injected into the `ResteasyWadlWriter` instance included by `ResteasyWadlDefaultResource` instance.

 

 

In addition, we have called the `wadlGrammar.enableSchemaGeneration()` method, and it will scan the resources classes, and generate grammar files for JAXB annotated classes. Suppose we have entity class like this:

 

 

```java

import javax.xml.bind.annotation.XmlElement;

import javax.xml.bind.annotation.XmlRootElement;

import java.util.List;

 

 

@XmlRootElement(name = "listType")

public class ListType {

 

 

    private List<String> values;

 

 

    @XmlElement

    public List<String> getValues() {

        return values;

    }

 

 

    public void setValues(List<String> values) {

        this.values = values;

    }

}

```

 

 

And it’s used in resource class:

 

 

```java

import javax.ws.rs.Consumes;

import javax.ws.rs.POST;

import javax.ws.rs.Path;

 

 

@Path("/extended")

public class ExtendedResource {

 

 

    @POST

    @Consumes({"application/xml"})

    public String post(ListType income) {

        return "foo";

    }

}

```

 

 

And if we enable the grammar generation as shown above, then we will get sample output from `/application.xml` like this:

 

 

```xml

$ http http://localhost:8081/application.xml

HTTP/1.1 200 OK

Content-type: application/xml;charset=UTF-8

Date: Wed, 31 Oct 2018 07:57:38 GMT

Transfer-encoding: chunked

 

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<application xmlns="http://wadl.dev.java.net/2009/02">

    <grammars>

        <include href="xsd0.xsd">

            <doc title="Generated" xml:lang="en"/>

        </include>

    </grammars>

</application>

```

 

 

The above output shows that a grammar file is genrated, and it is called `xsd0.xsd`. The instance of `ResteasyWadlDefaultResource` will prepare a URL link named `/wadl-extended`, and it will serve the generated grammar file. Here is the example:

 

 

```xml

$ http http://localhost:8081/wadl-extended/xsd0.xsd

HTTP/1.1 200 OK

Content-type: application/xml;charset=UTF-8

Date: Wed, 31 Oct 2018 07:58:53 GMT

Transfer-encoding: chunked

 

 

<?xml version="1.0" standalone="yes"?>

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

 

  <xs:element name="listType" type="listType"/>

 

 

  <xs:complexType name="listType">

    <xs:sequence>

      <xs:element name="values" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>

    </xs:sequence>

  </xs:complexType>

</xs:schema>

```

 

 

As shown in the above example, the grammar is generated for `ListType` entity class. If you don’t want RESTEasy to generate the grammar file for you, you can use the `includeGrammars()` method provided by the instance of `ResteasyWadlGrammar`. Here is an example:

 

 

```java

ResteasyWadlWriter.ResteasyWadlGrammar wadlGrammar = new ResteasyWadlWriter.ResteasyWadlGrammar();

wadlGrammar.includeGrammars(“application-grammars.xml”);

...

```

 

 

The `application-grammars.xml` file is grammar descriptor file provided by yourself, and it should be put into your project’s classpath. Here is a sample of `application-grammars.xml`:

 

 

```xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<grammars xmlns="http://wadl.dev.java.net/2009/02"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns:xi="http://www.w3.org/1999/XML/xinclude">

    <include href="schema.xsd" />

</grammars>

```

 

 

From above file we can see `schema.xsd` is the included schema file, and it should also be provided by yourself. Here is a sample of `schema.xsd`:

 

 

```xml

<?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?>

<xs:schema version=“1.0” xmlns:xs=“http://www.w3.org/2001/XMLSchema”>

 

 

    <xs:element name=“listType” type=“listType”/>

 

 

    <xs:complexType name=“listType”>

        <xs:sequence>

            <xs:element name=“values” type=“xs:string” minOccurs=“0” maxOccurs=“unbounded”/>

        </xs:sequence>

    </xs:complexType>

</xs:schema>

```

 

 

And if you have called `wadlGrammar.includeGrammars(“application-grammars.xml”)`, then you will get the included section in `/application.xml`:

 

 

```xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<application xmlns="http://wadl.dev.java.net/2009/02">

    <grammars>

        <include href="schema.xsd"/>

    </grammars>

...

</application>

```

 

 

As the example shown above, the `schema.xsd` is included, and it can be fetched by using `/wadl-extended/schema.xsd` if you have registered the instance of `ResteasyWadlDefaultResource` into your `Application` and setup `ResteasyWadlGrammar` properly:

 

 

```xml

$ http http://localhost:8081/wadl-extended/schema.xsd

HTTP/1.1 200 OK

Content-type: application/xml;charset=UTF-8

Date: Wed, 31 Oct 2018 08:12:56 GMT

Transfer-encoding: chunked

 

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

 

    <xs:element name="listType" type="listType"/>

 

 

    <xs:complexType name="listType">

        <xs:sequence>

            <xs:element name="values" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>

        </xs:sequence>

    </xs:complexType>

</xs:schema>

```

 

 

Above is the description about the RESTEasy WADL Grammar feature.

 

 

The other change is that `ResteasyWadlServlet` and `ResteasyWadlServletWriter` is now deprecated, because it doesn’t support the grammar feature, and these two classes will be removed from master branch in the future. Using `ResteasyWadlDefaultResource` is recommended to enable the WADL feature.