Author: doll
Date: Fri May 23 04:22:58 2008
New Revision: 659503

URL: http://svn.apache.org/viewvc?rev=659503&view=rev
Log:
SHINDIG-300
Patch from David Primmer. Refactors the people related rest urls to use the new 
base adapter class. Adds some more tests. 


Added:
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java
Modified:
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/SocialApiTestsGuiceModule.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/AbstractSocialEntityCollectionAdapter.java
 Fri May 23 04:22:58 2008
@@ -172,6 +172,18 @@
       return null;
     }
   }
+  
+  /**
+   * Gets the IDs of connections of the given user.
+   *
+   * @param request Abdera's RequestContext
+   * @param uid The User ID to get connections for.
+   * @return A list of ID strings.
+   */
+  protected List<String> getConnectionIds(RequestContext request, String uid) {
+    // TODO: Implement connections. For now, just return friends
+    return getFriendIds(request, uid);
+   }
 
   /**
    * Returns the format (jsoc or atom) from the RequestContext's URL 
parameters.

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java?rev=659503&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PersonAdapter.java
 Fri May 23 04:22:58 2008
@@ -0,0 +1,262 @@
+/*
+ * 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.shindig.social.abdera;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.opensocial.PeopleService;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * This Collection is backed by a set of Person entities
+ * The Adapter needs People and Groups.
+ * The PeopleService comes from the base class. Groups is unimplemented.
+ */
+public class PersonAdapter extends
+    AbstractSocialEntityCollectionAdapter<Person> {
+  private static Logger logger = Logger
+      .getLogger(PersonAdapter.class.getName());
+
+  /**
+   * Query the underlying model for an Person object.
+   *
+   * @param resourceName An id string that identifies a Person.
+   * @param request Abdera's RequestContext.
+   * @return An Person entity.
+   */
+  @Override
+  public Person getEntry(String resourceName, RequestContext request)
+      throws ResponseContextException {
+    String uid = request.getTarget().getParameter("uid");
+    // Get a token assuming the {uid} is the viewerid.
+    // TODO: Replace hardcoded token viewerid with a SubjectResolver.
+    SecurityToken authToken = getSecurityToken(request, uid);
+    return peopleService.getPerson(resourceName, authToken).getResponse();
+  }
+
+  /**
+   * Get's the name of the specific resource requested.
+   * There is some logic to handle some request parsing here since this
+   * adapter handles the getEntry method for two Person entries:
+   * PROFILE_OF_CONNECTION_OF_USER and PROFILE_OF_USER
+   */
+  @Override
+  protected String getResourceName(RequestContext request) {
+    String routeName = getRoute(request).getName();
+    switch (RequestUrlTemplate.getValue(routeName)) {
+      case PROFILE_OF_CONNECTION_OF_USER:
+        // TODO: Improve the service apis so we can get rid of relational code.
+        for (String cid : getConnectionIds(request, request.getTarget()
+            .getParameter("uid"))) {
+          if (cid.equals(request.getTarget().getParameter("pid"))) {
+            return cid;
+          }
+        }
+        return null;
+      case PROFILE_OF_USER:
+        return request.getTarget().getParameter("uid");
+      default:
+        // TODO: Clean this code up so we don't need this check
+        throw new UnsupportedOperationException(
+            "The person adpater was reached with an unsupported url");
+    }
+  }
+
+  /**
+   * atom:entry/atom:id aliases the "id" field. In the Atom format, it is
+   * translated into the required URI data type by prepending "urn:guid:" to 
the
+   * OpenSocial ID string.
+   */
+  @Override
+  public String getId(Person personObj) throws ResponseContextException {
+    return ID_PREFIX + personObj.getId();
+  }
+
+  // hoisting rule: atom:entry/atom:author/atom:uri aliases ?
+  @Override
+  public List<org.apache.abdera.model.Person> getAuthors(Person personObj,
+      RequestContext request) throws ResponseContextException {
+    org.apache.abdera.model.Person author = factory.newAuthor();
+    author.setUri(ID_PREFIX + personObj.getId());
+    return Arrays.asList(author);
+  }
+
+  /**
+   * Get the name of the entry resource (used to construct links)
+   */
+  @Override
+  public String getName(Person personObj) throws ResponseContextException {
+    return personObj.getId();
+  }
+
+  // hoisting rule: atom:entry/atom:title aliases ?
+  @Override
+  public String getTitle(Person personObj) throws ResponseContextException {
+    return personObj.getName().getUnstructured();
+  }
+
+  @Override
+  public Date getUpdated(Person personObj) throws ResponseContextException {
+    return personObj.getUpdated();
+  }
+
+  // hoisting rule: atom:entry/atom:summary aliases ?
+  @Override
+  public String getSummary(Person personObj) throws ResponseContextException {
+    return null;
+  }
+
+  // hoisting rule: atom:entry/atom:published aliases ?
+  public Long getPublished(Person personObj)
+      throws ResponseContextException {
+    // TODO: Add published element to the entry object.
+    // TODO: Switch based on output format from RFC date to epoch-based.
+    // POSTED_TIME is seconds since the epoch.
+    return null;
+  }
+
+  /**
+   * This is where some person entry format customization happens.
+   *
+   * @param request Abdera's RequestContext.
+   * @param entry The entry FOM object.
+   * @param feedIri The feed IRI that the entry came from.
+   * @param personObj The object that the entry is based on.
+   * @throws ResponseContextException
+   */
+  @Override
+  protected void addOptionalEntryDetails(RequestContext request, Entry entry,
+      IRI feedIri, Person personObj) throws ResponseContextException {
+    String link = getLink(personObj, feedIri, request);
+    // TODO: this should create links that are aware of the request format.
+    entry.addLink(link, "self", "application/atom+xml", null, null, 0);
+
+    // TODO:
+    // atom:entry/atom:published aliases ?
+  }
+
+  /**
+   * Unimplemented Data methods
+   */
+  @Override
+  public void deleteEntry(String resourceName, RequestContext request)
+      throws ResponseContextException {
+    // TODO: Auto-generated method stub
+  }
+
+  /**
+   * Query the underlying model for the list person objects.
+   *
+   * There is some logic to handle some request dispatching here since this
+   * adapter handles the getFeed method for three Person collections:
+   * PROFILES_OF_CONNECTIONS_OF_USER, PROFILES_OF_FRIENDS_OF_USER and
+   * PROFILES_IN_GROUP_OF_USER
+   *
+   * @param request RequestContext
+   * @return A List Person entities.
+   */
+  @Override
+  public Iterable<Person> getEntries(RequestContext request)
+      throws ResponseContextException {
+    String uid = request.getTarget().getParameter("uid");
+    String routeName = getRoute(request).getName();
+    List<String> ids = new ArrayList<String>();
+    switch (RequestUrlTemplate.getValue(routeName)) {
+      case PROFILES_OF_CONNECTIONS_OF_USER :
+        ids = getConnectionIds(request, uid);
+        break;
+      case PROFILES_OF_FRIENDS_OF_USER :
+        // TODO: Change activities service to handle the friend lookup itself
+        ids = getFriendIds(request, uid);
+        break;
+      case PROFILES_IN_GROUP_OF_USER :
+        // TODO: add something like ids = getGroupIds(request, gid);
+        // For now, this just returns the friends.
+        ids = getFriendIds(request, uid);
+        break;
+      default:
+        // TODO: Clean this code up so we don't need this check
+        throw new UnsupportedOperationException(
+            "The person adpater was reached with an unsupported url");
+    }
+    // Get a token assuming the {uid} is the viewerid.
+    // TODO: Replace hardcoded token viewerid with a SubjectResolver.
+    SecurityToken authToken = getSecurityToken(request, uid);
+    return peopleService.getPeople(ids, PeopleService.SortOrder.name, null, 0,
+        100, null, authToken).getResponse().getItems();
+  }
+
+  @Override
+  public Person postEntry(String title, IRI id, String summary, Date updated,
+      List<org.apache.abdera.model.Person> authors, Content content,
+      RequestContext request) throws ResponseContextException {
+    // TODO: Implement
+    return null;
+  }
+
+  @Override
+  public void putEntry(Person personObj, String title, Date updated,
+      List<org.apache.abdera.model.Person> authors, String summary,
+      Content content, RequestContext request) throws ResponseContextException 
{
+    // TODO: Implement
+  }
+
+  /**
+   * Collection-level hoisting rules
+   */
+
+  /**
+   * The collection-level URL. Calls the getFeedIriForEntry and nulls "pid".
+   *
+   * @param request RequestContext
+   * @return The absolute request URI (includes server name, port, etc) URL
+   */
+  @Override
+  public String getHref(RequestContext request) {
+    return getFeedIriForEntry(request, "pid");
+  }
+
+  @Override
+  public String getId(RequestContext request) {
+    // TODO: what really to return for the feed ID? Better data will help.
+    return getHref(request);
+  }
+
+  public String getTitle(RequestContext request) {
+    return getRoute(request).getName();
+  }
+
+  // hoisting rule: atom:entry/atom:author/atom:uri aliases ?
+  @Override
+  public String getAuthor(RequestContext request)
+      throws ResponseContextException {
+    return request.getTarget().getParameter("uid");
+  }
+
+}

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RequestUrlTemplate.java
 Fri May 23 04:22:58 2008
