Author: lresende
Date: Sat Aug  9 09:50:30 2008
New Revision: 684294

URL: http://svn.apache.org/viewvc?rev=684294&view=rev
Log:
TUSCANY-2477 - Applying Dan's patch that addes support for eTag and 
last-modified headers

Added:
    
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
   (with props)
    
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
   (with props)
    
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
   (with props)
Modified:
    tuscany/java/sca/modules/binding-atom-abdera/pom.xml
    
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
    
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java

Modified: tuscany/java/sca/modules/binding-atom-abdera/pom.xml
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/pom.xml?rev=684294&r1=684293&r2=684294&view=diff
==============================================================================
--- tuscany/java/sca/modules/binding-atom-abdera/pom.xml (original)
+++ tuscany/java/sca/modules/binding-atom-abdera/pom.xml Sat Aug  9 09:50:30 
2008
@@ -81,7 +81,7 @@
         <dependency>
             <groupId>org.apache.abdera</groupId>
             <artifactId>abdera-core</artifactId>
-            <version>0.3.0-incubating</version> 
+            <version>0.4.0-incubating</version> 
             <exclusions>
                 <exclusion>
                     <groupId>org.apache.geronimo.specs</groupId>
@@ -93,7 +93,7 @@
         <dependency>
            <groupId>org.apache.abdera</groupId>
             <artifactId>abdera-parser</artifactId>
-            <version>0.3.0-incubating</version>
+            <version>0.4.0-incubating</version>
             <exclusions>
                 <exclusion>
                     <groupId>stax</groupId>
@@ -105,6 +105,12 @@
                 </exclusion>
             </exclusions>
         </dependency>           
+        
+        <dependency>
+            <groupId>org.apache.abdera</groupId>
+            <artifactId>abdera-client</artifactId>
+            <version>0.4.0-incubating</version> 
+        </dependency>            
                 
         <dependency>
             <groupId>javax.servlet</groupId>

Modified: 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java?rev=684294&r1=684293&r2=684294&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
 (original)
+++ 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingInvoker.java
 Sat Aug  9 09:50:30 2008
@@ -86,7 +86,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Get an entry
             String id = (String)((Object[])msg.getBody())[0];
 
@@ -100,7 +99,8 @@
 
                 // Read the Atom entry
                 if (status == 200) {
-                    Document<org.apache.abdera.model.Entry> doc = 
abderaParser.parse(new InputStreamReader(getMethod.getResponseBodyAsStream()));
+                    Document<org.apache.abdera.model.Entry> doc = 
+                       abderaParser.parse(new 
InputStreamReader(getMethod.getResponseBodyAsStream()));
                     parsing = true;
                     org.apache.abdera.model.Entry feedEntry = doc.getRoot();
                     
@@ -148,7 +148,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Post an entry
             Object[] args = (Object[])msg.getBody();
             org.apache.abdera.model.Entry feedEntry;
@@ -173,7 +172,8 @@
                 // Write the Atom entry
                 StringWriter writer = new StringWriter();
                 feedEntry.writeTo(writer);
-                postMethod.setRequestHeader("Content-type", 
"application/atom+xml; charset=utf-8");
+                // postMethod.setRequestHeader("Content-type", 
"application/atom+xml; charset=utf-8");
+                postMethod.setRequestHeader("Content-type", 
"application/atom+xml;type=entry");
                 postMethod.setRequestEntity(new 
StringRequestEntity(writer.toString()));
 
                 httpClient.executeMethod(postMethod);
@@ -228,7 +228,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Put an entry
             Object[] args = (Object[])msg.getBody();
             String id;
@@ -250,6 +249,7 @@
             // Send an HTTP PUT
             PutMethod putMethod = new PutMethod(uri + "/" + id);
             putMethod.setRequestHeader("Authorization", authorizationHeader);
