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