@@ -32,15 +32,17 @@
 public enum RequestUrlTemplate {
   // People
   PROFILES_OF_CONNECTIONS_OF_USER("Profiles of Connections of User",
-      "people/:uid/:groupid", "/people/{uid}/{groupid}"),
+      "people/:uid/@all", "/people/{guid}/@all"),
   PROFILES_OF_FRIENDS_OF_USER("Profiles of Friends of User",
-      "people/:uid/@friends", "/people/{uid}/@friends"),
-  CONNECTIONS_OF_USER("Connections of User",
-      "people/:uid/@all", "/people/{uid}/@all"),
+      "people/:uid/@friends", "/people/{guid}/@friends"),
+  PROFILES_IN_GROUP_OF_USER("Profiles in Group of User",
+      "people/:uid/:gid", "/people/{guid}/{groupid}"),
   PROFILE_OF_CONNECTION_OF_USER("Profile of Connection of User",
-      "people/:uid/@all/:pid", "/people/{uid}/@all/{pid}"),
+      "people/:uid/@all/:pid", "/people/{guid}/@all/{pid}"),
   PROFILE_OF_USER("Profile of User",
-      "people/:uid/@self", "/people/{uid}/@self"),
+      "people/:uid/@self", "/people/{guid}/@self"),
+  PROFILE_OF_REQUESTER("Profile of Requester",
+          "people/@me/@self", "/people/@me/@self"),
   // Activities
   ACTIVITIES_OF_USER("Activities of User",
       "activities/:uid/@self", "/activities/{uid}/@self"),

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
 Fri May 23 04:22:58 2008
