abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r1239237 [9/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/protocol/server/provider/managed/FeedConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/FeedConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/FeedConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/FeedConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,249 @@
+/*
+ * 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.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.model.Collection;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+
+import com.google.common.base.Supplier;
+
+public class FeedConfiguration 
+  extends Configuration 
+  implements AtompubCollectionInfo {
+    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> {
+
+      private String feedId;
+      private String subUri;
+      private String adapterClassName;
+      private String feedConfigLocation;
+      private ServerConfiguration serverConfiguration;
+      private String feedTitle = "unknown";
+      private String feedAuthor = "unknown";
+      private final Map<Object, Object> optionalProperties = 
+        new HashMap<Object,Object>();
+      private 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 Map<Object, Object> optionalProperties = 
+      new HashMap<Object,Object>();
+    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.putAll(gen.optionalProperties);
+      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 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 : getCategoriesInfo(request)) {
+            collection.addCategories(catsinfo.asCategoriesElement(request));
+        }
+        return collection;
+    }
+
+    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/atom+xml;type=entry"};
+        else arr = ((String)accepts).split("\\s*,\\s*");
+        return Arrays.asList(arr);
+    }
+
+    public Iterable<AtompubCategoriesInfo> getCategoriesInfo(RequestContext request) {
+        return Collections.<AtompubCategoriesInfo>emptySet();
+    }
+
+    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/protocol/server/provider/managed/FeedConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedCollectionAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,56 @@
+/*
+ * 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.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContextException;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubCollectionAdapter;
+
+public abstract class ManagedCollectionAdapter 
+  extends AbstractAtompubCollectionAdapter {
+
+    protected final FeedConfiguration config;
+    protected final Abdera abdera;
+
+    protected ManagedCollectionAdapter(Abdera abdera, FeedConfiguration config) {
+      super(null);
+        this.config = config;
+        this.abdera = abdera;
+    }
+
+    public Abdera getAbdera() {
+        return this.abdera;
+    }
+
+    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/protocol/server/provider/managed/ManagedCollectionAdapter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/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.protocol.server.provider.managed;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubWorkspaceProvider;
+
+/**
+ * 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 AbstractAtompubWorkspaceProvider {
+  
+    protected abstract ServerConfiguration getServerConfiguration(RequestContext request);
+
+    protected ManagedProvider() {
+        addWorkspace(new ManagedWorkspace(this));
+    }
+
+    public CollectionAdapterManager getCollectionAdapterManager(RequestContext request) {
+      return new CollectionAdapterManager(abdera, getServerConfiguration(request));
+  }
+
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedWorkspace.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedWorkspace.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedWorkspace.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ManagedWorkspace.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.provider.managed;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.CollectionInfo;
+import org.apache.abdera2.model.Workspace;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+import org.apache.abdera2.protocol.server.model.AtompubWorkspaceInfo;
+
+public class ManagedWorkspace implements AtompubWorkspaceInfo {
+
+    private final ManagedProvider provider;
+
+    private String title = "Abdera";
+
+    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 (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return collections;
+    }
+    
+    public String getTitle(RequestContext request) {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Workspace asWorkspaceElement(RequestContext request) {
+        Workspace workspace = AbstractAtompubProvider.getAbdera(request).getFactory().newWorkspace();
+        workspace.setTitle(getTitle(null));
+        for (CollectionInfo c : getCollections(request)) {
+            AtompubCollectionInfo collection = (AtompubCollectionInfo) c;
+            workspace.addCollection(collection.asCollectionElement(request));
+        }
+        return workspace;
+    }
+}

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

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ServerConfiguration.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ServerConfiguration.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ServerConfiguration.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/provider/managed/ServerConfiguration.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.provider.managed;
+
+public abstract class ServerConfiguration extends Configuration {
+
+    public abstract int getPort();
+
+    public abstract String getServerUri();
+
+    public abstract String getFeedNamespace();
+
+    public abstract String getFeedNamespacePrefix();
+
+    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/protocol/server/provider/managed/ServerConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/test/pom.xml
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/pom.xml?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/pom.xml (added)
+++ abdera/abdera2-server/test/pom.xml Wed Feb  1 17:54:54 2012
@@ -0,0 +1,113 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.abdera2</groupId>
+    <artifactId>abdera2</artifactId>
+    <version>2.0-SNAPSHOT</version>  
+  </parent>  
+
+  <artifactId>abdera2-test</artifactId>
+  <packaging>bundle</packaging>
+  <name>Abdera2 Tests</name>
+  <version>2.0-SNAPSHOT</version>  
+  <description>Abdera Tests</description>
+
+  <properties>
+    <topDir>${basedir}/..</topDir> 
+  </properties>
+
+  <build>
+  <testSourceDirectory>src/main/java</testSourceDirectory>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-core</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-common</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-server</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-client</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-security</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-activities</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-ext</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.easymock</groupId>
+        <artifactId>easymock</artifactId>
+    </dependency> 
+    
+    <dependency>
+      <groupId>xalan</groupId>
+      <artifactId>xalan</artifactId>
+      <version>2.7.1</version>
+      <scope>test</scope>
+    </dependency>
+       
+  </dependencies>
+</project>

Propchange: abdera/abdera2-server/test/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/AbderaTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/AbderaTest.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/AbderaTest.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/AbderaTest.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,30 @@
+package org.apache.abdera2.test;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.writer.StreamWriter;
+import org.junit.Test;
+
+public class AbderaTest {
+
+  @Test
+  public void abderaTest() {
+    Abdera abdera = Abdera.getInstance();
+    assertNotNull(abdera);
+    assertNotNull(abdera.getConfiguration());
+    assertNotNull(abdera.getFactory());
+    assertNotNull(abdera.getParser());
+    assertNotNull(abdera.getParserFactory());
+    assertNotNull(abdera.getWriter());
+    assertNotNull(abdera.getWriterFactory());
+    assertNotNull(abdera.getXPath());
+    assertNotNull(abdera.newCategories());
+    assertNotNull(abdera.newEntry());
+    assertNotNull(abdera.newError());
+    assertNotNull(abdera.newFeed());
+    assertNotNull(abdera.newService());
+    assertNotNull(abdera.create(StreamWriter.class));
+  }
+  
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/JettyUtil.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/JettyUtil.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/JettyUtil.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/JettyUtil.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,93 @@
+/*
+ * 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.test;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+public class JettyUtil {
+
+    private static final String PORT_PROP = "abdera.test.client.port";
+
+    private static int PORT = 9002;
+    private static Server server = null;
+    private static ServletContextHandler handler = null;
+
+    public static int getPort() {
+        if (System.getProperty(PORT_PROP) != null) {
+            PORT = Integer.parseInt(System.getProperty(PORT_PROP));
+        }
+        return PORT;
+    }
+
+    public static void initServer() throws Exception {
+        server = new Server(getPort());      
+        handler = 
+          new ServletContextHandler(ServletContextHandler.SESSIONS);
+        handler.setContextPath("/");
+        server.setHandler(handler);
+    }
+
+    public static ServletContextHandler getSch() {
+      return (ServletContextHandler) server.getHandler();
+    }
+    
+    public static void addServlet(String _class, String path) {
+        try {
+            if (server == null)
+                initServer();
+        } catch (Exception e) {
+        }
+        handler.addServlet(_class, path);
+    }
+    
+    public static void addServlet(ServletHolder holder, String path) {
+      try {
+        if (server == null)
+          initServer();
+      } catch (Exception e) {
+        
+      }
+      handler.addServlet(holder, path);
+    }
+    
+    public static void setContextPath(String path) {
+      handler.setContextPath(path);
+    }
+
+    public static void start() throws Exception {
+        if (server == null)
+            initServer();
+        if (server.isRunning())
+            return;
+        server.start();
+    }
+
+    public static void stop() throws Exception {
+        if (server == null)
+            return;
+        server.stop();
+        server = null;
+    }
+
+    public static boolean isRunning() {
+        return (server != null);
+    }
+
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/AsyncBasicTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/AsyncBasicTest.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/AsyncBasicTest.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/AsyncBasicTest.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,121 @@
+package org.apache.abdera2.test.activities.server;
+/*
+ * 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.
+ */
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.abdera2.activities.client.ActivityEntity;
+import org.apache.abdera2.activities.model.ASObject;
+import org.apache.abdera2.activities.model.Activity;
+import org.apache.abdera2.activities.model.Collection;
+import org.apache.abdera2.activities.model.IO;
+import org.apache.abdera2.activities.model.Verb;
+import org.apache.abdera2.activities.model.objects.NoteObject;
+import org.apache.abdera2.activities.model.objects.PersonObject;
+import org.apache.abdera2.common.http.ResponseType;
+import org.apache.abdera2.protocol.client.BasicClient;
+import org.apache.abdera2.protocol.client.Client;
+import org.apache.abdera2.protocol.client.ClientResponse;
+import org.apache.abdera2.protocol.client.Session;
+import org.apache.abdera2.test.server.JettyServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class AsyncBasicTest {
+
+    private static JettyServer server;
+    private static Client client = new BasicClient();
+    private static IO io = IO.get();
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        if (server == null) {
+            server = new JettyServer();
+            server.startAsync(
+              BasicActivitiesServiceManager.class,
+              new TestChannelServlet());
+        }
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+      try {
+         Thread.sleep(20 * 1000);
+      } catch (Throwable t) {}
+        client.shutdown();
+        server.stop();
+    }
+
+    @Test
+    public void testGetFeed() throws IOException {
+        Session session = client.newSession();
+        ClientResponse resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        assertEquals("http://localhost:9002/sample", coll.getProperty("id").toString());
+        assertEquals("title for any sample feed", coll.getProperty("title"));
+        PersonObject person = coll.getProperty("author");
+        assertNotNull(person);
+        assertEquals("rayc", person.getDisplayName());
+        resp.release();
+    }
+ 
+    @Test
+    public void testPostEntry() throws IOException {
+      
+        try {
+          Thread.sleep(20 * 1000);
+        } catch (Throwable t) {}
+      
+        Activity activity = 
+          Activity.makeActivity()
+           .id("http://localhost:9002/sample/foo")
+           .title("test entry")
+           .verb(Verb.POST)
+           .publishedNow()
+           .actor(PersonObject.makePerson().displayName("James").get())
+           .object(NoteObject.makeNote().content("Test Content").get())
+           .get();
+        Session session = client.newSession();
+        ActivityEntity ae = new ActivityEntity(activity);
+        ClientResponse resp = session.post("http://localhost:9002/sample", ae);
+        assertNotNull(resp);
+        assertEquals(ResponseType.SUCCESSFUL, resp.getType());
+        assertEquals(201, resp.getStatus());
+        assertEquals("http://localhost:9002/sample/foo", resp.getLocation().toString());
+        resp.release();
+        resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        Iterable<ASObject> items = coll.getItems();
+        int n = 0;
+        for (ASObject obj : items) {
+          assertTrue(obj instanceof Activity);
+          activity = (Activity) obj;
+          assertEquals(Verb.POST, activity.getVerb());
+          n++;
+        }
+        assertEquals(1, n);
+        resp.release();
+    }
+
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicActivitiesServiceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicActivitiesServiceManager.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicActivitiesServiceManager.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicActivitiesServiceManager.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,21 @@
+package org.apache.abdera2.test.activities.server;
+
+import java.util.Map;
+
+import org.apache.abdera2.activities.protocol.ActivitiesServiceManager;
+import org.apache.abdera2.activities.protocol.basic.BasicProvider;
+import org.apache.abdera2.common.protocol.Provider;
+
+public class BasicActivitiesServiceManager 
+  extends ActivitiesServiceManager {
+
+  public BasicActivitiesServiceManager() {}
+  
+  @SuppressWarnings("unchecked")
+  public <P extends Provider> P newProvider(Map<String, Object> properties) {
+    BasicProvider bp = new BasicProvider();
+    bp.init(properties);
+    return (P)bp;
+  }
+
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicTest.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicTest.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/BasicTest.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,197 @@
+package org.apache.abdera2.test.activities.server;
+/*
+ * 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.
+ */
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.abdera2.activities.client.ActivityEntity;
+import org.apache.abdera2.activities.model.ASObject;
+import org.apache.abdera2.activities.model.Activity;
+import org.apache.abdera2.activities.model.Activity.ActivityBuilder;
+import org.apache.abdera2.activities.model.Collection.CollectionBuilder;
+
+import static org.apache.abdera2.activities.model.ASBase.withoutFields;
+import org.apache.abdera2.activities.model.Collection;
+import org.apache.abdera2.activities.model.IO;
+import org.apache.abdera2.activities.model.Verb;
+import org.apache.abdera2.activities.model.objects.NoteObject;
+import org.apache.abdera2.activities.model.objects.PersonObject;
+import org.apache.abdera2.protocol.client.BasicClient;
+import org.apache.abdera2.protocol.client.Client;
+import org.apache.abdera2.protocol.client.ClientResponse;
+import org.apache.abdera2.protocol.client.Session;
+import org.apache.abdera2.test.server.JettyServer;
+import org.apache.abdera2.common.Constants;
+import org.apache.abdera2.common.http.ResponseType;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BasicTest {
+
+    private static JettyServer server;
+    private static Client client = new BasicClient();
+    private static IO io = IO.get();
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        if (server == null) {
+            server = new JettyServer();
+            server.start(BasicActivitiesServiceManager.class);
+        }
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        client.shutdown();
+        server.stop();
+    }
+
+    @Test
+    public void testGetFeed() throws IOException {
+        Session session = client.newSession();
+        ClientResponse resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        assertEquals("http://localhost:9002/sample", coll.getProperty("id").toString());
+        assertEquals("title for any sample feed", coll.getProperty("title"));
+        PersonObject person = coll.getProperty("author");
+        assertNotNull(person);
+        assertEquals("rayc", person.getDisplayName());
+        resp.release();
+    }
+
+    @Test
+    public void testPostEntry() throws IOException {
+      Activity activity = 
+        Activity.makeActivity()
+         .id("http://localhost:9002/sample/foo")
+         .title("test entry")
+         .verb(Verb.POST)
+         .publishedNow()
+         .actor(PersonObject.makePerson().displayName("James").get())
+         .object(NoteObject.makeNote().content("Test Content").get())
+         .get();
+        Session session = client.newSession();
+        ActivityEntity ae = new ActivityEntity(activity);
+        ClientResponse resp = session.post("http://localhost:9002/sample", ae);
+        assertNotNull(resp);
+        assertEquals(ResponseType.SUCCESSFUL, resp.getType());
+        assertEquals(201, resp.getStatus());
+        assertEquals("http://localhost:9002/sample/foo", resp.getLocation().toString());
+        resp.release();
+        resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        Iterable<ASObject> items = coll.getItems();
+        int n = 0;
+        for (ASObject obj : items) {
+          assertTrue(obj instanceof Activity);
+          activity = (Activity) obj;
+          assertEquals(Verb.POST, activity.getVerb());
+          assertEquals("test entry", activity.getTitle());
+          n++;
+        }
+        assertEquals(1, n);
+        resp.release();
+    }
+
+    @Test
+    public void testPutEntry()  throws IOException {
+        Session session = client.newSession();
+        ClientResponse resp = session.get("http://localhost:9002/sample/foo");
+        assertTrue(MimeTypeHelper.isMatch(resp.getContentType().toString(), Constants.JSON_MEDIA_TYPE));
+        ASObject object = io.readObject(resp.getReader());
+        resp.release();
+        assertTrue(object instanceof Activity);
+        Activity activity = (Activity) object;
+        activity = 
+          activity.<Activity,ActivityBuilder>template(withoutFields("title"))
+            .title("This is the modified title")
+            .get();
+        ActivityEntity ae = new ActivityEntity(activity);
+        resp = session.put("http://localhost:9002/sample/foo", ae);
+        assertEquals(ResponseType.SUCCESSFUL, resp.getType());
+        assertEquals(200, resp.getStatus());
+        resp.release();
+        resp = session.get("http://localhost:9002/sample/foo");
+        object = io.readObject(resp.getReader());
+        resp.release();
+        assertTrue(object instanceof Activity);
+        activity = (Activity) object;
+        assertEquals("This is the modified title", activity.getTitle());
+        resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        Iterable<ASObject> items = coll.getItems();
+        int n = 0;
+        for (ASObject obj : items) {
+          assertTrue(obj instanceof Activity);
+          activity = (Activity) obj;
+          assertEquals(Verb.POST, activity.getVerb());
+          n++;
+        }
+        assertEquals(1, n);
+        resp.release();
+    }
+
+    @Test
+    public void testDeleteEntry() throws IOException {
+      Session session = client.newSession();
+        ClientResponse resp = session.delete("http://localhost:9002/sample/foo");
+        assertEquals(ResponseType.SUCCESSFUL, resp.getType());
+        resp.release();
+        resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        coll.getItems();
+        resp.release();
+    }
+    
+    @SuppressWarnings("unused")
+    @Test
+    public void testMultiPostEntry() throws IOException {
+        CollectionBuilder<Activity> builder = Collection.makeCollection();
+        for (int n = 0; n < 10; n++)
+          builder.item(
+            Activity.makeActivity()
+             .id("http://localhost:9002/sample/foo" + n)
+             .title("test entry "+n)
+             .verb(Verb.POST)
+             .publishedNow()
+             .actor(PersonObject.makePerson().displayName("James").get())
+             .object(NoteObject.makeNote().content("Test Content "+n).get())
+             .get());
+        Session session = client.newSession();
+        ActivityEntity ae = new ActivityEntity(builder.get());
+        ClientResponse resp = session.post("http://localhost:9002/sample", ae);
+        assertNotNull(resp);
+        assertEquals(ResponseType.SUCCESSFUL, resp.getType());
+        assertEquals(201, resp.getStatus());
+        resp.release();
+        resp = session.get("http://localhost:9002/sample");
+        Collection<ASObject> coll = io.readCollection(resp.getReader());
+        Iterable<ASObject> items = coll.getItems();
+        int n = 0;
+        for (ASObject obj : items) n++;
+        assertEquals(10, n);
+        resp.release();
+    }
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/SampleBasicAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/SampleBasicAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/SampleBasicAdapter.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/SampleBasicAdapter.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,165 @@
+package org.apache.abdera2.test.activities.server;
+/*
+ * 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.
+ */
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.abdera2.activities.model.ASBase;
+import org.apache.abdera2.activities.model.ASObject;
+import org.apache.abdera2.activities.model.Collection.CollectionBuilder;
+import org.apache.abdera2.activities.protocol.basic.BasicAdapter;
+import org.apache.abdera2.activities.protocol.managed.FeedConfiguration;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContextException;
+
+public class SampleBasicAdapter extends BasicAdapter {
+
+    private static final String ERROR_INVALID_ENTRY = "No Such Entry in the Feed";
+
+    public final static Logger logger = Logger.getLogger(SampleBasicAdapter.class.getName());
+    protected List<Item> entries = new LinkedList<Item>();
+
+    private static class Item {
+      private final String key;
+      private ASObject value;
+      Item(String key, ASObject value) {
+        this.key = key;
+        this.value = value;
+      }
+      String getKey() {
+        return key;
+      }
+      ASObject getValue() {
+        return value;
+      }
+      void setValue(ASObject value) {
+        this.value = value;
+      }
+    }
+    
+    public SampleBasicAdapter(FeedConfiguration config) {
+        super(config);
+    }
+
+    @Override
+    public CollectionBuilder<ASObject> getCollection() throws Exception {
+        CollectionBuilder<ASObject> col = createCollection();
+        for (Item item : entries)
+          col.item(item.getValue());
+        return col;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public ASObject.Builder<ASObject,?> getItem(Object entryId) throws Exception {
+      ASObject ret = null;
+      for (Item item : entries)
+        if (item.getKey().equals(entryId.toString())) {
+          ret = item.getValue();
+          break;
+        }
+      if (ret == null) return null;
+      return ret.<ASObject,ASObject.Builder>template();
+    }
+
+    @Override
+    public <T extends ASObject>ASObject.Builder<T,?> createItem(ASObject object) throws Exception {
+        return createItem(object,-1);
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public <T extends ASObject>ASObject.Builder<T,?> createItem(ASObject object, int c) throws Exception {
+      ASObject.Builder<T, ?> builder = object.<ASObject,ASObject.Builder>template(ASBase.withoutFields("editLink","updated"));
+      if (!object.has("id"))
+        setObjectId(builder);
+      logger.info("assigning id to Object: " + object.getId().toString());
+      String entryId = getObjectIdFromUri(object.getId().toString());
+      if (c != -1) entryId += c;
+      builder.updatedNow();
+      addEditLinkToObject(builder,object.getId());
+      storeObject(entryId, object);
+      logger.finest("returning this object from sampleadapter.createItem: " + object.toString());
+      return builder;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public <T extends ASObject>ASObject.Builder<T,?> updateItem(Object entryId, ASObject object) throws Exception {
+        if (!deleteItem(entryId))
+            throw new Exception(ERROR_INVALID_ENTRY);
+        ASObject.Builder<T, ?> builder = object.<ASObject,ASObject.Builder>template(ASBase.withoutFields("editLink","updated"));
+        builder.updatedNow();
+        addEditLinkToObject(builder,object.getId());
+        storeObject((String)entryId, builder.get());
+        logger.finest("returning this entry from sampleadapter.updateEntry: " + object.toString());
+        return builder;
+    }
+
+    @Override
+    public boolean deleteItem(Object entryId) throws Exception {
+      Item item = null;
+      for (Item i : entries) {
+        if (i.getKey().equals(entryId.toString())) {
+          item = i;
+          break;
+        }
+      }
+      if (item != null) {
+        entries.remove(item);
+        return true;
+      } else return false;
+    }
+
+    protected String getObjectIdFromUri(String uri) {
+        String[] segments = uri.split("/");
+        return segments[segments.length - 1];
+    }
+
+    protected void storeObject(String entryId, ASObject object) throws Exception {
+      Item item = null;
+      for (Item i : entries) {
+        if (i.getKey().equals(entryId)) {
+          item = i;
+          break;
+        }
+      }
+      if (item == null) { 
+        entries.add(0,new Item(entryId,object));
+      } else {
+        item.setValue(object);
+      }
+    }
+
+    @Override
+    public String getAuthor(RequestContext request) throws ResponseContextException {
+        return config.getFeedAuthor();
+    }
+
+    @Override
+    public String getId(RequestContext request) {
+        return config.getFeedId();
+    }
+
+    @Override
+    public String getTitle(RequestContext request) {
+        return config.getFeedTitle();
+    }
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/TestChannelServlet.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/TestChannelServlet.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/TestChannelServlet.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/activities/server/TestChannelServlet.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,43 @@
+package org.apache.abdera2.test.activities.server;
+
+import java.io.Writer;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.activities.model.ASObject;
+import org.apache.abdera2.activities.model.IO;
+import org.apache.abdera2.common.protocol.servlet.async.AbderaChannelServlet;
+
+public class TestChannelServlet 
+  extends AbderaChannelServlet {
+
+  private static final long serialVersionUID = 4020428773015858214L;
+
+  protected String getChannel(AsyncContext context) {
+    HttpServletRequest req = (HttpServletRequest) context.getRequest();
+    String pi = req.getPathInfo();
+    return pi.substring(pi.lastIndexOf('/')+1);
+  }
+
+  @Override
+  protected AsyncListener<ASObject> createListener(final AsyncContext context) {
+    return new AsyncListener<ASObject>(context) {
+
+      public void beforeItems() {}
+      protected void finish() {}
+      public void onItem(ASObject t) {
+        try {
+          HttpServletResponse response = 
+            (HttpServletResponse) context.getResponse();
+          Writer writer = response.getWriter();
+          IO.get().write(t,writer);
+          response.flushBuffer();
+          context.complete(); // close out the request, make the user come back for more
+        } catch (Throwable e) {}
+      }
+    };
+  }
+
+}

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

Added: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/client/AppTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/client/AppTest.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/client/AppTest.java (added)
+++ abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/client/AppTest.java Wed Feb  1 17:54:54 2012
@@ -0,0 +1,713 @@
+/*
+ * 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.test.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimeType;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.factory.Factory;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.model.Collection;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Feed;
+import org.apache.abdera2.model.Service;
+import org.apache.abdera2.model.Workspace;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.parser.ParserOptions;
+import org.apache.abdera2.protocol.client.AbderaClient;
+import org.apache.abdera2.protocol.client.AbderaClientResponse;
+import org.apache.abdera2.protocol.client.AbderaSession;
+import org.apache.abdera2.protocol.client.RequestOptions;
+import org.apache.abdera2.common.http.CacheControl;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.test.JettyUtil;
+import org.apache.abdera2.writer.WriterOptions;
+import org.joda.time.DateTime;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test to make sure that we can operate as a simple APP client
+ */
+@SuppressWarnings("serial")
+public class AppTest {
+
+    protected static void getServletHandler(String... servletMappings) {
+        for (int n = 0; n < servletMappings.length; n = n + 2) {
+            String name = servletMappings[n];
+            String root = servletMappings[n + 1];
+            JettyUtil.addServlet(name, root);
+        }
+    }
+
+    protected String getBase() {
+        return "http://localhost:" + JettyUtil.getPort();
+    }
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        getServletHandler();
+        JettyUtil.start();
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        JettyUtil.stop();
+    }
+
+    private static Abdera abdera = Abdera.getInstance();
+
+    private static Factory getFactory() {
+        return abdera.getFactory();
+    }
+
+    private static Parser getParser() {
+        return abdera.getParser();
+    }
+
+    private static AppTest INSTANCE = null;
+
+    private static Document<Service> init_service_document(String base) {
+        try {
+            Service service = getFactory().newService();
+            Workspace workspace = service.addWorkspace("Test");
+            workspace.addCollection("Entries", base + "/collections/entries").setAcceptsEntry();
+            workspace.addCollection("Other", base + "/collections/other").setAccept("text/plain");
+            Document<Service> doc = service.getDocument();
+            return doc;
+        } catch (Exception e) {
+        }
+        return null;
+    }
+
+    private static Document<Feed> init_entries_document(String base) {
+        try {
+            Feed feed = getFactory().newFeed();
+            feed.setId(base + "/collections/entries");
+            feed.setTitle("Entries");
+            feed.setUpdated(DateTime.now());
+            feed.addLink(base + "/collections/entries");
+            feed.addLink(base + "/collections/entries", "self");
+            feed.addAuthor("James");
+            Document<Feed> doc = feed.getDocument();
+            return doc;
+        } catch (Exception e) {
+        }
+        return null;
+    }
+
+    public static class ServiceDocumentServlet extends HttpServlet {
+        private Document<Service> service = init_service_document(AppTest.INSTANCE.getBase());
+
+        @Override
+        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
+
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType("application/atomsvc+xml; charset=utf-8");
+            WriterOptions options = service.makeDefaultWriterOptions()
+              .charset("UTF-8").get();
+            service.writeTo(response.getOutputStream(), options);
+        }
+    }
+
+    /**
+     * this implements a very simple (and quite buggy) APP server. It's just enough for us to test the client behaviors.
+     * I'm sure it could be greatly improved.
+     */
+    public static class CollectionServlet extends HttpServlet {
+        protected Document<Feed> feed = init_entries_document(AppTest.INSTANCE.getBase());
+        protected Map<String, String> media = new HashMap<String, String>();
+
+        private String[] tokens = null;
+        private final static int COLLECTION = 0;
+        private final static int ENTRY = 1;
+        private final static int MEDIA = 2;
+
+        private int getTargetType(HttpServletRequest request) {
+            tokens = request.getRequestURI().split("/");
+            if (tokens[2].equals("entries") && tokens.length == 3)
+                return COLLECTION;
+            if (tokens[2].equals("entries") && tokens.length == 4)
+                return ENTRY;
+            if (tokens[2].equals("media") && tokens.length == 4)
+                return MEDIA;
+            return -1;
+        }
+
+        private int getTarget() {
+            return (tokens.length != 4) ? -1 : Integer.parseInt(tokens[3]);
+        }
+
+        @Override
+        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
+            int t = getTargetType(request);
+            switch (t) {
+                case COLLECTION:
+                    response.setStatus(HttpServletResponse.SC_OK);
+                    response.setContentType("application/atom+xml; charset=utf-8");
+                    WriterOptions options = feed.makeDefaultWriterOptions()
+                    .charset("UTF-8").get();
+                    feed.writeTo(response.getOutputStream(), options);
+                    break;
+                case ENTRY:
+                    try {
+                        Entry entry = feed.getRoot().getEntries().get(getTarget());
+                        response.setStatus(HttpServletResponse.SC_OK);
+                        response.setContentType("application/atom+xml; charset=utf-8");
+                        options = entry.makeDefaultWriterOptions()
+                        .charset("UTF-8").get();
+                        entry.writeTo(response.getOutputStream(), options);
+                    } catch (Exception e) {
+                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                        break;
+                    }
+                    break;
+                case MEDIA:
+                    try {
+                        String m = media.get(AppTest.INSTANCE.getBase() + "/collections/entries/" + getTarget());
+                        if (m != null) {
+                            response.setStatus(HttpServletResponse.SC_OK);
+                            response.setContentType("text/plain");
+                            response.getWriter().write(m);
+                            break;
+                        } else {
+                            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                        }
+                    } catch (Exception e) {
+                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                    }
+            }
+        }
+
+        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
+            int t = getTargetType(request);
+            switch (t) {
+                case COLLECTION:
+                    try {
+                        if (MimeTypeHelper.isMatch(request.getContentType(), "application/atom+xml;type=entry")) {
+                            MimeType type = new MimeType(request.getContentType());
+                            String charset = type.getParameter("charset");
+                            String uri = AppTest.INSTANCE.getBase() + "/collections/entries";
+                            ParserOptions options = 
+                              getParser().makeDefaultParserOptions()
+                               .charset(charset).get();
+                            Document<?> doc = getParser().parse(request.getInputStream(), uri, options);
+                            if (doc.getRoot() instanceof Entry) {
+                                Entry entry = (Entry)doc.getRoot().clone();
+                                String newID =
+                                    AppTest.INSTANCE.getBase() + "/collections/entries/"
+                                        + feed.getRoot().getEntries().size();
+                                entry.setId(newID);
+                                entry.setUpdated(DateTime.now());
+                                entry.addLink(entry.getId().toString(), "edit");
+                                entry.addLink(entry.getId().toString(), "self");
+                                feed.getRoot().insertEntry(entry);
+                                response.setStatus(HttpServletResponse.SC_CREATED);
+                                response.setHeader("Location", entry.getId().toString());
+                                response.setHeader("Content-Location", entry.getId().toString());
+                                WriterOptions woptions = entry.makeDefaultWriterOptions()
+                                .charset("UTF-8").get();
+                                entry.writeTo(response.getOutputStream(), woptions);
+                                return;
+                            }
+                        }
+                        if (MimeTypeHelper.isMatch(request.getContentType(), "text/plain")) {
+                            int n = feed.getRoot().getEntries().size();
+                            String media = read(request.getInputStream());
+                            Entry entry = getFactory().newEntry();
+                            String newID = AppTest.INSTANCE.getBase() + "/collections/entries/" + n;
+                            String slug = request.getHeader("Slug");
+                            entry.setId(newID);
+                            entry.setTitle(slug);
+                            entry.setUpdated(DateTime.now());
+                            entry.setSummary(slug);
+                            entry.addLink(entry.getId().toString(), "edit");
+                            entry.addLink(AppTest.INSTANCE.getBase() + "/collections/media/" + n, "edit-media")
+                                .setMimeType("text/plain");
+                            entry.addLink(entry.getId().toString(), "self");
+                            entry.setContent(new IRI(AppTest.INSTANCE.getBase() + "/collections/media/" + n),
+                                             "text/plain");
+                            feed.getRoot().insertEntry(entry);
+                            this.media.put(entry.getId().toString(), media);
+                            response.setStatus(HttpServletResponse.SC_CREATED);
+                            response.setHeader("Location", entry.getId().toString());
+                            response.setHeader("Content-Location", entry.getId().toString());
+                            WriterOptions woptions = entry.makeDefaultWriterOptions()
+                              .charset("UTF-8").get();
+                            entry.writeTo(response.getOutputStream(), woptions);
+                            return;
+                        }
+                        response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+                    } catch (Exception e) {
+                    }
+                    break;
+                default:
+                    response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            }
+        }
+
+        protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
+            int t = getTargetType(request);
+            int target = getTarget();
+            switch (t) {
+                case ENTRY:
+                    try {
+                        if (MimeTypeHelper.isMatch(request.getContentType(), "application/atom+xml;type=entry")) {
+                            Entry entry = feed.getRoot().getEntries().get(target);
+                            MimeType type = new MimeType(request.getContentType());
+                            String charset = type.getParameter("charset");
+                            String uri = AppTest.INSTANCE.getBase() + "/collections/entries/" + target;
+                            ParserOptions options = 
+                              getParser().makeDefaultParserOptions()
+                                .charset(charset).get();
+                            Document<?> doc = getParser().parse(request.getInputStream(), uri, options);
+                            if (doc.getRoot() instanceof Entry) {
+                                Entry newentry = (Entry)doc.getRoot().clone();
+                                if (newentry.getId().equals(entry.getId())) {
+                                    newentry.setUpdated(DateTime.now());
+                                    entry.discard();
+                                    feed.getRoot().insertEntry(newentry);
+                                    response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                                    return;
+                                } else {
+                                    response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Cannot change atom:id");
+                                    return;
+                                }
+                            }
+                        }
+                        response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+                    } catch (Exception e) {
+                    }
+                    break;
+                case MEDIA:
+                    if (MimeTypeHelper.isMatch(request.getContentType(), "text/plain")) {
+                        String uri = AppTest.INSTANCE.getBase() + "/collections/entries/" + target;
+                        String media = read(request.getInputStream());
+                        this.media.put(uri, media);
+                        Entry entry = feed.getRoot().getEntries().get(target);
+                        entry.setUpdated(DateTime.now());
+                        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                        return;
+                    }
+                    response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+                    break;
+                default:
+                    response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            }
+        }
+
+        protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+            IOException {
+            int t = getTargetType(request);
+            int target = getTarget();
+            switch (t) {
+                case ENTRY:
+                case MEDIA:
+                    String uri = AppTest.INSTANCE.getBase() + "/collections/entries/" + target;
+                    Entry entry = feed.getRoot().getEntries().get(target);
+                    entry.discard();
+                    media.remove(uri);
+                    response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                    return;
+                default:
+                    response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            }
+        }
+    }
+
+    private static String read(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int m = -1;
+        while ((m = in.read()) != -1) {
+            out.write(m);
+        }
+        String resp = new String(out.toByteArray());
+        return resp.trim();
+    }
+
+    public AppTest() {
+        AppTest.INSTANCE = this;
+    }
+
+    protected static void getServletHandler() {
+        getServletHandler(ServiceDocumentServlet.class.getName(),
+                          "/service",
+                          CollectionServlet.class.getName(),
+                          "/collections/*");
+    }
+
+    @Test
+    public void testRequestOptions() throws Exception {
+
+        RequestOptions options = 
+          RequestOptions.make()
+            .ifModifiedSinceNow()
+            .requestException4xx()
+            .requestException5xx()
+            .usePostOverride()
+            .accept("text/plain")
+            .acceptCharset("UTF-8")
+            .acceptEncoding("gzip")
+            .acceptLanguage("en-US")
+            .cacheControl("no-cache")
+            .contentType("text/plain")
+            .encodedHeader("foo", "UTF-8", "bar")
+            .header("foo", "bar")
+            .ifMatch("testing")
+            .ifNoneMatch("testing")
+            .slug("This is the slug")
+            .get();
+
+        assertTrue(options.isUsePostOverride());
+        assertEquals("This is the slug", options.getSlug());
+        assertTrue(EntityTag.matchesAny(new EntityTag("testing"), options.getIfNoneMatch()));
+        assertTrue(EntityTag.matchesAny(new EntityTag("testing"), options.getIfMatch()));
+        assertEquals("bar", options.getHeader("foo"));
+        assertEquals("bar", options.getDecodedHeader("foo"));
+        assertTrue(MimeTypeHelper.isMatch(options.getContentType(), new MimeType("text/plain")));
+        CacheControl cc = options.getCacheControl();
+        assertTrue(cc.isNoCache());
+        assertEquals("en-US", options.getAcceptLanguage());
+        assertEquals("gzip", options.getAcceptEncoding());
+        assertEquals("UTF-8", options.getAcceptCharset());
+        assertEquals("text/plain", options.getAccept());
+        assertNotNull(options.getIfModifiedSince());
+        assertTrue(options.is4xxRequestException());
+        assertTrue(options.is5xxRequestException());
+
+    }
+
+    @Test
+    public void testAppClient() throws Exception {
+        AbderaClient abderaClient = new AbderaClient();
+        AbderaSession session = (AbderaSession) abderaClient.newSession();
+        Entry entry = getFactory().newEntry();
+        RequestOptions options = 
+          session.getDefaultRequestOptions()
+            .header("Connection", "close")
+            .doNotUseExpectContinue()
+            .get();
+        // do the introspection step
+        AbderaClientResponse response = 
+          (AbderaClientResponse) session.get(
+            "http://localhost:" + JettyUtil.getPort() + "/service", options);
+        String col_uri;
+
+        try {
+            assertEquals(200, response.getStatus());
+
+            Document<Service> service_doc = response.getDocument();
+            assertNotNull(service_doc);
+            assertEquals(1, service_doc.getRoot().getWorkspaces().size());
+
+            Workspace workspace = service_doc.getRoot().getWorkspace("Test");
+            assertNotNull(workspace);
+
+            for (Collection c : workspace.getCollections()) {
+                assertNotNull(c.getTitle());
+                assertNotNull(c.getHref());
+            }
+
+            col_uri = getBase() + "/collections/entries";
+        } finally {
+            response.release();
+        }
+
+        // post a new entry
+        response = (AbderaClientResponse) session.post(col_uri, entry, options);
+
+        String self_uri;
+
+        try {
+            assertEquals(201, response.getStatus());
+            assertNotNull(response.getLocation());
+            assertNotNull(response.getContentLocation());
+
+            self_uri = response.getLocation().toString();
+        } finally {
+            response.release();
+        }
+
+        // get the collection to see if our entry is there
+        response = (AbderaClientResponse) session.get(col_uri, options);
+
+        try {
+            assertEquals(200, response.getStatus());
+            Document<Feed> feed_doc = response.getDocument();
+            assertEquals(1, feed_doc.getRoot().getEntries().size());
+        } finally {
+            response.release();
+        }
+
+        // get the entry to see if we can get it
+        response = (AbderaClientResponse) session.get(self_uri, options);
+
+        String edit_uri;
+
+        try {
+            assertEquals(200, response.getStatus());
+            Document<Entry> entry_doc = response.getDocument();
+
+            // this isn't always true, but for our tests they are the same
+            assertEquals(self_uri, entry_doc.getRoot().getId().toString());
+
+            // get the edit uri from the entry
+            edit_uri = entry_doc.getRoot().getEditLink().getHref().toString();
+
+            // change the entry
+            Document<Entry> doc = response.getDocument();
+            entry = (Entry)doc.getRoot().clone();
+            entry.setTitle("New title");
+        } finally {
+            response.release();
+        }
+
+        // submit the changed entry back to the server
+        response = (AbderaClientResponse) session.put(edit_uri, entry, options);
+
+        try {
+            assertEquals(204, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // check to see if the entry was modified properly
+        response = (AbderaClientResponse) session.get(self_uri, options);
+
+        try {
+            assertEquals(200, response.getStatus());
+
+            Document<Entry> entry_doc = response.getDocument();
+            assertEquals("New title", entry_doc.getRoot().getTitle());
+        } finally {
+            response.release();
+        }
+
+        // delete the entry
+        response = (AbderaClientResponse) session.delete(edit_uri, options);
+
+        try {
+            assertEquals(204, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // is it gone?
+        response = (AbderaClientResponse) session.get(self_uri, options);
+
+        try {
+            assertEquals(404, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // YAY! We're a working APP client
+
+        // Now let's try to do a media post
+
+        // Post the media resource
+        options = session.getDefaultRequestOptions()
+          .contentType("text/plain")
+          .header("Connection", "close")
+          .doNotUseExpectContinue()
+          .get();
+
+        response = (AbderaClientResponse) session.post(col_uri, new ByteArrayInputStream("test".getBytes()), options);
+
+        try {
+            assertEquals(201, response.getStatus());
+            assertNotNull(response.getLocation());
+            assertNotNull(response.getContentLocation());
+
+            self_uri = response.getLocation().toString();
+        } finally {
+            response.release();
+        }
+
+        // was an entry created?
+        options = session.getDefaultRequestOptions()
+          .header("Connection", "close").get();
+        response = (AbderaClientResponse) session.get(self_uri, options);
+
+        String edit_media, media;
+
+        try {
+            assertEquals(200, response.getStatus());
+            Document<Entry> entry_doc = response.getDocument();
+
+            // this isn't always true, but for our tests they are the same
+            assertEquals(self_uri, entry_doc.getRoot().getId().toString());
+
+            // get the right links from the entry
+            edit_uri = entry_doc.getRoot().getEditLink().getHref().toString();
+            edit_media = entry_doc.getRoot().getLink("edit-media").getHref().toString();
+            media = entry_doc.getRoot().getContentElement().getSrc().toString();
+
+            // edit the entry
+            Document<Entry> doc = response.getDocument();
+            entry = (Entry)doc.getRoot().clone();
+            entry.setTitle("New title");
+        } finally {
+            response.release();
+        }
+
+        // submit the changes
+        options = session.getDefaultRequestOptions()
+          .contentType("application/atom+xml;type=entry")
+          .header("Connection", "close")
+          .doNotUseExpectContinue().get();
+
+        response = (AbderaClientResponse) session.put(edit_uri, entry, options);
+
+        try {
+            assertEquals(204, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // get the media resource
+        response = (AbderaClientResponse) session.get(media);
+
+        try {
+            assertEquals(200, response.getStatus());
+
+            String mediavalue = read(response.getInputStream());
+            assertEquals("test", mediavalue);
+        } finally {
+            response.release();
+        }
+
+        // edit the media resource
+        options = session.getDefaultRequestOptions()
+          .header("Connection", "close")
+          .contentType("text/plain")
+          .doNotUseExpectContinue()
+          .get();
+
+        response = (AbderaClientResponse) session.put(edit_media, new ByteArrayInputStream("TEST".getBytes()), options);
+
+        try {
+            assertEquals(204, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // was the resource changed?
+        response = (AbderaClientResponse) session.get(media, options);
+
+        try {
+            assertEquals(200, response.getStatus());
+
+            String mediavalue = read(response.getInputStream());
+            assertEquals("TEST", mediavalue);
+        } finally {
+            response.release();
+        }
+
+        // delete the entry
+        response = (AbderaClientResponse) session.delete(edit_uri, options);
+
+        try {
+            assertEquals(204, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // is the entry gone?
+        response = (AbderaClientResponse) session.get(self_uri, options);
+
+        try {
+            assertEquals(404, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // is the media resource gone?
+        options = options.template().cacheControl(CacheControl.NOCACHE()).get();
+
+        response = (AbderaClientResponse) session.get(media, options);
+
+        try {
+            assertEquals(404, response.getStatus());
+        } finally {
+            response.release();
+        }
+
+        // YAY! We can handle media link entries
+        abderaClient.shutdown();
+    }
+
+    private Iterable<EntityTag> i(EntityTag... tags) {
+      List<EntityTag> l = new ArrayList<EntityTag>();
+      for (EntityTag tag : tags)
+        l.add(tag);
+      return l;
+    }
+    
+    @Test
+    public void testEntityTag() throws Exception {
+        EntityTag tag1 = new EntityTag("tag");
+        EntityTag tag2 = new EntityTag("tag", true); // weak;
+        assertFalse(tag1.isWeak());
+        assertTrue(tag2.isWeak());
+        assertFalse(EntityTag.matches(tag1, tag2));
+        assertFalse(EntityTag.matchesAny(tag1, i(tag2)));
+        assertEquals("\"tag\"", tag1.toString());
+        assertEquals("W/\"tag\"", tag2.toString());
+        tag1 = EntityTag.parse("\"tag\"");
+        assertFalse(tag1.isWeak());
+        assertEquals("tag", tag1.getTag());
+        tag2 = EntityTag.parse("W/\"tag\"");
+        assertTrue(tag2.isWeak());
+        assertEquals("tag", tag2.getTag());
+        Iterable<EntityTag> tags = EntityTag.parseTags("\"tag1\", W/\"tag2\"");
+        Iterator<EntityTag> i = tags.iterator();
+        EntityTag tag = i.next();
+        assertFalse(tag.isWeak());
+        assertEquals("tag1", tag.getTag());
+        tag = i.next();
+        assertTrue(tag.isWeak());
+        assertEquals("tag2", tag.getTag());
+    }
+}

Propchange: abdera/abdera2-server/test/src/main/java/org/apache/abdera2/test/client/AppTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message