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 2012/02/01 18:55:02 UTC

svn commit: r1239237 [6/12] - in /abdera/abdera2-server: ./ .settings/ etc/ examples/ examples/src/ examples/src/main/ examples/src/main/java/ examples/src/main/java/org/ examples/src/main/java/org/apache/ examples/src/main/java/org/apache/abdera2/ exa...

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TargetType.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TargetType.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TargetType.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TargetType.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,143 @@
+/*
+ * 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.abdera2.common.protocol;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.abdera2.common.misc.MoreFunctions;
+
+/**
+ * Identifies the type of resource being requests.
+ */
+public final class TargetType {
+
+    public static final String UNKNOWN = "UNKNOWN";
+    public static final String NOT_FOUND = "NOT_FOUND";
+    public static final String SERVICE = "SERVICE";
+    public static final String COLLECTION = "COLLECTION";
+    public static final String ENTRY = "ENTRY";
+    public static final String MEDIA = "MEDIA";
+    public static final String CATEGORIES = "CATEGORIES";
+
+    private static final Map<String, TargetType> types = 
+      new ConcurrentHashMap<String, TargetType>();
+
+    /**
+     * An unknown target type
+     */
+    public static final TargetType TYPE_UNKNOWN = new TargetType(UNKNOWN);
+    /**
+     * A not found target type
+     */
+    public static final TargetType TYPE_NOT_FOUND = new TargetType(NOT_FOUND);
+    /**
+     * An Atompub Service Document
+     */
+    public static final TargetType TYPE_SERVICE = new TargetType(SERVICE);
+    /**
+     * An Atom Feed Document representing an Atompub Collection
+     */
+    public static final TargetType TYPE_COLLECTION = new TargetType(COLLECTION);
+    /**
+     * An Atompub Collection member entry
+     */
+    public static final TargetType TYPE_ENTRY = new TargetType(ENTRY);
+    /**
+     * An Atompub Collection media resource
+     */
+    public static final TargetType TYPE_MEDIA = new TargetType(MEDIA);
+    /**
+     * An Atompub Categories Document
+     */
+    public static final TargetType TYPE_CATEGORIES = new TargetType(CATEGORIES);
+
+    /**
+     * Return a listing of TargetTypes
+     */
+    public static Iterable<TargetType> values() {
+        return types.values();
+    }
+
+    /**
+     * Get the specified target type
+     */
+    public static TargetType get(String name) {
+        return types.get(name.toUpperCase());
+    }
+
+    /**
+     * Get the specified target type. If the target type does not currently exist, and create = true, a new type will be
+     * created.
+     */
+    public static TargetType get(String name, boolean create) {
+        if (name == null)
+            return null;
+        TargetType type = get(name);
+        return type != null ? type : create ? create(name) : null;
+    }
+
+    private static synchronized TargetType create(String name) {
+        TargetType type = new TargetType(name.toUpperCase());
+        types.put(type.name(), type);
+        return type;
+    }
+
+    private final String name;
+
+    private TargetType(String name) {
+        if (name == null || name.length() == 0)
+            throw new IllegalArgumentException();
+        if (get(name) != null)
+            throw new IllegalArgumentException();
+        this.name = name.toUpperCase();
+        types.put(name, this);
+    }
+
+    /**
+     * Return the target name
+     */
+    public String name() {
+        return name;
+    }
+
+    public String toString() {
+        return name;
+    }
+
+    public int hashCode() {
+      return MoreFunctions.genHashCode(1, name);
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final TargetType other = (TargetType)obj;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        return true;
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TargetType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.common.protocol;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.templates.Context;
+import org.apache.abdera2.common.templates.MapContext;
+import org.apache.abdera2.common.templates.ObjectContext;
+import org.apache.abdera2.common.templates.Template;
+import org.apache.abdera2.common.templates.TemplateManager;
+
+import com.google.common.collect.ImmutableMap;
+
+public class TemplateManagerTargetBuilder<T> 
+  extends TemplateManager<T>
+  implements TargetBuilder<T> {
+
+  public static <T>Builder<T> make() {
+    return new Builder<T>();
+  }
+  
+  public static <T>TemplateManagerTargetBuilder<T> fromMap(Map<T,Object> map) {
+    checkNotNull(map);
+    Builder<T> b = make();
+    b.add(map);
+    return (TemplateManagerTargetBuilder<T>) b.get();
+  }
+  
+  public static class Builder<T> extends TemplateManager.Builder<T> {
+    public TemplateManager<T> get() {
+      return new TemplateManagerTargetBuilder<T>(
+        templates.build(),isiri,base,defaultContexts.get());
+    }
+    public TemplateManagerTargetBuilder<T> getTargetBuilder() {
+      return (TemplateManagerTargetBuilder<T>) get();
+    }
+  }
+  
+  TemplateManagerTargetBuilder(
+      ImmutableMap<T,Template> templates, 
+      boolean isiri, 
+      IRI base, 
+      Context contextDefaults) {
+        super(templates,isiri,base,contextDefaults);
+    }
+  
+
+  public String urlFor(Request request, T key, Object param) {
+    RequestContext rc = (RequestContext) request;
+    if (param == null) param = new MapContext(true);
+    return expand(key,getContext(rc,param));
+  }
+
+  @SuppressWarnings("unchecked")
+  public static Context getContext(RequestContext request, Object param) {
+    Context context = null;
+    if (param != null) {
+        if (param instanceof Map) {
+            context = new MapContext((Map<String, Object>)param, true);
+        } else if (param instanceof Context) {
+            context = (Context)param;
+        } else {
+            context = new ObjectContext(param, true);
+        }
+    } else context = new MapContext();
+    return new RequestTemplateContext(request, context);
+  }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TemplateManagerTargetBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TransactionalRequestProcessor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TransactionalRequestProcessor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TransactionalRequestProcessor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TransactionalRequestProcessor.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,73 @@
+/*
+ * 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.abdera2.common.protocol;
+
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.base.Predicate;
+
+public abstract class TransactionalRequestProcessor 
+  extends RequestProcessor {
+
+  private final static Log log = 
+    LogFactory.getLog(
+      TransactionalRequestProcessor.class);
+  
+  protected TransactionalRequestProcessor(
+    WorkspaceManager workspaceManager,
+    CollectionAdapter adapter) {
+      super(workspaceManager, adapter);
+  }
+  
+  protected TransactionalRequestProcessor(
+    WorkspaceManager workspaceManager,
+    CollectionAdapter adapter,
+    Predicate<RequestContext> predicate) {
+      super(workspaceManager,adapter,predicate);
+  }
+
+  public void start(RequestContext request) {
+    // the default is to do nothing here
+  }
+
+  public void end(RequestContext request, ResponseContext response) {
+    // the default is to do nothing here
+  }
+
+  public void compensate(RequestContext request, Throwable t) {
+    // the default is to do nothing here
+  }
+
+  public ResponseContext apply(RequestContext input) {
+    ResponseContext response = null;
+    try {
+      start(input);
+      response = actuallyApply(input);
+      return response;
+    } catch (Throwable e) {
+      ExceptionHelper.log(log,e);
+      compensate(input,e);
+      throw ExceptionHelper.propogate(e);
+    } finally {
+      end(input, response);
+    }
+  }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/TransactionalRequestProcessor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceInfo.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,38 @@
+/*
+ * 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.abdera2.common.protocol;
+
+
+/**
+ * Metadata interface used by WorkspaceManager and Provider implementations to construct Atompub Service Documents. The
+ * WorkspaceInfo interface provides information used to construct an app:workspace element
+ */
+public interface WorkspaceInfo {
+
+    /**
+     * Return the value of the app:workspace element's atom:title. This assumes that the atom:title element uses
+     * type="text". This must not be null
+     */
+    String getTitle(RequestContext requsest);
+
+    /**
+     * Return the listing of collections available as part of the workspace
+     */
+    Iterable<CollectionInfo> getCollections(RequestContext request);
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,45 @@
+/*
+ * 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.abdera2.common.protocol;
+
+import java.util.Collection;
+
+import org.apache.abdera2.common.http.EntityTag;
+import org.joda.time.DateTime;
+
+/**
+ * The Workspace Manager is used by a Provider to access metadata used to construct Atompub service documents and to
+ * determine the appropriate CollectionAdapter to handle a particular request
+ */
+public interface WorkspaceManager {
+
+    /**
+     * Get the Collection Adapter that will handle this request
+     */
+    CollectionAdapter getCollectionAdapter(RequestContext request);
+
+    /**
+     * Return the list of available workspaces
+     */
+    Collection<WorkspaceInfo> getWorkspaces(RequestContext request);
+
+    DateTime getLastModified();
+    
+    EntityTag getEntityTag();
+    
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/WorkspaceManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbderaServlet.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbderaServlet.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbderaServlet.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbderaServlet.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,38 @@
+/*
+ * 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.abdera2.common.protocol.servlet;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class AbderaServlet 
+  extends AbstractAbderaServlet {
+
+    private static final long serialVersionUID = 2393643907128535158L;
+
+    @Override
+    protected void service(
+        HttpServletRequest request, 
+        HttpServletResponse response) 
+          throws ServletException,IOException {
+        process(request,response,getServletContext());
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbderaServlet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbstractAbderaServlet.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbstractAbderaServlet.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbstractAbderaServlet.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbstractAbderaServlet.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,170 @@
+/*
+ * 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.abdera2.common.protocol.servlet;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.activation.MimeType;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.common.http.CacheControl;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.ServiceManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+
+public abstract class AbstractAbderaServlet
+  extends HttpServlet {
+
+  private static final long serialVersionUID = 2722733242417632126L;
+  
+    private final static Log log = 
+      LogFactory.getLog(AbstractAbderaServlet.class);
+
+    protected ServiceManager manager;
+    protected Provider provider;
+
+    @Override
+    public void init() throws ServletException {
+      log.debug("Initialing Abdera Servlet");
+        manager = createServiceManager();
+        provider = createProvider();
+        log.debug("Using manager - " + manager);
+        log.debug("Using provider - " + provider);
+    }
+
+    protected ServiceManager getServiceManager() {
+        return manager;
+    }
+
+    protected ServiceManager createServiceManager() {
+        String prop = this.getInitParameter(ServiceManager.class.getName());
+        return prop != null ? 
+          ServiceManager.Factory.getInstance(prop) :  
+          ServiceManager.Factory.getInstance();
+    }
+
+    protected Provider createProvider() {
+        return manager.newProvider(
+          getProperties(
+            getServletConfig()));
+    }
+
+    protected void process(
+      HttpServletRequest request,
+      HttpServletResponse response,
+      ServletContext context) {
+      RequestContext reqcontext = 
+        new ServletRequestContext(
+          provider, request, context);
+      try {
+          output(request, response, provider.apply(reqcontext));
+      } catch (Throwable t) {
+          error("Error servicing request", t, response);
+          return;
+      }
+      log.debug("Request complete");
+    }
+    
+    protected void output(
+      HttpServletRequest request, 
+      HttpServletResponse response, 
+      ResponseContext context)
+        throws IOException {
+        if (context != null) {
+            response.setStatus(context.getStatus());
+            long cl = context.getContentLength();
+            CacheControl cc = context.getCacheControl();
+            if (cl > -1)
+                response.setHeader("Content-Length", Long.toString(cl));
+            if (cc != null)
+                response.setHeader("Cache-Control", cc.toString());
+            try {
+                MimeType ct = context.getContentType();
+                if (ct != null)
+                    response.setContentType(ct.toString());
+            } catch (Exception e) {
+              // ok to ignore the error
+            }
+            Iterable<String> names = context.getHeaderNames();
+            for (String name : names) {
+                Iterable<Object> headers = context.getHeaders(name);
+                for (Object value : headers) {
+                    if (value instanceof Date)
+                        response.addDateHeader(name, ((Date)value).getTime());
+                    else if (value instanceof DateTime)
+                        response.addDateHeader(name, ((DateTime)value).getMillis());
+                    else if (value instanceof Calendar)
+                        response.addDateHeader(name, ((Calendar)value).getTimeInMillis());
+                    else
+                        response.addHeader(name, value.toString());
+                }
+            }
+            if (!request.getMethod().equals("HEAD") && context.hasEntity()) {
+                context.writeTo(response.getOutputStream());
+            }
+        } else {
+            error("Internal Server Error", null, response);
+        }
+    }
+
+    protected void error(
+      String message, 
+      Throwable t, 
+      HttpServletResponse response) {
+      try {
+        if (t != null) log.error(message, t);
+        else log.error(message);
+        if (response.isCommitted())
+          log.error("Could not write an error message as the headers & HTTP status were already committed!");
+        else {
+            response.setCharacterEncoding("UTF-8");
+            response.setStatus(500);
+            provider.createErrorResponse(500, message, t)
+             .writeTo(response.getOutputStream());
+        }
+      } catch (IOException e) {
+        log.error("Error writing to output stream",e);
+      }
+    }
+
+    protected Map<String, Object> getProperties(ServletConfig config) {
+        Map<String, Object> properties = new HashMap<String, Object>();
+        Enumeration<String> e = config.getInitParameterNames();
+        while (e.hasMoreElements()) {
+            String key = e.nextElement();
+            String val = config.getInitParameter(key);
+            properties.put(key, val);
+        }
+        return properties;
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/AbstractAbderaServlet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/ServletRequestContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/ServletRequestContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/ServletRequestContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/ServletRequestContext.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,289 @@
+/*
+ * 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.abdera2.common.protocol.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.protocol.AbstractBaseRequestContext;
+import org.apache.abdera2.common.protocol.Provider;
+import org.joda.time.DateTime;
+
+import com.google.common.collect.Iterators;
+
+@SuppressWarnings({ "unchecked" })
+public class ServletRequestContext 
+  extends AbstractBaseRequestContext {
+
+    private final HttpServletRequest request;
+    private final ServletContext servletContext;
+    private HttpSession session;
+
+    public ServletRequestContext(
+      Provider provider, 
+      HttpServletRequest request, 
+      ServletContext servletContext) {
+        super(
+          provider, 
+          request.getMethod(), 
+          initRequestUri(request), 
+          initBaseUri(provider, request),
+          request.getUserPrincipal());
+        this.request = request;
+        this.servletContext = servletContext;
+        this.session = request.getSession(false);
+        this.subject = provider.resolveSubject(this);
+        this.target = initTarget();
+    }
+
+    public Reader getReader() throws IOException {
+        return request.getReader();
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return request.getInputStream();
+    }
+
+    public HttpServletRequest getRequest() {
+        return request;
+    }
+
+    public ServletContext getServletContext() {
+        return servletContext;
+    }
+
+    public synchronized HttpSession getSession() {
+        return getSession(false);
+    }
+
+    public synchronized HttpSession getSession(boolean create) {
+        if (session == null)
+            session = request.getSession(create);
+        return session;
+    }
+
+    public ServletRequestContext setAttribute(Scope scope, String name, Object value) {
+        switch (scope) {
+            case REQUEST:
+                request.setAttribute(name, value);
+                break;
+            case SESSION:
+                getSession(true).setAttribute(name, value);
+                break;
+            case CONTAINER: {
+                ServletContext scontext = getServletContext();
+                if (scontext != null)
+                    scontext.setAttribute(name, value);
+            }
+        }
+        return this;
+    }
+
+    public <T>T getAttribute(Scope scope, String name) {
+        switch (scope) {
+            case REQUEST:
+                return (T)request.getAttribute(name);
+            case SESSION:
+                return session != null ? (T)session.getAttribute(name) : null;
+            case CONTAINER: {
+                ServletContext scontext = getServletContext();
+                return scontext != null ? (T)scontext.getAttribute(name) : null;
+            }
+        }
+        return null;
+    }
+
+    public Iterable<String> getAttributeNames(Scope scope) {
+        switch (scope) {
+            case REQUEST:
+                return enum2array(request.getAttributeNames());
+            case SESSION:
+                return (session != null) ? enum2array(session.getAttributeNames()) : null;
+            case CONTAINER: {
+                ServletContext scontext = getServletContext();
+                return scontext != null ? enum2array(scontext.getAttributeNames()) : null;
+            }
+        }
+        return null;
+    }
+
+    public String getParameter(String name) {
+        return request.getParameter(name);
+    }
+
+    public Iterable<String> getParameterNames() {
+        return enum2array(request.getParameterNames());
+    }
+
+    public Iterable<String> getParameters(String name) {
+        String[] values = request.getParameterValues(name);
+        return values != null ? Arrays.<String>asList(values) : null;
+    }
+
+    public DateTime getDateHeader(String name) {
+        long value = request.getDateHeader(name);
+        return value != -1 ? new DateTime(value) : null;
+    }
+
+    public String getHeader(String name) {
+        return request.getHeader(name);
+    }
+
+    public Iterable<String> getHeaderNames() {
+        return enum2array(request.getHeaderNames());
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Iterable<Object> getHeaders(String name) {
+        final Enumeration e = request.getHeaders(name);
+        return new Iterable<Object>() {
+          public Iterator<Object> iterator() {
+            return Iterators.<Object>forEnumeration(e);
+          }
+        };
+    }
+
+    private static Iterable<String> enum2array(Enumeration<String> e) {
+        return Collections.<String>list(e);
+    }
+
+    private static String getHost(Provider provider, HttpServletRequest request) {
+        String host = provider.getProperty("org.apache.abdera.protocol.server.Host");
+        return (host != null) ? host : request.getServerName();
+    }
+
+    private static int getPort(Provider provider, HttpServletRequest request) {
+        String port = provider.getProperty("org.apache.abdera.protocol.server.Port");
+        return (port != null) ? Integer.parseInt(port) : request.getServerPort();
+    }
+
+    private static IRI initBaseUri(Provider provider, HttpServletRequest request) {
+        StringBuilder buffer = new StringBuilder((request.isSecure()) ? "https" : "http");
+        buffer.append("://");
+        buffer.append(getHost(provider, request));
+        int port = getPort(provider, request);
+        if ((port != 80) && (port != 443)) {
+            buffer.append(":");
+            buffer.append(port);
+        }
+        buffer.append(request.getContextPath());
+        // So that .resolve() works appropriately.
+        buffer.append("/");
+        return new IRI(buffer.toString());
+    }
+
+    private static IRI initRequestUri(HttpServletRequest request) {
+        IRI uri;
+        StringBuilder buf = new StringBuilder(request.getRequestURI());
+        String qs = request.getQueryString();
+        if (qs != null && qs.length() != 0)
+            buf.append("?").append(request.getQueryString());
+        uri = new IRI(buf.toString());
+        return uri;
+    }
+
+    public boolean isUserInRole(String role) {
+        return request.isUserInRole(role);
+    }
+
+    public String getContextPath() {
+        return request.getContextPath();
+    }
+
+    public Locale getPreferredLocale() {
+        return request.getLocale();
+    }
+
+    public Iterable<Locale> getPreferredLocales() {
+        return Collections.list(request.getLocales());
+    }
+
+    public String getTargetBasePath() {
+        return request.getContextPath() + request.getServletPath();
+    }
+
+    public Object getProperty(Property property) {
+      switch (property) {
+      case SESSIONID:
+          return (session != null) ? session.getId() : null;
+      case SESSIONCREATED:
+          return (session != null) ? new Date(session.getCreationTime()) : null;
+      case SESSIONACCESSED:
+          return (session != null) ? new Date(session.getLastAccessedTime()) : null;
+      case SESSIONTIMEOUT:
+          return (session != null) ? Integer.valueOf(session.getMaxInactiveInterval()) : Integer.valueOf((-1));
+      case CHARACTERENCODING:
+          return request.getCharacterEncoding();
+      case LOCALES:
+          return request.getLocales();
+      case PROTOCOL:
+          return request.getProtocol();
+      case REMOTEADDRESS:
+          return request.getRemoteAddr();
+      case REMOTEHOST:
+          return request.getRemoteHost();
+      case REMOTEUSER:
+          return request.getRemoteUser();
+      case SCHEME:
+          return request.getScheme();
+      case PRINCIPAL:
+          return request.getUserPrincipal();
+      case AUTHTYPE:
+          return request.getAuthType();
+      case CONTENTLENGTH:
+          return Integer.valueOf(request.getContentLength());
+      case CONTENTTYPE:
+          return request.getContentType();
+      case CONTEXTPATH:
+          return request.getContextPath();
+      case LOCALADDR:
+          return request.getLocalAddr();
+      case LOCALNAME:
+          return request.getLocalName();
+      case SERVERNAME:
+          return request.getServerName();
+      case SERVERPORT:
+          return Integer.valueOf(request.getServerPort());
+      case SECURE:
+          return (Boolean)request.isSecure();
+      case PARTS: {
+        try {
+          return request.getParts();
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+      default:
+          throw new UnsupportedOperationException(Localizer.get("PROPERTY.NOT.SUPPORTED"));
+  }
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/ServletRequestContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaAsyncService.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaAsyncService.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaAsyncService.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaAsyncService.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,232 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.ServiceManager;
+import org.apache.abdera2.common.pusher.ChannelManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.base.Predicate;
+import static com.google.common.base.Preconditions.*;
+
+@WebListener
+public class AbderaAsyncService 
+  implements ServletContextListener, Runnable {
+
+    private static final int DEFAULT_WORKER_THREADS = 10;
+    public static final String PROPERTY_WORKER_THREADS = "AbderaWorkerThreadCount";
+    public static final String PROPERTY_ATOMPUB_SERVICE = "AbderaAtompubService";
+    public static final String PROPERTY_CHANNEL_SERVICE = "AbderaChannelService";
+  
+    public static final String RUNNER = "AbderaRunner";
+    public static final String SERVICEMANAGER = "AbderaServiceManager";
+    public static final String PROVIDER = "AbderaProvider";
+    public static final String QUEUE = "AbderaProcessorQueue";
+    public static final String CM = "AbderaChannelManager";
+  
+    final static Log log = LogFactory.getLog(AbderaAsyncService.class);
+    
+    private ServletContext context;
+    private TaskExecutor exec;
+    private ProcessorQueue queue;
+    private ChannelManager cm;
+    private Map<String,Object> properties;
+  
+    public AbderaAsyncService() {
+      log.debug("Abdera Async Service Created");
+    }
+    
+    protected Map<String, Object> getProperties(ServletContext context) {
+      Map<String, Object> properties = new HashMap<String, Object>();
+      Enumeration<String> e = context.getInitParameterNames();
+      while (e.hasMoreElements()) {
+          String key = e.nextElement();
+          String val = context.getInitParameter(key);
+          properties.put(key, val);
+      }
+      return properties;
+    }
+    
+    private int worker_threads(Map<String,Object> properties) {
+      int c = DEFAULT_WORKER_THREADS;
+      if (properties.containsKey(PROPERTY_WORKER_THREADS)) {
+        Object v = properties.get(PROPERTY_WORKER_THREADS);
+        if (v != null) {
+          if (v instanceof Integer) 
+            c = ((Integer)v).intValue();
+          else
+            c = Math.max(1,Integer.parseInt(v.toString()));
+        } 
+      }
+      return c;
+    }
+    
+    static boolean getBooleanProperty(Map<String, Object> properties, String name, boolean def) {
+      boolean answer = def;
+      if (properties.containsKey(name)) {
+        Object v = properties.get(name);
+        if (v == null) answer = false;
+        else if (v instanceof Boolean) answer = ((Boolean)v).booleanValue();
+        else {
+          answer = "TRUE".equalsIgnoreCase(v.toString()) || 
+                   "1".equals(v.toString()) ||
+                   "YES".equalsIgnoreCase(v.toString());
+        }
+      }
+      return answer;
+    }
+    
+    public static final Predicate<Map<String,Object>> DEPLOY_ATOMPUB = 
+      isDeployAtompubService();
+    private static Predicate<Map<String,Object>> isDeployAtompubService() {
+      return new Predicate<Map<String,Object>>() {
+        public boolean apply(Map<String,Object> properties) {
+          return getBooleanProperty(properties,PROPERTY_ATOMPUB_SERVICE,false);
+        }
+      };
+    }
+    
+    public static final Predicate<Map<String,Object>> DEPLOY_CHANNEL =
+      isDeployChannelService();
+    private static Predicate<Map<String,Object>> isDeployChannelService() {
+      return new Predicate<Map<String,Object>>() {
+        public boolean apply(Map<String,Object> properties) {
+          return getBooleanProperty(properties,PROPERTY_CHANNEL_SERVICE,false);
+        }
+      };
+    }
+    
+    protected ServiceManager createServiceManager(ServletContext context) {
+      String prop = context.getInitParameter(ServiceManager.class.getName());
+      return prop != null ? 
+        ServiceManager.Factory.getInstance(prop) :  
+        ServiceManager.Factory.getInstance();
+    }
+
+    
+    public void contextInitialized(ServletContextEvent event) {   
+      this.context = event.getServletContext();
+      this.properties = getProperties(context);
+      ServiceManager manager = 
+        createServiceManager(context);      
+      checkState(
+        manager != null, 
+        "Service Manager is null"); 
+      if (DEPLOY_ATOMPUB.apply(properties)) {
+        log.debug("Initializing Abdera Atompub Service...");
+        queue = manager.newProcessorQueue(properties);
+        exec = manager.newTaskExecutor(properties);
+        Provider provider = manager.newProvider(properties);
+        Processor processor = queue != null ? queue.getProcessor() : null;
+        
+        log.debug(String.format("Queue:           %s",queue));
+        log.debug(String.format("Processor:       %s",processor));
+        log.debug(String.format("Executor:        %s",exec));
+        log.debug(String.format("Service Manager: %s",manager));
+        log.debug(String.format("Provider:        %s",provider));
+        
+        checkState(processor != null, "Queue Processor is null");
+        checkState(exec != null, "Task Executor is null");
+        checkState(provider != null, "Provider is null");
+        checkState(queue != null, "Queue is null");
+        
+        context.setAttribute(Processor.NAME, processor);
+        context.setAttribute(RUNNER, exec);
+        context.setAttribute(PROVIDER, provider);
+        context.setAttribute(QUEUE, queue);
+        context.setAttribute(SERVICEMANAGER, manager);
+        int ct = worker_threads(properties);
+        log.debug(String.format("Launching watcher threads [%d]",ct));
+        
+        exec.startWorker(ct,this);
+        
+        log.debug("Abdera Atompub Service is ready...");
+      }
+      
+      if (DEPLOY_ATOMPUB.apply(properties)) {
+        log.debug("Initializing Abdera Channel Service");
+        cm = manager.newChannelManager(properties);
+        log.debug(String.format("Channel Manager: %s", cm));
+        if (cm != null) {
+          context.setAttribute(CM, cm);
+          log.debug("Abdera Channel Service is ready...");
+        } else log.debug("Abdera Channel Service could not be started");
+      }
+    }
+    
+    public void contextDestroyed(ServletContextEvent event) {
+      ServletContext context = event.getServletContext();
+      if (DEPLOY_ATOMPUB.apply(properties)) {
+        log.debug("Shutting down the Abdera Service...");
+        if (exec != null)
+          exec.shutdown();
+        // if there are remaining outstanding requests after 
+        // shutdown we need to deal with them
+        if (queue != null)
+          queue.cancelRemaining();
+        
+        context.removeAttribute(Processor.NAME);
+        context.removeAttribute(RUNNER);
+        context.removeAttribute(SERVICEMANAGER);
+        context.removeAttribute(PROVIDER);
+        context.removeAttribute(QUEUE);
+      }
+      if (DEPLOY_ATOMPUB.apply(properties)) {
+        if (cm != null)
+          cm.shutdown();
+        context.removeAttribute(CM);
+      }
+    }
+
+    public void run() {
+      TaskExecutor exec = 
+        (TaskExecutor) context.getAttribute(RUNNER);
+      ProcessorQueue processor =
+        (ProcessorQueue) context.getAttribute(QUEUE);
+      while(exec.isRunning()) {
+        if (processor.hasNext()) {
+          final AbderaTask task = processor.next();
+          if (task != null) {
+              log.debug(String.format("Processing New AbderaTask (%s)...",task.getId())); 
+              exec.execute(new Runnable() {
+                public void run() {
+                  try {
+                    task.invoke();
+                  } catch (Throwable t) {
+                    log.error(String.format("Error invoking AbderaTask (%s)",task.getId()),t);
+                  }
+                  log.debug(String.format("AbderaTask (%s) is complete",task.getId()));
+                }
+              });
+          }
+        }
+      }
+    }
+	
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaAsyncService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaChannelServlet.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaChannelServlet.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaChannelServlet.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaChannelServlet.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,181 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.io.IOException;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.common.http.Preference;
+import org.apache.abdera2.common.pusher.ChannelManager;
+import org.apache.abdera2.common.pusher.Listener;
+import org.apache.abdera2.common.pusher.Receiver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+@WebServlet(asyncSupported=true)
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public abstract class AbderaChannelServlet extends HttpServlet {
+
+  private final static Log log = LogFactory.getLog(AbderaChannelServlet.class);
+  
+  private static final long serialVersionUID = 3751815744618869423L;
+
+  protected abstract String getChannel(AsyncContext context);
+  
+  protected abstract AsyncListener<?> createListener(AsyncContext context);
+  
+  protected long getMaxTimeout(ServletConfig config, ServletContext context) {
+    return 30 * 1000;
+  }
+  
+  /**
+   * By default, we look for the Prefer: wait=<n> header to grab the 
+   * wait time, or return -1 to skip setting the timeout
+   */
+  protected long getTimeout(HttpServletRequest req, ServletConfig config, ServletContext context) {
+    return Math.min(getMaxTimeout(config,context),timeout(req));
+  }
+  
+  private static long timeout(HttpServletRequest req) {
+    try {
+      Iterable<Preference> i = Preference.parse(req.getHeader("Prefer"));
+      Preference waitPref = Preference.get(i, Preference.WAIT);
+      long wait = waitPref != null ? waitPref.getLongValue() : -1;
+      return Math.max(0, wait);
+    } catch (Throwable t) {
+      return -1;
+    }
+  }
+  
+  protected void doGet(
+      final HttpServletRequest request, 
+      final HttpServletResponse response) 
+        throws ServletException, IOException {
+    final ServletContext sc = getServletContext();
+    final ChannelManager cm = (ChannelManager) sc.getAttribute(AbderaAsyncService.CM);
+    if (cm == null || !cm.isShutdown()) {
+      final AsyncContext context = request.startAsync(request, response);
+      long timeout = getTimeout(request,getServletConfig(),sc);
+      if (timeout > -1)
+        context.setTimeout(timeout);
+      context.start(
+        new Runnable() {
+          public void run() {
+            String channel = getChannel(context);
+            log.debug(String.format("Selected Channel Name: %s",channel));
+            if (channel != null) {
+              final Receiver receiver = cm.getReceiver(channel);
+              log.debug(String.format("Selected Receiver: %s",receiver));
+              if (receiver != null) {
+                final Listener listener = createListener(context);
+                context.addListener(
+                  new javax.servlet.AsyncListener() {
+                    public void onComplete(AsyncEvent event) throws IOException {
+                      try {
+                        receiver.stopListening(listener);
+                      } catch (Throwable t) {}
+                    }
+                    public void onError(AsyncEvent event) throws IOException {
+                      event.getThrowable().printStackTrace();
+                      try {
+                        receiver.stopListening(listener);
+                      } catch (Throwable t) {}
+                    }
+                    public void onStartAsync(AsyncEvent event)
+                        throws IOException {
+                    }
+                    public void onTimeout(AsyncEvent event) throws IOException {
+                      try {
+                        receiver.stopListening(listener);
+                      } catch (Throwable t) {}
+                    }
+                  }
+                );
+                log.debug(String.format("Listener: %s",listener));
+                if (listener != null) {
+                  request.setAttribute("AbderaChannel", channel);
+                  request.setAttribute("AbderaReceiver", receiver);
+                  request.setAttribute("AbderaListener", listener);
+                  receiver.startListening(listener);      
+                }
+              } 
+            }
+          }
+        }
+      );
+    } else {
+      response.sendError(
+        HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
+        "Abdera Service in unavailable");
+    }
+    
+  }
+  
+  public abstract static class AsyncListener<T> implements Listener<T> {
+
+    private final AsyncContext context;
+    private boolean done = false;
+    
+    protected AsyncListener(AsyncContext context) {
+      this.context = context;
+    }
+    
+    protected HttpServletRequest getRequest() {
+      return (HttpServletRequest) context.getRequest();
+    }
+    
+    protected HttpServletResponse getResponse() {
+      return (HttpServletResponse) context.getResponse();
+    }
+    
+    protected boolean isDone() {
+      return done;
+    }
+    
+    public void afterItems() {
+      if (!done) {
+        try {
+          finish();
+          getResponse().flushBuffer();
+          context.complete();
+        } catch (Throwable t) {
+          // whoops, must have lost the connection before the request completed.
+        } finally {
+          done = true;
+        }
+      }
+    }
+    
+    protected void finish() {
+      // by default do nothing
+    }
+    
+    public void beforeItems() {
+      // by default do nothing
+    }
+  }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaChannelServlet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaTask.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaTask.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaTask.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaTask.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,181 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.activation.MimeType;
+import javax.servlet.AsyncContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.common.http.CacheControl;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+
+public class AbderaTask {
+
+  private final static Log log = LogFactory.getLog(AbderaTask.class);
+  
+  private final String id;
+  private final AsyncContext context;
+  private final RequestContext requestContext;
+  private final Provider provider;
+  
+  AbderaTask(
+    AsyncContext context, 
+    Provider provider, 
+    RequestContext requestContext) {
+      this.context = context;
+      this.provider = provider;
+      this.requestContext = requestContext;
+      this.id = UUID.randomUUID().toString();
+  }
+    
+  public String getId() {
+    return id;
+  }
+  
+  public void cancel() {
+    cancel(context,getId());
+  }
+  
+  public static void cancel(AsyncContext context, String id) {
+    try {
+      HttpServletResponse resp = 
+        (HttpServletResponse) context.getResponse();
+      if (!resp.isCommitted())
+        resp.reset();
+      resp.sendError(
+        HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
+        "Server is shutting down. Unable to process request");
+      resp.flushBuffer();
+    } catch (Throwable t) {
+      log.error(String.format("Unrecoverable error canceling Abdera Task (%s)",id), t);
+    } finally {
+      context.complete();
+    }
+  }
+  
+  public void invoke() {
+    try {
+      log.debug(String.format("Invoking Abdera Task (%s)",getId()));
+      HttpServletRequest req = 
+        (HttpServletRequest) context.getRequest();
+      HttpServletResponse resp = 
+        (HttpServletResponse) context.getResponse();
+      process(provider,req,resp);
+      resp.flushBuffer();
+    } catch (Throwable t) {
+      log.error(String.format("Unrecoverable error processing Abdera Task (%s)",getId()), t);
+    } finally {
+      context.complete();
+    }
+  }
+  
+  protected void process(
+    Provider provider,
+    HttpServletRequest request,
+    HttpServletResponse response) {
+    try {
+        log.debug(String.format("Using RequestContext: %s",requestContext.getClass().getName()));
+        output(request, response, provider.apply(requestContext), provider);
+    } catch (Throwable t) {
+        error("Error servicing request", t, response, provider);
+        return;
+    }
+  }
+    
+    protected void output(HttpServletRequest request, HttpServletResponse response, ResponseContext context, Provider provider)
+        throws IOException {
+        log.debug(String.format("Received ResponseContext: %s", context));
+        if (context != null) {
+          log.debug(String.format("Status: %d",context.getStatus()));
+          response.setStatus(context.getStatus());
+            long cl = context.getContentLength();
+            CacheControl cc = context.getCacheControl();
+            if (cl > -1)
+                response.setHeader("Content-Length", Long.toString(cl));
+            if (cc != null)
+                response.setHeader("Cache-Control", cc.toString());
+            try {
+                MimeType ct = context.getContentType();
+                if (ct != null) {
+                  log.debug(String.format("Content-Type: %s",ct.toString()));
+                    response.setContentType(ct.toString());
+                }
+            } catch (Exception e) {
+              // ok to ignore the error
+            }
+            Iterable<String> names = context.getHeaderNames();
+            for (String name : names) {
+                Iterable<Object> headers = context.getHeaders(name);
+                for (Object value : headers) {
+                  log.debug(String.format("Header [%s]: %s", name, value.toString()));
+                  if (value instanceof Date)
+                    response.addDateHeader(name, ((Date)value).getTime());
+                  else if (value instanceof DateTime)
+                    response.addDateHeader(name, ((DateTime)value).getMillis());
+                  else if (value instanceof Calendar)
+                    response.addDateHeader(name, ((Calendar)value).getTimeInMillis());
+                  else
+                    response.addHeader(name, value.toString());
+                }
+            }
+            if (!request.getMethod().equals("HEAD") && context.hasEntity()) {
+                log.debug("Writing entity...");
+                context.writeTo(response.getOutputStream());
+            } else {
+              log.debug("No entity to write...");
+            }
+        } else {
+            error("Internal Server Error", null, response, provider);
+        }
+    }
+
+    protected void error(String message, Throwable t, HttpServletResponse response, Provider provider) {
+      try {
+        message = 
+          String.format(
+            "Error in Abdera Task (%s): %s", 
+            getId(), message);
+        if (t != null)
+            log.error(message, t);
+        else
+            log.error(message);
+
+        if (response.isCommitted()) {
+            log.error("Could not write an error message as the headers & HTTP status were already committed!");
+        } else {
+          response.setCharacterEncoding("UTF-8");
+          response.setStatus(500);
+          provider.createErrorResponse(500, message, t)
+           .writeTo(response.getOutputStream());
+        }
+      } catch (IOException e) {
+        log.error(String.format("Error writing to output stream (%s)",getId()),e);
+      }
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AbderaTask.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AsyncAbderaServlet.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AsyncAbderaServlet.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AsyncAbderaServlet.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AsyncAbderaServlet.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,96 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.common.http.Preference;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ServiceManager;
+import org.apache.abdera2.common.protocol.servlet.ServletRequestContext;
+
+@WebServlet(asyncSupported=true)
+public class AsyncAbderaServlet 
+  extends HttpServlet {
+
+      protected Map<String, Object> getProperties(ServletConfig config) {
+        Map<String, Object> properties = new HashMap<String, Object>();
+        Enumeration<String> e = config.getInitParameterNames();
+        while (e.hasMoreElements()) {
+            String key = e.nextElement();
+            String val = config.getInitParameter(key);
+            properties.put(key, val);
+        }
+        return properties;
+    }
+  
+    private static final long serialVersionUID = 2086707888078611321L;
+    @Override
+    protected void service(
+        final HttpServletRequest request, 
+        final HttpServletResponse response) 
+          throws ServletException, IOException {
+      ServletContext sc = getServletContext();
+      Processor proc = (Processor) sc.getAttribute(Processor.NAME);
+      if (proc != null && !proc.isShutdown()) {
+        final AsyncContext context = request.startAsync(request, response);
+        ServiceManager sm = (ServiceManager) sc.getAttribute(AbderaAsyncService.SERVICEMANAGER);
+        Provider provider = sm.newProvider(getProperties(getServletConfig()));
+        ServletRequestContext reqcontext = new ServletRequestContext(provider, request, sc);
+        long timeout = getTimeout(reqcontext);
+        if (timeout > -1) context.setTimeout(timeout);
+        proc.submit(context,provider,reqcontext);
+      } else {
+        response.sendError(
+          HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
+          "Abdera Service in unavailable");
+      }
+    }
+    
+    public static long getTimeout(RequestContext req) {
+      return Math.min(getMaxTimeout(req),timeout(req));
+    }
+    
+    public static long getMaxTimeout(RequestContext req) {
+      return 30 * 1000;
+    }
+    
+    private static long timeout(RequestContext req) {
+      try {
+        Iterable<Preference> i = req.getPrefer();
+        Preference waitPref = Preference.get(i, Preference.WAIT);
+        long wait = waitPref != null ? waitPref.getLongValue() : -1;
+        return Math.max(0, wait);
+      } catch (Throwable t) {
+        return -1;
+      }
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/AsyncAbderaServlet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultProcessor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultProcessor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultProcessor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultProcessor.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,68 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.servlet.AsyncContext;
+
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.RequestContext;
+
+public class DefaultProcessor 
+  implements Processor, ProcessorQueue {
+
+  private final Queue<AbderaTask> queue = 
+    new ConcurrentLinkedQueue<AbderaTask>();
+  boolean rejectNew = false;
+  
+  public void submit(AsyncContext context, Provider provider, RequestContext requestContext) {
+    if (!rejectNew) {
+      queue.offer(new AbderaTask(context,provider,requestContext));
+    } else {
+      AbderaTask.cancel(context, "NEW");
+    }
+  }
+
+  public AbderaTask next() {
+    return queue.poll();
+  }
+  
+  public boolean hasNext() {
+    return !queue.isEmpty();
+  }
+
+  public Processor getProcessor() {
+    return this;
+  }
+  
+  public boolean isShutdown() {
+    return rejectNew;
+  }
+
+  public void cancelRemaining() {
+    rejectNew = true;
+    while(hasNext())
+      next().cancel();
+  }
+
+  public void init(Map<String, Object> properties) {}
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultProcessor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultTaskExecutor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultTaskExecutor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultTaskExecutor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultTaskExecutor.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,72 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class DefaultTaskExecutor 
+  implements TaskExecutor {
+
+  private ThreadPoolExecutor exec;
+
+  public static final String TERMINATION_TIMEOUT = "AbderaDefaultTaskExecutorTerminationTimout";
+  public static final long DEFAULT_TERMINATION_TIMEOUT = 10;
+  
+  private long terminationTimeout = DEFAULT_TERMINATION_TIMEOUT;
+  
+  public DefaultTaskExecutor() {}
+  
+  public void execute(Runnable task) {
+    exec.execute(task);
+  }
+
+  public void init(Map<String, Object> properties) {
+    exec = (ThreadPoolExecutor) Executors.newCachedThreadPool();
+    if (properties.containsKey(TERMINATION_TIMEOUT)) {
+      String val = (String)properties.get(TERMINATION_TIMEOUT);
+      terminationTimeout = Math.max(1,Long.parseLong(val));
+    }
+  }
+
+  public void startWorker(Runnable worker) {
+    exec.execute(worker);
+  }
+  
+  public void startWorker(int count, Runnable worker) {
+    for (int n = 0; n < count; n++)
+      startWorker(worker);
+  }
+
+  public void shutdown() {
+    exec.shutdown();
+    try {
+      exec.awaitTermination(
+        terminationTimeout, TimeUnit.SECONDS);
+    } catch (Throwable t) {}
+  }
+
+  public boolean isRunning() {
+    return !exec.isShutdown() && 
+           !exec.isTerminated() && 
+           !exec.isTerminating(); 
+  }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/DefaultTaskExecutor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/Processor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/Processor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/Processor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/Processor.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.common.protocol.servlet.async;
+
+import javax.servlet.AsyncContext;
+
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.RequestContext;
+
+public interface Processor {
+
+  public static final String NAME = "AbderaProcessor";
+  
+  void submit(
+    AsyncContext context, 
+    Provider provider,
+    RequestContext requestContext);
+  
+  boolean isShutdown();
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/Processor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/ProcessorQueue.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/ProcessorQueue.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/ProcessorQueue.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/ProcessorQueue.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,33 @@
+/*
+ * 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.abdera2.common.protocol.servlet.async;
+
+import org.apache.abdera2.common.misc.Initializable;
+
+public interface ProcessorQueue 
+  extends Initializable {
+
+  boolean hasNext();
+  
+  AbderaTask next();
+  
+  Processor getProcessor();
+  
+  void cancelRemaining();
+  
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/ProcessorQueue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/TaskExecutor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/TaskExecutor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/TaskExecutor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/TaskExecutor.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.common.protocol.servlet.async;
+
+import java.util.concurrent.Executor;
+
+import org.apache.abdera2.common.misc.Initializable;
+
+public interface TaskExecutor
+  extends Executor, Initializable {
+  
+  void startWorker(Runnable runnable);
+  
+  void startWorker(int count, Runnable runnable);
+  
+  void shutdown();
+  
+  boolean isRunning();
+  
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/servlet/async/TaskExecutor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,36 @@
+/*
+ * 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.abdera2.protocol.server;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.TargetType;
+
+/**
+ * Providers are responsible for processing all requests to the Atompub 
+ * server. Actual request processing is delegated to {@link RequestProcessor} 
+ * implementations, depending on the request {@link TargetType}.
+ */
+public interface AtompubProvider extends Provider {
+
+    /**
+     * Retrieve the Abdera instance associated with this provider
+     */
+    Abdera getAbdera();
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,47 @@
+/*
+ * 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.abdera2.protocol.server;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+/**
+ * Extends the core ResponseContext object with methods used to 
+ * output Atom data using a specific Abdera Writer instance.
+ */
+public interface AtompubResponseContext extends ResponseContext {
+
+    /**
+     * Write the response out to the specified OutputStream
+     */
+    void writeTo(OutputStream out, Writer writer) throws IOException;
+
+    /**
+     * Write the response out to the specified Writer
+     */
+    void writeTo(java.io.Writer javaWriter, Writer abderaWriter) throws IOException;
+
+    /**
+     * Set the Abdera Writer for this response. This can be used to customize the serialization of the response
+     */
+    AtompubResponseContext setWriter(Writer writer);
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,53 @@
+/*
+ * 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.abdera2.protocol.server;
+
+import java.util.Map;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.protocol.AbstractServiceManager;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.protocol.server.impl.DefaultAtompubProvider;
+
+/**
+ * The ServiceManager is used by the AbderaServlet to bootstrap the server instance.
+ */
+public class AtompubServiceManager 
+  extends AbstractServiceManager {
+
+    private final Abdera abdera;
+
+    public AtompubServiceManager() {
+      this.abdera = Abdera.getInstance();
+    }
+    
+    public AtompubServiceManager(Abdera abdera) {
+      this.abdera = abdera;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <P extends Provider>P newProvider(
+      Map<String, Object> properties) {
+      properties.put("abdera",abdera);
+      return (P)MoreFunctions
+        .discoverInitializable(
+          Provider.class,
+          DefaultAtompubProvider.class).apply(properties);
+    }    
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain