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 [8/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/protocol/server/impl/SimpleCollectionInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCollectionInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCollectionInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCollectionInfo.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,103 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.BasicCollectionInfo;
+import org.apache.abdera2.model.Collection;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+
+import com.google.common.collect.ImmutableSet;
+
+public class SimpleCollectionInfo 
+  extends BasicCollectionInfo
+  implements AtompubCollectionInfo, 
+             Serializable {
+
+    private static final long serialVersionUID = 8026455829158149510L;
+
+    public static Generator make() {
+      return new Generator();
+    }
+    
+    public static class Generator extends BasicCollectionInfo.Generator {
+      final ImmutableSet.Builder<AtompubCategoriesInfo> catinfos =
+        ImmutableSet.builder();
+      public Generator category(AtompubCategoriesInfo info) {
+        this.catinfos.add(info);
+        return this;
+      }
+      public CollectionInfo get() {
+        return new SimpleCollectionInfo(this);
+      }
+    }
+    
+    private final Set<AtompubCategoriesInfo> catinfos;
+
+    protected SimpleCollectionInfo(Generator generator) {
+      super(generator);
+      this.catinfos = generator.catinfos.build();
+    }
+
+    public Iterable<AtompubCategoriesInfo> getCategoriesInfo(RequestContext request) {
+        return catinfos;
+    }
+
+    @Override
+    public int hashCode() {
+      return MoreFunctions.genHashCode(super.hashCode(), catinfos);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj)
+        return true;
+      if (!super.equals(obj))
+        return false;
+      if (getClass() != obj.getClass())
+        return false;
+      SimpleCollectionInfo other = (SimpleCollectionInfo) obj;
+      if (catinfos == null) {
+        if (other.catinfos != null)
+          return false;
+      } else if (!catinfos.equals(other.catinfos))
+        return false;
+      return true;
+    }
+
+    public Collection asCollectionElement(RequestContext request) {
+      Collection collection = 
+        AbstractAtompubProvider
+          .getAbdera(request)
+          .getFactory()
+          .newCollection();
+      collection.setHref(getHref(request));
+      collection.setTitle(getTitle(request));
+      collection.setAccept(getAccepts(request));
+      for (AtompubCategoriesInfo catsinfo : this.catinfos)
+        collection.addCategories(catsinfo.asCategoriesElement(request));
+      return collection;
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleWorkspaceInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleWorkspaceInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleWorkspaceInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleWorkspaceInfo.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,64 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.BasicWorkspaceInfo;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.model.Workspace;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+import org.apache.abdera2.protocol.server.model.AtompubWorkspaceInfo;
+
+public class SimpleWorkspaceInfo 
+  extends BasicWorkspaceInfo
+  implements AtompubWorkspaceInfo, Serializable {
+
+    private static final long serialVersionUID = -8459688584319762878L;
+
+    public static Generator make() {
+      return new Generator();
+    }
+    
+    public static class Generator extends BasicWorkspaceInfo.Generator {
+      public WorkspaceInfo get() {
+        return new SimpleWorkspaceInfo(this);
+      } 
+    }
+    
+    public SimpleWorkspaceInfo(Generator generator) {
+      super(generator);
+    }
+
+    public SimpleWorkspaceInfo(String title) {
+        super(title);
+    }
+
+    public Workspace asWorkspaceElement(RequestContext request) {
+        Workspace workspace = AbstractAtompubProvider.getAbdera(request).getFactory().newWorkspace();
+        workspace.setTitle(title);
+        for (CollectionInfo c : this.collections) {
+            AtompubCollectionInfo collection = (AtompubCollectionInfo) c;
+            workspace.addCollection(collection.asCollectionElement(request));
+        }
+        return workspace;
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoriesInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoriesInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoriesInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoriesInfo.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.protocol.server.model;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.model.Categories;
+
+/**
+ * Metadata interface used by WorkspaceManager and Provider implementations to construct Atompub Service Documents. The
+ * CategoriesInfo interface provides information used to construct an app:categories element within an app:collection.
+ */
+public interface AtompubCategoriesInfo extends Iterable<AtompubCategoryInfo> {
+
+    /**
+     * Return true of the app:categories element fixed attribute should be set
+     */
+    boolean isFixed(RequestContext request);
+
+    /**
+     * Return the value of the app:categories element scheme attribute or null if the scheme should be omitted
+     */
+    String getScheme(RequestContext request);
+
+    /**
+     * Return the value of the app:categories element href attribute or null if the href should be omitted
+     */
+    String getHref(RequestContext request);
+
+    /**
+     * Convert this into an instance of the FOM Categories interface
+     */
+    Categories asCategoriesElement(RequestContext request);
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoryInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoryInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoryInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCategoryInfo.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,49 @@
+/*
+ * 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.model;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.model.Category;
+
+/**
+ * Metadata interface used by WorkspaceManager and Provider implementations to construct Atompub Service Documents. The
+ * CategoryInfo interface provides information used to construct an atom:category element within an app:categories
+ */
+public interface AtompubCategoryInfo {
+
+    /**
+     * Return the value of the atom:category scheme attribute or null if the scheme should be omitted
+     */
+    String getScheme(RequestContext request);
+
+    /**
+     * Return the value of the atom:category term attribute. This value MUST be provided
+     */
+    String getTerm(RequestContext request);
+
+    /**
+     * Return the value of the atom:category label attribute or null if the label should be omitted. This value is
+     * language-sensitive
+     */
+    String getLabel(RequestContext request);
+
+    /**
+     * Convert this into an instance of the FOM Category interface
+     */
+    Category asCategoryElement(RequestContext request);
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCollectionInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCollectionInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCollectionInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubCollectionInfo.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,42 @@
+/*
+ * 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.model;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.model.Collection;
+
+/**
+ * Metadata interface used by WorkspaceManager and Provider implementations to construct Atompub Service Documents. The
+ * CollectionInfo interface provides information used to construct an app:collection element
+ */
+public interface AtompubCollectionInfo
+  extends CollectionInfo {
+
+    /**
+     * Return the collection of CategoriesInfo objects for the app:collection element's app:categories elements. These
+     * tell a client which atom:category elements are defined for use in the collections atom:entries
+     */
+    Iterable<AtompubCategoriesInfo> getCategoriesInfo(RequestContext request);
+
+    /**
+     * Converts this to an instance of the FOM Collection interface
+     */
+    Collection asCollectionElement(RequestContext request);
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubWorkspaceInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubWorkspaceInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubWorkspaceInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/model/AtompubWorkspaceInfo.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.model;
+
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.model.Workspace;
+
+/**
+ * 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 AtompubWorkspaceInfo 
+  extends WorkspaceInfo {
+
+    /**
+     * Returns an instance of the FOM Workspace interface
+     */
+    Workspace asWorkspaceElement(RequestContext request);
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/AbstractMultipartCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/AbstractMultipartCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/AbstractMultipartCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/AbstractMultipartCollectionAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,304 @@
+/*
+ * 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.multipart;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.activation.MimeType;
+import javax.mail.Header;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetHeaders;
+
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.parser.ParseException;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubCollectionAdapter;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.common.Constants;
+import org.apache.abdera2.common.io.MultipartInputStream;
+import org.apache.abdera2.common.protocol.AbstractCollectionAdapter;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.commons.codec.binary.Base64;
+import static org.apache.abdera2.common.mediatype.MimeTypeHelper.*;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+import static org.apache.abdera2.common.misc.ExceptionHelper.*;
+import static com.google.common.base.Preconditions.*;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractMultipartCollectionAdapter 
+  extends AbstractAtompubCollectionAdapter 
+  implements MultipartRelatedCollectionInfo {
+
+    public AbstractMultipartCollectionAdapter(String href) {
+      super(href);
+    }
+
+    private static final String CONTENT_TYPE_HEADER = "content-type";
+    private static final String CONTENT_ID_HEADER = "content-id";
+    private static final String START_PARAM = "start";
+    private static final String TYPE_PARAM = "type";
+    private static final String BOUNDARY_PARAM = "boundary";
+
+    protected Map<String, String> accepts;
+
+    public Predicate<RequestContext> acceptable() {
+      return Predicates.or(
+        AbstractCollectionAdapter.HAS_NO_ENTITY,
+        new Predicate<RequestContext>() {
+        public boolean apply(RequestContext input) {
+          MimeType mt = input.getContentType();
+          if (mt == null) return false;
+          return isMultipart(mt.toString()) ||
+                 isAtom(mt.toString());
+        }
+      });
+    }
+    
+    public Iterable<String> getAccepts(RequestContext request) {
+        Collection<String> acceptKeys = getAlternateAccepts(request).keySet();
+        return Iterables.unmodifiableIterable(acceptKeys);
+    }
+
+    protected MultipartRelatedPost getMultipartRelatedData(
+      RequestContext request) 
+        throws IOException, 
+               ParseException,
+               MessagingException {
+      MultipartInputStream multipart = getMultipartStream(request);
+      multipart.skipBoundary();
+      String start = request.getContentType().getParameter(START_PARAM);
+      Document<Entry> entry = null;
+      Map<String, String> entryHeaders = new HashMap<String, String>();
+      InputStream data = null;
+      Map<String, String> dataHeaders = new HashMap<String, String>();
+      Map<String, String> headers = getHeaders(multipart);
+        // check if the first boundary is the media link entry
+      if (start == null || start.length() == 0 || 
+         (headers.containsKey(CONTENT_ID_HEADER) && 
+          start.equals(headers.get(CONTENT_ID_HEADER))) || 
+         (headers.containsKey(CONTENT_TYPE_HEADER) && 
+          isAtom(headers.get(CONTENT_TYPE_HEADER)))) {
+        entry = getEntry(multipart, request);
+        entryHeaders.putAll(headers);
+      } else {
+        data = getDataInputStream(multipart);
+        dataHeaders.putAll(headers);
+      }
+      multipart.skipBoundary();
+      headers = getHeaders(multipart);
+
+      if (start != null && 
+          (headers.containsKey(CONTENT_ID_HEADER) && 
+           start.equals(headers.get(CONTENT_ID_HEADER))) && 
+          (headers.containsKey(CONTENT_TYPE_HEADER) && 
+           isAtom(headers.get(CONTENT_TYPE_HEADER)))) {
+        entry = getEntry(multipart, request);
+        entryHeaders.putAll(headers);
+      } else {
+        data = getDataInputStream(multipart);
+        dataHeaders.putAll(headers);
+      }
+      checkMultipartContent(entry, dataHeaders, request);
+      return new MultipartRelatedPost(
+        entry, 
+        data, 
+        entryHeaders, 
+        dataHeaders);
+    }
+
+    private MultipartInputStream getMultipartStream(
+      RequestContext request) 
+        throws IOException, ParseException {
+      String boundary = request.getContentType().getParameter(BOUNDARY_PARAM);
+      checked(
+        boundary != null,
+        ParseException.class,
+        "multipart/related stream invalid, boundary parameter is missing.");
+      boundary = "--" + boundary;
+      String type = request.getContentType().getParameter(TYPE_PARAM);     
+      checked(
+        type != null && isAtom(type),
+        ParseException.class,
+        "multipart/related stream invalid, type parameter should be ",
+        Constants.ATOM_MEDIA_TYPE);
+      PushbackInputStream pushBackInput = 
+        new PushbackInputStream(request.getInputStream(), 2);
+      pushBackInput.unread("\r\n".getBytes());
+      return new MultipartInputStream(pushBackInput, boundary.getBytes());
+    }
+
+    private void checkMultipartContent(
+      Document<Entry> entry, 
+      Map<String, String> dataHeaders, 
+      RequestContext request)
+        throws ParseException {
+      checked(
+        entry != null, 
+        ParseException.class, 
+        "multipart/related stream invalid, media link entry is missing");
+      checked(
+        dataHeaders.containsKey(CONTENT_TYPE_HEADER), 
+        ParseException.class,
+        "multipart/related stream invalid, data content-type is missing");
+      checked(
+        isContentTypeAccepted(dataHeaders.get(CONTENT_TYPE_HEADER),request),
+        ParseException.class,
+        "multipart/related stream invalid, content-type is not acceptable", 
+        dataHeaders.get(CONTENT_TYPE_HEADER));
+    }
+
+    private Map<String, String> getHeaders(
+      MultipartInputStream multipart) 
+        throws IOException, 
+               MessagingException {
+        Map<String, String> mapHeaders = new HashMap<String, String>();
+        moveToHeaders(multipart);
+        InternetHeaders headers = new InternetHeaders(multipart);
+        Enumeration<Header> allHeaders = headers.getAllHeaders();
+        if (allHeaders != null) {
+          while (allHeaders.hasMoreElements()) {
+            Header header = allHeaders.nextElement();
+            mapHeaders.put(header.getName().toLowerCase(), header.getValue());
+          }
+        }
+        return mapHeaders;
+    }
+
+    private boolean moveToHeaders(
+      InputStream stream) 
+        throws IOException {
+      boolean dash = false;
+      boolean cr = false;
+      int byteReaded;
+      while ((byteReaded = stream.read()) != -1) {
+          switch (byteReaded) {
+              case '\r':
+                  cr = true;
+                  dash = false;
+                  break;
+              case '\n':
+                  if (cr == true)
+                      return true;
+                  dash = false;
+                  break;
+              case '-':
+                  if (dash == true) { // two dashes
+                      stream.close();
+                      return false;
+                  }
+                  dash = true;
+                  cr = false;
+                  break;
+              default:
+                  dash = false;
+                  cr = false;
+          }
+      }
+      return false;
+    }
+
+    private InputStream getDataInputStream(
+      InputStream stream) 
+        throws IOException {
+        Base64 base64 = new Base64();
+        ByteArrayOutputStream bo = 
+          new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        while (stream.read(buffer) != -1)
+          bo.write(buffer);
+        return new ByteArrayInputStream(
+          base64.decode(bo.toByteArray()));
+    }
+
+    private <T extends Element> Document<T> getEntry(
+      InputStream stream, 
+      RequestContext request) 
+        throws ParseException,
+               IOException {
+        Parser parser = AbstractAtompubProvider.getAbdera(request).getParser();
+        checkNotNull(parser,"No parser implementation provided");
+        Document<?> document =
+          parser.parse(
+            stream, 
+            request.getResolvedUri().toString(), 
+            parser.getDefaultParserOptions());
+        return (Document<T>)document;
+    }
+
+    private boolean isContentTypeAccepted(
+      String contentType, 
+      RequestContext request) {
+        if (getAlternateAccepts(request) == null)
+          return false;
+        for (Map.Entry<String, String> accept : getAlternateAccepts(request).entrySet())
+          if (isMatch(contentType, accept.getKey()) &&
+              accept.getValue() != null && 
+              accept.getValue().equalsIgnoreCase(
+                Constants.LN_ALTERNATE_MULTIPART_RELATED))
+              return true;
+        return false;
+    }
+
+    protected static class MultipartRelatedPost {
+        private final Document<Entry> entry;
+        private final InputStream data;
+        private final Map<String, String> entryHeaders;
+        private final Map<String, String> dataHeaders;
+
+        public MultipartRelatedPost(
+          Document<Entry> entry,
+          InputStream data,
+          Map<String, String> entryHeaders,
+          Map<String, String> dataHeaders) {
+            this.entry = entry;
+            this.data = data;
+            this.entryHeaders = entryHeaders;
+            this.dataHeaders = dataHeaders;
+        }
+
+        public Document<Entry> getEntry() {
+          return entry;
+        }
+
+        public InputStream getData() {
+          return data;
+        }
+
+        public Map<String, String> getEntryHeaders() {
+          return entryHeaders;
+        }
+
+        public Map<String, String> getDataHeaders() {
+          return dataHeaders;
+        }
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/MultipartRelatedCollectionInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/MultipartRelatedCollectionInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/MultipartRelatedCollectionInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/multipart/MultipartRelatedCollectionInfo.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.protocol.server.multipart;
+
+import java.util.Map;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+
+public interface MultipartRelatedCollectionInfo extends AtompubCollectionInfo {
+
+    /**
+     * Returns a map of MIME media types for the app:collection element's app:accept elements. These tell a client which
+     * media types the collection will accept on a POST. The key element is the default media type and the value element
+     * is the alternate type or null if it doesn't accept alternates.
+     */
+    public Map<String, String> getAlternateAccepts(RequestContext request);
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/CategoriesRequestProcessor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/CategoriesRequestProcessor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/CategoriesRequestProcessor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/CategoriesRequestProcessor.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.protocol.server.processors;
+
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.RequestProcessor;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+
+import com.google.common.base.Predicate;
+
+/**
+ * {@link org.apache.AtompubRequestProcessor.protocol.server.RequestProcessor} implementation which processes requests for categories
+ * documents.
+ */
+public class CategoriesRequestProcessor 
+  extends RequestProcessor {
+
+  public CategoriesRequestProcessor(
+    WorkspaceManager manager,
+    CollectionAdapter adapter) {
+      super(manager,adapter);
+  }
+  
+  public CategoriesRequestProcessor(
+      WorkspaceManager manager,
+      CollectionAdapter adapter,
+      Predicate<RequestContext> predicate) {
+        super(manager,adapter,predicate);
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/MultipartRelatedServiceRequestProcessor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/MultipartRelatedServiceRequestProcessor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/MultipartRelatedServiceRequestProcessor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/MultipartRelatedServiceRequestProcessor.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,122 @@
+/*
+ * 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.processors;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.abdera2.common.Constants;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+import org.apache.abdera2.protocol.server.context.StreamWriterResponseContext;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCategoryInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+import org.apache.abdera2.protocol.server.multipart.MultipartRelatedCollectionInfo;
+import org.apache.abdera2.writer.StreamWriter;
+
+import com.google.common.base.Predicate;
+
+/**
+ * {@link org.apache.AtompubRequestProcessor.protocol.server.RequestProcessor} implementation which processes requests for service
+ * documents. It writes multipart/related accept attributes when is enabled.
+ */
+public class MultipartRelatedServiceRequestProcessor 
+  extends ServiceRequestProcessor {
+
+    public MultipartRelatedServiceRequestProcessor(
+      WorkspaceManager workspaceManager, 
+      CollectionAdapter adapter) {
+        super(workspaceManager, adapter);
+    }
+    
+    public MultipartRelatedServiceRequestProcessor(
+        WorkspaceManager workspaceManager, 
+        CollectionAdapter adapter,
+        Predicate<RequestContext> predicate) {
+          super(workspaceManager, adapter, predicate);
+      }
+
+    protected ResponseContext getServiceDocument(
+      final RequestContext request, 
+      final WorkspaceManager workspaceManager) {
+        return new StreamWriterResponseContext(
+            AbstractAtompubProvider.getAbdera(request)) {
+            @Override
+            protected void writeTo(StreamWriter sw) throws IOException {
+                sw.startDocument().startService();
+                for (WorkspaceInfo wi : workspaceManager.getWorkspaces(request)) {
+                    sw.startWorkspace().writeTitle(wi.getTitle(request));
+                    Iterable<CollectionInfo> collections = wi.getCollections(request);
+
+                    if (collections != null) {
+                        for (CollectionInfo c : collections) {
+                            AtompubCollectionInfo ci = (AtompubCollectionInfo) c;
+                            sw.startCollection(ci.getHref(request)).writeTitle(ci.getTitle(request));
+                            if (ci instanceof MultipartRelatedCollectionInfo) {
+                              MultipartRelatedCollectionInfo multipartCi = (MultipartRelatedCollectionInfo)ci;
+                              for (Map.Entry<String, String> accept : multipartCi.getAlternateAccepts(request).entrySet()) {
+                                  sw.startElement(Constants.ACCEPT);
+                                  if (accept.getValue() != null && accept.getValue().length() > 0) {
+                                      sw.writeAttribute(Constants.LN_ALTERNATE, accept.getValue());
+                                  }
+                                  sw.writeElementText(accept.getKey()).endElement();
+                              }
+                            } else {
+                              sw.writeAccepts(ci.getAccepts(request));
+                            }
+                            Iterable<AtompubCategoriesInfo> catinfos = 
+                              ci.getCategoriesInfo(request);
+                            if (catinfos != null) {
+                                for (AtompubCategoriesInfo catinfo : catinfos) {
+                                    String cathref = catinfo.getHref(request);
+                                    if (cathref != null) {
+                                      sw.startCategories()
+                                        .writeAttribute(
+                                          "href",
+                                          request.getTargetBasePath() + cathref)
+                                        .endCategories();
+                                    } else {
+                                        sw.startCategories(
+                                          catinfo.isFixed(request), 
+                                          catinfo.getScheme(request));
+                                        for (AtompubCategoryInfo cat : catinfo)
+                                          sw.writeCategory(
+                                            cat.getTerm(request), 
+                                            cat.getScheme(request), 
+                                            cat.getLabel(request));
+                                        sw.endCategories();
+                                    }
+                                }
+                            }
+                            sw.endCollection();
+                        }
+                    }
+                    sw.endWorkspace();
+                }
+                sw.endService().endDocument();
+            }
+        }.setStatus(200).setContentType(Constants.APP_MEDIA_TYPE);
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/ServiceRequestProcessor.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/ServiceRequestProcessor.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/ServiceRequestProcessor.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/processors/ServiceRequestProcessor.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,137 @@
+/*
+ * 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.processors;
+
+import java.io.IOException;
+
+import org.apache.abdera2.common.Constants;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.RequestProcessor;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+import org.apache.abdera2.protocol.server.context.StreamWriterResponseContext;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCategoryInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+import org.apache.abdera2.writer.StreamWriter;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Predicate;
+
+/**
+ * {@link org.apache.AtompubRequestProcessor.protocol.server.RequestProcessor} implementation which processes requests for service
+ * documents.
+ */
+public class ServiceRequestProcessor 
+  extends RequestProcessor {
+
+    public ServiceRequestProcessor(
+      WorkspaceManager workspaceManager,
+      CollectionAdapter adapter) {
+        super(workspaceManager, adapter);
+    }
+    
+    public ServiceRequestProcessor(
+        WorkspaceManager workspaceManager,
+        CollectionAdapter adapter,
+        Predicate<RequestContext> predicate) {
+          super(workspaceManager, adapter,predicate);
+      }
+
+
+    public ResponseContext apply(
+        RequestContext request) {
+      return processService(request, workspaceManager);
+    }
+  
+    private ResponseContext processService(
+        RequestContext context, 
+        WorkspaceManager workspaceManager) {
+        String method = context.getMethod();
+        if (method.equalsIgnoreCase("GET")) {
+            return getServiceDocument(context, workspaceManager);
+        } else {
+            return null;
+        }
+    }
+
+    protected ResponseContext getServiceDocument(
+        final RequestContext request, 
+        final WorkspaceManager workspaceManager) {
+ 
+        return new StreamWriterResponseContext(
+            AbstractAtompubProvider.getAbdera(request)) {
+
+          // JIRA: https://issues.apache.org/jira/browse/ABDERA-255
+          @Override
+          public EntityTag getEntityTag() {
+            EntityTag etag = workspaceManager.getEntityTag();
+            return etag != null ? etag : super.getEntityTag();
+          }
+
+          // JIRA: https://issues.apache.org/jira/browse/ABDERA-255
+          @Override
+          public DateTime getLastModified() {
+            DateTime lm = workspaceManager.getLastModified();
+            return lm != null ? lm : super.getLastModified();
+          }
+
+            protected void writeTo(StreamWriter sw) throws IOException {
+                sw.startDocument().startService();
+                for (WorkspaceInfo wi : workspaceManager.getWorkspaces(request)) {
+                    sw.startWorkspace().writeTitle(wi.getTitle(request));
+                    Iterable<CollectionInfo> collections = wi.getCollections(request);
+                    if (collections != null) {
+                        for (CollectionInfo c : collections) {
+                            AtompubCollectionInfo ci = (AtompubCollectionInfo) c;
+                            sw.startCollection(ci.getHref(request)).writeTitle(ci.getTitle(request)).writeAccepts(ci
+                                .getAccepts(request));
+                            Iterable<AtompubCategoriesInfo> catinfos = ci.getCategoriesInfo(request);
+                            if (catinfos != null) {
+                                for (AtompubCategoriesInfo catinfo : catinfos) {
+                                    String cathref = catinfo.getHref(request);
+                                    if (cathref != null) {
+                                        sw.startCategories().writeAttribute("href",
+                                                                            request.getTargetBasePath() + cathref)
+                                            .endCategories();
+                                    } else {
+                                        sw.startCategories(catinfo.isFixed(request), catinfo.getScheme(request));
+                                        for (AtompubCategoryInfo cat : catinfo) {
+                                            sw.writeCategory(cat.getTerm(request), cat.getScheme(request), cat
+                                                .getLabel(request));
+                                        }
+                                        sw.endCategories();
+                                    }
+                                }
+                            }
+                            sw.endCollection();
+                        }
+                    }
+                    sw.endWorkspace();
+                }
+                sw.endService().endDocument();
+            }
+        }.setStatus(200).setContentType(Constants.APP_MEDIA_TYPE);
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,201 @@
+/*
+ * 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.provider.basic;
+
+import java.util.logging.Logger;
+
+import javax.activation.MimeType;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Feed;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.protocol.server.provider.managed.FeedConfiguration;
+import org.apache.abdera2.protocol.server.provider.managed.ManagedCollectionAdapter;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.common.protocol.Target;
+import org.apache.abdera2.common.protocol.TargetType;
+
+import com.google.common.base.Function;
+
+/**
+ * The BasicAdapter provides a simplistic interface for working with Atompub collections with a restricted set of
+ * options/features. The idea of the basic adapter is to make it easy to provide a minimally capable Atompub server
+ */
+public abstract class BasicAdapter extends ManagedCollectionAdapter {
+
+    public final static Logger logger = 
+      Logger.getLogger(BasicAdapter.class.getName());
+
+    protected BasicAdapter(Abdera abdera, FeedConfiguration config) {
+        super(abdera,config);
+        putHandler(TargetType.TYPE_CATEGORIES,"GET",getCategories());
+        putHandler(TargetType.TYPE_CATEGORIES,"HEAD",getCategories());
+        putHandler(TargetType.TYPE_COLLECTION,"GET",getItemList());
+        putHandler(TargetType.TYPE_COLLECTION,"HEAD",getItemList());
+        putHandler(TargetType.TYPE_COLLECTION,"POST",postItem());
+        putHandler(TargetType.TYPE_ENTRY,"GET",getItem());
+        putHandler(TargetType.TYPE_ENTRY,"HEAD",getItem());
+        putHandler(TargetType.TYPE_ENTRY,"PUT",putItem());
+        putHandler(TargetType.TYPE_ENTRY,"DELETE",deleteItem());
+    }
+
+    public String getProperty(String key) throws Exception {
+        Object val = config.getProperty(key);
+        if (val == null) {
+            logger.warning("Cannot find property " + key + "in Adapter properties file for feed " + config.getFeedId());
+            throw new RuntimeException();
+        }
+        if (val instanceof String)
+            return (String)val;
+        throw new RuntimeException();
+    }
+
+    protected Feed createFeed() throws Exception {
+        Feed feed = abdera.newFeed();
+        feed.setId(config.getFeedUri());
+        feed.setTitle(config.getFeedTitle());
+        feed.setUpdatedNow();
+        feed.addAuthor(config.getFeedAuthor());
+        return feed;
+    }
+
+    protected void addEditLinkToEntry(Entry entry) throws Exception {
+      if (AbstractAtompubProvider.getEditUriFromEntry(entry) == null)
+        entry.addLink(entry.getId(), "edit");
+    }
+
+    protected void setEntryIdIfNull(Entry entry) throws Exception {
+        // if there is no id in Entry, assign one.
+        if (entry.getId() != null)
+            return;
+        String uuidUri = abdera.getFactory().newUuidUri();
+        String[] segments = uuidUri.split(":");
+        String entryId = segments[segments.length - 1];
+        entry.setId(createEntryIdUri(entryId));
+    }
+
+    protected String createEntryIdUri(String entryId) throws Exception {
+      return config.getFeedUri() + "/" + entryId;
+    }
+
+    private ResponseContext createOrUpdateEntry(RequestContext request, boolean createFlag) {
+        try {
+            MimeType mimeType = request.getContentType();
+            String contentType = mimeType == null ? null : mimeType.toString();
+            if (contentType != null && !MimeTypeHelper.isAtom(contentType) && !MimeTypeHelper.isXml(contentType))
+                return ProviderHelper.notsupported(request);
+            Entry inputEntry = AbstractAtompubProvider.<Entry>getDocument(request).getRoot();
+            Target target = request.getTarget();
+            String entryId = !createFlag ? target.getParameter(BasicProvider.PARAM_ENTRY) : null;
+            Entry newEntry = createFlag ? createEntry(inputEntry) : updateEntry(entryId, inputEntry);
+            if (newEntry != null) {
+                Document<Entry> newEntryDoc = newEntry.getDocument();
+                String loc = newEntry.getEditLinkResolvedHref().toString();
+                return AbstractAtompubProvider.returnBase(newEntryDoc, createFlag ? 201 : 200, null).setLocation(loc);
+            } else {
+                return ProviderHelper.notfound(request);
+            }
+        } catch (Exception e) {
+            return ProviderHelper.servererror(request, e.getMessage(), e);
+        }
+    }
+
+    private Function<RequestContext,ResponseContext> postItem() {
+      return new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          return createOrUpdateEntry(input,true);
+        }
+      };
+    }
+    
+    private Function<RequestContext,ResponseContext> deleteItem() {
+      return new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          Target target = input.getTarget();
+          String entryId = target.getParameter(BasicProvider.PARAM_ENTRY);
+          try {
+            return deleteEntry(entryId) ? 
+              ProviderHelper.nocontent() : 
+              ProviderHelper.notfound(input);
+          } catch (Exception e) {
+            return ProviderHelper.servererror(input, e.getMessage(), e);
+          }  
+        }
+      };
+    }
+
+    private Function<RequestContext,ResponseContext> putItem() {
+      return new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          return createOrUpdateEntry(input,false);
+        }
+      };
+    }
+
+    private Function<RequestContext,ResponseContext> getItem() {
+      return new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          Target target = input.getTarget();
+          String entryId = target.getParameter(BasicProvider.PARAM_ENTRY);
+          try {
+            Entry entry = getEntry(entryId);
+            return entry != null ? 
+              AbstractAtompubProvider.returnBase(entry.getDocument(), 200, null) : 
+              ProviderHelper.notfound(input);
+          } catch (Exception e) {
+            return ProviderHelper.servererror(input, e.getMessage(), e);
+          }
+        }
+      };
+    }
+
+    private Function<RequestContext,ResponseContext> getItemList() {
+      return new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          try {
+            Feed feed = getFeed();
+            return feed != null ? 
+              AbstractAtompubProvider.returnBase(feed.getDocument(), 200, null) : 
+              ProviderHelper.notfound(input);
+          } catch (Exception e) {
+            return ProviderHelper.servererror(input, e.getMessage(), e);
+          }
+        }
+      };
+    }
+
+    private Function<RequestContext,ResponseContext> getCategories() {
+      return NOT_FOUND;
+    }
+    
+    public abstract Feed getFeed() throws Exception;
+
+    public abstract Entry getEntry(Object entryId) throws Exception;
+
+    public abstract Entry createEntry(Entry entry) throws Exception;
+
+    public abstract Entry updateEntry(Object entryId, Entry entry) throws Exception;
+
+    public abstract boolean deleteEntry(Object entryId) throws Exception;
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/basic/BasicProvider.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,76 @@
+/*
+ * 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.provider.basic;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+import org.apache.abdera2.common.protocol.RouteManager;
+import org.apache.abdera2.common.protocol.TargetType;
+import org.apache.abdera2.protocol.server.provider.managed.BasicServerConfiguration;
+import org.apache.abdera2.protocol.server.provider.managed.ManagedProvider;
+import org.apache.abdera2.protocol.server.provider.managed.ServerConfiguration;
+
+/**
+ * Provider implementation intended to be used with BasicAdapter implementations
+ */
+public class BasicProvider extends ManagedProvider {
+
+    public static final String PARAM_FEED = "feed";
+    public static final String PARAM_ENTRY = "entry";
+
+    public BasicProvider() {
+        super();
+        init();
+    }
+
+    private void init() {
+        RouteManager<TargetType,RequestContext,String> routeManager =
+          RouteManager.<TargetType,RequestContext,String>make()
+            .with(
+              "service", 
+              "/", 
+              TargetType.TYPE_SERVICE)
+            .with(
+              "feed",
+              "/:feed",
+              TargetType.TYPE_COLLECTION)
+            .with(
+              "entry", 
+              "/:feed/:entry", 
+              TargetType.TYPE_ENTRY)
+            .get();
+        setTargetBuilder(
+            routeManager);
+        setTargetResolver(
+            routeManager);
+    }
+
+    public CollectionAdapter getCollectionAdapter(RequestContext request) {
+        try {
+            return getCollectionAdapterManager(request)
+              .getAdapter(request.getTarget().getParameter(PARAM_FEED));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    protected ServerConfiguration getServerConfiguration(RequestContext request) {
+        return new BasicServerConfiguration(request);
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/AbstractServerConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/AbstractServerConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/AbstractServerConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/AbstractServerConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,85 @@
+/*
+ * 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.provider.managed;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+
+public abstract class AbstractServerConfiguration extends ServerConfiguration {
+
+    private final String host;
+    private final int port;
+    private final boolean secure;
+
+    protected AbstractServerConfiguration(RequestContext request) {
+        Object ohost = request.getProperty(RequestContext.Property.SERVERNAME);
+        Object oport = request.getProperty(RequestContext.Property.SERVERPORT);
+        Object osec = request.getProperty(RequestContext.Property.SECURE);
+        host = ohost != null ? (String)ohost : "localhost";
+        port = oport != null ? ((Integer)oport).intValue() : 9002;
+        secure = osec != null ? ((Boolean)osec).booleanValue() : false;
+    }
+
+    @Override
+    public String getAdapterConfigLocation() {
+        return "abdera/adapter/config/";
+    }
+
+    @Override
+    public String getFeedConfigLocation() {
+        return "abdera/adapter/";
+    }
+
+    @Override
+    public String getFeedConfigSuffix() {
+        return ".properties";
+    }
+
+    @Override
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public String getServerUri() {
+        StringBuilder buf = new StringBuilder();
+        buf.append(secure ? "https://" : "http://");
+        buf.append(host);
+        if (port != 80) {
+            buf.append(":");
+            buf.append(port);
+        }
+        return buf.toString();
+    }
+
+    @Override
+    public FeedConfiguration loadFeedConfiguration(String feedId) throws IOException {
+        String fileName = getFeedConfigLocation() + feedId + getFeedConfigSuffix();
+        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
+        if (in == null)
+            throw new FileNotFoundException();
+        Properties props = new Properties();
+        props.load(in);
+        in.close();
+        return FeedConfiguration.getFeedConfiguration(feedId, props, this);
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/BasicServerConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/BasicServerConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/BasicServerConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/BasicServerConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,41 @@
+/*
+ * 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.provider.managed;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.anno.AnnoUtil;
+import org.apache.abdera2.common.anno.Version;
+import org.apache.abdera2.common.protocol.RequestContext;
+
+public class BasicServerConfiguration extends AbstractServerConfiguration {
+
+    public BasicServerConfiguration(RequestContext request) {
+        super(request);
+    }
+
+    @Override
+    public String getFeedNamespace() {
+      Version version = AnnoUtil.getVersion(Abdera.class);
+        return version.uri() + "/" + version.value() + "/";
+    }
+
+    @Override
+    public String getFeedNamespacePrefix() {
+        return "a";
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,49 @@
+/*
+ * 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.provider.managed;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+public class CollectionAdapterConfiguration extends Configuration {
+
+    private final String fileLocation;
+    private final ServerConfiguration serverConfiguration;
+
+    public CollectionAdapterConfiguration(
+      ServerConfiguration serverConfiguration, 
+      String fileLocation) {
+        this.fileLocation = fileLocation;
+        this.serverConfiguration = serverConfiguration;
+    }
+
+    public InputStream getConfigAsFileInputStream() throws IOException {
+        String filePath = serverConfiguration.getAdapterConfigLocation() + fileLocation;
+        return Configuration.loadFileAsInputStream(filePath);
+    }
+
+    public Reader getAdapterConfigAsReader() throws IOException {
+        return new InputStreamReader(getConfigAsFileInputStream());
+    }
+
+    public ServerConfiguration getServerConfiguration() {
+        return serverConfiguration;
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/CollectionAdapterManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,109 @@
+/*
+ * 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.provider.managed;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+
+public class CollectionAdapterManager {
+
+    public final static Logger logger = Logger.getLogger(CollectionAdapterManager.class.getName());
+
+    // maps a feed id to an adapter instance
+    protected final static Map<String, CollectionAdapter> adapterInstanceMap = 
+      new HashMap<String, CollectionAdapter>();
+
+    protected final Abdera abdera;
+    protected final ServerConfiguration config;
+
+    public CollectionAdapterManager(Abdera abdera, ServerConfiguration config) {
+        this.abdera = abdera;
+        this.config = config;
+    }
+
+    public CollectionAdapter getAdapter(String feedId) throws Exception {
+        FeedConfiguration feedConfiguration = config.loadFeedConfiguration(feedId);
+        return createAdapterInstance(feedConfiguration, abdera);
+    }
+
+    public Map<String, FeedConfiguration> listAdapters() throws Exception {
+        Map<String, FeedConfiguration> results = new HashMap<String, FeedConfiguration>();
+        Enumeration<URL> e =
+            Thread.currentThread().getContextClassLoader().getResources(config.getFeedConfigLocation());
+        while (e.hasMoreElements()) {
+            URL url = e.nextElement();
+            File file = new File(url.toURI());
+            if (!file.exists()) {
+                throw new RuntimeException("Could not convert properties path to a File! \"" + file.getAbsolutePath()
+                    + "\" does not exist.");
+            }
+            File[] files = file.listFiles(new FileFilter() {
+                public boolean accept(File file) {
+                    return !file.isDirectory();
+                }
+            });
+            if (files != null) {
+                for (File _file : files) {
+                    String name = _file.getName();
+                    int i = name.indexOf(config.getFeedConfigSuffix());
+                    String id = i > -1 ? name.substring(0, i) : null;
+                    if (id != null) {
+                        FeedConfiguration feedConfiguration = loadFeedInfo(id);
+                        if (null != feedConfiguration)
+                            results.put(id, feedConfiguration);
+                    }
+                }
+            }
+        }
+        return results;
+    }
+
+    protected FeedConfiguration loadFeedInfo(String feedId) throws Exception {
+        return config.loadFeedConfiguration(feedId);
+    }
+
+    protected static synchronized CollectionAdapter createAdapterInstance(FeedConfiguration config, Abdera abdera)
+        throws Exception {
+        CollectionAdapter basicAdapter = adapterInstanceMap.get(config.getFeedId());
+        if (basicAdapter != null) {
+            return basicAdapter;
+        }
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Class<?> adapterClass = cl.loadClass(config.getAdapterClassName());
+        Constructor<?>[] ctors = adapterClass.getConstructors();
+        for (Constructor<?> element : ctors)
+          logger.finest("Public constructor found: " + element.toString());
+        Constructor<?> c = adapterClass.getConstructor(new Class[] {Abdera.class, FeedConfiguration.class});
+        c.setAccessible(true);
+        CollectionAdapter adapterInstance = (CollectionAdapter)c.newInstance(abdera, config);
+
+        // put this adapter instance in adapterInstanceMap
+        adapterInstanceMap.put(config.getFeedId(), adapterInstance);
+        return adapterInstance;
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/Configuration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/Configuration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/Configuration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/Configuration.java Wed Feb  1 17:54:54 2012
@@ -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.abdera2.protocol.server.provider.managed;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public abstract class Configuration {
+
+    static Properties loadFileAsProperties(String fileLocation) throws IOException {
+        Properties props = new Properties();
+        FileInputStream in = new FileInputStream(fileLocation);
+        props.load(in);
+        in.close();
+        return props;
+    }
+
+    static InputStream loadFileAsInputStream(String fileLocation) throws IOException {
+        return Thread.currentThread().getContextClassLoader().getResourceAsStream(fileLocation);
+    }
+
+    static String getProperty(Properties prop, String key) {
+        String val = prop.getProperty(key);
+        if (val == null)
+            throw new RuntimeException();
+        return val;
+    }
+
+    protected Configuration() {
+    }
+}

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