You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by do...@apache.org on 2008/06/12 02:51:24 UTC

svn commit: r666935 - in /incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social: dataservice/ samplecontainer/

Author: doll
Date: Wed Jun 11 17:51:23 2008
New Revision: 666935

URL: http://svn.apache.org/viewvc?rev=666935&view=rev
Log:
Added three new service interfaces for activity, person and app data that better fit the restful model. They use two new objects RestfulCollection (that is just like ApiCollection but with its fields matching the new restful format) and DataCollection (which matches the return format for data).

Updated the Basic*Services to implement both these new interfaces and the old ones. The abdera code should switch to using these new apis to clean up the handlers. 

(sorry for the confusing service names - when we get around to deprecating the old format things will be better...)


Added:
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/ActivityService.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/AppDataService.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataCollection.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/PersonService.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RestfulCollection.java
Modified:
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicDataService.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java

Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/ActivityService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/ActivityService.java?rev=666935&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/ActivityService.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/ActivityService.java Wed Jun 11 17:51:23 2008
@@ -0,0 +1,63 @@
+/*
+ * 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.shindig.social.dataservice;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.opensocial.model.Activity;
+
+public interface ActivityService {
+
+  /**
+   * Returns a list of activities that correspond to the passed in person ids.
+   *
+   * @param userId The id of the person to fetch activities for.
+   * @param groupId Indicates whether to fetch activities for a group.
+   * @param token A valid SecurityToken
+   * @return a response item with the list of activities.
+   */
+  public ResponseItem<RestfulCollection<Activity>> getActivities(String userId,
+      DataServiceServlet.GroupId groupId, SecurityToken token);
+
+  /**
+   * Returns the activity for the passed in user and group that corresponds to
+   * the activityId.
+   *
+   * @param userId The id of the person to fetch activities for.
+   * @param groupId Indicates whether to fetch activities for a group.
+   * @param activityId The id of the activity to fetch.
+   * @param token A valid SecurityToken
+   * @return a response item with the list of activities.
+   */
+  public ResponseItem<Activity> getActivity(String userId,
+      DataServiceServlet.GroupId groupId, String activityId,
+      SecurityToken token);
+
+  /**
+   * Creates the passed in activity for the given user. Once createActivity is
+   * called, getActivities will be able to return the Activity.
+   *
+   * @param personId The id of the person to create the activity for.
+   * @param activity The activity to create.
+   * @param token A valid SecurityToken
+   * @return a response item containing any errors
+   */
+  public ResponseItem createActivity(String personId, Activity activity,
+      SecurityToken token);
+
+}

Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/AppDataService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/AppDataService.java?rev=666935&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/AppDataService.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/AppDataService.java Wed Jun 11 17:51:23 2008
@@ -0,0 +1,71 @@
+/*
+ * 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.shindig.social.dataservice;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.ResponseItem;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AppDataService {
+
+  /**
+   * Retrives app data for the specified user and group.
+   * @param userId The user
+   * @param groupId The group
+   * @param fields The fields to filter the data by.
+   * @param appId The app
+   * @param token The security token
+   * @return The data fetched
+   */
+  public ResponseItem<DataCollection> getPersonData(
+      String userId, DataServiceServlet.GroupId groupId,
+      List<String> fields, String appId, SecurityToken token);
+
+  /**
+   * Updates app data for the specified user and group with the new values. 
+   *
+   * @param userId The user
+   * @param groupId The group
+   * @param fields The fields to filter the data by.
+   * @param values The values to set
+   * @param appId The app
+   * @param token The security token
+   * @return an error if one occurs
+   */
+  public ResponseItem updatePersonData(String userId,
+      DataServiceServlet.GroupId groupId, List<String> fields,
+      Map<String, String> values, String appId, SecurityToken token);
+
+  /**
+   * Deletes data for the specified user and group.
+   *
+   * @param userId The user
+   * @param groupId The group
+   * @param fields The fields to delete.
+   * @param appId The app
+   * @param token The security token
+   * @return an error if one occurs
+   */
+  public ResponseItem deletePersonData(String userId,
+      DataServiceServlet.GroupId groupId, List<String> fields, String appId,
+      SecurityToken token);
+}
+
+

Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataCollection.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataCollection.java?rev=666935&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataCollection.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataCollection.java Wed Jun 11 17:51:23 2008
@@ -0,0 +1,37 @@
+/*
+ * 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.shindig.social.dataservice;
+
+import java.util.Map;
+
+public class DataCollection {
+  private Map<String, Map<String, String>> entry;
+
+  public DataCollection(Map<String, Map<String, String>> entry) {
+    this.entry = entry;
+  }
+
+  public Map<String, Map<String, String>> getEntry() {
+    return entry;
+  }
+
+  public void setEntry(Map<String, Map<String, String>> entry) {
+    this.entry = entry;
+  }
+
+}
\ No newline at end of file

Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/PersonService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/PersonService.java?rev=666935&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/PersonService.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/PersonService.java Wed Jun 11 17:51:23 2008
@@ -0,0 +1,62 @@
+/*
+ * 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.shindig.social.dataservice;
+
+import org.apache.shindig.common.SecurityToken;
+import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import java.util.Set;
+
+public interface PersonService {
+
+  public enum SortOrder {
+    topFriends, name
+  }
+
+  public enum FilterType {
+    all, hasApp, topFriends
+  }
+
+  /**
+   * Returns a list of people that correspond to the passed in person ids.
+   *
+   * @param userId The user
+   * @param groupId The group
+   * @param sortOrder How to sort the people
+   * @param filter How the people should be filtered.
+   * @param first The index of the first person to fetch.
+   * @param max The max number of people to fetch.
+   * @param profileDetails The profile details to fetch
+   * @param token The gadget token
+   * @return a list of people.
+   */
+  public ResponseItem<RestfulCollection<Person>> getPeople(String userId,
+      DataServiceServlet.GroupId groupId,
+      SortOrder sortOrder, FilterType filter, int first, int max,
+      Set<String> profileDetails, SecurityToken token);
+
+  /**
+   * Returns a person that corresponds to the passed in person id.
+   *
+   * @param id The id of the person to fetch.
+   * @param token The gadget token
+   * @return a list of people.
+   */
+  public ResponseItem<Person> getPerson(String id, SecurityToken token);
+}