@@ -27,19 +27,16 @@
   //TODO why is this hardcoded here. can't this be from servletContext?
   private static final String BASE = "/social/rest/";
 
-  private PeopleServiceAdapter peopleAdapter;
-  private FriendsServiceAdapter friendsAdapter;
+  private PersonAdapter personAdapter;
   private DataServiceAdapter dataAdapter;
   private ActivityAdapter activityAdapter;
 
   @Inject
   public void setAdapters(
-      PeopleServiceAdapter peopleAdapter,
-      FriendsServiceAdapter friendsAdapter,
+      PersonAdapter personAdapter,
       DataServiceAdapter dataAdapter,
       ActivityAdapter activityAdapter) {
-    this.peopleAdapter = peopleAdapter;
-    this.friendsAdapter = friendsAdapter;
+    this.personAdapter = personAdapter;
     this.dataAdapter = dataAdapter;
     this.activityAdapter = activityAdapter;
   }
@@ -53,16 +50,16 @@
   public void initialize() {
     routeManager = new SocialRouteManager(BASE)
         // People
-        .addRoute(RequestUrlTemplate.CONNECTIONS_OF_USER,
-            TargetType.TYPE_COLLECTION, friendsAdapter)
-        .addRoute(RequestUrlTemplate.PROFILES_OF_FRIENDS_OF_USER,
-            TargetType.TYPE_COLLECTION, friendsAdapter)
         .addRoute(RequestUrlTemplate.PROFILES_OF_CONNECTIONS_OF_USER,
-            TargetType.TYPE_COLLECTION, null)
+            TargetType.TYPE_COLLECTION, personAdapter)
+        .addRoute(RequestUrlTemplate.PROFILES_OF_FRIENDS_OF_USER,
+            TargetType.TYPE_COLLECTION, personAdapter)
+        .addRoute(RequestUrlTemplate.PROFILES_IN_GROUP_OF_USER,
+            TargetType.TYPE_COLLECTION, personAdapter)
         .addRoute(RequestUrlTemplate.PROFILE_OF_CONNECTION_OF_USER,
-            TargetType.TYPE_ENTRY, friendsAdapter)
+            TargetType.TYPE_ENTRY, personAdapter)
         .addRoute(RequestUrlTemplate.PROFILE_OF_USER,
-            TargetType.TYPE_ENTRY, peopleAdapter)
+            TargetType.TYPE_ENTRY, personAdapter)
 
          // Activities
         .addRoute(RequestUrlTemplate.ACTIVITIES_OF_USER,

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
 Fri May 23 04:22:58 2008
@@ -37,7 +37,8 @@
         .getConfiguration()
         .setAttributesForPrimitives(false);
     writer.getBindingConfiguration().setMapIDs(false);
-    writer.enablePrettyPrint();
+    // Print no line endings to match Abdera.
+    writer.setEndOfLine("");
     writer.setWriteEmptyElements(false);
     String toReturn = null;
     try {

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/SocialApiTestsGuiceModule.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/SocialApiTestsGuiceModule.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/SocialApiTestsGuiceModule.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/SocialApiTestsGuiceModule.java
 Fri May 23 04:22:58 2008
@@ -149,11 +149,15 @@
       allPeople.put(simpleDoe.getId(), simpleDoe);
 
       // Jane and Simple are John's friends.
-      // Nobody else has friends
       List<String> johnsFriends = new ArrayList<String>();
       johnsFriends.add(janeDoe.getId());
       johnsFriends.add(simpleDoe.getId());
       friendIds.put(johnDoe.getId(), johnsFriends);
+
+      // John is Jane's friend.      
+      List<String> janesFriends = new ArrayList<String>();
+      janesFriends.add(johnDoe.getId());
+      friendIds.put(janeDoe.getId(), janesFriends);
     }
 
     public List<String> getIds(IdSpec idSpec, SecurityToken token)

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java?rev=659503&r1=659502&r2=659503&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RestfulAtomPeopleTest.java
 Fri May 23 04:22:58 2008
@@ -17,13 +17,15 @@
  */
 package org.apache.shindig.social.abdera;
 
+import static org.junit.Assert.assertEquals;
+
 import org.apache.shindig.social.SocialApiTestsGuiceModule;
 import org.apache.shindig.social.opensocial.model.Person;
 
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Entry;
 import org.apache.abdera.model.Feed;
-import static org.junit.Assert.assertEquals;
+
 import org.junit.Test;
 
 import java.util.List;
@@ -31,7 +33,7 @@
 
 public class RestfulAtomPeopleTest extends AbstractLargeRestfulTests {
   @Test
-  public void testGetPeople() throws Exception {
+  public void testGetProfilesOfConnectionsOfUserAtom() throws Exception {
     resp = client.get(BASEURL + "/people/john.doe/@all?format=atom");
     checkForGoodAtomResponse(resp);
 
@@ -55,23 +57,41 @@
       assertEquals(simpleDoe.getId(), id1);
     }
   }
+  
+  @Test
+  public void testGetProfilesOfFriendsOfUserAtom() throws Exception {
+    resp = client.get(BASEURL + "/people/john.doe/@friends?format=atom");
+    checkForGoodAtomResponse(resp);
+
+    Document<Feed> doc = resp.getDocument();
+    prettyPrint(doc);
+    Feed feed = doc.getRoot();
+    assertEquals(2, feed.getEntries().size());
+  }
 
   @Test
-  public void testGetIndirectPerson() throws Exception {
-    resp = client.get(BASEURL + "/people/john.doe/@all/jane.doe?format=atom");
+  public void testGetProfileOfConnectionOfUserAtom() throws Exception {
+    resp = client.get(BASEURL + "/people/jane.doe/@all/john.doe?format=atom");
     checkForGoodAtomResponse(resp);
 
     Document<Entry> doc = resp.getDocument();
     Entry entry = doc.getRoot();
     prettyPrint(entry);
 
-    Person expectedJaneDoe = SocialApiTestsGuiceModule
-        .MockPeopleService.janeDoe;
-    assertEquals(expectedJaneDoe.getId(),
+    Person expectedJohnDoe = SocialApiTestsGuiceModule
+        .MockPeopleService.johnDoe;
+    assertEquals(expectedJohnDoe.getId(), 
         getIdFromXmlContent(entry.getContentElement().getValue()));
   }
 
   @Test
+  public void testGetProfileOfNotConnectionOfUserAtom() throws Exception {
+    // jane is friends with john but not simple
+    resp = client.get(BASEURL + 
"/people/jane.doe/@all/simple.doe?format=atom");
+    checkForBadResponse(resp);
+  }
+  
+  @Test
   public void testGetInvalidPerson() throws Exception {
     resp = client.get(BASEURL + "/people/john.doe/@all/nobody?format=atom");
     checkForBadResponse(resp);


Reply via email to