Here's a patch for the trunk version of WadlGenerator that adds the
methods for resources accessed via sub-resource locators. I also
attach the WADL generated for the SimpleConsole sample application
which uses a sub resource locator for the Colours resource class.
One issue that occurred to me is how to handle circular references,
e.g. a resource class that has a subresource locator that returns an
instance of itself could generate an infinitely nested WADL. For now
I've protected against this with a simple list of visited classes but
this could be improved upon by generating a top level resource_type
element for each resource class and referring to that from each
resource element. With this a client could infer the circular
relationship which isn't possible with the current solution which just
includes a bare resource element for previously visited resource
classes. The downside is that the WADL would become more verbose.
Marc.
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: /Users/mh124079/Development/
Java/jersey/jersey/src/impl/com/sun/jersey/impl/wadl
# This patch can be applied using context Tools: Patch action on
respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: WadlGenerator.java
--- WadlGenerator.java Base (BASE)
+++ WadlGenerator.java Locally Modified (Based On LOCAL)
@@ -50,7 +50,9 @@
import com.sun.jersey.api.model.AbstractSubResourceLocator;
import com.sun.jersey.api.model.AbstractSubResourceMethod;
import com.sun.jersey.api.model.Parameter;
+import com.sun.jersey.impl.modelapi.annotation.IntrospectionModeller;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MediaType;
@@ -71,10 +73,11 @@
public static Application generate(Set<AbstractResource>
resources) {
Application wadlApplication = new Application();
Resources wadlResources = new Resources();
+ Set<Class<?>> visitedClasses = new HashSet<Class<?>>();
// for each resource
for (AbstractResource r: resources) {
- Resource wadlResource = generateResource(r);
+ Resource wadlResource = generateResource(r, null,
visitedClasses);
wadlResources.getResource().add(wadlResource);
}
wadlApplication.setResources(wadlResources);
@@ -89,7 +92,8 @@
public static Application generate(AbstractResource resource) {
Application wadlApplication = new Application();
Resources wadlResources = new Resources();
- Resource wadlResource = generateResource(resource);
+ Set<Class<?>> visitedClasses = new HashSet<Class<?>>();
+ Resource wadlResource = generateResource(resource, null,
visitedClasses);
wadlResources.getResource().add(wadlResource);
wadlApplication.setResources(wadlResources);
return wadlApplication;
@@ -203,11 +207,19 @@
return wadlParam;
}
- private static Resource generateResource(AbstractResource r) {
+ private static Resource generateResource(AbstractResource r,
String path, Set<Class<?>> visitedClasses) {
Resource wadlResource = new Resource();
- if (r.isRootResource())
+ if (path != null)
+ wadlResource.setPath(path);
+ else if (r.isRootResource())
wadlResource.setPath(r.getUriPath().getValue());
+ // prevent infinite recursion
+ if (visitedClasses.contains(r.getResourceClass()))
+ return wadlResource;
+ else
+ visitedClasses.add(r.getResourceClass());
+
// for each resource method
Map<String, Param> wadlResourceParams = new HashMap<String,
Param>();
for (AbstractResourceMethod m : r.getResourceMethods()) {
@@ -251,12 +263,8 @@
// for each sub resource locator
for (AbstractSubResourceLocator l :
r.getSubResourceLocators()) {
- Resource wadlSubResource = new Resource();
- wadlSubResource.setPath(l.getUriPath().getValue());
- for (Parameter p : l.getParameters()) {
- Param wadlParam = generateParam(p);
- wadlSubResource.getParam().add(wadlParam);
- }
+ AbstractResource subResource =
IntrospectionModeller.createResource( l.getMethod().getReturnType() );
+ Resource wadlSubResource = generateResource(subResource,
l.getUriPath().getValue(), visitedClasses);
wadlResource.getMethodOrResource().add(wadlSubResource);
}
return wadlResource;
The generated WADL for the SimpleConsole sample.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="
http://research.sun.com/wadl/2006/10">
<resources base="
http://localhost:9998/resources/">
<resource path="/form">
<method name="GET">
<response>
<representation mediaType="text/html" />
</response>
</method>
<method name="POST">
<request>
<representation mediaType="application/x-www-form-urlencoded" />
</request>
<response>
<representation mediaType="text/html" />
</response>
</method>
<resource path="colours">
<method name="GET">
<request>
<param xmlns:xs="
http://www.w3.org/2001/XMLSchema"
type="xs:string" style="query" name="match" />
</request>
<response>
<representation mediaType="text/plain" />
</response>
</method>
<method name="GET">
<request>
<param xmlns:xs="
http://www.w3.org/2001/XMLSchema"
type="xs:string" style="query" name="match" />
</request>
<response>
<representation mediaType="application/json" />
</response>
</method>
</resource>
</resource>
</resources>
</application>
---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.