abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r1239237 [3/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...
Date Wed, 01 Feb 2012 17:55:02 GMT
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterConfiguration.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.activities.protocol.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/activities/protocol/managed/CollectionAdapterConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/CollectionAdapterManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,106 @@
+/*
+ * 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.activities.protocol.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.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 ServerConfiguration config;
+
+    public CollectionAdapterManager(ServerConfiguration config) {
+        this.config = config;
+    }
+
+    public CollectionAdapter getAdapter(String feedId) throws Exception {
+        FeedConfiguration feedConfiguration = config.loadFeedConfiguration(feedId);
+        return createAdapterInstance(feedConfiguration);
+    }
+
+    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)
+        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[] {FeedConfiguration.class});
+        c.setAccessible(true);
+        CollectionAdapter adapterInstance = (CollectionAdapter)c.newInstance(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/activities/protocol/managed/CollectionAdapterManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/Configuration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/Configuration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/Configuration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/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.activities.protocol.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/activities/protocol/managed/Configuration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/FeedConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/FeedConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/FeedConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/FeedConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,227 @@
+/*
+ * 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.activities.protocol.managed;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.RequestContext;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+
+public class FeedConfiguration extends Configuration implements CollectionInfo {
+    public static final String PROP_NAME_ADAPTER_CLASS = "adapterClassName";
+    public static final String PROP_SUB_URI_NAME = "subUri";
+    public static final String PROP_AUTHOR_NAME = "author";
+    public static final String PROP_TITLE_NAME = "title";
+    public static final String PROP_ACCEPTS = "accepts";
+    public static final String PROP_ENTRY_TITLE_NAME = "entryTitle";
+    public static final String PROP_FEED_CONFIG_LOCATION_NAME = "configFile";
+
+    public static final String ENTRY_ELEM_NAME_ID = "id";
+    public static final String ENTRY_ELEM_NAME_TITLE = "title";
+    public static final String ENTRY_ELEM_NAME_CONTENT = "content";
+    public static final String ENTRY_ELEM_NAME_AUTHOR = "author";
+    public static final String ENTRY_ELEM_NAME_UPDATED = "updated";
+    public static final String ENTRY_ELEM_NAME_LINK = "link";
+
+    public static class Generator implements Supplier<FeedConfiguration> {
+
+      String feedId;
+      String subUri;
+      String adapterClassName;
+      String feedConfigLocation;
+      ServerConfiguration serverConfiguration;
+      String feedTitle = "unknown";
+      String feedAuthor = "unknown";
+      final ImmutableMap.Builder<Object,Object> optionalProperties =
+        ImmutableMap.builder();
+      CollectionAdapterConfiguration adapterConfiguration;      
+      
+      public Generator id(String id) {
+        this.feedId = id;
+        return this;
+      }
+      
+      public Generator subUri(String uri) {
+        this.subUri = uri;
+        return this;
+      }
+      
+      public Generator adapter(String className) {
+        this.adapterClassName = className;
+        return this;
+      }
+      
+      public Generator location(String location) {
+        this.feedConfigLocation = location;
+        return this;
+      }
+      
+      public Generator serverConfig(ServerConfiguration config) {
+        this.serverConfiguration = config;
+        return this;
+      }
+      
+      public Generator title(String title) {
+        this.feedTitle = title;
+        return this;
+      }
+      
+      public Generator author(String author) {
+        this.feedAuthor = author;
+        return this;
+      }
+      
+      public Generator set(Object key, Object val) {
+        this.optionalProperties.put(key, val);
+        return this;
+      }
+      
+      public Generator setAll(Map<Object,Object> props) {
+        this.optionalProperties.putAll(props);
+        return this;
+      }
+      
+      public Generator adapterConfif(CollectionAdapterConfiguration config) {
+        this.adapterConfiguration = config;
+        return this;
+      }
+      
+      public FeedConfiguration get() {
+        return new FeedConfiguration(this);
+      }
+      
+    }
+    
+    public static Generator make() {
+      return new Generator();
+    }
+    
+    private final String feedId;
+    private final String subUri;
+    private final String adapterClassName;
+    private final String feedConfigLocation;
+    private final ServerConfiguration serverConfiguration;
+    private final String feedTitle;
+    private final String feedAuthor;
+    private final ImmutableMap<Object, Object> optionalProperties;
+    private final CollectionAdapterConfiguration adapterConfiguration;
+
+    protected FeedConfiguration(Generator gen) {
+      this.feedId = gen.feedId;
+      this.subUri = gen.subUri;
+      this.adapterClassName = gen.adapterClassName;
+      this.feedConfigLocation = gen.feedConfigLocation;
+      this.serverConfiguration = gen.serverConfiguration;
+      this.feedTitle = gen.feedTitle;
+      this.feedAuthor = gen.feedAuthor;
+      this.optionalProperties = gen.optionalProperties.build();
+      this.adapterConfiguration = gen.adapterConfiguration;
+    }
+
+    public static FeedConfiguration getFeedConfiguration(
+        String feedId,
+        Properties properties,
+        ServerConfiguration serverConfiguration) {
+        
+        String author = "unknown";
+        String title = "unknown";
+        
+        if (properties.containsKey(PROP_AUTHOR_NAME))
+          author = Configuration.getProperty(properties, PROP_AUTHOR_NAME);
+        if (properties.containsKey(PROP_TITLE_NAME))
+          title = Configuration.getProperty(properties, PROP_TITLE_NAME);
+        
+        return FeedConfiguration
+          .make()
+            .id(feedId)
+            .subUri(Configuration.getProperty(properties, PROP_SUB_URI_NAME))
+            .adapter(Configuration.getProperty(properties, PROP_NAME_ADAPTER_CLASS))
+            .location(Configuration.getProperty(properties, PROP_FEED_CONFIG_LOCATION_NAME))
+            .serverConfig(serverConfiguration)
+            .title(title)
+            .author(author)
+            .setAll(properties)
+          .get();
+      }
+
+    public String getAdapterClassName() {
+        return adapterClassName;
+    }
+
+    public String getFeedAuthor() {
+        return feedAuthor;
+    }
+
+    public String getFeedConfigLocation() {
+        return feedConfigLocation;
+    }
+
+    public String getFeedId() {
+        return feedId;
+    }
+
+    public String getFeedTitle() {
+        return feedTitle;
+    }
+
+    public String getSubUri() {
+        return subUri;
+    }
+
+    public String getFeedUri() {
+        return serverConfiguration.getServerUri() + "/" + getSubUri();
+    }
+
+    public boolean hasProperty(String key) {
+        return optionalProperties.containsKey(key);
+    }
+
+    public Object getProperty(String key) {
+        return optionalProperties.get(key);
+    }
+
+    public CollectionAdapterConfiguration getAdapterConfiguration() {
+        return adapterConfiguration;
+    }
+    
+    public Iterable<String> getAccepts(RequestContext request) {
+        Object accepts = optionalProperties.get(PROP_ACCEPTS);
+        String[] arr = null;
+        if (accepts == null || !(accepts instanceof String))
+            arr = new String[] {"application/json"};
+        else arr = ((String)accepts).split("\\s*,\\s*");
+        return Arrays.<String>asList(arr);
+    }
+
+    public String getHref(RequestContext request) {
+        return getFeedUri();
+    }
+
+    public String getTitle(RequestContext request) {
+        return getFeedTitle();
+    }
+
+    public ServerConfiguration getServerConfiguration() {
+        return adapterConfiguration.getServerConfiguration();
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedCollectionAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,51 @@
+/*
+ * 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.activities.protocol.managed;
+
+import org.apache.abdera2.activities.protocol.AbstractActivitiesCollectionAdapter;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContextException;
+
+public abstract class ManagedCollectionAdapter 
+  extends AbstractActivitiesCollectionAdapter 
+  implements CollectionAdapter {
+
+    protected final FeedConfiguration config;
+
+    protected ManagedCollectionAdapter(FeedConfiguration config) {
+      super(null);
+        this.config = config;
+    }
+
+    public FeedConfiguration getConfiguration() {
+        return this.config;
+    }
+
+    public String getAuthor(RequestContext request) throws ResponseContextException {
+        return config.getFeedAuthor();
+    }
+
+    public String getId(RequestContext request) {
+        return config.getFeedId();
+    }
+
+    public String getTitle(RequestContext request) {
+        return config.getFeedTitle();
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedProvider.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.activities.protocol.managed;
+
+import org.apache.abdera2.activities.protocol.AbstractActivitiesWorkspaceProvider;
+import org.apache.abdera2.common.protocol.RequestContext;
+
+/**
+ * The ManagedProvider uses *.properties files discovered in the webapp classpath to configure CollectionAdapter
+ * instances. The ManagedWorkspace implementation will automatically discover the *.properties files and will use those
+ * to create the appropriate CollectionAdapter objects. Properties files must be located in the classpath at
+ * /abdera/adapter/*.properties. Refer to the Abdera Server Implementation Guide for additional details
+ */
+public abstract class ManagedProvider 
+  extends AbstractActivitiesWorkspaceProvider {
+  
+  protected abstract ServerConfiguration getServerConfiguration(RequestContext request);
+
+  protected ManagedProvider() {
+    addWorkspace(new ManagedWorkspace(this));
+  }
+
+  public CollectionAdapterManager getCollectionAdapterManager(RequestContext request) {
+    return new CollectionAdapterManager(getServerConfiguration(request));
+  }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedWorkspace.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedWorkspace.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedWorkspace.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ManagedWorkspace.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,60 @@
+/*
+ * 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.activities.protocol.managed;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+
+public class ManagedWorkspace implements WorkspaceInfo {
+
+    private final ManagedProvider provider;
+
+    private String title = "Abdera - Activities";
+
+    public ManagedWorkspace(ManagedProvider provider) {
+      this.provider = provider;
+    }
+
+    public Collection<CollectionInfo> getCollections(RequestContext request) {
+      CollectionAdapterManager cam = provider.getCollectionAdapterManager(request);
+      List<CollectionInfo> collections = new ArrayList<CollectionInfo>();
+      try {
+        Map<String, FeedConfiguration> map = cam.listAdapters();
+        for (FeedConfiguration config : map.values())
+          collections.add(config);
+      } catch (Throwable e) {
+        throw ExceptionHelper.propogate(e);
+      }
+      return collections;
+    }
+    
+    public String getTitle(RequestContext request) {
+      return title;
+    }
+
+    public void setTitle(String title) {
+      this.title = title;
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ServerConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ServerConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ServerConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/activities/protocol/managed/ServerConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,34 @@
+/*
+ * 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.activities.protocol.managed;
+
+public abstract class ServerConfiguration extends Configuration {
+
+    public abstract int getPort();
+
+    public abstract String getServerUri();
+
+    public abstract String getFeedConfigLocation();
+
+    public abstract String getFeedConfigSuffix();
+
+    public abstract String getAdapterConfigLocation();
+
+    public abstract FeedConfiguration loadFeedConfiguration(String feedId) throws Exception;
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractBaseRequestContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractBaseRequestContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractBaseRequestContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractBaseRequestContext.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,123 @@
+/*
+ * 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.security.Principal;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.apache.abdera2.common.iri.IRI;
+
+import com.google.common.collect.ImmutableSet;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractBaseRequestContext 
+  extends AbstractRequest 
+  implements RequestContext {
+
+    protected final Provider provider;
+    protected final String method;
+    protected final IRI requestUri;
+    protected final IRI baseUri;
+    protected final Principal principal;
+    protected Subject subject;
+    protected Target target;
+    
+    protected AbstractBaseRequestContext(
+      Provider provider, 
+      String method, 
+      IRI requestUri, 
+      IRI baseUri,
+      Principal principal) {
+        this.provider = provider;
+        this.method = method;
+        this.baseUri = baseUri;
+        this.requestUri = requestUri;
+        this.principal = principal;
+    }
+    
+    protected Target initTarget() {
+      try {
+        Target target = provider.resolveTarget(this);
+        return target != null ? 
+          target : 
+          new SimpleTarget(TargetType.TYPE_NOT_FOUND, this);
+      } catch (Exception e) {
+          throw new RuntimeException(e);
+      }
+    }
+
+    public IRI getBaseUri() {
+        return baseUri;
+    }
+
+    public IRI getResolvedUri() {
+        return baseUri.resolve(getUri());
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public IRI getUri() {
+        return requestUri;
+    }
+
+    public Subject getSubject() {
+        return subject;
+    }
+
+    public Principal getPrincipal() {
+        return principal;
+    }
+
+    public Target getTarget() {
+        return target;
+    }
+
+    public Provider getProvider() {
+        return provider;
+    }
+
+    public String getTargetPath() {
+        String uri = getUri().toString();
+        String cpath = getContextPath();
+        return cpath == null ? uri : uri.substring(cpath.length());
+    }
+
+    public <T extends RequestContext>T setAttribute(String name, Object value) {
+        return (T)setAttribute(Scope.REQUEST, name, value);
+    }
+
+    public String urlFor(Object key, Object param) {
+        return provider.urlFor(this, key, param);
+    }
+
+    public String absoluteUrlFor(Object key, Object param) {
+        return getResolvedUri().resolve(urlFor(key, param)).toString();
+    }
+
+    private static final Set<Property> properties = 
+      ImmutableSet.copyOf(Property.values());
+    public Iterator<Property> iterator() {
+      return properties.iterator();
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractCollectionAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,226 @@
+/*
+ * 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.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.abdera2.common.text.UrlEncoding;
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+/**
+ * Base CollectionAdapter implementation that provides a number of helper 
+ * utility methods for adapter implementations.
+ */
+public abstract class AbstractCollectionAdapter 
+  implements CollectionAdapter, 
+             CollectionInfo {
+
+    private final static Log log = 
+      LogFactory.getLog(AbstractCollectionAdapter.class);
+
+    private String href;
+    private final Map<String, Object> hrefParams = 
+      new HashMap<String, Object>();
+    
+    private final Map<HandlerKey,Function<RequestContext,ResponseContext>> handlers = 
+      new HashMap<HandlerKey,Function<RequestContext,ResponseContext>>();
+
+    private static class HandlerKey implements Serializable {
+      private static final long serialVersionUID = -580349554867112812L;
+      final TargetType type;
+      final String method;
+      HandlerKey(TargetType type, String method) {
+        this.type = type;
+        this.method = method.toUpperCase();
+      }
+      public int hashCode() {
+        return MoreFunctions.genHashCode(1, method,type);
+      }
+      public boolean equals(Object obj) {
+        if (this == obj)
+          return true;
+        if (obj == null)
+          return false;
+        if (getClass() != obj.getClass())
+          return false;
+        HandlerKey other = (HandlerKey) obj;
+        if (method == null) {
+          if (other.method != null)
+            return false;
+        } else if (!method.equals(other.method))
+          return false;
+        if (type == null) {
+          if (other.type != null)
+            return false;
+        } else if (!type.equals(other.type))
+          return false;
+        return true;
+      }
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected synchronized <X extends AbstractCollectionAdapter>X putHandler(
+      TargetType targetType,
+      String method,
+      Function<RequestContext,ResponseContext> handler) {
+        HandlerKey key = new HandlerKey(targetType,method);
+        handlers.put(key, handler);
+        return (X)this;
+    }
+    
+    public AbstractCollectionAdapter(String href) {
+        super();
+        putHandler(TargetType.TYPE_CATEGORIES, "GET", NOT_FOUND);
+        putHandler(TargetType.TYPE_CATEGORIES, "HEAD", NOT_FOUND);
+        setHref(href);
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    private void setHref(String href) {
+        this.href = href;
+        if (href != null)
+          hrefParams.put("collection", href);
+    }
+
+    public String getHref(RequestContext request) {
+        return request.urlFor("feed", hrefParams);
+    }
+
+    public abstract String getAuthor(
+      RequestContext request) 
+        throws ResponseContextException;
+
+    public abstract String getId(
+      RequestContext request);
+
+    /**
+     * Creates the ResponseContext for a HEAD entry request. By default, an EmptyResponseContext is returned. The Etag
+     * header will be set.
+     */
+    protected ResponseContext buildHeadEntryResponse(
+      RequestContext request, 
+      String id, 
+      DateTime updated)
+        throws ResponseContextException {
+        return new EmptyResponseContext(200)
+          .setEntityTag(
+            EntityTag.generate(
+              id, 
+              DateTimes.format(updated)));
+    }
+
+    /**
+     * Create a ResponseContext (or take it from the Exception) for an exception that occurred in the application.
+     * 
+     * @param e
+     * @return
+     */
+    protected ResponseContext createErrorResponse(
+      ResponseContextException e) {
+        ExceptionHelper.responseLog(log,e);
+        return e.getResponseContext();
+    }
+
+    /**
+     * Get's the name of the specific resource requested
+     */
+    protected String getResourceName(RequestContext request) {
+        String path = request.getTargetPath();
+        int q = path.indexOf("?");
+        if (q != -1) {
+            path = path.substring(0, q);
+        }
+        String[] segments = path.split("/");
+        String id = segments[segments.length - 1];
+        return UrlEncoding.decode(id);
+    }
+
+    protected String[] getMethods(RequestContext request) {
+        return ProviderHelper.getDefaultMethods(request);
+    }
+
+    private static final Predicate<HandlerKey> COLLECTION_POST_CHECK = 
+      new Predicate<HandlerKey>() {
+        public boolean apply(HandlerKey input) {
+          return input.method.equalsIgnoreCase("POST") && 
+                 input.type == TargetType.TYPE_COLLECTION;
+        }
+    };
+    
+    public Function<RequestContext,ResponseContext> handlerFor(
+      Target target, 
+      String method) {
+        HandlerKey key = new HandlerKey(target.getType(),method);
+        Function<RequestContext,ResponseContext> handler = handlers.get(key);
+        return handler != null ?
+          handler :
+          COLLECTION_POST_CHECK.apply(key) ? // if this is a post to a collection, and the handler is null
+            UNSUPPORTED_TYPE :               // return an unsupported_type reponse since POST is always 
+            NOT_ALLOWED;                     // allowed on the collection
+    }
+    
+    protected final Function<RequestContext,ResponseContext> UNSUPPORTED_TYPE = 
+      new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          return ProviderHelper.notsupported(input);
+        }
+    };
+    
+    protected final Function<RequestContext,ResponseContext> NOT_ALLOWED =
+      new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          return ProviderHelper.notallowed(input,getMethods(input));
+        }
+    };
+    
+    protected final Function<RequestContext,ResponseContext> NOT_FOUND = 
+      new Function<RequestContext,ResponseContext>() {
+        public ResponseContext apply(RequestContext input) {
+          return ProviderHelper.notfound(input);
+        }
+    };
+    
+    public final static Predicate<RequestContext> HAS_NO_ENTITY = 
+      new Predicate<RequestContext>() {
+        public boolean apply(RequestContext input) {
+          String method = input.getMethod();
+          return method.equalsIgnoreCase("GET") ||
+                 method.equalsIgnoreCase("DELETE") ||
+                 method.equalsIgnoreCase("HEAD") ||
+                 method.equalsIgnoreCase("OPTIONS");
+        }
+    };
+    
+    public Predicate<RequestContext> acceptable() {
+      return HAS_NO_ENTITY;
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractMessage.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractMessage.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractMessage.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractMessage.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,110 @@
+/*
+ * 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 javax.activation.MimeType;
+
+import org.apache.abdera2.common.http.CacheControl;
+import org.apache.abdera2.common.http.Preference;
+import org.apache.abdera2.common.http.WebLink;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.text.Codec;
+import org.apache.abdera2.common.text.UrlEncoding;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+
+import static com.google.common.base.Preconditions.*;
+/**
+ * Root impl for Message interface impls. This is provided solely as a way of keeping the interface and impl's
+ * consistent across the Request and Response objects.
+ */
+public abstract class AbstractMessage 
+  implements Message {
+
+    public <T>T getHeader(String name, Function<String,T> transform) {
+      checkNotNull(transform);
+      return transform.apply(getHeader(name));
+    }
+    
+    public <T>Iterable<T> getHeaders(String name, Function<String,T> transform) {
+      Iterable<Object> objs = this.getHeaders(name);
+      ImmutableList.Builder<T> list = ImmutableList.builder();
+      for (Object obj : objs)
+        list.add(transform.apply(obj.toString()));
+      return list.build();
+    }
+  
+    public CacheControl getCacheControl() {
+      return getHeader("Cache-Control", CacheControl.parser);
+    }
+
+    public String getContentLanguage() {
+      return getHeader("Content-Language");
+    }
+
+    public IRI getContentLocation() {
+      return getHeader("Content-Location", IRI.parser);
+    }
+
+    public MimeType getContentType() {
+      return getHeader("Content-Type", MimeTypeHelper.parser);
+    }
+
+    private static final Function<String,String> DEC = 
+      Functions.<String,String,String>compose(
+        UrlEncoding.decoder(),
+        Codec.decode());
+    
+    public String getDecodedHeader(String header) {
+      return getHeader(
+        header, 
+        DEC);
+    }
+
+    public Iterable<String> getDecodedHeaders(String header) {
+      return getHeaders(header, DEC);
+    }
+
+    public String getSlug() {
+      return getDecodedHeader("Slug");
+    }
+
+    public Iterable<WebLink> getWebLinks() {
+      ImmutableList.Builder<WebLink> links = ImmutableList.builder();
+      Iterable<Object> headers = this.getHeaders("Link");      
+      for (Object obj : headers)
+        links.addAll(
+          WebLink.parse(
+            obj.toString()));
+      return links.build();
+    }
+    
+    public Iterable<Preference> getPrefer() {
+      ImmutableList.Builder<Preference> links = ImmutableList.builder();
+      Iterable<Object> headers = this.getHeaders("Prefer");
+      for (Object obj : headers)
+        links.addAll(
+          Preference.parse(
+             obj.toString()));
+      return links.build();
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractProvider.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,197 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.misc.Task;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import static java.util.Collections.unmodifiableMap;
+import static com.google.common.collect.Iterables.*;
+import static org.apache.abdera2.common.protocol.ProviderHelper.*;
+
+/**
+ * Base Provider implementation that provides the core implementation details for all Providers. This class provides the
+ * basic request routing logic.
+ */
+@SuppressWarnings({"unchecked","rawtypes"})
+public abstract class AbstractProvider
+  implements Provider {
+
+    private final static Log log = LogFactory.getLog(AbstractProvider.class);
+    protected Map<String, Object> properties;
+    protected Set<Task<RequestContext,ResponseContext>> filters = 
+      new LinkedHashSet<Task<RequestContext,ResponseContext>>();
+    protected Map<TargetType, Function<CollectionAdapter,? extends RequestProcessor>> requestProcessors = 
+      new HashMap<TargetType, Function<CollectionAdapter,? extends RequestProcessor>>();
+
+    public void init(Map<String,Object> properties) {
+      this.properties = properties != null ? properties : new HashMap<String,Object>();
+    }
+
+    public String getProperty(String name) {
+        return (String)properties.get(name);
+    }
+
+    public Iterable<String> getPropertyNames() {
+        return properties.keySet();
+    }
+
+    public Subject resolveSubject(RequestContext request) {
+        Function<Request,Subject> subjectResolver = getSubjectResolver(request);
+        return subjectResolver != null ? subjectResolver.apply(request) : null;
+    }
+
+    public Target resolveTarget(RequestContext request) {
+        Function<RequestContext,Target> targetResolver = getTargetResolver(request);
+        return targetResolver != null ? targetResolver.apply(request) : null;
+    }
+
+    public String urlFor(Request request, Object key, Object param) {
+        TargetBuilder tm = getTargetBuilder(request);
+        return tm != null ? tm.urlFor(request, key, param) : null;
+    }
+
+    protected Function<Request,Subject> getSubjectResolver(RequestContext request) {
+        return new SimpleSubjectResolver();
+    }
+
+    protected abstract TargetBuilder getTargetBuilder(Request request);
+
+    protected abstract Function<RequestContext,Target> getTargetResolver(RequestContext request);
+
+    public ResponseContext apply(RequestContext request) {
+      Target target = request.getTarget();
+      if (Target.NOT_FOUND.apply(target))
+          return notfound(request);
+      TargetType type = target.getType();
+      log.debug(String.format(
+        "Processing [%s] request for Target [%s] of Type [%s]",
+        request.getMethod(),
+        target.getIdentity(),
+        type.toString()));
+      CollectionAdapter adapter = 
+        getWorkspaceManager()
+          .getCollectionAdapter(request);
+      if (adapter == null && type != TargetType.TYPE_SERVICE)
+        return notfound(request);
+      RequestProcessor processor = 
+        requestProcessors
+          .get(type)
+          .apply(adapter);
+      if (processor == null)
+        return notfound(request);
+      Chain<RequestContext,ResponseContext> chain = 
+        Chain.<RequestContext,ResponseContext>make()
+        .to(processor)
+        .via(getFilters(request))
+        .get();
+      ResponseContext response = null;
+      try {
+        response = chain.apply(request);
+      } catch (Throwable t) {
+        response = createErrorResponse(request, t);
+      }
+      return response != null ? 
+        response : 
+        badrequest(request);
+    }
+
+    /**
+     * Subclass to customize the kind of error response to return
+     */
+    protected ResponseContext createErrorResponse(RequestContext request, Throwable e) {
+      return servererror(request, e);
+    }
+
+    protected abstract WorkspaceManager getWorkspaceManager();
+
+    public void setFilters(Collection<Task<RequestContext,ResponseContext>> filters) {
+      this.filters = new LinkedHashSet<Task<RequestContext,ResponseContext>>(filters);
+    }
+
+    public Iterable<Task<RequestContext,ResponseContext>> getFilters(RequestContext request) {
+      return unmodifiableIterable(filters);
+    }
+
+    public void addFilter(Task<RequestContext,ResponseContext>... filters) {
+      for (Task<RequestContext,ResponseContext> filter : filters)
+        this.filters.add(filter);
+    }
+
+    public void setRequestProcessors(
+      Map<
+        TargetType, 
+        Function<
+          CollectionAdapter,
+          ? extends RequestProcessor>> 
+            requestProcessors) {
+        requestProcessors.clear();
+        requestProcessors.putAll(requestProcessors);
+    }
+
+    public void addRequestProcessor(
+      TargetType type, 
+      Class<? extends RequestProcessor> _class, 
+      Predicate<RequestContext> predicate,
+      WorkspaceManager workspaceManager) {
+        requestProcessors.put(
+          type, 
+          RequestProcessor.forClass(
+            _class,
+            workspaceManager,
+            predicate));
+    }
+    
+    public void addRequestProcessor(
+        TargetType type, 
+        Class<? extends RequestProcessor> _class,
+        WorkspaceManager workspaceManager) {
+          requestProcessors.put(
+            type, 
+            RequestProcessor.forClass(
+              _class,
+              workspaceManager));
+    }
+    
+    public void addRequestProcessors(
+      Map<
+        TargetType, 
+        Function<
+          CollectionAdapter,
+          ? extends RequestProcessor>> 
+            requestProcessors) {
+        this.requestProcessors.putAll(requestProcessors);
+    }
+
+    public Map<TargetType, Function<CollectionAdapter,? extends RequestProcessor>> getRequestProcessors() {
+        return unmodifiableMap(this.requestProcessors);
+    }
+    
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractRequest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractRequest.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractRequest.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractRequest.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,62 @@
+/*
+ * 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.http.Authentication;
+import org.apache.abdera2.common.http.EntityTag;
+import org.joda.time.DateTime;
+
+public abstract class AbstractRequest extends AbstractMessage implements Request {
+
+    public String getAccept() {
+        return getHeader("Accept");
+    }
+
+    public String getAcceptCharset() {
+        return getHeader("Accept-Charset");
+    }
+
+    public String getAcceptEncoding() {
+        return getHeader("Accept-Encoding");
+    }
+
+    public String getAcceptLanguage() {
+        return getHeader("Accept-Language");
+    }
+
+    public Iterable<Authentication> getAuthentication() {
+      return getHeader("Authorization", Authentication.parser);
+    }
+    
+    public Iterable<EntityTag> getIfMatch() {
+      return getHeader("If-Match", EntityTag.parseMultiple);
+    }
+
+    public DateTime getIfModifiedSince() {
+        return getDateHeader("If-Modified-Since");
+    }
+
+    public Iterable<EntityTag> getIfNoneMatch() {
+      return getHeader("If-None-Match", EntityTag.parseMultiple);
+    }
+
+    public DateTime getIfUnmodifiedSince() {
+        return getDateHeader("If-Unmodified-Since");
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponse.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponse.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponse.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponse.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.common.protocol;
+
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.http.Authentication;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.http.ResponseType;
+import org.joda.time.DateTime;
+
+public abstract class AbstractResponse extends AbstractMessage implements Response {
+  
+    public long getAge() {
+      return getHeader("Age", MoreFunctions.parseLong);
+    }
+
+    public String getAllow() {
+        return getHeader("Allow");
+    }
+
+    public long getContentLength() {
+      return getHeader("Content-Length", MoreFunctions.parseLong);
+    }
+
+    public EntityTag getEntityTag() {
+      return getHeader("ETag", EntityTag.parser);
+    }
+
+    public DateTime getExpires() {
+        return getDateHeader("Expires");
+    }
+
+    public DateTime getLastModified() {
+        return getDateHeader("Last-Modified");
+    }
+
+    public IRI getLocation() {
+      return getHeader("Location",IRI.parser);
+    }
+
+    public ResponseType getType() {
+      return ResponseType.select(getStatus());
+    }
+
+    public Iterable<Authentication> getAuthentication() {
+      return getHeader("WWW-Authenticate", Authentication.parser);
+  }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponseContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponseContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractResponseContext.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,295 @@
+/*
+ * 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.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.activation.MimeType;
+
+
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.text.Codec;
+import org.apache.abdera2.common.text.UrlEncoding;
+import org.apache.abdera2.common.text.CharUtils.Profile;
+import org.apache.abdera2.common.http.CacheControl;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.http.Preference;
+import org.apache.abdera2.common.http.WebLink;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.joda.time.DateTime;
+
+import com.google.common.collect.Iterables;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractResponseContext extends AbstractResponse implements ResponseContext {
+
+    protected static final String[] EMPTY = new String[0];
+
+    protected int status = 0;
+    protected String status_text = null;
+    protected boolean binary = false;
+
+    protected final Map<String, Iterable<Object>> headers = 
+      new HashMap<String,Iterable<Object>>();
+
+    public <T extends ResponseContext>T setBinary(boolean binary) {
+        this.binary = binary;
+        return (T)this;
+    }
+
+    public boolean isBinary() {
+        return binary;
+    }
+
+    public <T extends ResponseContext>T setCacheControl(CacheControl cc) {
+      return (T)setCacheControl(cc.toString());
+    }
+    
+    public <T extends ResponseContext>T setCacheControl(String cc) {
+      return (T)this.setHeader("Cache-Control", cc);
+    }
+    
+    public <T extends ResponseContext>T removeHeader(String name) {
+        headers.remove(name);
+        return (T)this;
+    }
+
+    public <T extends ResponseContext>T setEncodedHeader(String name, String charset, String value) {
+        return (T)setHeader(name, Codec.encode(value, charset));
+    }
+
+    public <T extends ResponseContext>T setEncodedHeader(String name, String charset, String... vals) {
+        String[] evals = 
+          MoreFunctions.<String,String>each(
+            vals, Codec.encodeStar(charset), String.class);
+        return (T)setHeader(name, (Object[])evals);
+    }
+
+    public <T extends ResponseContext>T setEscapedHeader(String name, Profile profile, String value) {
+        return (T)setHeader(name, UrlEncoding.encode(value, profile));
+    }
+
+    public <T extends ResponseContext>T setHeader(String name, Object value) {
+        return (T)setHeader(name, new Object[] {value});
+    }
+
+    public <T extends ResponseContext>T setHeader(String name, Object... vals) {
+        Set<Object> values = new HashSet<Object>();
+        values.addAll(Arrays.asList(vals));
+        headers.put(name, values);
+        return (T)this;
+    }
+
+    public <T extends ResponseContext>T addEncodedHeader(String name, String charset, String value) {
+        return (T)addHeader(name, Codec.encode(value, charset));
+    }
+
+    public <T extends ResponseContext>T addEncodedHeaders(String name, String charset, String... vals) {
+      String[] evals = MoreFunctions.<String,String>each(vals, Codec.encodeStar(charset),String.class);
+      addHeaders(name,(Object[])evals);
+      return (T)this;
+    }
+
+    public <T extends ResponseContext>T addHeader(String name, Object value) {
+        return (T)addHeaders(name, new Object[] {value});
+    }
+
+    public <T extends ResponseContext>T addHeaders(String name, Object... vals) {
+        Iterable<Object> values = headers.get(name);
+        Set<Object> l = 
+          values == null ? 
+            new HashSet<Object>() :
+            (Set<Object>)values;
+        l.addAll(Arrays.asList(vals));
+        headers.put(name, l);
+        return (T)this;
+    }
+
+    public Map<String, Iterable<Object>> getHeaders() {
+        return headers;
+    }
+
+    public DateTime getDateHeader(String name) {
+        Iterable<Object> values = headers.get(name);
+        if (values != null) {
+            for (Object value : values) {
+                if (value instanceof Date)
+                    return new DateTime(value);
+                else if (value instanceof DateTime)
+                    return (DateTime)value;
+                else if (value instanceof Long)
+                    return new DateTime((Long)value);
+                else if (value instanceof String)
+                    return new DateTime(value);
+                else if (value instanceof Calendar)
+                    return new DateTime(value);
+            }
+        }
+        return null;
+    }
+
+    private Object getFirst(Iterable<Object> i, Object def) {
+      if (i == null) return def;
+      return Iterables.getFirst(i, def);
+    }
+    
+    public String getHeader(String name) {
+      Iterable<Object> values = headers.get(name);
+      Object obj = getFirst(values,null);
+      return obj != null ? obj.toString() : null;
+    }
+
+    public Iterable<Object> getHeaders(String name) {
+        return headers.get(name);
+    }
+
+    public Iterable<String> getHeaderNames() {
+        return headers.keySet();
+    }
+
+    public <T extends ResponseContext>T setAge(long age) {
+        return (T)(age <= -1 ? 
+          removeHeader("Age") : 
+            setHeader("Age", String.valueOf(age)));
+    }
+
+    public <T extends ResponseContext>T setContentLanguage(String language) {
+        return (T)(language == null ? 
+          removeHeader("Content-Language") : 
+          setHeader("Content-Language", language));
+    }
+
+    public <T extends ResponseContext>T setContentLength(long length) {
+        return (T)(length <= -1 ? 
+          removeHeader("Content-Length") : 
+          setHeader("Content-Length", String.valueOf(length)));
+    }
+
+    public <T extends ResponseContext>T setContentLocation(String uri) {
+        return (T)(uri == null ? 
+          removeHeader("Content-Location") : 
+          setHeader("Content-Location", uri));
+    }
+
+    public <T extends ResponseContext>T setSlug(String slug) {
+        if (slug == null)
+            return (T)removeHeader("Slug");
+        if (slug.indexOf((char)10) > -1 || 
+            slug.indexOf((char)13) > -1)
+          throw new IllegalArgumentException(
+            Localizer.get("SLUG.BAD.CHARACTERS"));
+        return (T)setEscapedHeader(
+          "Slug", 
+          Profile.PATHNODELIMS, slug);
+    }
+
+    public <T extends ResponseContext>T setContentType(String type) {
+        return (T)setContentType(type, null);
+    }
+
+    public <T extends ResponseContext>T setContentType(String type, String charset) {
+        if (type == null)
+            return (T)removeHeader("Content-Type");
+        MimeType mimeType = MimeTypeHelper.unmodifiableMimeType(type);
+        if (charset != null)
+            mimeType.setParameter("charset", charset);
+        return (T)setHeader("Content-Type", mimeType.toString());
+    }
+
+    public <T extends ResponseContext>T setEntityTag(String etag) {
+        return (T)(etag != null ? 
+          setEntityTag(new EntityTag(etag)) : 
+          removeHeader("ETag"));
+    }
+
+    public <T extends ResponseContext>T setEntityTag(EntityTag etag) {
+        return (T)(etag == null ? 
+          removeHeader("ETag") : 
+          setHeader("ETag", etag.toString()));
+    }
+
+    public <T extends ResponseContext>T setExpires(DateTime date) {
+        return (T)(date == null ? 
+          removeHeader("Expires") : 
+          setHeader("Expires", date));
+    }
+
+    public <T extends ResponseContext>T setLastModified(DateTime date) {
+        return (T)(date == null ? 
+          removeHeader("Last-Modified") : 
+          setHeader("Last-Modified", date));
+    }
+
+    public <T extends ResponseContext>T setLocation(String uri) {
+        return (T)(uri == null ? 
+          removeHeader("Location") : 
+          setHeader("Location", uri));
+    }
+    public <T extends ResponseContext>T setLocation(IRI iri) {
+      return (T)setLocation(iri == null ? null : iri.toString());
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public <T extends ResponseContext>T setStatus(int status) {
+        this.status = status;
+        return (T)this;
+    }
+
+    public String getStatusText() {
+        return status_text;
+    }
+
+    public <T extends ResponseContext>T setStatusText(String text) {
+        this.status_text = text;
+        return (T)this;
+    }
+
+    public <T extends ResponseContext>T setAllow(String method) {
+        return (T)setHeader("Allow", method);
+    }
+
+    public <T extends ResponseContext>T setAllow(String... methods) {
+        StringBuilder buf = new StringBuilder();
+        for (String method : methods) {
+            if (buf.length() > 0)
+                buf.append(", ");
+            buf.append(method);
+        }
+        return (T)setAllow(buf.toString());
+    }
+
+    public <T extends ResponseContext>T setWebLinks(WebLink link, WebLink... links) {
+      return (T)setHeader("Link", WebLink.toString(link,links));
+    }
+    
+    public <T extends ResponseContext>T setPrefer(Preference pref, Preference... prefs) {
+      return (T)setHeader("Prefer", Preference.toString(pref,prefs));
+    }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractServiceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractServiceManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractServiceManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractServiceManager.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.common.protocol;
+
+import java.util.Map;
+
+import org.apache.abdera2.common.protocol.servlet.async.DefaultProcessor;
+import org.apache.abdera2.common.protocol.servlet.async.DefaultTaskExecutor;
+import org.apache.abdera2.common.protocol.servlet.async.ProcessorQueue;
+import org.apache.abdera2.common.protocol.servlet.async.TaskExecutor;
+import org.apache.abdera2.common.pusher.ChannelManager;
+import org.apache.abdera2.common.pusher.SimpleChannelManager;
+import static org.apache.abdera2.common.misc.MoreFunctions.*;
+
+/**
+ * The ServiceManager is used by the AbderaServlet to bootstrap the server 
+ * instance. There should be little to no reason why an end user would 
+ * need to use this class directly.
+ */
+public abstract class AbstractServiceManager 
+  implements ServiceManager {
+
+    protected AbstractServiceManager() {}
+
+    public ProcessorQueue newProcessorQueue(
+      Map<String, Object> properties) {    
+        return discoverInitializable(
+          ProcessorQueue.class,
+          DefaultProcessor.class)
+            .apply(properties);
+    }
+    
+    public TaskExecutor newTaskExecutor(
+      Map<String, Object> properties) {  
+        return discoverInitializable(
+            TaskExecutor.class,
+            DefaultTaskExecutor.class)
+              .apply(properties);
+    }
+    
+    public ChannelManager newChannelManager(
+      Map<String, Object> properties) {
+        return discoverInitializable(
+            ChannelManager.class,
+            SimpleChannelManager.class)
+              .apply(properties);
+    }
+    
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceManager.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.common.protocol;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.http.EntityTag;
+import org.joda.time.DateTime;
+
+/**
+ * Base implementation for WorkspaceManager implementations
+ */
+public abstract class AbstractWorkspaceManager 
+  implements WorkspaceManager {
+
+    protected final Set<WorkspaceInfo> workspaces = 
+      new LinkedHashSet<WorkspaceInfo>();
+    public static final String COLLECTION_ADAPTER_ATTRIBUTE = "collectionProvider";
+
+    public synchronized Collection<WorkspaceInfo> getWorkspaces(RequestContext request) {
+        return workspaces;
+    }
+
+    public synchronized void setWorkspaces(Collection<WorkspaceInfo> workspaces) {
+        this.workspaces.clear();
+        this.workspaces.addAll(workspaces);
+    }
+
+    public synchronized void addWorkspace(WorkspaceInfo workspace) {
+        workspaces.add(workspace);
+    }
+    
+    public DateTime getLastModified() {
+      return DateTimes.utcNow();
+    }
+    
+    public EntityTag getEntityTag() { 
+      return null;
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceManager.java
------------------------------------------------------------------------------
    svn:executable = *

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/common/protocol/AbstractWorkspaceProvider.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,88 @@
+/*
+ * 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 java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.http.EntityTag;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Function;
+
+/**
+ * An abstract base Provider implementation that implements the 
+ * WorkspaceManager interface. This is intended to be used by 
+ * Provider's that do not wish to use a separate WorkspaceManager object.
+ */
+public abstract class AbstractWorkspaceProvider
+  extends AbstractProvider 
+  implements WorkspaceManager {
+
+    protected Function<RequestContext,Target> targetResolver;
+    protected TargetBuilder<?> targetBuilder;
+    protected final Set<WorkspaceInfo> workspaces = 
+      new LinkedHashSet<WorkspaceInfo>();
+
+    protected WorkspaceManager getWorkspaceManager() {
+      return this;
+    }
+
+    protected Function<RequestContext,Target> getTargetResolver(
+      RequestContext request) {
+      return targetResolver;
+    }
+
+    @SuppressWarnings("rawtypes")
+    protected TargetBuilder getTargetBuilder(Request request) {
+        return (TargetBuilder)targetBuilder;
+    }
+
+    protected void setTargetBuilder(TargetBuilder<?> targetBuilder) {
+        this.targetBuilder = targetBuilder;
+    }
+
+    protected void setTargetResolver(Function<RequestContext,Target> targetResolver) {
+        this.targetResolver = targetResolver;
+    }
+
+    public synchronized Collection<WorkspaceInfo> getWorkspaces(RequestContext request) {
+        return workspaces;
+    }
+
+    public synchronized void setWorkspaces(Collection<WorkspaceInfo> workspaces) {
+      workspaces.clear();
+      workspaces.addAll(workspaces);
+    }
+    
+    public synchronized void addWorkspace(WorkspaceInfo workspace) {
+        workspaces.add(workspace);
+    }
+
+    // JIRA: https://issues.apache.org/jira/browse/ABDERA-255
+    public EntityTag getEntityTag() {
+      return null;
+    }
+    
+    // JIRA: https://issues.apache.org/jira/browse/ABDERA-255
+    public DateTime getLastModified() {
+      return DateTimes.utcNow();
+    }
+}

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



Mime
View raw message