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);