Added: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RestfulCollection.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RestfulCollection.java?rev=666935&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RestfulCollection.java (added)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RestfulCollection.java Wed Jun 11 17:51:23 2008
@@ -0,0 +1,60 @@
+/*
+ * 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.shindig.social.dataservice;
+
+import java.util.List;
+
+public class RestfulCollection<T> {
+  private List<T> entry;
+  private int startIndex;
+  private int totalResults;
+
+  public RestfulCollection(List<T> entry) {
+    this(entry, 0, entry.size());
+  }
+
+  public RestfulCollection(List<T> entry, int startIndex, int totalResults) {
+    this.entry = entry;
+    this.startIndex = startIndex;
+    this.totalResults = totalResults;
+  }
+
+  public List<T> getEntry() {
+    return entry;
+  }
+
+  public void setEntry(List<T> entry) {
+    this.entry = entry;
+  }
+
+  public int getStartIndex() {
+    return startIndex;
+  }
+
+  public void setStartIndex(int startIndex) {
+    this.startIndex = startIndex;
+  }
+
+  public int getTotalResults() {
+    return totalResults;
+  }
+
+  public void setTotalResults(int totalResults) {
+    this.totalResults = totalResults;
+  }
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java?rev=666935&r1=666934&r2=666935&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java Wed Jun 11 17:51:23 2008
@@ -20,8 +20,12 @@
 import org.apache.shindig.common.SecurityToken;
 import org.apache.shindig.social.ResponseError;
 import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.dataservice.ActivityService;
+import org.apache.shindig.social.dataservice.DataServiceServlet;
+import org.apache.shindig.social.dataservice.RestfulCollection;
 import org.apache.shindig.social.opensocial.ActivitiesService;
 import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.ApiCollection;
 
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
@@ -31,7 +35,8 @@
 import java.util.List;
 import java.util.Map;
 
-public class BasicActivitiesService implements ActivitiesService {
+public class BasicActivitiesService implements ActivitiesService,
+    ActivityService {
   private XmlStateFileFetcher fetcher;
 
   @Inject
@@ -71,6 +76,51 @@
         "Activity not found", null);
   }
 
+  // New interface methods
+
+  public ResponseItem<RestfulCollection<Activity>> getActivities(String userId,
+      DataServiceServlet.GroupId groupId, SecurityToken token) {
+    List<String> ids = Lists.newArrayList();
+    switch (groupId) {
+      case ALL:
+      case FRIENDS:
+        List<String> friendIds = fetcher.getFriendIds().get(userId);
+        if (friendIds != null) {
+          ids.addAll(friendIds);
+        }
+      case SELF:
+        ids.add(userId);
+    }
+
+    Map<String, List<Activity>> allActivities = fetcher.getActivities();
+    List<Activity> activities = Lists.newArrayList();
+
+    for (String id : ids) {
+      List<Activity> personActivities = allActivities.get(id);
+      if (personActivities != null) {
+        activities.addAll(personActivities);
+      }
+    }
+
+    // TODO: Sort them
+    return new ResponseItem<RestfulCollection<Activity>>(
+        new RestfulCollection<Activity>(activities));
+  }
+
+  public ResponseItem<Activity> getActivity(String userId,
+      DataServiceServlet.GroupId groupId, String activityId,
+      SecurityToken token) {
+    RestfulCollection<Activity> allActivities = getActivities(userId, groupId,
+        token).getResponse();
+    for (Activity activity : allActivities.getEntry()) {
+      if (activity.getId().equals(activityId)) {
+        return new ResponseItem<Activity>(activity);
+      }
+    }
+    return new ResponseItem<Activity>(ResponseError.BAD_REQUEST,
+        "Activity not found", null);
+  }
+
   public ResponseItem createActivity(String personId, Activity activity,
       SecurityToken token) {
     // TODO: Validate the activity and do any template expanding

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicDataService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicDataService.java?rev=666935&r1=666934&r2=666935&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicDataService.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicDataService.java Wed Jun 11 17:51:23 2008
@@ -20,16 +20,20 @@
 import org.apache.shindig.common.SecurityToken;
 import org.apache.shindig.social.ResponseError;
 import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.dataservice.AppDataService;
+import org.apache.shindig.social.dataservice.DataServiceServlet;
+import org.apache.shindig.social.dataservice.DataCollection;
 import org.apache.shindig.social.opensocial.DataService;
 
 import com.google.common.collect.Maps;
+import com.google.common.collect.Lists;
 import com.google.inject.Inject;
 import org.json.JSONObject;
 
 import java.util.List;
 import java.util.Map;
 
-public class BasicDataService implements DataService {
+public class BasicDataService implements DataService, AppDataService {
 
   private XmlStateFileFetcher fetcher;
 
@@ -108,4 +112,73 @@
     return true;
   }
 
+
+  // New interface methods
+
+  public ResponseItem<DataCollection> getPersonData(
+      String userId, DataServiceServlet.GroupId groupId, List<String> fields,
+      String appId, SecurityToken token) {
+    List<String> ids = Lists.newArrayList();
+    switch (groupId) {
+      case ALL:
+      case FRIENDS:
+        List<String> friendIds = fetcher.getFriendIds().get(userId);
+        if (friendIds != null) {
+          ids.addAll(friendIds);
+        }
+        break;
+      case SELF:
+        ids.add(userId);
+    }
+
+    // TODO: Respect appId
+    Map<String, Map<String, String>> data
+        = getPersonData(ids, fields, token).getResponse();
+    return new ResponseItem<DataCollection>(new DataCollection(data));
+  }
+
+  public ResponseItem updatePersonData(String userId,
+      DataServiceServlet.GroupId groupId, List<String> fields,
+      Map<String, String> values, String appId, SecurityToken token) {
+    for (String field : fields) {
+      if (!isValidKey(field)) {
+        return new ResponseItem<Object>(ResponseError.BAD_REQUEST,
+            "The person data key had invalid characters",
+            new JSONObject());
+      }
+    }
+
+    switch(groupId) {
+      case SELF:
+        for (String field : fields) {
+          String value = values.get(field);
+          // TODO: Respect appId
+          fetcher.setAppData(userId, field, value);
+        }
+        break;
+      default:
+        return new ResponseItem<Object>(ResponseError.NOT_IMPLEMENTED,
+            "We don't support updating data in batches yet", new Object());
+    }
+
+    return new ResponseItem<JSONObject>(new JSONObject());
+  }
+
+  public ResponseItem deletePersonData(String userId,
+      DataServiceServlet.GroupId groupId, List<String> fields, String appId,
+      SecurityToken token) {
+    switch(groupId) {
+      case SELF:
+        for (String field : fields) {
+          // TODO: Respect appId
+          fetcher.setAppData(userId, field, null);
+        }
+        break;
+      default:
+        return new ResponseItem<Object>(ResponseError.NOT_IMPLEMENTED,
+            "We don't support deleting data in batches yet", new Object());
+    }
+
+    return new ResponseItem<JSONObject>(new JSONObject());
+  }
 }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java?rev=666935&r1=666934&r2=666935&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java Wed Jun 11 17:51:23 2008
@@ -20,6 +20,9 @@
 import org.apache.shindig.common.SecurityToken;
 import org.apache.shindig.social.ResponseItem;
 import org.apache.shindig.social.ResponseError;
+import org.apache.shindig.social.dataservice.PersonService;
+import org.apache.shindig.social.dataservice.DataServiceServlet;
+import org.apache.shindig.social.dataservice.RestfulCollection;
 import org.apache.shindig.social.opensocial.PeopleService;
 import org.apache.shindig.social.opensocial.model.ApiCollection;
 import org.apache.shindig.social.opensocial.model.IdSpec;
@@ -35,7 +38,7 @@
 import java.util.Map;
 import java.util.Set;
 
-public class BasicPeopleService implements PeopleService {
+public class BasicPeopleService implements PeopleService, PersonService {
   private static final Comparator<Person> NAME_COMPARATOR
       = new Comparator<Person>() {
     public int compare(Person person, Person person1) {
@@ -73,12 +76,13 @@
   }
 
   public ResponseItem<ApiCollection<Person>> getPeople(List<String> ids,
-      SortOrder sortOrder, FilterType filter, int first, int max,
+      PeopleService.SortOrder sortOrder, PeopleService.FilterType filter,
+      int first, int max,
       Set<String> profileDetails, SecurityToken token) {
     List<Person> people = getPeople(ids, token);
 
     // We can pretend that by default the people are in top friends order
-    if (sortOrder.equals(SortOrder.name)) {
+    if (sortOrder.equals(PeopleService.SortOrder.name)) {
       Collections.sort(people, NAME_COMPARATOR);
     }
 
@@ -135,4 +139,43 @@
     return ids;
   }
 
+
+  // New interface methods
+
+  public ResponseItem<RestfulCollection<Person>> getPeople(String userId,
+      DataServiceServlet.GroupId groupId, PersonService.SortOrder sortOrder,
+      PersonService.FilterType filter, int first, int max,
+      Set<String> profileDetails, SecurityToken token) {
+    List<String> ids = Lists.newArrayList();
+    switch (groupId) {
+      case ALL:
+      case FRIENDS:
+        List<String> friendIds = fetcher.getFriendIds().get(userId);
+        if (friendIds != null) {
+          ids.addAll(friendIds);
+        }
+        break;
+      case SELF:
+        ids.add(userId);
+    }
+
+    List<Person> people = getPeople(ids, token);
+
+    // We can pretend that by default the people are in top friends order
+    if (sortOrder.equals(PersonService.SortOrder.name)) {
+      Collections.sort(people, NAME_COMPARATOR);
+    }
+
+    // TODO: The samplecontainer doesn't really have the concept of HAS_APP so
+    // we can't support any filters yet. We should fix this.
+
+    int totalSize = people.size();
+    int last = first + max;
+    people = people.subList(first, Math.min(last, totalSize));
+
+    RestfulCollection<Person> collection = new RestfulCollection<Person>(people,
+        first, totalSize);
+    return new ResponseItem<RestfulCollection<Person>>(collection);
+  }
+
 }