You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/09/13 04:00:38 UTC

svn commit: r442792 [1/2] - in /incubator/abdera/java/trunk: client/src/main/java/org/apache/abdera/protocol/client/ examples/src/main/java/org/apache/abdera/examples/appserver/ examples/src/main/resources/org/apache/abdera/examples/appserver/ protocol...

Author: jmsnell
Date: Tue Sep 12 19:00:35 2006
New Revision: 442792

URL: http://svn.apache.org/viewvc?view=rev&rev=442792
Log:
Ok, so the server code was coming along but it was getting rather difficult to manage
and was quickly becoming complicated and way too overabstracted.  So, I decided to 
simplify things a bit.  This is a big update that greatly improves the overall design 
of the server code.

RequestHandlers have been refactored to depend directly on the servlet api and a 
default implementation provided.  End developers should only have to worry about 
implementing a RequestHandler if they are extending the core APP methods (e.g. if 
someone wants to support COPY, etc).  RequestHandler's are pooled by default.

Provider has been fleshed out more and is the primary interface for interacting with 
a backend Atom Store.  

AbderaServer has been replaced by a much more improved ServiceContext element that is
accessed from a Singleton ServiceManager.

TargetResolver is still there are pretty much does the same thing it did before except
with a relatively minor API change.

SubjectResolver is still there and I have successfully tested it with third party auth 
tools like Acegi.

A new EntityTag class is provided that implements strong and weak entity tags, checking 
for matches between entity tags, etc.  The client and server code has been modified to 
use this new class.

The example APP server has been updated to demonstrate the new design.

A test suite for the server component has been started, but has not yet been plugged into
the build.

Added:
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleServiceContext.java
    incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/EntityTag.java
    incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/ResponseInfo.java
    incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/PoolManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbstractServiceContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/DefaultServiceContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/SubjectResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractProviderManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractRequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractTarget.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/BaseResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/EmptyResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Provider.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ProviderManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/RequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Target.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetType.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/HttpServletRequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/test/
    incubator/abdera/java/trunk/server/src/test/java/
    incubator/abdera/java/trunk/server/src/test/java/org/
    incubator/abdera/java/trunk/server/src/test/java/org/apache/
    incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/
    incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/
    incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/
    incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/UtilityTest.java
Removed:
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleRequestHandler.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleRequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/Provider.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ProviderManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/RequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/RequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/RequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/SubjectResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/Target.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/TargetResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractPooledProviderManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractProvider.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandlerManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractSimpleProviderManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/EmptyResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/PoolManager.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/TargetIterator.java
Modified:
    incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProvider.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProviderManager.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleTargetResolver.java
    incubator/abdera/java/trunk/examples/src/main/resources/org/apache/abdera/examples/appserver/web.xml
    incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/Response.java
    incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/AbstractResponse.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ServerConstants.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/SimpleSubjectResolver.java

Modified: incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java (original)
+++ incubator/abdera/java/trunk/client/src/main/java/org/apache/abdera/protocol/client/CommonsClient.java Tue Sep 12 19:00:35 2006
@@ -119,7 +119,7 @@
             // revalidate the cached entry
             if (cached_response != null) {
               options.setIfModifiedSince(cached_response.getLastModified());
-              options.setIfNoneMatch(cached_response.getEntityTag());
+              options.setIfNoneMatch(cached_response.getEntityTag().toString());
             } else {
               disp = CacheDisposition.TRANSPARENT;
             }

Modified: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProvider.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProvider.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProvider.java (original)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProvider.java Tue Sep 12 19:00:35 2006
@@ -17,190 +17,314 @@
 */
 package org.apache.abdera.examples.appserver;
 
+import java.net.URI;
+import java.security.MessageDigest;
 import java.util.Date;
 
+import javax.activation.MimeType;
+
+import org.apache.abdera.Abdera;
 import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Collection;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Entry;
 import org.apache.abdera.model.Feed;
-import org.apache.abdera.model.Link;
 import org.apache.abdera.model.Service;
-import org.apache.abdera.model.Source;
 import org.apache.abdera.model.Workspace;
+import org.apache.abdera.parser.ParseException;
+import org.apache.abdera.parser.Parser;
 import org.apache.abdera.parser.stax.util.FOMHelper;
-import org.apache.abdera.protocol.server.AbderaServer;
-import org.apache.abdera.protocol.server.Provider;
-import org.apache.abdera.protocol.server.RequestContext;
-import org.apache.abdera.protocol.server.Target;
-import org.apache.abdera.protocol.server.exceptions.AbderaServerException;
-import org.apache.abdera.protocol.server.exceptions.AbderaServerException.Code;
-import org.apache.abdera.protocol.server.util.AbstractProvider;
+import org.apache.abdera.protocol.EntityTag;
+import org.apache.abdera.protocol.ResponseInfo;
+import org.apache.abdera.protocol.server.provider.AbstractResponseContext;
+import org.apache.abdera.protocol.server.provider.BaseResponseContext;
+import org.apache.abdera.protocol.server.provider.EmptyResponseContext;
+import org.apache.abdera.protocol.server.provider.Provider;
+import org.apache.abdera.protocol.server.provider.RequestContext;
+import org.apache.abdera.protocol.server.provider.ResponseContext;
+import org.apache.abdera.protocol.server.provider.TargetType;
+import org.apache.abdera.util.MimeTypeHelper;
+import org.apache.axiom.om.util.Base64;
 
 public class SimpleProvider 
