Basic Integration

Develop an annotation processor for dependency injection and template handling. Similar syntax to JBoss Seam.

Resource Identification

A resource is identified by the @Resource annotation.

@Resource("/full/url/path/with/{template}/{variables}")
public class Example {
}

Dependency Injection

Dependencies are identified with the @In annotation and can be sourced from the URL template or request parameters. Unless specified, search order is request parameters first. For example a request to /full/url/path/with/foo/bar?param=value&variables=blah could be injected into resource:

@Resource("/full/url/path/with/{template}/{variables}")
public class Example {
    @In(source=SourceType.TEMPLATE) private String template;
    @In private String variables;
    @In(name="param", required=false) private String widget;
}

After instantiation: template will contain "foo"; variables will contain "blah"; and param will contain "value".

Representation Association

An XTC template can be associated with a resource for representing a particular content type. The default content type is "text/html". The association is made with the @Representation annotation:

@Resource("/full/url/path/with/{template}/{variables}")
@Representation("/path/to/template.xhtml")
@Representation("/path/to/another.xml", contentType="text/xml")
public class Example {
}

XTC Context

The XTC template context is initialised by out-jection from the resource. Objects to be made available to the template context are annotated with the @Out annotation:

    @In(name="var") @Out private String variables;
    @Out(name="myData") private MyDataObject data;

Request Handling

Resources may perform some processing for a request by providing a void method annotated with the appropriate request type. Available request types annotations are @Get, @Post, @Put and @Delete. Typically, this is where the resource will initialise variables for out-jection to the template context. A complete example, using the request URL of /list/1?size=10:

@Resource("/list/{id}")
@Representation("ListTemplate.xhtml")
public class ListResource {
    @In @Out private Integer id;
    @In(required=false) private Integer size;
    @Out private List list;

    @Get public void processGet() {
        list = retrieveListFromDatasource(id);
        if (list.size() > size) {
            list = list.subList(0, size);
        }
    }
}

ListTemplate.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:c="http://java.sun.com/jstl/core">
<body>
<h1>List ${id}</h1>
<ul>
  <c:forEach var="item" varStatus="status" items="${list}">
    <li><a href="${status.index}">${item.name}</a></li>
  </c:forEach>
</ul>
</body>
</html>

Google Guice

How much of the above can be achieved using Guice rather than creating a new annotation processor and dependency injector? Not much really. Guice mostly handles class level bindings, not named instance binding like we desire. It could be done, but it would be clunky.

Resource Relations

How can we handle relationships between resources? For example Invoice would contain Items, perhaps with a URL mapping of /invoice/{invoiceNumber}/item/{itemNumber}. Using the above techniques requires us to have an InvoiceItemResource which handles the full URL above, as well as an InvoiceResource for just /invoice/{invoiceNumber} URLs. Wouldn't it be better to be able to specify that ItemResource is a sub-resource of InvoiceResource with relative URL item/{itemNumber}? Then we could re-use the ItemResource in an InventoryResource (perhaps with a different relative URL).

Option A

Sub-resources are identified in the parent resource with a complete relative URL:

@Resource("/invoice/{invoiceNumber}")
public class InvoiceResource {
    @SubResource("/item/{itemNumber}")
    private ItemResource items;
}

First the parent is initialised and processed for @Get, then the sub-resource is processed.