+
             try {
 
                 // Write the Atom entry
@@ -260,7 +260,7 @@
 
                 httpClient.executeMethod(putMethod);
                 int status = putMethod.getStatusCode();
-                if (status == 200 || status == 201) {
+                if (status == 200 || status == 201 || status == 412) {
 
                     msg.setBody(null);
 
@@ -291,7 +291,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Delete an entry
             String id = (String)((Object[])msg.getBody())[0];
 
@@ -331,7 +330,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Get a feed
 
             // Send an HTTP GET
@@ -341,6 +339,7 @@
             try {
                 httpClient.executeMethod(getMethod);
                 int status = getMethod.getStatusCode();
+                // AtomBindingInvoker.printResponseHeader( getMethod );
 
                 // Read the Atom feed
                 if (status == 200) {
@@ -396,7 +395,6 @@
 
         @Override
         public Message invoke(Message msg) {
-
             // Get a feed from a query
             String queryString = (String)((Object[])msg.getBody())[0];
 

Modified: 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java?rev=684294&r1=684293&r2=684294&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
 (original)
+++ 
tuscany/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
 Sat Aug  9 09:50:30 2008
@@ -26,6 +26,8 @@
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.net.URLDecoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.StringTokenizer;
 import java.util.logging.Logger;
 
@@ -37,6 +39,7 @@
 
 import org.apache.abdera.Abdera;
 import org.apache.abdera.factory.Factory;
+import org.apache.abdera.i18n.iri.IRI;
 import org.apache.abdera.model.Collection;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Feed;
@@ -58,7 +61,6 @@
 import org.apache.tuscany.sca.invocation.MessageFactory;
 import org.apache.tuscany.sca.runtime.RuntimeWire;
 
-
 /**
  * A resource collection binding listener, implemented as a Servlet and
  * registered in a Servlet host provided by the SCA hosting runtime.
@@ -71,6 +73,11 @@
 
     private static final Factory abderaFactory = Abdera.getNewFactory();
     private static final Parser abderaParser = Abdera.getNewParser();
+    private static final String ETAG = "ETag";
+    private static final String LASTMODIFIED = "Last-Modified";    
+    private static final String LOCATION = "Location";    
+    private static final String CONTENTLOCATION = "Content-Location";    
+    private static final SimpleDateFormat dateFormat = new SimpleDateFormat( 
"EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
     
     private RuntimeWire wire;
     private Invoker getFeedInvoker;
@@ -248,18 +255,76 @@
                     } else {
                         feed.setTitle("Feed");
                     }
+                    // All feeds must provide Id and updated elements.
+                    // However, some do not, so provide some program 
protection.
+                    feed.setId( "Feed" + feed.hashCode());
+                    Date lastModified = new Date( 0 );
                     
                     // Add entries to the feed
                     for (Entry<Object, Object> entry: collection) {
                         org.apache.abdera.model.Entry feedEntry = 
feedEntry(entry, itemClassType, itemXMLType, mediator, abderaFactory);
+                        // Use the most recent entry update as the feed update
+                        Date entryUpdated = feedEntry.getUpdated();
+                        if (( entryUpdated != null ) && 
(entryUpdated.compareTo( lastModified  ) > 0 ))
+                               lastModified = entryUpdated;
                         feed.addEntry(feedEntry);
                     }
+                    // If no entries were newly updated,
+                    if ( lastModified.compareTo( new Date( 0 ) ) == 0 ) 
+                       lastModified = new Date();
                 }
             }
             if (feed != null) {
+                String feedETag = "\"" + generateFeedETag( feed ) + "\"";
+                Date feedUpdated = feed.getUpdated();
+                // Test request for predicates.
+                String predicate = request.getHeader( "If-Match" );
+                if (( predicate != null ) && ( !predicate.equals(feedETag) )) {
+                       // No match, should short circuit
+                    
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                    return;
+                }
+                predicate = request.getHeader( "If-None-Match" );
+                if (( predicate != null ) && ( predicate.equals(feedETag) )) {
+                       // Match, should short circuit
+                    response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
+                    return;
+                }
+                if ( feedUpdated != null ) {
+                       predicate = request.getHeader( "If-Unmodified-Since" ); 
               
+                       if ( predicate != null ) {
+                               try {
+                                       Date predicateDate = dateFormat.parse( 
predicate ); 
+                                       if ( predicateDate.compareTo( 
feedUpdated ) < 0 ) {
+                                               // Match, should short circuit
+                                               
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
+                                               return;
+                                       }                       
+                               } catch ( java.text.ParseException e ) {
+                                       // Ignore and move on
+                               }
+                       }
+                       predicate = request.getHeader( "If-Modified-Since" );   
             
+                       if ( predicate != null ) {
+                               try {
+                                       Date predicateDate = dateFormat.parse( 
predicate ); 
+                                       if ( predicateDate.compareTo( 
feedUpdated ) > 0 ) {
+                                               // Match, should short circuit
+                                               
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
+                                               return;
+                                       }                       
+                               } catch ( java.text.ParseException e ) {
+                                       // Ignore and move on
+                               }
+                       }
+                }
                 
                 // Write the Atom feed
                 response.setContentType("application/atom+xml; charset=utf-8");
+                // Provide Etag based on Id and time.               
+                response.addHeader(ETAG, feedETag );
+                if ( feedUpdated != null )
+                   response.addHeader(LASTMODIFIED, dateFormat.format( 
feedUpdated ));
                 try {
                          
feed.getDocument().writeTo(response.getOutputStream());
                 } catch (IOException ioe) {
@@ -270,7 +335,6 @@
             }
             
         } else if (path.startsWith("/")) {
-
             // Return a specific entry in the collection
             org.apache.abdera.model.Entry feedEntry;
 
@@ -282,7 +346,6 @@
             if (responseMessage.isFault()) {
                 throw new 
ServletException((Throwable)responseMessage.getBody());
             }
-            
             if (supportsFeedEntries) {
                 // The service implementation returns a feed entry 
                 feedEntry = responseMessage.getBody();
@@ -292,10 +355,26 @@
                 Entry<Object, Object> entry = new Entry<Object, Object>(id, 
responseMessage.getBody()); 
                 feedEntry = feedEntry(entry, itemClassType, itemXMLType, 
mediator, abderaFactory);
             }
-
             // Write the Atom entry
             if (feedEntry != null) {
-                response.setContentType("application/atom+xml; charset=utf-8");
+                IRI feedId = feedEntry.getId();
+                if ( feedId != null )
+                   response.addHeader(ETAG, "\"" + feedId.toString() + "\"" );
+                Date entryUpdated = feedEntry.getUpdated();
+                if ( entryUpdated != null )
+                   response.addHeader(LASTMODIFIED, dateFormat.format( 
entryUpdated ));
+                // TODO Check If-Modified-Since If-Unmodified-Since predicates 
against LASTMODIFIED. 
+                // If true return 304 and null body.            
+                Link link = feedEntry.getSelfLink();
+                if (link != null) {
+                    response.addHeader(LOCATION, link.getHref().toString());
+                } else {
+                   link = feedEntry.getLink( "Edit" );
+                   if (link != null) {
+                      response.addHeader(LOCATION, link.getHref().toString());
+                   }
+                }
+                response.setContentType("application/atom+xml;type=entry");
                 try {
                         feedEntry.writeTo(getWriter(response));
                 } catch (IOException ioe) {
@@ -314,7 +393,6 @@
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse 
response) throws ServletException,
         IOException {
-
         // Authenticate the user
         String user = processAuthorizationHeader(request);
         if (user == null) {
@@ -390,14 +468,25 @@
             if (createdFeedEntry != null) {
 
                 // Set location of the created entry in the Location header
+                IRI feedId = createdFeedEntry.getId();
+                if ( feedId != null )
+                   response.addHeader(ETAG, "\"" + feedId.toString() + "\"" );
+                Date entryUpdated = createdFeedEntry.getUpdated();
+                if ( entryUpdated != null )
+                   response.addHeader(LASTMODIFIED, dateFormat.format( 
entryUpdated ));
                 Link link = createdFeedEntry.getSelfLink();
                 if (link != null) {
-                    response.addHeader("Location", link.getHref().toString());
+                    response.addHeader(LOCATION, link.getHref().toString());
+                } else {
+                   link = createdFeedEntry.getLink( "Edit" );
+                   if (link != null) {
+                      response.addHeader(LOCATION, link.getHref().toString());
+                   }
                 }
 
                 // Write the created Atom entry
                 response.setStatus(HttpServletResponse.SC_CREATED);
-                response.setContentType("application/atom+xml; charset=utf-8");
+                response.setContentType("application/atom+xml;type=entry");
                 try {
                         createdFeedEntry.writeTo(getWriter(response));
                 } catch (ParseException pe) {
@@ -420,7 +509,6 @@
 
     @Override
     protected void doPut(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {
-
         // Authenticate the user
         String user = processAuthorizationHeader(request);
         if (user == null) {
@@ -449,7 +537,6 @@
 
                 // Let the component implementation create it
                 if (supportsFeedEntries) {
-                    
                     // The service implementation supports feed entries, pass 
the entry to it
                     Message requestMessage = messageFactory.createMessage();
                     requestMessage.setBody(new Object[] {id, feedEntry});
@@ -463,7 +550,6 @@
                         }
                     }
                 } else {
-                    
                     // The service implementation does not support feed 
entries, pass the data item to it
                     Message requestMessage = messageFactory.createMessage();
                     Entry<Object, Object> entry = entry(feedEntry, 
itemClassType, itemXMLType, mediator);
@@ -600,4 +686,28 @@
         response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\"");
         response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
     }
+    
+    /**
+     * Generate ETag based on feed Id and updated fields.
+     * @param feed
+     * @return ETag
+     */
+    public static String generateFeedETag( Feed feed ) {
+       if ( feed == null ) {
+               return null; 
+       }
+        
+       IRI feedIdIRI = feed.getId();
+        String feedId = "ID";
+        if ( feedIdIRI != null ) {
+               feedId = feedIdIRI.toString();
+        }
+        
+        Date feedUpdated = feed.getUpdated();
+        if ( feedUpdated == null ) {
+               return feedId;
+        }
+        
+        return feedId + "-" + feedUpdated.hashCode();
+    }
 }

Added: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java?rev=684294&view=auto
==============================================================================
--- 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
 (added)
+++ 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
 Sat Aug  9 09:50:30 2008
@@ -0,0 +1,96 @@
+/*
+ * 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.    
+ */
+package org.apache.tuscany.sca.binding.atom;
+
+import java.io.IOException;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.protocol.client.ClientResponse;
+import org.apache.abdera.protocol.client.RequestOptions;
+import org.apache.abdera.writer.Writer;
+import org.apache.abdera.writer.WriterFactory;
+
+/**
+ * Utilities to help print and test various aspects of entity tag support.
+ */
+public class AtomTestCaseUtils {
+
+    public static void prettyPrint(Abdera abdera, Base doc) throws IOException 
{
+        WriterFactory factory = abdera.getWriterFactory();
+        Writer writer = factory.getWriter("prettyxml");
+        writer.writeTo(doc, System.out);
+        System.out.println();
+       }
+
+    public static void printRequestHeaders( String title, String indent, 
RequestOptions request ) {
+       System.out.println( title );
+       if ( request == null ) {
+               System.out.println( indent + " request is null");
+               return;
+       }
+       String [] headerNames = request.getHeaderNames();
+       for ( String headerName: headerNames) {
+               String header = request.getHeader(headerName);
+              System.out.println( indent + " header name,value=" + headerName 
+ "," + header );        
+       }                                  
+     }
+    
+     public static void printResponseHeaders( String title, String indent, 
ClientResponse response ) {
+       System.out.println( title );
+       if ( response == null ) {
+               System.out.println( indent + " response is null");
+               return;
+       }
+       String [] headerNames = response.getHeaderNames();
+       for ( String headerName: headerNames) {
+           String header = response.getHeader(headerName);
+           System.out.println( indent + " header name,value=" + headerName + 
"," + header );
+       }
+                                  
+     }
+
+       public static Entry newEntry(String value) {
+               Abdera abdera = new Abdera();
+               Entry entry = abdera.newEntry();
+               entry.setTitle("customer " + value);
+
+               Content content = abdera.getFactory().newContent();
+               content.setContentType(Content.Type.TEXT);
+               content.setValue(value);
+               entry.setContentElement(content);
+
+               return entry;
+       }
+
+       public static Entry updateEntry(Entry entry, String value) {
+               Abdera abdera = new Abdera();
+               entry.setTitle("customer " + value);
+
+               Content content = abdera.getFactory().newContent();
+               content.setContentType(Content.Type.TEXT);
+               content.setValue(value);
+               entry.setContentElement(content);
+
+               return entry;
+       }               
+       
+}

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/AtomTestCaseUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java?rev=684294&view=auto
==============================================================================
--- 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
 (added)
+++ 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
 Sat Aug  9 09:50:30 2008
@@ -0,0 +1,436 @@
+/*
+ * 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.    
+ */
+package org.apache.tuscany.sca.binding.atom;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.tuscany.sca.binding.atom.collection.Collection;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.protocol.Response.ResponseType;
+import org.apache.abdera.protocol.client.AbderaClient;
+import org.apache.abdera.protocol.client.ClientResponse;
+import org.apache.abdera.protocol.client.RequestOptions;
+import org.apache.abdera.protocol.client.util.BaseRequestEntity;
+import org.apache.abdera.util.EntityTag;
+import org.apache.abdera.parser.Parser;
+
+/**
+ * Tests use of server provided entry entity tags for Atom binding in Tuscany.
+ * Tests conditional gets (e.g. get if-none-match) or conditional posts (post 
if-match)
+ * using entity tags or last modified header entries. 
+ * Uses the SCA provided Provider composite to act as a server.
+ * Uses the Abdera provided Client to act as a client.
+ */
+public class ProviderEntryEntityTagsTest {
+       public final static String providerURI = 
"http://localhost:8084/customer";;
+       protected static SCADomain scaConsumerDomain;
+       protected static SCADomain scaProviderDomain;
+       protected static CustomerClient testService;
+    protected static Abdera abdera;
+    protected static AbderaClient client;
+    protected static Parser abderaParser;    
+    protected static String eTag;
+    protected static Date lastModified;
+    protected static final SimpleDateFormat dateFormat = new SimpleDateFormat( 
"EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
+
+       @BeforeClass
+       public static void init() throws Exception {
+               System.out.println(">>>ProviderEntryEntityTagsTest.init");
+               scaProviderDomain = 
SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Provider.composite");
+               abdera = new Abdera();
+               client = new AbderaClient(abdera);
+               abderaParser = Abdera.getNewParser();
+       }
+
+       @AfterClass
+       public static void destroy() throws Exception {
+               System.out.println(">>>ProviderEntryEntityTagsTest.destroy");
+               scaProviderDomain.close();
+       }
+
+       @Test
+       public void testPrelim() throws Exception {
+               Assert.assertNotNull(scaProviderDomain);
+               Assert.assertNotNull( client );
+       }
+       
+    @Test
+       public void testEmptyCachePost() throws Exception {
+               // Pseudo-code
+               // 1) Example HTTP POST request (new entry put, new etag 
response)
+               // User client post request       
+               //        POST /myblog/entries HTTP/1.1
+               //        Slug: First Post
+               //        
+               //        <?xml version="1.0" ?>
+               //        <entry xmlns="http://www.w3.org/2005/Atom";>
+               //          <title>Atom-Powered Robots Run Amok</title>
+               //          
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+               //          <updated>2007-02-123T17:09:02Z</updated>
+               //          <author><name>Captain Lansing</name></author>
+               //          <content>It's something moving... solid 
metal</content>
+               //        </entry>
+
+               // Expected Atom server response (note unique ETag)
+               //       HTTP/1.1 201 Created
+               //       Date: Fri, 23 Feb 2007 21:17:11 GMT
+               //       Content-Length: nnn
+               //       Content-Type: application/atom+xml;type=entry
+               //       Location: http://example.org/edit/first-post.atom
+               //       Content-Location: 
http://example.org/edit/first-post.atom
+               //       ETag: "e180ee84f0671b1"
+               //       Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500
+               // 
+               //        <?xml version="1.0" ?>
+               //        <entry xmlns="http://www.w3.org/2005/Atom";>
+               //          <title>Atom-Powered Robots Run Amok</title>
+               //          
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+               //          <updated>2007-02-123T17:09:02Z</updated>
+               //          <author><name>Captain Lansing</name></author>
+               //          <content>It's something moving... solid 
metal</content>
+               //        </entry>              
+               
+               // Testing of entry creation
+               Factory factory = abdera.getFactory();
+               String customerName = "Fred Farkle";
+               Entry entry = factory.newEntry();
+               entry.setTitle("customer " + customerName);
+               entry.setUpdated(new Date());
+               entry.addAuthor("Apache Tuscany");
+               // ID created by collection.
+        // entry.setId(id); // auto-provided
+        // entry.addLink("" + id, "edit"); // auto-provided
+        // entry.addLink("" + id, "alternate"); // auto-provided
+               Content content = abdera.getFactory().newContent();
+               content.setContentType(Content.Type.TEXT);
+               content.setValue(customerName);
+               entry.setContentElement(content);
+
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               // AtomTestCaseUtils.printRequestHeaders( "Post request 
headers", "   ", opts );
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               ClientResponse res = client.post(colUri.toString(), entry, 
opts);
+               
+           // Assert response status code is 201-OK.
+               // Assert response header Content-Type: application/atom+xml; 
charset=UTF-8
+               // Assert response header Location: 
http://example.org/edit/first-post.atom
+               // Assert response header Content-Location: 
http://example.org/edit/first-post.atom
+               // Assert response header ETag: "e180ee84f0671b1"
+               // Assert response header Last-Modified: Fri, 25 Jul 2008 
14:36:44 -0500            
+           // Assert collection size is 1.
+       Assert.assertEquals(201, res.getStatus());
+       Assert.assertEquals(contentType, 
res.getContentType().toString().trim());
+       // Assert.assertNotNull( res.getLocation().toString() );
+       // Assert.assertEquals( "", res.getContentLocation().toString() );
+       // Save eTag for subsequent tests;
+       eTag = res.getHeader( "ETag" );
+       Assert.assertNotNull( eTag );           
+       lastModified = res.getLastModified();
+       Assert.assertNotNull(lastModified);
+       }
+
+       @Test
+       public void testDirtyCachePut() throws Exception {
+               // 2) Conditional PUT request (post with etag. entry provided 
is stale)
+               // User client PUT request
+               //        PUT /edit/first-post.atom HTTP/1.1
+               // >      If-Match: "e180ee84f0671b1"
+               // 
+               //        <?xml version="1.0" ?>
+               //        <entry xmlns="http://www.w3.org/2005/Atom";>
+               //         <title>Atom-Powered Robots Run Amok</title>
+               //         
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+               //         <updated>2007-02-24T16:34:06Z</updated>
+               //         <author><name>Captain Lansing</name></author>
+               //         <content>Update: it's a hoax!</content>
+               //       </entry>
+               // Testing of entry creation
+               Factory factory = abdera.getFactory();
+               String customerName = "Molly Ringwald";
+               Entry entry = factory.newEntry();
+               entry.setTitle("customer " + customerName);
+               entry.setUpdated( new Date());
+               entry.addAuthor("Apache Tuscany");
+               String id = eTag.substring( 1, eTag.length()-1);
+        entry.setId(id); // auto-provided
+        // entry.addLink("" + id, "edit"); // auto-provided
+        // entry.addLink("" + id, "alternate"); // auto-provided
+               Content content = abdera.getFactory().newContent();
+               content.setContentType(Content.Type.TEXT);
+               content.setValue(customerName);
+               entry.setContentElement(content);
+
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-None-Match", eTag);
+               
+               AtomTestCaseUtils.printRequestHeaders( "Put request headers", " 
  ", opts );
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+           id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.put(colUri.toString() + "/" + id, 
new BaseRequestEntity( entry ), opts);
+               // Expected Atom server response (item was edited by another 
user)
+               // >      HTTP/1.1 412 Precondition Failed
+               //       Date: Sat, 24 Feb 2007 16:34:11 GMT
+
+           // If-Match Assert response status code is 412. Precondition failed.
+           // If-None-Match Assert response status code is 200. OK
+       Assert.assertEquals(200, res.getStatus());
+       // Put provides null body and no etags.
+       res.release();
+       }
+       
+       @Test
+       public void testETagMissGet() throws Exception {
+               // 4) Conditional GET example (get with etag. etag not in cache)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               // >      If-None-Match: "e180ee84f0671b1"
+
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-None-Match", "123456");
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.get(colUri.toString() + "/" + id, 
opts);
+               // Expected Atom server response (item was edited by another 
user)
+               // >      HTTP/1.1 412 Precondition Failed
+               //       Date: Sat, 24 Feb 2007 16:34:11 GMT
+
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 200 OK
+               //        Date: Sat, 24 Feb 2007 13:17:11 GMT
+               // >      ETag: "bb4f5e86e92ddb8549604a0df0763581"
+               // >      Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500
+
+           // Assert response status code is 200 OK.
+               // Assert header Content-Type: application/atom+xml;type=entry
+               // Assert header Location: 
http://example.org/edit/first-post.atom
+               // Assert header Content-Location: 
http://example.org/edit/first-post.atom
+               // Assert header ETag: "555555" (etag response != etag request)
+               // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500
+       Assert.assertEquals(200, res.getStatus());
+       Assert.assertEquals(contentType, 
res.getContentType().toString().trim());
+       // Assert.assertNotNull( res.getLocation().toString() );
+       // Assert.assertEquals( "", res.getContentLocation().toString() );
+       Assert.assertNotNull( res.getHeader( "ETag" ) );        
+       lastModified = res.getLastModified();
+       Assert.assertNotNull(lastModified);
+               res.release();
+       }
+
+       @Test
+       public void testETagHitGet() throws Exception {
+               // 3) Conditional GET example (get with etag. etag match)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               // >      If-None-Match: "e180ee84f0671b1"
+
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-None-Match", eTag);
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching               
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.get(colUri.toString() + "/" + id, 
opts);
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 304 Not Modified
+               //       Date: Sat, 24 Feb 2007 13:17:11 GMT
+
+           // Assert response status code is 304 Not Modified.
+               // Assert header ETag: "e180ee84f0671b1"
+               // Assert header Last-Modified: Fri, 25 Jul 2008 14:36:44 -0500
+       // Assert.assertEquals(304, res.getStatus());
+               res.release();      
+       }
+
+
+       @Test
+       public void testUpToDateGet() throws Exception {
+               // 3) Conditional GET example (get with If-Mod. entry is up to 
date)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               // >      If-Modified-Since: Sat, 29 Oct 2025 19:43:31 GMT
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Modified-Since", "Sat, 29 Oct 2025 19:43:31 
GMT"); // "EEE, dd MMM yyyy HH:mm:ss Z // RFC 822 Date
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.get(colUri.toString() + "/" + 
id, opts);
+               ClientResponse res = client.execute( "GET", colUri.toString(), 
(BaseRequestEntity)null, opts);
+
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 304 Not Modified
+               //       Date: Sat, 24 Feb 2007 13:17:11 GMT
+
+           // Assert response status code is 304 Not Modified.
+       Assert.assertEquals(304, res.getStatus());
+               res.release();      
+       }
+
+       @Test
+       public void testOutOfDateGet() throws Exception {
+               // 4) Conditional GET example (get with If-Mod. entry is not to 
date)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               // >      If-Modified-Since: Sat, 29 Oct 1844 19:43:31 GMT
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Modified-Since", "Sat, 29 Oct 1844 19:43:31 
GMT"); // "EEE, dd MMM yyyy HH:mm:ss Z // RFC 822 Date
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.get(colUri.toString() + "/" + id, 
opts);
+
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 200 OK
+               //        Date: Sat, 24 Feb 2007 13:17:11 GMT
+               // >      ETag: "bb4f5e86e92ddb8549604a0df0763581"
+               // >      Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500
+
+           // Assert response status code is 200 OK.
+               // Assert header ETag: "e180ee84f0671b1"
+               // Assert header Last-Modified: Greater than If-Mod         
+       Assert.assertEquals(200, res.getStatus());
+       Assert.assertEquals(contentType, 
res.getContentType().toString().trim());
+       // Assert.assertNotNull( res.getLocation().toString() );
+       // Assert.assertEquals( "", res.getContentLocation().toString() );
+       Assert.assertNotNull( res.getHeader( "ETag" ) );        
+       lastModified = res.getLastModified();
+       Assert.assertNotNull(lastModified);
+               res.release();
+       }
+       
+       @Test
+       public void testUpToDateUnModGet() throws Exception {
+               // 3) Conditional GET example (get with If-Unmod. entry is up 
to date)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               // >      If-Unmodified-Since: Sat, 29 Oct 2025 19:43:31 GMT
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Unmodified-Since", "Sat, 29 Oct 2050 
19:43:31 GMT" );
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.get(colUri.toString() + "/" + id, 
opts);
+
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 304 Not Modified
+               //       Date: Sat, 24 Feb 2007 13:17:11 GMT
+
+           // Assert response status code is 304 Not Modified.
+       // Assert.assertEquals(304, res.getStatus());
+               // TODO Update when If-Unmodified-Since enabled.
+       Assert.assertEquals(200, res.getStatus());
+               res.release();          
+       }
+
+       @Test
+       public void testOutOfDateUnModGet() throws Exception {
+               // 4) Conditional GET example (get with If-Unmod. entry is not 
to date)
+               // User client GET request
+               //       GET /edit/first-post.atom HTTP/1.1
+               //        Host: example.org
+               // >      If-Unmodified-Since: Sat, 29 Oct 1844 19:43:31 GMT
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Unmodified-Since", "Sat, 29 Oct 1844 
19:43:31 GMT" );
+               opts.setHeader( "Pragma", "no-cache"); // turn off client 
caching
+               
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               // res = client.post(colUri.toString() + "?test=foo", entry, 
opts);
+               String id = eTag.substring( 1, eTag.length()-1);
+               // Warning. AbderaClient.put(String uri,Base 
base,RequestOptions options) caches on the client side.
+               // ClientResponse res = client.put(colUri.toString() + id, 
entry, opts);
+               ClientResponse res = client.get(colUri.toString() + "/" + id, 
opts);
+
+               // Atom server response (item was up to date)
+               // >      HTTP/1.1 200 OK
+               //        Date: Sat, 24 Feb 2007 13:17:11 GMT
+               // >      ETag: "bb4f5e86e92ddb8549604a0df0763581"
+               // >      Last-Modified: Mon, 28 Jul 2008 10:25:37 -0500
+
+           // Assert response status code is 200 OK.
+               // Assert header Content-Type: application/atom+xml;type=entry
+               // Assert header Location: 
http://example.org/edit/first-post.atom
+               // Assert header Content-Location: 
http://example.org/edit/first-post.atom
+               // Assert header ETag: "e180ee84f0671b1"
+               // Assert header Last-Modified: Less than If-Unmod          
+       Assert.assertEquals(200, res.getStatus());
+       Assert.assertEquals(contentType, 
res.getContentType().toString().trim());
+       // Assert.assertNotNull( res.getLocation().toString() );
+       // Assert.assertEquals( "", res.getContentLocation().toString() );
+       Assert.assertNotNull( res.getHeader( "ETag" ) );        
+       lastModified = res.getLastModified();
+       Assert.assertNotNull(lastModified);
+               res.release();
+       }
+}

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderEntryEntityTagsTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java?rev=684294&view=auto
==============================================================================
--- 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
 (added)