-  extends AbstractProvider
   implements Provider {
 
-  private static Document<Service> service_doc = null;
-  private static Document<Feed> feed_doc = null;
+  private EntityTag service_etag = new EntityTag("simple");
+  private Document<Service> service_doc;
+  private Document<Feed> feed_doc;
   
-  public SimpleProvider(AbderaServer abderaServer, SimpleProviderManager factory) {
-    super(abderaServer, factory);
+  private Document<Service> init_service_doc(Abdera abdera) {
+    Factory factory = abdera.getFactory();
+    Service service = factory.newService();
+    Workspace workspace = service.addWorkspace("Simple");
+    try {
+      Collection collection = workspace.addCollection("Simple", "atom/feed");
+      collection.setAccept("entry");
+    } catch (Exception e) {}
+    return service.getDocument();
+  }
+  
+  private Document<Feed> init_feed_doc(Abdera abdera) {
+    Factory factory = abdera.getFactory();
+    Feed feed = factory.newFeed();
+    try {
+      feed.setId("tag:example.org,2006:feed");
+      feed.setTitle("Simple");
+      feed.setUpdated(new Date());
+      feed.addLink("");
+      feed.addLink("","self");
+      feed.addAuthor("Simple");
+    } catch (Exception e) {}
+    return feed.getDocument();
   }
   
-  private synchronized Document<Service> getService() {
+  private synchronized Document<Service> get_service_doc(Abdera abdera) {
     if (service_doc == null) {
-      try {
-        Factory factory = getFactory();
-        service_doc = factory.newDocument();
-        Service service = factory.newService(service_doc);
-        Workspace workspace = service.addWorkspace("Simple");
-        Collection entries = workspace.addCollection("foo", "atom/foo");
-        entries.setAccept("entry");
-      } catch (Exception e) {}
+      service_doc = init_service_doc(abdera);
     }
     return service_doc;
   }
   
-  private synchronized Document<Feed> getFeed() {
+  private synchronized Document<Feed> get_feed_doc(Abdera abdera) {
     if (feed_doc == null) {
-      try {
-        Factory factory = getFactory();
-        feed_doc = factory.newDocument();
-        Feed feed = factory.newFeed(feed_doc);
-        feed.setId(FOMHelper.generateUuid());
-        feed.setTitle("Foo");
-        feed.setUpdated(new Date());
-        feed.addLink("http://example.org");
-        feed.addLink("", "self");
-        feed.addAuthor("Simple Service");
-      } catch (Exception e) {}
+      feed_doc = init_feed_doc(abdera);
     }
     return feed_doc;
   }
-
-  public void checkExists(
-    RequestContext context) 
-      throws AbderaServerException {
+  
+  public ResponseContext getService(
+    RequestContext request, 
+    boolean full) {
+      Abdera abdera = request.getServiceContext().getAbdera();
+      Document<Service> service = get_service_doc(abdera);
+      AbstractResponseContext rc; 
+      rc = (full) ? 
+        new BaseResponseContext<Document<Service>>(service) : 
+        new EmptyResponseContext(200);
+      rc.setEntityTag(service_etag);
+      return rc;
+  }
+  
+  public ResponseContext getFeed(
+    RequestContext request, 
+    boolean full) {
+      Abdera abdera = request.getServiceContext().getAbdera();
+      Document<Feed> feed = get_feed_doc(abdera);
+      AbstractResponseContext rc; 
+      rc = (full) ? 
+        new BaseResponseContext<Document<Feed>>(feed) : 
+        new EmptyResponseContext(200);
+      rc.setEntityTag(calculateEntityTag(feed.getRoot()));
+      return rc;
+  }
+
+  public ResponseInfo getInfo(
+    RequestContext request) {
+      TargetType type = request.getTarget().getType();
+      if (type == TargetType.TYPE_SERVICE) return getService(request, false);
+      if (type == TargetType.TYPE_COLLECTION) return getFeed(request, false);
+      if (type == TargetType.TYPE_ENTRY_EDIT) return getEntry(request, false, true);
+      return null;
   }
 
-  public void checkModified(
-    RequestContext context)
-      throws AbderaServerException {
+  
+  @SuppressWarnings("unchecked")
+  public ResponseContext createEntry(
+    RequestContext request) {
+      Abdera abdera = request.getServiceContext().getAbdera();
+      Parser parser = abdera.getParser();
+      try {
+        MimeType contentType = request.getContentType();
+        String ctype = (contentType != null) ? contentType.toString() : null;
+        if (ctype != null && !MimeTypeHelper.isAtom(ctype) && !MimeTypeHelper.isXml(ctype))
+          return new EmptyResponseContext(415);
+
+        Document<Entry> entry_doc = 
+          (Document<Entry>) request.getDocument(parser).clone();
+        if (entry_doc != null) {
+          Entry entry = entry_doc.getRoot();
+          if (!isValidEntry(entry))
+            return new EmptyResponseContext(400);
+          entry.setUpdated(new Date());
+          entry.getIdElement().setValue(FOMHelper.generateUuid());
+          entry.addLink("feed/" + entry.getId().toString(), "edit");
+          Feed feed = get_feed_doc(abdera).getRoot();
+          feed.insertEntry(entry);
+          feed.setUpdated(new Date());
+          BaseResponseContext rc = new BaseResponseContext(entry);
+          URI baseUri = resolveBase(request);
+          rc.setLocation(baseUri.resolve(entry.getEditLinkResolvedHref()).toString());
+          rc.setEntityTag(calculateEntityTag(entry));
+          rc.setStatus(201);
+          return rc;
+        } else {
+          return new EmptyResponseContext(400);
+        }
+      } catch (ParseException pe) {
+        return new EmptyResponseContext(415);
+      } catch (ClassCastException cce) {
+        return new EmptyResponseContext(415);
+      } catch (Exception e) {
+        return new EmptyResponseContext(400);
+      }
   }
   
-  public Entry addEntry(
-    RequestContext context) 
-      throws AbderaServerException {
-    try {
-      Document<Entry> entry_doc = 
-        getEntryFromRequestContext(context);
-      Entry entry = null;
-      if (entry_doc != null) {
-        entry = (Entry) entry_doc.getRoot().clone();
-        if (!isValidEntry(entry))
-          throw new AbderaServerException(
-            AbderaServerException.Code.BADREQUEST, "Invalid Entry", "");
-        entry.setUpdated(new Date());
-        entry.setModified(entry.getUpdated());
-        entry.getIdElement().setValue(FOMHelper.generateUuid());
-        entry.addLink("foo/" + entry.getId().toString(), "edit");
-        getFeed().getRoot().insertEntry((Entry) entry.clone());
+  private URI resolveBase(RequestContext request) {
+    return request.getBaseUri().resolve(request.getUri());
+  }
+  
+  public ResponseContext deleteEntry(
+    RequestContext request) {
+      Entry entry = getEntry(request);
+      if (entry != null)
+        entry.discard();
+      return new EmptyResponseContext(204);
+  }
+
+  public ResponseContext getEntry(
+    RequestContext request, 
+    boolean full,
+    boolean editable) {
+      Entry entry = (Entry) getEntry(request);
+      if (entry != null) {
+        Feed feed = entry.getParentElement();
+        entry = (Entry) entry.clone();
+        entry.setSource(feed.getAsSource());
+        Document<Entry> entry_doc = entry.getDocument();
+        AbstractResponseContext rc = (full) ?
+          new BaseResponseContext<Document<Entry>>(entry_doc) :
+          new EmptyResponseContext(200);
+        rc.setEntityTag(calculateEntityTag(entry));
+        return rc;
+      } else {
+        return new EmptyResponseContext(404);
       }
-      return entry;
-    } catch (Exception e) {
-      throw new AbderaServerException(Code.INTERNALSERVERERROR);
-    }
   }
 
-  public void deleteEntry(
-    RequestContext context) 
-      throws AbderaServerException {
-    Entry entry = getEntryFromFeed(context);
-    if (entry != null)
-      entry.discard();
-    else
-      throw new AbderaServerException(Code.NOTFOUND);
-  }
-
-  public Entry getEntry(
-    RequestContext context) 
-      throws AbderaServerException {
-    Entry entry = getEntryFromFeed(context);
-    if (entry != null)
-      return (Entry)entry.clone();
-    else
-      throw new AbderaServerException(Code.NOTFOUND);
-  }
-
-  public Entry updateEntry(
-    RequestContext context) 
-      throws AbderaServerException {
-    Entry entry = getEntryFromFeed(context);
-    if (entry == null) throw new AbderaServerException(Code.NOTFOUND);
+  @SuppressWarnings("unchecked")
+  public ResponseContext updateEntry(
+    RequestContext request) {
+      Abdera abdera = request.getServiceContext().getAbdera();
+      Parser parser = abdera.getParser();
+      Entry orig_entry = getEntry(request);
+      if (orig_entry != null) {
+        try {
+          MimeType contentType = request.getContentType();
+          if (contentType != null && !MimeTypeHelper.isAtom(contentType.toString()))
+            return new EmptyResponseContext(415);
+          
+          Document<Entry> entry_doc = 
+            (Document<Entry>) request.getDocument(parser).clone();
+          if (entry_doc != null) {
+            Entry entry = entry_doc.getRoot();
+            if (!entry.getId().equals(orig_entry.getId()))
+              return new EmptyResponseContext(409);
+            if (!isValidEntry(entry))
+              return new EmptyResponseContext(400);
+            entry.setUpdated(new Date());
+            entry.getIdElement().setValue(FOMHelper.generateUuid());
+            entry.addLink("atom/feed/" + entry.getId().toString(), "edit");
+            orig_entry.discard();
+            Feed feed = get_feed_doc(abdera).getRoot();
+            feed.insertEntry(entry);
+            feed.setUpdated(new Date());
+            return new EmptyResponseContext(204);
+          } else {
+            return new EmptyResponseContext(400);
+          }
+        } catch (ParseException pe) {
+          return new EmptyResponseContext(415);
+        } catch (ClassCastException cce) {
+          return new EmptyResponseContext(415);
+        } catch (Exception e) {
+          return new EmptyResponseContext(400);
+        }
+      } else {
+        return new EmptyResponseContext(404);
+      }
+  }
+
+  private EntityTag calculateEntityTag(Base base) {
     try {
-      Document<Entry> entry_doc = getEntryFromRequestContext(context);
-      if (entry_doc == null) 
-        throw new AbderaServerException(
-          AbderaServerException.Code.UNSUPPORTEDMEDIATYPE, 
-          "Unsupported Media Type", "");
-      Document<Feed> feed_doc = getFeed();
-      Entry e = (Entry) entry_doc.getRoot().clone();
-      // check to see if it's a valid atom entry
-      if (!isValidEntry(entry))
-        throw new AbderaServerException(
-          AbderaServerException.Code.BADREQUEST, "Invalid Entry", "");
-      // check to see if the atom:id matches
-      if (!e.getId().equals(entry.getId()))
-        throw new AbderaServerException(
-          AbderaServerException.Code.CONFLICT, "Conflict. Cannot change atom:id", "");
-      // override atom:updated 
-      e.setUpdated(new Date());
-      // set the app:modified date
-      e.setModified(e.getUpdated());
-      // make sure the edit link stays the same
-      Link editLink = e.getEditLink();
-      if (editLink == null) 
-        e.addLink("foo/" + e.getId().toString(), "edit");
-      else editLink.setHref("foo/" + e.getId().toString());
-      // discard the original
-      entry.discard();
-      // insert the new
-      e = (Entry) e.clone();
-      feed_doc.getRoot().insertEntry(e);
-      return e;
+      String id = null;
+      String modified = null;
+      if (base instanceof Entry) {
+        id = ((Entry)base).getId().toString();
+        modified = ((Entry)base).getUpdatedElement().getText();
+      } else if (base instanceof Feed) {
+        id = ((Feed)base).getId().toString();
+        modified = ((Feed)base).getUpdatedElement().getText();
+      }
+      String tag = id + ":" + modified;
+      byte[] digest = MessageDigest.getInstance("sha1").digest(tag.getBytes());
+      String etag = Base64.encode(digest);
+      return new EntityTag(etag);
     } catch (Exception e) {
-      throw new AbderaServerException(e);
+      // Not going to happen
     }
+    return null;
   }
   
-  public Feed getFeed(
-    RequestContext context) 
-      throws AbderaServerException {
-    return getFeed().getRoot();
+  private Entry getEntry(RequestContext request) {
+    Abdera abdera = request.getServiceContext().getAbdera();
+    String entry_id = getEntryID(request);
+    Document<Feed> feed = get_feed_doc(abdera);
+    try { 
+      return feed.getRoot().getEntry(entry_id); 
+    } catch (Exception e) {}
+    return null;
   }
-
-  public Source getFeedForEntry(
-    Entry entry) 
-      throws AbderaServerException {
-    return getFeed().getRoot().getAsSource();
+  
+  private String getEntryID(RequestContext request) {
+    if (request.getTarget().getType() != TargetType.TYPE_ENTRY_EDIT) 
+      return null;
+    String path = request.getUri().toString();
+    String[] segments = path.split("/");
+    return segments[segments.length-1];
   }
-
-  public Service getService(
-    RequestContext context)
-      throws AbderaServerException {
-    return getService().getRoot();
+  
+  public ResponseContext entryPost(
+    RequestContext request) {
+      return new EmptyResponseContext(403);
+  }
+  
+  public ResponseContext deleteMedia(
+    RequestContext request) {
+      throw new UnsupportedOperationException();
+  }
+  
+  public ResponseContext mediaPost(
+    RequestContext request) {
+      throw new UnsupportedOperationException();
+  }
+  
+  public ResponseContext getMedia(
+    RequestContext request, 
+    boolean full,
+    boolean editable) {
+      throw new UnsupportedOperationException();
+  }
+  
+  public ResponseContext updateMedia(
+    RequestContext request) {
+      throw new UnsupportedOperationException();
   }
 
-  private Entry getEntryFromFeed(RequestContext context) {
+  private boolean isValidEntry(Entry entry) {
     try {
-      Target target = context.getTarget();
-      Document<Feed> doc_feed = getFeed();
-      String id = target.getValue(2);
-      return doc_feed.getRoot().getEntry(id);
+      if (entry.getId() == null || 
+          entry.getId().toString().length() == 0) return false;
+      if (entry.getTitle() == null) return false;
+      if (entry.getAuthor() == null) return false;
+      if (entry.getUpdated() == null) return false;
+      if (entry.getContent() == null) {
+        if (entry.getAlternateLink() == null) return false;
+        if (entry.getSummary() == null) return false;
+      }
     } catch (Exception e) {
-      return null;
+      e.printStackTrace();
     }
+    return true;
   }
-  
 }

Modified: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProviderManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProviderManager.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProviderManager.java (original)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleProviderManager.java Tue Sep 12 19:00:35 2006
@@ -17,24 +17,20 @@
 */
 package org.apache.abdera.examples.appserver;
 
-import org.apache.abdera.protocol.server.AbderaServer;
-import org.apache.abdera.protocol.server.Provider;
-import org.apache.abdera.protocol.server.ProviderManager;
-import org.apache.abdera.protocol.server.exceptions.AbderaServerException;
-import org.apache.abdera.protocol.server.util.AbstractSimpleProviderManager;
+import org.apache.abdera.protocol.server.provider.Provider;
+import org.apache.abdera.protocol.server.provider.ProviderManager;
 
 public class SimpleProviderManager 
-  extends AbstractSimpleProviderManager
   implements ProviderManager {
 
-  private Provider provider = null;
-  
-  protected synchronized Provider getProvider(
-    AbderaServer abderaServer) throws AbderaServerException {
-      if (provider == null)  {
-        provider = new SimpleProvider(abderaServer, this);
-      }
-      return provider;
+  private static Provider provider = null; 
+
+  public synchronized Provider getProvider() {
+    if (provider == null)
+      provider = new SimpleProvider();
+    return provider;
   }
+
+  public void release(Provider provider) {}
 
 }

Added: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleServiceContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleServiceContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleServiceContext.java (added)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleServiceContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.examples.appserver;
+
+import org.apache.abdera.protocol.server.DefaultServiceContext;
+
+public class SimpleServiceContext 
+  extends DefaultServiceContext {
+
+  @Override
+  protected String getDefaultProviderManager() {
+    return SimpleProviderManager.class.getName();
+  }
+
+  @Override
+  protected String getDefaultTargetResolver() {
+    return SimpleTargetResolver.class.getName();
+  }
+  
+}

Modified: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleTargetResolver.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleTargetResolver.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleTargetResolver.java (original)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/appserver/SimpleTargetResolver.java Tue Sep 12 19:00:35 2006
@@ -17,16 +17,16 @@
 */
 package org.apache.abdera.examples.appserver;
 
+import org.apache.abdera.protocol.server.provider.TargetType;
 import org.apache.abdera.protocol.server.util.RegexTargetResolver;
-import org.apache.abdera.protocol.server.util.ResourceType;
 
 public class SimpleTargetResolver 
   extends RegexTargetResolver {
 
   public SimpleTargetResolver() {
-    setPattern(ResourceType.SERVICE, "/appserver/atom(\\?[^#]*)?");
-    setPattern(ResourceType.COLLECTION, "/appserver/atom/([^/#?]+)(\\?[^#]*)?");
-    setPattern(ResourceType.ENTRY_EDIT, "/appserver/atom/([^/#?]+)/([^/#?]+)(\\?[^#]*)?");
+    setPattern("/appserver/atom(\\?[^#]*)?", TargetType.TYPE_SERVICE);
+    setPattern("/appserver/atom/feed(\\?[^#]*)?", TargetType.TYPE_COLLECTION);
+    setPattern("/appserver/atom/feed/([^/#?]+)(\\?[^#]*)?", TargetType.TYPE_ENTRY_EDIT);
   }
   
 }

Modified: incubator/abdera/java/trunk/examples/src/main/resources/org/apache/abdera/examples/appserver/web.xml
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/resources/org/apache/abdera/examples/appserver/web.xml?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/resources/org/apache/abdera/examples/appserver/web.xml (original)
+++ incubator/abdera/java/trunk/examples/src/main/resources/org/apache/abdera/examples/appserver/web.xml Tue Sep 12 19:00:35 2006
@@ -8,12 +8,8 @@
     <servlet-name>Abdera</servlet-name>  
     <servlet-class>org.apache.abdera.protocol.server.servlet.AbderaServlet</servlet-class>
     <init-param>
-      <param-name>org.apache.abdera.protocol.server.RequestHandlerFactory</param-name>
-      <param-value>org.apache.abdera.examples.appserver.SimpleRequestHandlerFactory</param-value>
-    </init-param>
-    <init-param>
-      <param-name>org.apache.abdera.protocol.server.TargetResolver</param-name>
-      <param-value>org.apache.abdera.examples.appserver.SimpleTargetResolver</param-value>
+      <param-name>org.apache.abdera.protocol.server.ServiceContext</param-name>
+      <param-value>org.apache.abdera.examples.appserver.SimpleServiceContext</param-value>
     </init-param>
   </servlet>
   <servlet-mapping id="abdera-mapping">

Added: incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/EntityTag.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/EntityTag.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/EntityTag.java (added)
+++ incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/EntityTag.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,163 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a simple Entity Tag
+ */
+public class EntityTag {
+
+  public static EntityTag parse(String entity_tag) {
+    if (entity_tag == null || entity_tag.length() == 0) 
+      throw new IllegalArgumentException();    
+    boolean weak = entity_tag.startsWith("W/");
+    String tag = entity_tag.substring((weak)?3:1, entity_tag.length() - 1);
+    return new EntityTag(tag, weak);
+  }
+
+  public static EntityTag[] parseTags(String entity_tags) {
+    if (entity_tags == null || entity_tags.length() == 0)
+      return new EntityTag[0];
+    List<EntityTag> etags = new ArrayList<EntityTag>();
+    String[] tags = entity_tags.split(",");
+    for (String tag : tags) {
+      tag = tag.trim();
+      etags.add(parse(tag));
+    }
+    return etags.toArray(new EntityTag[etags.size()]);
+  }
+  
+  public static boolean matchesAny(EntityTag tag1, String tags) {
+    return matchesAny(tag1, parseTags(tags), false);
+  }
+  
+  public static boolean matchesAny(EntityTag tag1, String tags, boolean weak) {
+    return matchesAny(tag1, parseTags(tags), weak);
+  }
+  
+  public static boolean matchesAny(String tag1, String tags) {
+    return matchesAny(parse(tag1), parseTags(tags), false);
+  }
+  
+  public static boolean matchesAny(String tag1, String tags, boolean weak) {
+    return matchesAny(parse(tag1), parseTags(tags), weak);
+  }
+  
+  public static boolean matchesAny(EntityTag tag1, EntityTag[] tags) {
+    return matchesAny(tag1,tags,false);
+  }
+  
+  public static boolean matchesAny(EntityTag tag1, EntityTag[] tags, boolean weak) {
+    if (tags == null) return (tag1 == null) ? true : false;
+    for (EntityTag tag : tags) {
+      if (matches(tag1,tag,weak)) return true;
+    }
+    return false;
+  }
+  
+  public static boolean matches(EntityTag tag1, EntityTag tag2) {
+    return matches(tag1,tag2,false);
+  }
+  
+  public static boolean matches(EntityTag tag1, EntityTag tag2, boolean weak) {
+    return tag1.equals(tag2,weak);
+  }
+  
+  public static boolean matches(String tag1, String tag2) { 
+    return matches(tag1,tag2,false);
+  }
+  
+  public static boolean matches(String tag1, String tag2, boolean weak) {
+    EntityTag etag1 = parse(tag1);
+    EntityTag etag2 = parse(tag2);
+    return etag1.equals(etag2, weak);
+  }
+  
+  public static boolean matches(EntityTag tag1, String tag2) {
+    return matches(tag1,tag2,false);
+  }
+  
+  public static boolean matches(EntityTag tag1, String tag2, boolean weak) {
+    EntityTag etag2 = parse(tag2);
+    return tag1.equals(etag2, weak);
+  }
+  
+  private final String tag;
+  private final boolean weak;
+  
+  public EntityTag(String tag) {
+    this(tag,false);
+  }
+  
+  public EntityTag(String tag, boolean weak) {
+    this.tag = tag;
+    this.weak = weak;
+  }
+  
+  public String getTag() {
+    return tag;
+  }
+  
+  public boolean isWeak() {
+    return weak;
+  }
+  
+  public String toString() {
+    StringBuffer buf = new StringBuffer();
+    if (weak) buf.append("W/");
+    buf.append("\"");
+    buf.append(tag);
+    buf.append("\"");
+    return buf.toString();
+  }
+  
+
+  public int hashCode() {
+    final int PRIME = 31;
+    int result = 1;
+    result = PRIME * result + ((tag == null) ? 0 : tag.hashCode());
+    result = PRIME * result + (weak ? 1231 : 1237);
+    return result;
+  }
+
+  public boolean equals(Object obj) {
+    return equals(obj,false);
+  }
+  
+  private boolean equals(Object obj, boolean weak) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    final EntityTag other = (EntityTag) obj;
+    if (tag == null) {
+      if (other.tag != null)
+        return false;
+    } else if (!tag.equals(other.tag))
+      return false;
+    if (weak != other.weak)
+      return false;
+    return true;
+  }
+  
+}

Modified: incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/Response.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/Response.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/Response.java (original)
+++ incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/Response.java Tue Sep 12 19:00:35 2006
@@ -28,7 +28,8 @@
 
 import org.apache.abdera.protocol.util.ProtocolConstants;
 
-public interface Response extends ProtocolConstants {
+public interface Response
+  extends ResponseInfo, ProtocolConstants {
 
   public static enum ResponseType {
     SUCCESS, REDIRECTION, CLIENT_ERROR, SERVER_ERROR, UNKNOWN;
@@ -50,8 +51,6 @@
   public String getStatusText();
   
   public Date getLastModified();
-  
-  public String getEntityTag();
   
   public String getContentLanguage();
   

Added: incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/ResponseInfo.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/ResponseInfo.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/ResponseInfo.java (added)
+++ incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/ResponseInfo.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol;
+
+import java.util.Date;
+
+
+public interface ResponseInfo {
+
+  Date getLastModified();
+  
+  EntityTag getEntityTag();
+  
+}

Modified: incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/AbstractResponse.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/AbstractResponse.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/AbstractResponse.java (original)
+++ incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/AbstractResponse.java Tue Sep 12 19:00:35 2006
@@ -24,6 +24,7 @@
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
 
+import org.apache.abdera.protocol.EntityTag;
 import org.apache.abdera.protocol.Response;
 
 public abstract class AbstractResponse 
@@ -70,8 +71,9 @@
     return (value != null) ? new MimeType(value) : null;
   }
 
-  public String getEntityTag() {
-    return getHeader("ETag");
+  public EntityTag getEntityTag() {
+    String etag = getHeader("ETag");
+    return (etag != null) ? EntityTag.parse(getHeader("ETag")) : null;
   }
 
   public Date getExpires() {

Added: incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/PoolManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/PoolManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/PoolManager.java (added)
+++ incubator/abdera/java/trunk/protocol/src/main/java/org/apache/abdera/protocol/util/PoolManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,37 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.util;
+
+import java.util.Stack;
+
+public abstract class PoolManager<T> {
+
+  private final Stack<T> pool = new Stack<T>();
+  
+  protected synchronized T getInstance() {
+    return (!pool.empty()) ? pool.pop() : internalNewInstance();
+  }
+
+  public synchronized void release(T t) {
+    if (t == null || pool.contains(t)) return;
+    pool.push(t);
+  }
+  
+  protected abstract T internalNewInstance();
+ 
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbstractServiceContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbstractServiceContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbstractServiceContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbstractServiceContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,58 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.protocol.server.auth.SubjectResolver;
+import org.apache.abdera.protocol.server.provider.ProviderManager;
+import org.apache.abdera.protocol.server.provider.TargetResolver;
+import org.apache.abdera.protocol.server.servlet.RequestHandlerManager;
+
+public abstract class AbstractServiceContext 
+  implements ServiceContext {
+
+  protected Abdera abdera;
+  protected Map<String,String> config;
+  protected ProviderManager providerManager;
+  protected RequestHandlerManager handlerManager;
+  protected SubjectResolver subjectResolver;
+  protected TargetResolver targetResolver;
+  
+  public synchronized void init(
+    Abdera abdera, 
+    Map<String,String> config) {
+     this.abdera = abdera;
+     this.config = (config != null) ? config : new HashMap<String,String>();
+  }
+  
+  public Abdera getAbdera() {
+    return abdera;
+  }
+
+  public String getProperty(String name) {
+    return config.get(name);
+  }
+
+  public String[] getPropertyNames() {
+    return config.keySet().toArray(new String[config.size()]);
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/DefaultServiceContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/DefaultServiceContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/DefaultServiceContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/DefaultServiceContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,87 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server;
+
+import org.apache.abdera.protocol.server.auth.SubjectResolver;
+import org.apache.abdera.protocol.server.provider.ProviderManager;
+import org.apache.abdera.protocol.server.provider.TargetResolver;
+import org.apache.abdera.protocol.server.servlet.DefaultRequestHandlerManager;
+import org.apache.abdera.protocol.server.servlet.RequestHandlerManager;
+import org.apache.abdera.protocol.server.util.RegexTargetResolver;
+import org.apache.abdera.protocol.server.util.ServerConstants;
+import org.apache.abdera.protocol.server.util.SimpleSubjectResolver;
+import org.apache.abdera.util.ServiceUtil;
+
+public class DefaultServiceContext 
+  extends AbstractServiceContext
+  implements ServerConstants {
+
+  private Object instance(String id, String _default) {
+    String instance = getProperty(id);
+    return ServiceUtil.newInstance( id, (instance!=null)?instance:_default, abdera);
+  }
+  
+  public synchronized ProviderManager getProviderManager() {
+    if (providerManager == null) {
+      providerManager = (ProviderManager) instance(
+        PROVIDER_MANAGER, getDefaultProviderManager());
+    }
+    return providerManager;
+  }
+  
+  protected String getDefaultProviderManager() {
+    return null;
+  }
+
+  public synchronized RequestHandlerManager getRequestHandlerManager() {
+    if (handlerManager == null) {
+      handlerManager = (RequestHandlerManager) instance(
+        REQUEST_HANDLER_MANAGER, getDefaultRequestHandlerManager());
+    }
+    return handlerManager;
+  }
+  
+  protected String getDefaultRequestHandlerManager() {
+    return DefaultRequestHandlerManager.class.getName();
+  }
+
+  public SubjectResolver getSubjectResolver() {
+    if (subjectResolver == null) {
+      subjectResolver = (SubjectResolver) instance(
+        SUBJECT_RESOLVER, getDefaultSubjectResolver());
+    }
+    return subjectResolver;
+  }
+  
+  protected String getDefaultSubjectResolver() {
+    return SimpleSubjectResolver.class.getName();
+  }
+
+  public TargetResolver getTargetResolver() {
+    if (targetResolver == null) {
+      targetResolver = (TargetResolver) instance(
+        TARGET_RESOLVER, getDefaultTargetResolver());
+    }
+    return targetResolver;
+  }
+  
+  protected String getDefaultTargetResolver() {
+    return RegexTargetResolver.class.getName();
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server;
+
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.protocol.server.auth.SubjectResolver;
+import org.apache.abdera.protocol.server.provider.ProviderManager;
+import org.apache.abdera.protocol.server.provider.TargetResolver;
+import org.apache.abdera.protocol.server.servlet.RequestHandlerManager;
+
+public interface ServiceContext {
+
+  Abdera getAbdera();
+  
+  void init(Abdera abdera, Map<String,String> config);
+  
+  RequestHandlerManager getRequestHandlerManager();
+  
+  ProviderManager getProviderManager();
+  
+  SubjectResolver getSubjectResolver();
+  
+  TargetResolver getTargetResolver();
+  
+  String getProperty(String name);
+  
+  String[] getPropertyNames();
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/ServiceManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server;
+
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.protocol.server.util.ServerConstants;
+import org.apache.abdera.util.ServiceUtil;
+
+public class ServiceManager 
+  implements ServerConstants {
+  
+  private static ServiceManager INSTANCE = null;
+  private static Abdera abdera = null;
+  
+  ServiceManager() {}
+  
+  public static synchronized ServiceManager getInstance() {
+    if (INSTANCE == null) INSTANCE = new ServiceManager();
+    return INSTANCE;
+  }
+  
+  public static synchronized Abdera getAbdera() {
+    if (abdera == null) abdera = new Abdera();
+    return abdera;
+  }
+  
+  public ServiceContext newServiceContext(
+    Map<String,String> properties) {
+    Abdera abdera = getAbdera();
+    String instance = properties.get(SERVICE_CONTEXT);
+    ServiceContext context = 
+      (ServiceContext) ServiceUtil.newInstance(
+        SERVICE_CONTEXT, 
+        (instance != null) ? 
+          instance : 
+          DefaultServiceContext.class.getName(),
+        abdera);
+    context.init(abdera, properties);
+    return context;
+  }
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/SubjectResolver.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/SubjectResolver.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/SubjectResolver.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/auth/SubjectResolver.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.auth;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+public interface SubjectResolver {
+
+  Subject resolve(Principal principal);
+  
+  Subject resolve(String userid);
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractProviderManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractProviderManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractProviderManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractProviderManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import org.apache.abdera.protocol.util.PoolManager;
+
+public abstract class AbstractProviderManager
+  extends PoolManager<Provider>
+  implements ProviderManager {
+
+  public Provider getProvider() {
+    return getInstance();
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractRequestContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractRequestContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractRequestContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractRequestContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,119 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.security.auth.Subject;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.ParseException;
+import org.apache.abdera.parser.Parser;
+import org.apache.abdera.parser.ParserOptions;
+import org.apache.abdera.protocol.server.ServiceContext;
+import org.apache.abdera.protocol.util.AbstractRequest;
+
+public abstract class AbstractRequestContext 
+  extends AbstractRequest
+  implements RequestContext {
+
+  protected final ServiceContext context;
+  protected Subject subject;
+  protected Target target;
+  protected final String method;
+  protected final URI requestUri;
+  protected final URI baseUri;
+  
+  protected AbstractRequestContext(
+    ServiceContext context,
+    String method, 
+    URI requestUri,
+    URI baseUri) {
+      this.context = context;
+      this.method = method;
+      this.baseUri = baseUri;
+      this.requestUri = requestUri;
+  }
+    
+  public <T extends Element>Document<T> getDocument()
+    throws ParseException, 
+           IOException {
+    Abdera abdera = context.getAbdera();
+    Parser parser = abdera.getParser();
+    ParserOptions options = parser.getDefaultParserOptions();
+    return getDocument(parser, options);
+  }
+  
+  public <T extends Element>Document<T> getDocument(
+    Parser parser)
+      throws ParseException, 
+             IOException {
+      ParserOptions options = parser.getDefaultParserOptions();
+      return getDocument(parser, options);
+  }
+  
+  public <T extends Element>Document<T> getDocument(
+    ParserOptions options)
+     throws ParseException, 
+            IOException  {
+      Abdera abdera = context.getAbdera();
+      Parser parser = abdera.getParser();
+      return getDocument(parser, options);
+  }
+  
+  public <T extends Element>Document<T> getDocument(
+    Parser parser, 
+    ParserOptions options) 
+      throws ParseException, 
+             IOException {
+      return parser.parse(
+        getInputStream(), 
+        (URI)null, options);
+  }
+  
+  public URI getBaseUri() {
+    return baseUri;
+  }
+
+  public URI getResolvedUri() {
+    return baseUri.resolve(getUri());
+  }
+  
+  public String getMethod() {
+    return method;
+  }
+
+  public URI getUri() {
+    return requestUri;
+  }
+  
+  public Subject getSubject() {
+    return subject;
+  }
+
+  public Target getTarget() {
+    return target;
+  }
+  
+  public ServiceContext getServiceContext() {
+    return context;
+  }
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractResponseContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractResponseContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractResponseContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,260 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.abdera.protocol.EntityTag;
+import org.apache.abdera.protocol.server.provider.ResponseContext;
+import org.apache.abdera.protocol.util.AbstractResponse;
+
+public abstract class AbstractResponseContext
+  extends AbstractResponse
+  implements ResponseContext {
+
+  protected static final String[] EMPTY = new String[0];
+  
+  protected int status = 0;
+  protected String status_text = null;
+  
+  protected Map<String,List<Object>> headers = null;
+
+  public void removeHeader(String name) {
+    Map<String,List<Object>> headers = getHeaders();
+    headers.remove(name);
+  }
+  
+  public void setHeader(String name, Object value) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = new ArrayList<Object>();
+    values.add(value);
+    headers.put(name, values);
+  }
+  
+  public void setHeader(String name, Object... vals) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = new ArrayList<Object>();
+    for (Object value : vals) {
+      values.add(value);
+    }
+    headers.put(name, values);
+  }
+  
+  public void addHeader(String name, Object value) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = new ArrayList<Object>();
+    if (values == null) {
+      values = new ArrayList<Object>();
+      headers.put(name, values);
+    } 
+    values.add(value);
+  }
+  
+  public void addHeaders(String name, Object... vals) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = new ArrayList<Object>();
+    if (values == null) {
+      values = new ArrayList<Object>();
+      headers.put(name,values);
+    }
+    for (Object value : vals) {
+      values.add(value);
+    }
+  }
+  
+  public Map<String, List<Object>> getHeaders() {
+    if (headers == null)
+      headers = new HashMap<String,List<Object>>();
+    return headers;
+  }
+    
+  public Date getDateHeader(String name) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = headers.get(name);
+    if (values != null) {
+      for (Object value : values) {
+        if (value instanceof Date) 
+          return (Date)value;
+      }
+    }
+    return null;
+  }
+  
+  public String getHeader(String name) {
+    Map<String,List<Object>> headers = getHeaders();
+    List<Object> values = headers.get(name);
+    if (values != null && values.size() > 0) 
+      return values.get(0).toString();
+    return null;
+  }
+
+  public List<Object> getHeaders(String name) {
+    Map<String,List<Object>> headers = getHeaders();
+    return headers.get(name);
+  }
+
+  public String[] getHeaderNames() {
+    Map<String,List<Object>> headers = getHeaders();
+    return headers.keySet().toArray(new String[headers.size()]);
+  }
+  
+  private void append(StringBuffer buf, String value) {
+    if (buf.length() > 0) buf.append(", ");
+    buf.append(value);
+  }
+    
+  public String getCacheControl() {
+    StringBuffer buf = new StringBuffer();
+    if (isPublic()) append(buf,"public");
+    if (isPrivate()) append(buf,"private");
+    if (private_headers != null && private_headers.length > 0) {
+      buf.append("=\"");
+      for (String header : private_headers) {
+        append(buf,header);
+      }
+      buf.append("\"");
+    }
+    if (isNoCache()) append(buf,"no-cache");
+    if (nocache_headers != null && nocache_headers.length > 0) {
+      buf.append("=\"");
+      for (String header : nocache_headers) {
+        append(buf,header);
+      }
+      buf.append("\"");
+    }
+    if (isNoStore()) append(buf,"no-store");
+    if (isMustRevalidate()) append(buf,"must-revalidate");
+    if (isNoTransform()) append(buf, "no-transform");
+    if (getMaxAge() != -1) append(buf, "max-age=" + getMaxAge());
+    if (getSMaxAge() != -1) append(buf, "smax-age=" + getMaxAge());
+    return buf.toString();
+  }
+
+  public void setAge(long age) {
+    if (age == -1) {
+      removeHeader("Age"); 
+      return;
+    }
+    setHeader("Age", String.valueOf(age));
+  }
+  
+  public void setContentLanguage(String language) {
+    if (language == null) {
+      removeHeader("Content-Language");
+      return;
+    }
+    setHeader("Content-Language", language);
+  }
+
+  public void setContentLength(long length) {
+    if (length == -1) {
+      removeHeader("Content-Length");
+      return;
+    }
+    setHeader("Content-Length", String.valueOf(length));
+  }
+
+  public void setContentLocation(String uri) {
+    if (uri == null) {
+      removeHeader("Content-Location");
+      return;
+    }
+    setHeader("Content-Location", uri);
+  }
+  
+  public void setSlug(String slug) {
+    if (slug == null) {
+      removeHeader("Slug");
+      return;
+    }
+    setHeader("Slug", slug);
+  }
+  
+  public void setContentType(String type) {
+    if (type == null) {
+      removeHeader("Content-Type");
+      return;
+    }
+    setHeader("Content-Type", type);
+  }
+
+  public void setEntityTag(EntityTag etag) {
+    if (etag == null) {
+      removeHeader("ETag");
+      return;
+    }
+    setHeader("ETag", etag.toString());
+  }
+
+  public void setExpires(Date date) {
+    if (date == null) {
+      removeHeader("Expires");
+      return;
+    }
+    setHeader("Expires", date);
+  }
+  
+  public void setLastModified(Date date) {
+    if (date == null) {
+      removeHeader("Last-Modified");
+      return;
+    }
+    setHeader("Last-Modified", date);
+  }
+
+  public void setLocation(String uri) {
+    if (uri == null) {
+      removeHeader("Location");
+      return;
+    }
+    setHeader("Location", uri);
+  }
+  
+  public int getStatus() {
+    return status;
+  }
+  
+  public void setStatus(int status) {
+    this.status = status;
+  }
+
+  public String getStatusText() {
+    return status_text;
+  }
+  
+  public void setStatusText(String text) {
+    this.status_text = text;
+  }
+
+  public void setAllow(String method) {
+    setHeader("Allow", method);
+  }
+  
+  public void setAllow(String... methods) {
+    StringBuffer buf = new StringBuffer();
+    for(String method : methods) {
+      if (buf.length() > 0) buf.append(", ");
+      buf.append(method);
+    }
+    setAllow(buf.toString());
+  }
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractTarget.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractTarget.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractTarget.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/AbstractTarget.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,80 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+public abstract class AbstractTarget 
+  implements Target {
+
+  protected final TargetType type;
+  protected final RequestContext context;
+  
+  protected AbstractTarget(
+    TargetType type, 
+    RequestContext context) {
+      this.type = type;
+      this.context = context;
+  }
+  
+  public String getIdentity() {
+    return context.getUri().toString();
+  }
+
+  public String getParameter(String name) {
+    return context.getParameter(name);
+  }
+
+  public String[] getParameterNames() {
+    return context.getParameterNames();
+  }
+
+  public TargetType getType() {
+    return type;
+  }
+
+  @Override
+  public int hashCode() {
+    final int PRIME = 31;
+    int result = 1;
+    result = PRIME * result + ((context == null) ? 0 : context.hashCode());
+    result = PRIME * result + ((type == null) ? 0 : type.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    final AbstractTarget other = (AbstractTarget) obj;
+    if (context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!context.equals(other.context))
+      return false;
+    if (type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!type.equals(other.type))
+      return false;
+    return true;
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/BaseResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/BaseResponseContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/BaseResponseContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/BaseResponseContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,83 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.util.MimeTypeHelper;
+
+public class BaseResponseContext<T extends Base>
+  extends AbstractResponseContext {
+
+  private final T base;
+  private final boolean chunked;
+  
+  public BaseResponseContext(T base) {
+    this(base, true);
+  }
+  
+  public BaseResponseContext(T base, boolean chunked) {
+    this.base = base;
+    setStatus(200);
+    setStatusText("OK");
+    this.chunked = chunked;
+  }
+  
+  public T getBase() {
+    return base;
+  }
+  
+  public boolean hasEntity() {
+    return (base != null);
+  }
+
+  public void writeTo(OutputStream out) throws IOException {
+    if (hasEntity()) base.writeTo(out);
+  }
+
+  @Override
+  public MimeType getContentType() 
+    throws MimeTypeParseException {
+      MimeType t = super.getContentType();
+      if (t == null) {
+        String type = MimeTypeHelper.getMimeType(base);
+        if (type != null) t = new MimeType(type);
+      }
+      return t;
+  }
+
+  @Override
+  public long getContentLength() {
+    long len = super.getContentLength();
+    if (hasEntity() && len == -1 && !chunked) {
+      try {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        base.writeTo(out);
+        len = out.size();
+        super.setContentLength(len);
+      } catch (Exception e) {}
+    }
+    return len;
+  }
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/EmptyResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/EmptyResponseContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/EmptyResponseContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/EmptyResponseContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,37 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public final class EmptyResponseContext 
+  extends AbstractResponseContext {
+
+  public EmptyResponseContext(int status) {
+    setStatus(status);
+  }
+  
+  public boolean hasEntity() {
+    return false;
+  }
+
+  public void writeTo(OutputStream out) 
+    throws IOException {}
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Provider.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Provider.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Provider.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Provider.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,48 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import org.apache.abdera.protocol.ResponseInfo;
+
+public interface Provider {
+
+  ResponseInfo getInfo(RequestContext request);
+  
+  ResponseContext createEntry(RequestContext request);
+  
+  ResponseContext deleteEntry(RequestContext request);
+  
+  ResponseContext deleteMedia(RequestContext request);
+  
+  ResponseContext updateEntry(RequestContext request);
+  
+  ResponseContext updateMedia(RequestContext request);
+  
+  ResponseContext getService(RequestContext request, boolean full);
+  
+  ResponseContext getFeed(RequestContext request, boolean full);
+  
+  ResponseContext getEntry(RequestContext request, boolean full, boolean editable);
+  
+  ResponseContext getMedia(RequestContext request, boolean full, boolean editable);
+  
+  ResponseContext entryPost(RequestContext request);
+  
+  ResponseContext mediaPost(RequestContext request);
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ProviderManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ProviderManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ProviderManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ProviderManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+public interface ProviderManager {
+
+  Provider getProvider();
+  
+  void release(Provider provider);
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/RequestContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/RequestContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/RequestContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/RequestContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,84 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.ParseException;
+import org.apache.abdera.parser.Parser;
+import org.apache.abdera.parser.ParserOptions;
+import org.apache.abdera.protocol.Request;
+import org.apache.abdera.protocol.server.ServiceContext;
+
+public interface RequestContext 
+  extends Request {
+
+  public enum Scope { REQUEST, SESSION };
+  public enum Property { 
+    SESSIONID, SESSIONCREATED, SESSIONACCESSED, SESSIONTIMEOUT,
+    CHARACTERENCODING, LOCALES, PROTOCOL, REMOTEADDRESS, REMOTEHOST,
+    REMOTEUSER, SCHEME, PRINCIPAL};
+  
+  ServiceContext getServiceContext();
+    
+  Target getTarget();
+    
+  Subject getSubject();
+  
+  String getMethod();
+  
+  URI getUri();
+  
+  URI getResolvedUri();
+  
+  URI getBaseUri();
+  
+  Object getProperty(Property property);
+  
+  String getParameter(String name);
+  
+  String[] getParameterNames();
+  
+  List<String> getParameters(String name);
+  
+  Object getAttribute(Scope scope,String name);
+  
+  String[] getAttributeNames(Scope scope);
+  
+  void setAttribute(Scope scope, String name, Object value);
+  
+  InputStream getInputStream() throws IOException;
+  
+  Reader getReader() throws IOException;
+  
+  <T extends Element>Document<T> getDocument() throws ParseException, IOException;
+  
+  <T extends Element>Document<T> getDocument(Parser parser) throws ParseException, IOException;
+  
+  <T extends Element>Document<T> getDocument(Parser parser, ParserOptions options) throws ParseException, IOException;
+  
+  <T extends Element>Document<T> getDocument(ParserOptions options) throws ParseException, IOException;
+}