Ok, given the discussions around Adapter/CollectionProvider and the complex way the existing server code has evolved, I decided to take a step back and look at the server module as a whole. I believe I've come up with a refactoring that will greatly simplify things overall and make it easier to support not only the capabilities that our friends from google want, but also things like extension methods (e.g. patch), protocol extensions (e.g. opensearch), etc.

Note: the refactoring would actually take place above the functionality that the google feed-server provides, so there could potentially be very little impact on that work, but we'll address that shortly.

The refactoring that I have in mind changes everything from AbderaServlet up through CollectionProvider and is focused on reducing the number of moving parts and number of things a developer has to do when implementing an atompub server.

In this note, I want to provide a quick run through of the changes I have in mind. I'll post some of the preliminary implementation ideas to a jira issue.

Structure:

Package: org.apache.abdera.protocol.server.refactor

  CollectionAdapter.java
  MediaCollectionAdapter.java
  Provider.java
  ProviderHelper.java
  Transactional.java
  WorkspaceManager.java

Package: org.apache.abdera.protocol.server.refactor.impl

  AbstractProvider.java
  AbstractWorkspaceManager.java
  AbstractWorkspaceManagerProvider.java


The code flow in the current implementation is:

  AbderaServlet -> RequestHandler -> Provider -> CollectionProvider

After refactoring, RequestHandler will be removed completely. The Provider interface is simplified to a single request method.

There will be a single base abstract Provider implementation provided but advanced developers will be able to replace that implementation with their own.

The default provider implementation will extend AbstractWorkspaceManagerProvider.java. This class implements boththe Provider and WorkspaceManager interfaces.

The WorkspaceManager is equivalent to the current WorkspaceInfo interface. It's primary function is to lookup the appropriate CollectionAdapter instance.

CollectionAdapter is the equivalent to the current CollectionProvider interface.

MediaCollectionAdapter extends CollectionAdapter to provide methods for handling media resources.

A CollectionAdapter instance can choose to implement the Provider interface in order to support extension methods.

A CollectionAdapter instance can choose to implement the Transactional interface if it wishes to support begin/end/compensate semantics.

All of the methods on CollectionAdapter take RequestContext and return ResponseContext, maintaining the ability to parameterize requests and utilize streaming responses.

The flow is simple: request comes into the servlet, which dispatches to the Provider. The Provider gets the WorkspaceManager and uses it to get the CollectionAdapter. If the request is for a known method and a known target type, the provider dispatches to the appropriate method on CollectionAdapter (e.g. getFeed, deleteEntry, etc). If the request is for an unknown method and an unknown target type, the provider checks to see if the CollectionAdapter implements the Provider interface, and if so, forwards the request on to it for processing, otherwise, an unsupported method response is returned. If CollectionAdapter implements Transactional, all of this is preceeded by a Transactional.begin() and proceeded by Transactional.end().

A CollectionAdapter can be implemented that wraps the simplified Adapter interface used by feed-server. Initially, this interface would not implement either Transactional or MediaCollectionAdapter keeping it in line with the current functionality offered by feed-server.

Additional refactorings would be required to implement this but overall the code structure would be greatly simplified, more logical, easier to extend, easier to maintain, and more accessible for end users.

Anyway, please take a look and let me know what you think.

- James

Reply via email to