+++ 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
 Sat Aug  9 09:50:30 2008
@@ -0,0 +1,356 @@
+/*
+ * 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.    
+ */
+package org.apache.tuscany.sca.binding.atom;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.protocol.Response.ResponseType;
+import org.apache.abdera.protocol.client.AbderaClient;
+import org.apache.abdera.protocol.client.ClientResponse;
+import org.apache.abdera.protocol.client.RequestOptions;
+import org.apache.abdera.protocol.client.util.BaseRequestEntity;
+import org.apache.abdera.util.EntityTag;
+import org.apache.abdera.parser.Parser;
+
+/**
+ * Tests use of server provided feed entity tags for Atom binding in Tuscany.
+ * Tests conditional gets (e.g. get if-none-match) or conditional posts (post 
if-match)
+ * using entity tags and last modified entries in headers. 
+ * Uses the SCA provided Provider composite to act as a server.
+ * Uses the Abdera provided Client to act as a client.
+ */
+public class ProviderFeedEntityTagsTest {
+       public final static String providerURI = 
"http://localhost:8084/customer";;
+       protected static SCADomain scaConsumerDomain;
+       protected static SCADomain scaProviderDomain;
+       protected static CustomerClient testService;
+    protected static Abdera abdera;
+    protected static AbderaClient client;
+    protected static Parser abderaParser;    
+    protected static String eTag;
+    protected static Date lastModified;
+    protected static final SimpleDateFormat dateFormat = new SimpleDateFormat( 
"EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
+
+       @BeforeClass
+       public static void init() throws Exception {
+               System.out.println(">>>ProviderFeedEntityTagsTest.init");
+               scaProviderDomain = 
SCADomain.newInstance("org/apache/tuscany/sca/binding/atom/Provider.composite");
+               abdera = new Abdera();
+               client = new AbderaClient(abdera);
+               abderaParser = Abdera.getNewParser();
+       }
+
+       @AfterClass
+       public static void destroy() throws Exception {
+               System.out.println(">>>ProviderFeedEntityTagsTest.destroy");
+               scaProviderDomain.close();
+       }
+
+       @Test
+       public void testPrelim() throws Exception {
+               Assert.assertNotNull(scaProviderDomain);
+               Assert.assertNotNull( client );
+       }
+                       
+       @Test
+    public void testFeedBasics() throws Exception {            
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedBasics");
+               // Normal feed request
+               ClientResponse res = client.get(providerURI);
+               Assert.assertNotNull(res);
+               try {
+                       // Asser feed provided since no predicates
+                       Assert.assertEquals(200, res.getStatus());
+                       Assert.assertEquals(ResponseType.SUCCESS, 
res.getType());
+               // AtomTestCaseUtils.printResponseHeaders( "Feed response 
headers:", "   ", res );
+               // System.out.println("Feed response content:");
+               // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument());
+
+               // Perform other tests on feed.
+                       Document<Feed> doc = res.getDocument();
+                       Assert.assertNotNull( doc );
+                       Feed feed = doc.getRoot();
+                       Assert.assertNotNull( feed );
+                       printFeed( "Feed values", "   ", feed );
+                       // RFC 4287 requires non-null id, title, updated 
elements
+                       Assert.assertNotNull( feed.getId() );
+                       Assert.assertNotNull( feed.getTitle() );
+                       Assert.assertNotNull( feed.getUpdated() );
+                       
+                       eTag = res.getHeader("ETag");
+                       Assert.assertNotNull( eTag );
+                       lastModified = res.getLastModified();
+                       Assert.assertNotNull( lastModified );
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testUnmodifiedGetIfMatch() throws Exception {          
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfMatch");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Match", eTag);
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+               String thisETag = res.getHeader("ETag");
+                       Assert.assertNotNull( thisETag );
+                       Date thisLastModified = res.getLastModified();
+                       Assert.assertNotNull( thisLastModified );
+                        
+                       // Should return 200 - Feed provided since it matches 
etag.
+                       Assert.assertEquals(200, res.getStatus());
+                       Assert.assertEquals(ResponseType.SUCCESS, 
res.getType());
+               // AtomTestCaseUtils.printResponseHeaders( "Feed response 
headers:", "   ", res );
+               // System.out.println("Feed response content:");
+               // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testUnmodifiedGetIfNoneMatch() throws Exception {              
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfNoneMatch");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-None-Match", eTag);
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 304 - Feed not provided since it 
matches ETag.
+                       Assert.assertEquals(304, res.getStatus());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testUnmodifiedGetIfUnModified() throws Exception {             
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfUnModified");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Unmodified-Since", dateFormat.format( new 
Date() ));
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 304 - Feed not provided since feed is 
modified since.
+                       Assert.assertEquals(304, res.getStatus());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testUnmodifiedGetIfModified() throws Exception {               
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfModified");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Modified-Since", dateFormat.format( new 
Date( 0 ) ));
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 200 - Feed provided since feed is 
changed.
+                       Assert.assertEquals(200, res.getStatus());
+                       Assert.assertEquals(ResponseType.SUCCESS, 
res.getType());
+
+                       String thisETag = res.getHeader("ETag");
+                       Assert.assertNotNull( thisETag );
+                       Date thisLastModified = res.getLastModified();
+                       Assert.assertNotNull( thisLastModified );               
         
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testModifiedGetIfNoneMatch() throws Exception {                
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedModifiedGetIfNoneMatch");
+               // Post some new content to the feed.
+               Factory factory = abdera.getFactory();
+               String customerName = "Fred Farkle";
+               Entry entry = factory.newEntry();
+               entry.setTitle("customer " + customerName);
+               entry.setUpdated(new Date());
+               entry.addAuthor("Apache Tuscany");
+               Content content = abdera.getFactory().newContent();
+               content.setContentType(Content.Type.TEXT);
+               content.setValue(customerName);
+               entry.setContentElement(content);
+
+               RequestOptions opts = new RequestOptions();
+               String contentType = "application/atom+xml; type=entry"; 
+               opts.setContentType(contentType);
+               IRI colUri = new IRI(providerURI).resolve("customer");
+               ClientResponse res = client.post(colUri.toString(), entry, 
opts);
+                       
+               // Feed request with predicates
+               opts = new RequestOptions();
+               contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-None-Match", eTag);
+               
+               res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+               String thisETag = res.getHeader("ETag");
+                       Assert.assertNotNull( thisETag );
+                       Date thisLastModified = res.getLastModified();
+                       Assert.assertNotNull( thisLastModified );
+                        
+                       // Should return 200 - value since feed is changed
+                       Assert.assertEquals(200, res.getStatus());
+                       Assert.assertEquals(ResponseType.SUCCESS, 
res.getType());
+                       
+               // AtomTestCaseUtils.printResponseHeaders( "Feed modified 
if-none-match response headers:", "   ", res );
+               // System.out.println("Feed response content:");
+               // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testModifiedGetIfMatch() throws Exception {            
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedModifiedGetIfMatch");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Match", eTag);
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 412 - Precondition failed since feed 
changed.
+                       Assert.assertEquals(412, res.getStatus());
+               // AtomTestCaseUtils.printResponseHeaders( "Feed response 
headers:", "   ", res );
+               // System.out.println("Feed response content:");
+               // AtomTestCaseUtils.prettyPrint(abdera, res.getDocument());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testModifiedGetIfUnModified() throws Exception {               
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfUnModified");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Unmodified-Since", dateFormat.format( new 
Date() ));
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 304 - Feed not provided since feed is 
modified since.                  
+                       Assert.assertEquals(304, res.getStatus());
+               } finally {
+                       res.release();
+               }
+       }               
+
+       @Test
+    public void testModifiedGetIfModified() throws Exception {         
+               
System.out.println(">>>ProviderFeedEntityTagsTest.testFeedUnmodifiedGetIfModified");
+               // Feed request with predicates
+               RequestOptions opts = new RequestOptions();
+               final String contentType = "application/atom+xml"; 
+               opts.setContentType(contentType);
+               opts.setHeader( "If-Modified-Since", dateFormat.format( 
lastModified ));
+               
+               ClientResponse res = client.get(providerURI, opts);
+               Assert.assertNotNull(res);
+               try {
+                       // Should return 200 - Feed provided since feed is 
changed.
+                       Assert.assertEquals(200, res.getStatus());
+                       Assert.assertEquals(ResponseType.SUCCESS, 
res.getType());
+
+                       String thisETag = res.getHeader("ETag");
+                       Assert.assertNotNull( thisETag );
+                       Date thisLastModified = res.getLastModified();
+                       Assert.assertNotNull( thisLastModified );               
         
+               } finally {
+                       res.release();
+               }
+       }               
+
+
+       public static void printFeed( String title, String indent, Feed feed ) {
+               if ( feed == null ) {
+                       System.out.println( title + " feed is null");
+                       return;
+               }
+                       
+               System.out.println( title );
+               System.out.println( indent + "id=" + feed.getId() );
+               System.out.println( indent + "title=" + feed.getTitle() );
+               System.out.println( indent + "updated=" + feed.getUpdated() );
+               System.out.println( indent + "author=" + feed.getAuthor() );
+               Collection collection = feed.getCollection();
+               if ( collection == null ) {
+                       System.out.println( indent + "collection=null" );
+               } else {
+                       System.out.println( indent + "collection=" + collection 
);
+               }
+               // System.out.println( indent + "collection size=" + 
feed.getCollection() );
+               // for (Collection collection : workspace.getCollections()) {
+               //    if (collection.getTitle().equals("customers")) {
+               //       String expected = uri + "customers";
+               //       String actual = 
collection.getResolvedHref().toString();
+               //       assertEquals(expected, actual);
+               //    }
+               // }
+
+       }
+
+}

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
tuscany/java/sca/modules/binding-atom-abdera/src/test/java/org/apache/tuscany/sca/binding/atom/ProviderFeedEntityTagsTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to