You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@abdera.apache.org by Karthik Ananth1 <ka...@in.ibm.com> on 2009/01/30 09:56:47 UTC

Multiple providers for an AbderaServlet

Hi All,

I wanted to confirm that the way I have achieved support for multiple 
providers by a single AbderaServlet, does not create any other issues.

Let me breif you through my requirement and the way I achieved it.

Requirement:
I am building an AbderaServlet to serve 3 different kind of COLLECTIONS. I 
want URL for each of the COLLECTION cascaded as shown below, I will 
consider COLLECTION names as collectionA, collectionB and collectionC. And 
corresponding ENTRY as entryA, entryB and entryC. I have created 3 
collection adapters to serve my 3 COLLECTIONS,  CollectionAdapterA, 
CollectionAdapterB and CollectionAdapterC
 
URL
TargetType
Method to be called
/collectionA/
COLLECTION  A
getFeed() of CollectionAdapterA
/collectionA/ANY/
ENTRY  A
getEntry() of CollectionAdapterA
/collectionA/ANY/collectionB/
COLLECTION  B
getFeed() of CollectionAdapterB
/collectionA/ANY/collectionB/ANY/
ENTY  B
getEntry() of CollectionAdapterB
/collectionA/ANY/collectionB/ANY/collectionC/
COLLECTION C
getFeed() of CollectionAdapterC
/collectionA/ANY/collectionB/ANY/collectionC/ANY/
ENTRY C
getEntry() of CollectionAdapterC

My solution to achive:
The idea is to created 3 different Providers to serve each kind of 
COLLECTION. TargerResolver of 3 providers are set such that if satisfies 
above requirement, as given below
Provider
Collection Regex
Entry Regex
ProviderA
/collectionA/
/collectionA/ANY/
ProviderB
/collectionA/ANY/collectionB/
/collectionA/ANY/collectionB/ANY/
ProviderC
/collectionA/ANY/collectionB/ANY/collectionC/
/collectionA/ANY/collectionB/ANY/collectionC/ANY/

Now, the problem is I cannot register 3 providers to a single 
AbderaServlet. I noticed from the AbderaServlet source, it holds a single 
protected Provider field. I have to dynamically  choose any one of these 
providers depending on the Request URL. I noticed that a method "service" 
defined in AbderaServlet will be called on each Request. In the service 
method it uses its protected Provider instance.

So, I extended AbderaServlet as  "CustomAbderaServlet". The 
CustomAbderaServlet intializes holds all my 3 Providers. I override 
"service" method where I check the Request URL and choose appropriate 
Provider, code is pasted below,

public class AdaptersAbderaServlet 
  extends AbderaServlet {
 
protected ServiceManager manager;
protected Provider providerA;
protected Provider providerB;
protected Provider providerC;


public void init() throws ServletException {
 
    manager = createServiceManager();

/* Initializing providers */
    providerA = new providerA();
    providerA.init(getAbdera(), getProperties(getServletConfig()));
 
    providerB = new providerB();
    providerB.init(getAbdera(), getProperties(getServletConfig()));
 
    providerC = new providerC();
    providerC.init(getAbdera(), getProperties(getServletConfig()));
 
    log.debug("Created providers " +  datasourceProvider + ", " + 
botypeProvider);
  }

@Override  
protected void service(
    HttpServletRequest request, 
    HttpServletResponse response) 
      throws ServletException, IOException {
 
/* Call to get a suitable provider depending on the request */ 
Provider myProvider = getProvider(request); 
 
    RequestContext reqcontext = 
      new ServletRequestContext(myProvider, request);
    FilterChain chain = new FilterChain(myProvider,reqcontext);
    try {
      output(
        request,
        response,
        chain.next(
          reqcontext));
    } catch (Throwable t) {
      error("Error servicing request", t, response);
      return;
    }
    log.debug("Request complete");
  }

private Provider getProvider(HttpServletRequest request) {
        String path = request.getRequestURI();
        if(path.contains("collectionC"))
                return providerC;
        else if(path.contains("collectionB"))
                return providerB;
        else if(path.contains("collectionC"))
                return providerA;

        // TODO Handle this situation 
        return null;
}

}

So far its working fine for me. 

My questions are: 
1. whether this change is fine to have Or will will it leads to any other 
issues?
2. Is there any other way to achieve the same?
3. If there is no other way, is it possible for Abdera to consider this 
requirement and provide users a way to give their custom providers 
depending upon the Request URL? Or Is abdera framework is such a that a 
Servlet  should be associated with a single provider?