dev@jsr311.java.net

Inheritance of Java classes

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 15 May 2007 19:11:54 +0200

Hi,

In the "resource" programming model Marc and I developed a Java class
may extend another Java class and thus inherit the HTTP methods.

Jerome, in what you have proposed the ClientsResource (and others)
extend from AccountResource:

   @ApplicationClass(Application.class)
   public class AccountResource {
       @Output
       public Account getAccount() {
           return account;
       }
   }

   @ResourceRef("/clients")
   public class ClientsResource extends AccountResource {
       @Output
       public List<Client> getClients() {
           return getAccount().getClients();
       }
   }

What does it mean for the ClientsResource to inherit the getAccount
method from the AccountResource?



To explain inheritance more clearly an example might help using Java
classes for an Atom-based server. Some APP based examples i have seen
use one URI for read only access and another URI for read/write access.
For example, given some Java classes (see end of email) the following
URI templates to Java classes can be supported:

   URI Java class
-------------------------------------------------------
/collection/ FeedResource
/collection/{entry} EntryResource
/collection/{entry}/media EntryResource
/collection/edit/{entry} EditEntryResource
/collection/edit/{entry}/media EditEntryResource


The EditEntryResource inherits from EntryResource, overrides the URI
template (while keeping the same URI template name "{entry}"), inherits
the ProduceMime, and inherits the read only HTTP methods of
EntryResource. The familiar rules of inheritance are applied (note that
the Consume/ProduceMime and UriTemplate use the meta-annotation
Inherited). (There are a couple of edge cases but i don't what to
highlight those in this email so as not to detract from the main point.)



Inheritance may also be useful in another area. An instance of a class
returned to proceed further with the matching process may not be the
same class as declared by the return type. Thus it is possible to return
a concrete instance with additional HTTP methods to those that are
supported by the declared returned class. For example, see the
FeedResource2 class at the end of the email.

Paul.


[Note that the use of a constructor can stop the repeating
@UriParam("entry") annotation on EntryResource and EditEntryResource]

@UriTemplate("/collection/")
@ProduceMime("application/atom+xml")
@SubResources({EntryResource.class, EditEntryResource.class})
public class FeedResource {
     @Resource HttpContext context;

     @HttpMethod
     public Feed getFeed() {
     }

     @HttpMethod
     @ConsumeMime("application/atom+xml")
     public HttpResponse postEntry(Entry e) {
     }

     @HttpMethod
     public HttpResponse postMediaEntry(Entity<byte[]> entry) {
     }
}

@UriTemplate("{entry}")
@ProduceMime("application/atom+xml")
public class EntryResource {

     @HttpMethod
     public Entry getEntry(@UriParam("entry") String entryId) {
     }

     @HttpMethod
     @UriTemplate("media")
     @ProduceMime("*/*")
     public Representation<InputStream> getMedia(
             @UriParam("entry") String entryId) {
     }
}

@UriTemplate("edit/{entry}")
@ConsumeMime("application/atom+xml")
public class EditEntryResource extends EntryResource {

     @HttpMethod
     public void putEntry(@UriParam("entry") String entryId, Entry e) {
     }

     @HttpMethod
     public void deleteEntry(@UriParam("entry") String entryId) {
     }

     @HttpMethod
     @UriTemplate("media")
     @ConsumeMime("*/*")
     public void putMedia(@UriParam("entry") String entryId,
             Entity<byte[]> update)
     }
}



@UriTemplate("/collection/")
@ProduceMime("application/atom+xml")
public class FeedResource2 {
     @Resource HttpContext context;

     @HttpMethod
     public Feed getFeed() {
     }

     @HttpMethod
     @ConsumeMime("application/atom+xml")
     public HttpResponse postEntry(Entry e) {
     }

     @HttpMethod
     public HttpResponse postMediaEntry(Entity<byte[]> entry) {
     }

     @UriTemplate("{entry}")
     public EntryResource getEntryResource() {
         return new EntryResource();
     }

     @UriTemplate("edit/{entry}")
     public EntryResource getEditEntryResource() {
         return new EditEntryResource();
     }
}

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109