You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/05/14 22:07:08 UTC

svn commit: r944438 - in /shindig/branches/activitystreams-prototype: content/samplecontainer/examples/ActivityStreams/ java/social-api/src/main/java/org/apache/shindig/social/core/config/ java/social-api/src/main/java/org/apache/shindig/social/core/mo...

Author: lindner
Date: Fri May 14 20:07:08 2010
New Revision: 944438

URL: http://svn.apache.org/viewvc?rev=944438&view=rev
Log:
SHINDIG-1329 | Patch from Eric Woods | ActivityStreams support

Added:
    shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/
    shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreamGadget.xml
    shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreams.js
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityEntryImpl.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityObjectImpl.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityStreamImpl.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityEntry.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityObject.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityStream.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/service/ActivityStreamHandler.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/spi/ActivityStreamService.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java.orig
      - copied, changed from r944421, shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java
Modified:
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/config/SocialApiGuiceModule.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/util/xstream/XStream081Configuration.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java
    shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java

Added: shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreamGadget.xml
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreamGadget.xml?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreamGadget.xml (added)
+++ shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreamGadget.xml Fri May 14 20:07:08 2010
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<Module>
+	<ModulePrefs title="ActivityStreams Gadget!">
+		<Require feature="opensocial-0.9"/>
+		<Require feature="osapi"/>
+		<Require feature="dynamic-height"/>
+	</ModulePrefs>
+	
+	<Content type="html">
+	<![CDATA[	 
+		<script type="text/javascript" src="ActivityStreams.js"></script>
+		
+		<script type="text/javascript">
+			// Stores the HTML for rendering
+			var htmlWelcome = "";
+			var htmlActivities = "";
+			var htmlActivityEntries = "";
+			var htmlCreateActivityEntry = "";
+			var htmlDeleteActivityEntry = "";
+			var htmlGetActivityEntryId = "";
+			
+			// ================= PEOPLE =================
+			// Composes a list of friends
+			function displayWelcome() {
+				// Load the viewer, owner, and friends
+				ActivityStreams.loadPeople();
+				alert("Loading friends...");
+			
+				// Compose HTML
+				htmlWelcome = "Hi, " + viewer.getDisplayName() + "!  You are viewing " + owner.getDisplayName() + "'s data. <br><br>";
+				htmlWelcome += "Here is a list of your friends: <br>";
+				htmlWelcome += "<lu>";
+				viewerFriends.each(function(friend) {
+					htmlWelcome += "<li>" + friend.getDisplayName() + "</li>";
+				});
+				htmlWelcome += "</lu>";
+			}
+			
+			// ================= ACTIVITY STREAMS =================
+			// Form to input ActivityEntry
+			function displayCreateActivityEntry() {
+				htmlCreateActivityEntry = "<br><form name='form_postActivityEntry'>"
+				htmlCreateActivityEntry += "Post an ActivityEntry comment:<br>"
+				htmlCreateActivityEntry += "<input type='text' size=100 name ='activityEntryComment'>"
+				htmlCreateActivityEntry += "<input type='button' value='Post!' onclick='createActivityEntry(document.form_postActivityEntry.activityEntryComment.value)'>"
+				htmlCreateActivityEntry += "</form>"
+			}
+			
+			function createActivityEntry(comment) {
+				ActivityStreams.postActivityEntry(comment);
+				displayActivityEntries();
+				refreshHTML();
+			}
+			
+			function displayDeleteActivityEntry() {
+				htmlDeleteActivityEntry = "<br><form name='form_deleteActivityEntry'>"
+				htmlDeleteActivityEntry += "Delete an ActivityEntry by ID:<br>"
+				htmlDeleteActivityEntry += "<input type='text' size=100 name ='activityEntryId'>"
+				htmlDeleteActivityEntry += "<input type='button' value='Delete!' onclick='deleteActivityEntry(document.form_deleteActivityEntry.activityEntryId.value)'>"
+				htmlDeleteActivityEntry += "</form>"
+			}
+			
+			function deleteActivityEntry(activityEntryId) {
+				alert('Deleting Id: ' + activityEntryId);
+				ActivityStreams.deleteActivityEntry(activityEntryId);
+				displayActivityEntries();
+				refreshHTML();
+			}
+			
+			function displayGetActivityEntryId() {
+				htmlGetActivityEntryId = "<br><form name='form_getActivityEntryId'>"
+				htmlGetActivityEntryId += "Get an ActivityEntry by ID:<br>"
+				htmlGetActivityEntryId += "<input type='text' size=100 name ='activityEntryId'>"
+				htmlGetActivityEntryId += "<input type='button' value='Get!' onclick='getActivityEntryId(document.form_getActivityEntryId.activityEntryId.value)'>"
+				htmlGetActivityEntryId += "</form>"
+			}
+			
+			function getActivityEntryId(activityEntryId) {
+				alert('Getting Id: ' + activityEntryId);
+				ActivityStreams.loadActivityEntryId(activityEntryId);
+				displayActivities();
+				refreshHTML();
+			}
+			
+			function displayActivityEntries() {
+				// Load recent activityentries
+				ActivityStreams.loadActivityEntriesFriends();
+				ActivityStreams.loadActivityEntriesViewer();
+				alert('Loading ActivityEntries...');
+				
+				// Compose HTML
+				htmlActivityEntries = "<br><br>All ActivityEntries: <br>";
+				htmlActivityEntries += "<table border='1'>";
+				htmlActivityEntries += "<tr>";
+				htmlActivityEntries += "<td>Title</td>";
+				htmlActivityEntries += "<td>Body</td>";
+				htmlActivityEntries += "<td>Actor</td>";
+				htmlActivityEntries += "<td>ID</td>";
+				htmlActivityEntries += "<td>Posted</td>";
+				htmlActivityEntries += "<td>Text</td>";
+				htmlActivityEntries += "</tr>"
+				processActivityEntries(viewerActivityEntries);
+				processActivityEntries(friendActivityEntries);
+				htmlActivityEntries += "</table>";
+			}
+			
+			function processActivityEntries(activityentries) {
+				for(idx = 0; idx < activityentries.list.length; idx++) {
+					htmlActivityEntries += "<tr>";
+					htmlActivityEntries += "<td>" + activityentries.list[idx].title + "</td>";
+					htmlActivityEntries += "<td>" + activityentries.list[idx].body + "</td>";
+					htmlActivityEntries += "<td>" + activityentries.list[idx].actor.displayName + "</td>";
+					htmlActivityEntries += "<td>" + activityentries.list[idx].id + "</td>";
+					htmlActivityEntries += "<td>" + activityentries.list[idx].postedTime + "</td>";
+					htmlActivityEntries += "<td><textarea>" + JSON.stringify(activityentries.list[idx]) + "</textarea></td>";
+					htmlActivityEntries += "</tr>";
+				}
+			}
+			
+			// ================= ACTIVITIES =================
+			// Composes the list of activities by the viewer and friends
+			function displayActivities() {
+				// Load recent activities
+				ActivityStreams.loadActivitiesFriends();
+				ActivityStreams.loadActivitiesViewer();
+				alert('Loading Activities...');
+				
+				// Compose HTML
+				htmlActivities = "<br><br>All Activities: <br>";
+				htmlActivities += "<table border='1'>";
+				htmlActivities += "<tr>";
+				htmlActivities += "<td>Name</td>";
+				htmlActivities += "<td>Title</td>";
+				htmlActivities += "<td>Body</td>";
+				htmlActivities += "<td>Images</td>";
+				htmlActivities += "</tr>"
+				processActivities(viewerActivities);
+				processActivities(friendActivities);
+				htmlActivities += "</table>";
+			}
+			
+			function processActivities(activities) {
+				for(idx = 0; idx < activities.list.length; idx++) {
+					htmlActivities += "<tr>";
+					htmlActivities += "<td>" + activities.list[idx].userId + "</td>";
+					htmlActivities += "<td>" + activities.list[idx].title + "</td>";
+					htmlActivities += "<td>" + activities.list[idx].body + "</td>";
+					var mediaItems = activities.list[idx].mediaItems;
+					if(mediaItems != null) {
+						for(itemIdx = 0; itemIdx < mediaItems.length; itemIdx++) {
+							if(mediaItems[itemIdx].type == "image") {
+								htmlActivities += "<td><img src='" + mediaItems[itemIdx].url + "' width=150 height=150/></td>";
+							}
+						}
+					}
+					htmlActivities += "</tr>";
+				}
+			}
+			
+			// =================== GADGET SET UP ================
+			// Refreshes the HTML content
+			function refreshHTML() {
+				document.getElementById('message').innerHTML = htmlWelcome + htmlActivities + htmlActivityEntries + htmlCreateActivityEntry + htmlDeleteActivityEntry + htmlGetActivityEntryId;
+				gadgets.window.adjustHeight();
+			}
+		
+			// Initializes the gadget
+			function init() {
+				displayWelcome();
+				displayActivities();
+				displayActivityEntries();
+				displayCreateActivityEntry();
+				displayDeleteActivityEntry();
+				displayGetActivityEntryId();
+				refreshHTML();
+			}
+			
+			gadgets.util.registerOnLoadHandler(init);
+		</script>
+		<div id='message'></div>
+	]]>
+	</Content>
+</Module>
\ No newline at end of file

Added: shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreams.js
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreams.js?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreams.js (added)
+++ shindig/branches/activitystreams-prototype/content/samplecontainer/examples/ActivityStreams/ActivityStreams.js Fri May 14 20:07:08 2010
@@ -0,0 +1,197 @@
+/**
+ * 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.
+ */
+
+var ActivityStreams = new function() {
+
+	// =============================== PEOPLE ===============================
+	// Loads viewer and friends
+	this.loadPeople = function() {
+		var req = opensocial.newDataRequest();
+		req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
+		req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), 'owner');
+		var idSpec = opensocial.newIdSpec({'userId':'VIEWER', 'groupId':'FRIENDS'});
+		req.add(req.newFetchPeopleRequest(idSpec), 'viewerFriends');
+		req.send(this.onLoadPeople);	
+	}
+
+	// Callback for loading viewer and friends
+	this.onLoadPeople = function(response) {
+		viewer = response.get('viewer').getData();					// Load viewer (type: person)
+		owner = response.get('owner').getData();					// Load owner (type: person)
+		viewerFriends = response.get('viewerFriends').getData();	// Load viewer's friends (type: Collection<Person>)
+		CommentStream.renderWelcome();
+	}
+
+	// Loads viewer and friends using OSAPI
+	this.loadFriendsOsapi = function() {
+		var batch = osapi.newBatch();
+		batch.add('viewer', osapi.people.getViewer());
+		batch.add('viewerFriends', osapi.people.getViewerFriends());
+		batch.execute(this.onLoadFriendsOsapi);
+	}
+
+	// Callback for loading viewer and friends using OSAPI
+	this.onLoadFriendsOsapi = function(response) {
+		viewer = response.viewer;				// Type: JSON object
+		viewerFriends = response.viewerFriends;	// Type: JSON object
+		alert(JSON.stringify(response));		// Prints the raw JSON response :D
+	}
+	
+	// ========================= ACTIVITY STREAMS =============================
+	// Creates and sends an ActivityEntry
+	this.postActivityEntry = function(comment) {
+		var params = {
+			userId: '@viewer',
+			groupId: '@self',
+			activityEntry: {
+				id: 'myEntryId',
+				permalink: 'http://www.myactivityentry1.com',
+				postedTime: '2010-04-27T06:02:36+0000',
+				title: 'My Comment',
+				body: comment,
+				actor: {
+					id: 'john.doe',
+					displayName: 'Eric Woods'
+				},
+				verb: ['play', 'post'],
+				object: {
+						id: 'activityObjectID',
+						displayName: 'My Object',
+						permalinkUrl: 'http://www.myobject.com',
+						objectType: ['event', 'meetup']
+				}
+			}
+		}
+		
+		// Send the request and register callback
+		osapi.activitystreams.create(params).execute(this.onPostActivityEntry);
+	}
+	this.onPostActivityEntry = function(response) {
+		//alert('onPostActivityEntry: ' + JSON.stringify(response));
+	}
+	
+	// Deletes the ActivityEntry with the given id
+	this.deleteActivityEntry = function(activityEntryId) {
+		// Generate request
+		var params = {
+			userId: '@viewer',
+			groupId: '@self',
+			activityEntryId: activityEntryId
+		}
+		
+		// Send request
+		osapi.activitystreams.delete(params).execute(this.onDeleteActivityEntry);
+	}
+	this.onDeleteActivityEntry = function(response) {
+		//alert('onDeleteActivityEntry: ' + JSON.stringify(response));
+	}
+	
+	// Loads the ActivityEntries of the viewer
+	this.loadActivityEntriesViewer = function() {
+		var params = {userId: '@viewer', groupId: '@self'}
+		osapi.activitystreams.get(params).execute(this.onLoadActivityEntriesViewer);
+	}
+	this.onLoadActivityEntriesViewer = function(response) {
+		viewerActivityEntries = response;
+		//alert('onLoadActivityEntriesViewer: ' + JSON.stringify(response));
+	}
+	
+	// Loads the ActivityEntries of the viewer's friends
+	this.loadActivityEntriesFriends = function() {
+		var params = {userId: '@viewer', groupId: '@friends'}
+		osapi.activitystreams.get(params).execute(this.onLoadActivityEntriesFriends);
+	}
+	this.onLoadActivityEntriesFriends = function(response) {
+		//alert('onLoadActivityEntriesFriends: ' + JSON.stringify(response));
+		friendActivityEntries = response;
+	}
+	
+	// Loads the ActivityEntry with the given ID
+	this.loadActivityEntryId = function(activityEntryId) {
+		var params = {activityEntryIds: ['myEntryID', activityEntryId]};
+		osapi.activitystreams.get(params).execute(this.onLoadActivityEntryId);
+	}
+	this.onLoadActivityEntryId = function(response) {
+		alert('onLoadActivityEntryId: ' + JSON.stringify(response));
+	}
+	
+	// ============================== ACTIVITIES ==============================
+	// Gets the activities of the viewer
+	this.loadActivitiesViewer = function() {
+		var req = osapi.activities.get({userId: '@viewer', groupId: '@self'});
+		req.execute(this.onLoadActivitiesViewer);
+	}
+	
+	// Callback to get the activities of the viewer
+	this.onLoadActivitiesViewer = function(response) {
+		viewerActivities = response;
+		//alert(JSON.stringify(response));		// Prints the raw JSON response :D
+	}
+	
+	// Gets the activities of the viewer's friends
+	this.loadActivitiesFriends = function() {
+		var req = osapi.activities.get({userId: '@viewer', groupId: '@friends'});
+		req.execute(this.onLoadActivitiesFriends);
+	}
+	
+	// Callback to get the activities of the viewer's friends
+	this.onLoadActivitiesFriends = function(response) {
+		friendActivities = response;
+		//alert(JSON.stringify(response));		// Prints the raw JSON response :D
+	}
+	
+	// Creates and sends an activity.
+	this.postActivity = function(title, body, photoURL, photoUploaded) {
+		//alert('postActivity(' + title + ', ' + body + ',' + photoURL + ',' + photoUploaded + ')');
+		
+		if(false && photoURL != '') {
+			alert('uploading image at URL: ' + photoURL);
+			
+			var params = {};
+			params[opensocial.MediaItem.Field.MIME_TYPE] = 'image/jpeg';
+			params[opensocial.MediaItem.Field.TYPE] = opensoical.MediaItem.Type.IMAGE;
+			params[opensocial.MediaItem.Field.URL] = photoURL;
+			var media = opensocial.newMediaItem('image/jpeg', photoURL, params);
+			var req = opensocial.newDataRequest();
+			var idSpec = opensocial.newIdSpec({'userId':'VIEWER', 'groupId':'FRIENDS'});
+			req.add(req.newCreateMediaItemRequest(idSpec, '1', media), 'media');
+			req.send(function(response) {
+				alert('respone!');
+				alert(JSON.stringify(response));
+			});
+		}
+			
+		var params = {
+			auth: {"default" : null, "type" : "AuthToken"},
+			userId: '@viewer',
+			groupId: '@self',
+			activity: {
+				userId: viewer.getId(),
+				title: title,
+				body: body,
+				updated: '2009-06-01T12:54:00Z'
+			}
+		};
+		osapi.activities.create(params).execute(this.onPostActivity);
+	}
+	
+	// Callback for posting activities
+	this.onPostActivity = function(response) {
+		alert(JSON.stringify(response));		// Prints the raw JSON response :D
+	}
+}
\ No newline at end of file

Modified: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/config/SocialApiGuiceModule.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/config/SocialApiGuiceModule.java?rev=944438&r1=944437&r2=944438&view=diff
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/config/SocialApiGuiceModule.java (original)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/config/SocialApiGuiceModule.java Fri May 14 20:07:08 2010
@@ -30,6 +30,7 @@ import org.apache.shindig.social.core.oa
 import org.apache.shindig.social.core.util.BeanXStreamAtomConverter;
 import org.apache.shindig.social.core.util.xstream.XStream081Configuration;
 import org.apache.shindig.social.opensocial.service.ActivityHandler;
+import org.apache.shindig.social.opensocial.service.ActivityStreamHandler;
 import org.apache.shindig.social.opensocial.service.AppDataHandler;
 import org.apache.shindig.social.opensocial.service.MessageHandler;
 import org.apache.shindig.social.opensocial.service.PersonHandler;
@@ -82,7 +83,11 @@ public class SocialApiGuiceModule extend
    * to add or replace additional handlers.
    */
   protected Set<Class<?>> getHandlers() {
-    return ImmutableSet.<Class<?>>of(ActivityHandler.class, AppDataHandler.class,
-        PersonHandler.class, MessageHandler.class);
+    return ImmutableSet.<Class<?>>of(
+      ActivityHandler.class, 
+      AppDataHandler.class,
+      PersonHandler.class,
+      MessageHandler.class,
+      ActivityStreamHandler.class );
   }
 }

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityEntryImpl.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityEntryImpl.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityEntryImpl.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityEntryImpl.java Fri May 14 20:07:08 2010
@@ -0,0 +1,131 @@
+/*
+ * 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.core.model;
+
+import java.util.List;
+
+import org.apache.shindig.social.opensocial.model.ActivityEntry;
+import org.apache.shindig.social.opensocial.model.ActivityObject;
+
+public class ActivityEntryImpl implements ActivityEntry {
+
+	private String id;
+	private String streamFavicon;
+	private String postedTime;
+	private ActivityObject actor;
+	private List<String> verb;
+	private ActivityObject object;
+	private ActivityObject target;
+	private String permalink;
+	private String title;
+	private String body;
+	
+	public ActivityEntryImpl() {
+		this.id = null;
+		this.streamFavicon = null;
+		this.postedTime = null;
+		this.actor = null;
+		this.verb = null;
+		this.object = null;
+		this.target = null;
+		this.permalink = null;
+		this.title = null;
+		this.body = null;
+	}
+	
+	public void setId(String id) {
+		this.id = id;
+	}
+	
+	public String getId() {
+		return id;
+	}
+	
+	public void setStreamFavicon(String streamFavicon) {
+		this.streamFavicon = streamFavicon;
+	}
+	
+	public String getStreamFavicon() {
+		return streamFavicon;
+	}
+	
+	public void setPostedTime(String postedTime) {
+		this.postedTime = postedTime;
+	}
+	
+	public String getPostedTime() {
+		return postedTime;
+	}
+	
+	public void setActor(ActivityObject actor) {
+		this.actor = actor;
+	}
+	
+	public ActivityObject getActor() {
+		return actor;
+	}
+	
+	public void setVerb(List<String> verb) {
+		this.verb = verb;
+	}
+	
+	public List<String> getVerb() {
+		return verb;
+	}
+	
+	public void setObject(ActivityObject object) {
+		this.object = object;
+	}
+	
+	public ActivityObject getObject() {
+		return object;
+	}
+	
+	public void setTarget(ActivityObject target) {
+		this.target = target;
+	}
+	
+	public ActivityObject getTarget() {
+		return target;
+	}
+	
+	public void setPermalink(String permalink) {
+		this.permalink = permalink;
+	}
+	
+	public String getPermalink() {
+		return permalink;
+	}
+	
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	public String getTitle() {
+		return title;
+	}
+		
+	public void setBody(String body) {
+		this.body = body;
+	}
+	
+	public String getBody() {
+		return body;
+	}
+}

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityObjectImpl.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityObjectImpl.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityObjectImpl.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityObjectImpl.java Fri May 14 20:07:08 2010
@@ -0,0 +1,200 @@
+/*
+ * 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.core.model;
+
+import java.util.List;
+
+import org.apache.shindig.social.opensocial.model.ActivityObject;
+
+public class ActivityObjectImpl implements ActivityObject {
+	
+	private String id;
+	private String displayName;
+	private String summary;
+	private String permalink;
+	private String image;
+	private List<String> objectType;
+	private String content;
+	private String audioStream;
+	private String videoStream;
+	private String playerApplet;
+	private String bookmarkTarget;
+	private String thumbnail;
+	private String subject;
+	private String description;
+	private String rating;
+	private String icon;
+	private ActivityObject inReplyTo;
+	
+	public ActivityObjectImpl() {
+		this.id = null;
+		this.displayName = null;
+		this.summary = null;
+		this.permalink = null;
+		this.image = null;
+		this.content = null;
+		this.audioStream = null;
+		this.videoStream = null;
+		this.playerApplet = null;
+		this.bookmarkTarget = null;
+		this.thumbnail = null;
+		this.subject = null;
+		this.description = null;
+		this.rating = null;
+		this.icon = null;
+		this.objectType = null;
+		this.inReplyTo = null;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getDisplayName() {
+		return displayName;
+	}
+
+	public void setDisplayName(String displayName) {
+		this.displayName = displayName;
+	}
+
+	public String getSummary() {
+		return summary;
+	}
+
+	public void setSummary(String summary) {
+		this.summary = summary;
+	}
+
+	public String getPermalink() {
+		return permalink;
+	}
+
+	public void setPermalink(String permalink) {
+		this.permalink = permalink;
+	}
+
+	public String getImage() {
+		return image;
+	}
+
+	public void setImage(String image) {
+		this.image = image;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getAudioStream() {
+		return audioStream;
+	}
+
+	public void setAudioStream(String audioStream) {
+		this.audioStream = audioStream;
+	}
+
+	public String getVideoStream() {
+		return videoStream;
+	}
+
+	public void setVideoStream(String videoStream) {
+		this.videoStream = videoStream;
+	}
+
+	public String getPlayerApplet() {
+		return playerApplet;
+	}
+
+	public void setPlayerApplet(String playerApplet) {
+		this.playerApplet = playerApplet;
+	}
+
+	public String getBookmarkTarget() {
+		return bookmarkTarget;
+	}
+
+	public void setBookmarkTarget(String bookmarkTarget) {
+		this.bookmarkTarget = bookmarkTarget;
+	}
+
+	public String getThumbnail() {
+		return thumbnail;
+	}
+
+	public void setThumbnail(String thumbnail) {
+		this.thumbnail = thumbnail;
+	}
+
+	public String getSubject() {
+		return subject;
+	}
+
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getRating() {
+		return rating;
+	}
+
+	public void setRating(String rating) {
+		this.rating = rating;
+	}
+
+	public String getIcon() {
+		return icon;
+	}
+
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	public List<String> getObjectType() {
+		return objectType;
+	}
+
+	public void setObjectType(List<String> objectType) {
+		this.objectType = objectType;
+	}
+
+	public ActivityObject getInReplyTo() {
+		return inReplyTo;
+	}
+
+	public void setInReplyTo(ActivityObject inReplyTo) {
+		this.inReplyTo = inReplyTo;
+	}
+}

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityStreamImpl.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityStreamImpl.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityStreamImpl.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/model/ActivityStreamImpl.java Fri May 14 20:07:08 2010
@@ -0,0 +1,81 @@
+/*
+ * 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.core.model;
+
+import java.util.List;
+
+import org.apache.shindig.social.opensocial.model.ActivityEntry;
+import org.apache.shindig.social.opensocial.model.ActivityStream;
+
+public class ActivityStreamImpl implements ActivityStream {
+
+	private String displayName;
+	private String language;
+	private List<ActivityEntry> entries;
+	private String id;
+	private String subject;
+	
+	public ActivityStreamImpl() {
+		this.displayName = null;
+		this.language = null;
+		this.entries = null;
+		this.id = null;
+		this.subject = null;
+	}
+
+	public String getDisplayName() {
+		return displayName;
+	}
+
+	public List<ActivityEntry> getEntries() {
+		return entries;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getLanguage() {
+		return language;
+	}
+
+	public String getSubject() {
+		return subject;
+	}
+
+	public void setDisplayName(String displayName) {
+		this.displayName = displayName;
+	}
+
+	public void setEntries(List<ActivityEntry> entries) {
+		this.entries = entries;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public void setLanguage(String language) {
+		this.language = language;
+	}
+
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+}

Modified: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/util/xstream/XStream081Configuration.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/util/xstream/XStream081Configuration.java?rev=944438&r1=944437&r2=944438&view=diff
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/util/xstream/XStream081Configuration.java (original)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/core/util/xstream/XStream081Configuration.java Fri May 14 20:07:08 2010
@@ -17,6 +17,12 @@
  */
 package org.apache.shindig.social.core.util.xstream;
 
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.apache.shindig.protocol.DataCollection;
 import org.apache.shindig.protocol.RestfulCollection;
 import org.apache.shindig.protocol.conversion.xstream.ClassFieldMapping;
@@ -41,6 +47,7 @@ import org.apache.shindig.social.core.ut
 import org.apache.shindig.social.core.util.atom.AtomLinkConverter;
 import org.apache.shindig.social.opensocial.model.Account;
 import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.ActivityStream;
 import org.apache.shindig.social.opensocial.model.Address;
 import org.apache.shindig.social.opensocial.model.BodyType;
 import org.apache.shindig.social.opensocial.model.ListField;
@@ -69,12 +76,6 @@ import com.thoughtworks.xstream.io.Hiera
 import com.thoughtworks.xstream.mapper.AttributeMapper;
 import com.thoughtworks.xstream.mapper.Mapper;
 
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  * Opensocial 0.81 compliant Xstream binding
  */
@@ -135,6 +136,7 @@ public class XStream081Configuration imp
         .put("feed", atom)
         .put("person", os)
         .put("activity", os)
+        .put("activityStream", os)
         .put("account", os)
         .put("address", os)
         .put("bodyType", os)
@@ -154,6 +156,7 @@ public class XStream081Configuration imp
         new ClassFieldMapping("content", AtomContent.class),
 
         new ClassFieldMapping("activity", Activity.class),
+        new ClassFieldMapping("activityStream", ActivityStream.class),
         new ClassFieldMapping("account", Account.class),
         new ClassFieldMapping("address", Address.class),
         new ClassFieldMapping("bodyType", BodyType.class),
@@ -188,6 +191,7 @@ public class XStream081Configuration imp
         new ClassFieldMapping("content", AtomContent.class),
 
         new ClassFieldMapping("activity", Activity.class),
+        new ClassFieldMapping("activityStream", ActivityStream.class),
         new ClassFieldMapping("account", Account.class),
         new ClassFieldMapping("address", Address.class),
         new ClassFieldMapping("bodyType", BodyType.class),
@@ -223,6 +227,7 @@ public class XStream081Configuration imp
         .put("map", ConcurrentHashMap.class)
         .put("appdata", DataCollection.class)
         .put("activity", Activity.class)
+        .put("activityStream", ActivityStream.class)
         .put("account", Account.class)
         .put("address", Address.class)
         .put("bodyType", BodyType.class)

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityEntry.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityEntry.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityEntry.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityEntry.java Fri May 14 20:07:08 2010
@@ -0,0 +1,150 @@
+/*
+ * 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.opensocial.model;
+
+import java.util.List;
+
+import org.apache.shindig.protocol.model.Exportablebean;
+import org.apache.shindig.social.core.model.ActivityEntryImpl;
+
+import com.google.inject.ImplementedBy;
+
+@ImplementedBy(ActivityEntryImpl.class)
+@Exportablebean
+public interface ActivityEntry {
+	
+	/*
+	 * Fields that represent JSON elements for an activity entry.
+	 */
+	public static enum Field {
+		ID("id"),
+		STREAM_FAVICON_("streamFavicon"),
+		POSTED_TIME("postedTime"),
+		ACTOR("actor"),
+		VERB("verb"),
+		OBJECT("object"),
+		TARGET("target"),
+		PERMALINK_("permalink"),
+		TITLE("title"),
+		BODY("body");
+		
+		/*
+		 * The name of the JSON element.
+		 */
+		private final String jsonString;
+		
+		/*
+		 * Constructs the field base for the JSON element.
+		 * 
+		 * @param jsonString the name of the element
+		 */
+		private Field(String jsonString) {
+			this.jsonString = jsonString;
+		}
+		
+		/*
+		 * Returns the name of the JSON element.
+		 * 
+		 * @return String the name of the JSON element
+		 */
+		public String toString() {
+			return jsonString;
+		}
+	}
+	
+	/*
+	 * Possible verbs for an activity stream entry.
+	 */
+	public static enum Verb {
+		MARK_AS_FAVORITE("markAsFavorite"),
+		START_FOLLOWING("startFollowing"),
+		MARK_AS_LIKED("markAsLiked"),
+		MAKE_FRIEND("makeFriend"),
+		JOIN("join"),
+		PLAY("play"),
+		POST("post"),
+		SAVE("save"),
+		SHARE("share"),
+		TAG("tag"),
+		UPDATE("update");
+		
+		/*
+		 * The name of the JSON element.
+		 */
+		private final String jsonString;
+		
+		/*
+		 * Constructs the field base for the JSON element.
+		 * 
+		 * @param jsonString the name of the element
+		 */
+		private Verb(String jsonString) {
+			this.jsonString = jsonString;
+		}
+		
+		/*
+		 * Returns the name of the JSON element.
+		 * 
+		 * @return String the name of the JSON element
+		 */
+		public String toString() {
+			return jsonString;
+		}
+	}
+	
+	void setId(String id);
+	
+	String getId();
+	
+	void setStreamFavicon(String streamFavicon);
+	
+	String getStreamFavicon();
+	
+	void setPostedTime(String postedTime);
+	
+	String getPostedTime();
+	
+	void setActor(ActivityObject actor);
+	
+	ActivityObject getActor();
+	
+	void setVerb(List<String> verb);
+	
+	List<String> getVerb();
+	
+	void setObject(ActivityObject object);
+	
+	ActivityObject getObject();
+	
+	void setTarget(ActivityObject target);
+	
+	ActivityObject getTarget();
+	
+	void setPermalink(String permalink);
+	
+	String getPermalink();
+	
+	void setTitle(String title);
+	
+	String getTitle();
+	
+	void setBody(String body);
+	
+	String getBody();
+}
\ No newline at end of file

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityObject.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityObject.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityObject.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityObject.java Fri May 14 20:07:08 2010
@@ -0,0 +1,145 @@
+/*
+ * 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.opensocial.model;
+
+import java.util.List;
+
+import org.apache.shindig.protocol.model.Exportablebean;
+import org.apache.shindig.social.core.model.ActivityObjectImpl;
+
+import com.google.inject.ImplementedBy;
+
+@ImplementedBy(ActivityObjectImpl.class)
+@Exportablebean
+public interface ActivityObject {
+	
+	/*
+	 * Fields that represent JSON elements for an activity entry.
+	 */
+	public static enum Field {
+		ID("id"),
+		DISPLAY_NAME("displayName"),
+		SUMMARY("summary"),
+		PERMALINK("permalink"),
+		IMAGE("image"),
+		CONTENT("content"),
+		AUDIO_STREAM("audioStream"),
+		VIDEO_STREAM("videoStream"),
+		PLAYER_APPLET("playerApplet"),
+		BOOKMARK_TARGET("bookmarkTarget"),
+		THUMBNAIL("thumbnail"),
+		SUBJECT("subject"),
+		DESCRIPTION("description"),
+		RATING("rating"),
+		ICON("icon"),
+		IN_REPLY_TO("inReplyTo"),
+		OBJECT_TYPE("objectType");
+		
+		/*
+		 * The name of the JSON element.
+		 */
+		private final String jsonString;
+		
+		/*
+		 * Constructs the field base for the JSON element.
+		 * 
+		 * @param jsonString the name of the element
+		 */
+		private Field(String jsonString) {
+			this.jsonString = jsonString;
+		}
+		
+		/*
+		 * Returns the name of the JSON element.
+		 * 
+		 * @return String the name of the JSON element
+		 */
+		public String toString() {
+			return jsonString;
+		}
+	}
+	
+	String getId();
+
+	void setId(String id);
+
+	String getDisplayName();
+
+	void setDisplayName(String displayName);
+
+	String getSummary();
+
+	void setSummary(String summary);
+
+	String getPermalink();
+
+	void setPermalink(String permalink);
+
+	String getImage();
+
+	void setImage(String image);
+
+	String getContent();
+
+	void setContent(String content);
+
+	String getAudioStream();
+
+	void setAudioStream(String audioStream);
+
+	String getVideoStream();
+
+	void setVideoStream(String videoStream);
+
+	String getPlayerApplet();
+
+	void setPlayerApplet(String playerApplet);
+
+	String getBookmarkTarget();
+
+	void setBookmarkTarget(String bookmarkTarget);
+	
+	String getThumbnail();
+
+	void setThumbnail(String thumbnail);
+
+	String getSubject();
+
+	void setSubject(String subject);
+
+	String getDescription();
+
+	void setDescription(String description);
+
+	String getRating();
+
+	void setRating(String rating);
+
+	String getIcon();
+
+	void setIcon(String icon);
+
+	List<String> getObjectType();
+
+	void setObjectType(List<String> objectType);
+
+	ActivityObject getInReplyTo();
+
+	void setInReplyTo(ActivityObject inReplyTo);
+}
\ No newline at end of file

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityStream.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityStream.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityStream.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/ActivityStream.java Fri May 14 20:07:08 2010
@@ -0,0 +1,91 @@
+/*
+ * 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.opensocial.model;
+
+import java.util.List;
+
+import org.apache.shindig.protocol.model.Exportablebean;
+import org.apache.shindig.social.core.model.ActivityStreamImpl;
+
+import com.google.inject.ImplementedBy;
+
+/*
+ * Interface for an Activity Stream.
+ * <p>
+ * See the Activity Streams specification for more detail:
+ * http://activitystrea.ms/
+ */
+@ImplementedBy(ActivityStreamImpl.class)
+@Exportablebean
+public interface ActivityStream {
+	
+	/*
+	 * Fields that represent JSON elements for an activity entry.
+	 */
+	public static enum Field {
+		DISPLAY_NAME("displayName"),
+		LANGUAGE("language"),
+		ENTRIES("entries"),
+		ID("id"),
+		SUBJECT("subject");
+		
+		/*
+		 * The name of the JSON element.
+		 */
+		private final String jsonString;
+		
+		/*
+		 * Constructs the field base for the JSON element.
+		 * 
+		 * @param jsonString the name of the element
+		 */
+		private Field(String jsonString) {
+			this.jsonString = jsonString;
+		}
+		
+		/*
+		 * Returns the name of the JSON element.
+		 * 
+		 * @return String the name of the JSON element
+		 */
+		public String toString() {
+			return jsonString;
+		}
+	}
+	
+	void setId(String id);
+	
+	String getId();
+	
+	void setEntries(List<ActivityEntry> entries);
+	
+	List<ActivityEntry> getEntries();
+	
+	void setLanguage(String language);
+	
+	String getLanguage();
+	
+	void setSubject(String subject);
+	
+	String getSubject();
+	
+	void setDisplayName(String displayName);
+	
+	String getDisplayName();
+}
\ No newline at end of file

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/service/ActivityStreamHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/service/ActivityStreamHandler.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/service/ActivityStreamHandler.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/service/ActivityStreamHandler.java Fri May 14 20:07:08 2010
@@ -0,0 +1,156 @@
+/*
+ * 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.opensocial.service;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.protocol.HandlerPreconditions;
+import org.apache.shindig.protocol.Operation;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RequestItem;
+import org.apache.shindig.protocol.Service;
+import org.apache.shindig.social.opensocial.model.ActivityEntry;
+import org.apache.shindig.social.opensocial.spi.ActivityStreamService;
+import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+import org.apache.shindig.social.opensocial.spi.UserId;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+@Service(name = "activitystreams", path="/{userId}+/{groupId}/{appId}/{activitystream}/{activityEntryId}+")
+public class ActivityStreamHandler  {
+
+  private final ActivityStreamService service;
+  private final ContainerConfig config;
+
+  @Inject
+  public ActivityStreamHandler(ActivityStreamService service, ContainerConfig config) {
+    this.service = service;
+    this.config = config;
+  }
+
+  /**
+   * Allowed end-points /activities/{userId}/@self/{actvityId}+
+   *
+   * examples: /activities/john.doe/@self/1
+   */
+  @Operation(httpMethods="DELETE")
+  public Future<?> delete(SocialRequestItem request)
+      throws ProtocolException {
+
+    Set<UserId> userIds = request.getUsers();
+    Set<String> activityEntryIds = ImmutableSet.copyOf(request.getListParameter("activityEntryId"));
+
+    HandlerPreconditions.requireNotEmpty(userIds, "No userId specified");
+    HandlerPreconditions.requireSingular(userIds, "Multiple userIds not supported");
+    // Throws exceptions if userIds contains more than one element or zero elements
+    return service.deleteActivityEntries(Iterables.getOnlyElement(userIds), request.getGroup(),
+        request.getAppId(), activityEntryIds, request.getToken());
+  }
+
+  /**
+   * Allowed end-points /activities/{userId}/@self
+   *
+   * examples: /activities/john.doe/@self - postBody is an activity object
+   * 
+   * TODO: REST end-point
+   */
+  @Operation(httpMethods="PUT", bodyParam = "activityEntry")
+  public Future<?> update(SocialRequestItem request) throws ProtocolException {
+    return create(request);
+  }
+
+  /**
+   * Allowed end-points /activities/{userId}/@self
+   *
+   * examples: /activities/john.doe/@self - postBody is an activity object
+   * 
+   * TODO: REST end-point
+   */
+  @Operation(httpMethods="POST", bodyParam = "activityEntry")
+  public Future<?> create(SocialRequestItem request) throws ProtocolException {
+    Set<UserId> userIds = request.getUsers();
+    List<String> activityEntryIds = request.getListParameter("activityEntryId");
+
+    HandlerPreconditions.requireNotEmpty(userIds, "No userId specified");
+    HandlerPreconditions.requireSingular(userIds, "Multiple userIds not supported");
+    // TODO(lryan) This seems reasonable to allow on PUT but we don't have an update verb.
+    HandlerPreconditions.requireEmpty(activityEntryIds, "Cannot specify activityEntryId in create");
+
+    return service.createActivityEntry(Iterables.getOnlyElement(userIds), request.getGroup(),
+        request.getAppId(), request.getFields(),
+        request.getTypedParameter("activityEntry", ActivityEntry.class),
+        request.getToken());
+  }
+
+  /**
+   * Allowed end-points /activities/{userId}/{groupId}/{optionalActvityId}+
+   * /activities/{userId}+/{groupId}
+   *
+   * examples: /activities/john.doe/@self/1 /activities/john.doe/@self
+   * /activities/john.doe,jane.doe/@friends
+   */
+  @Operation(httpMethods="GET")
+  public Future<?> get(SocialRequestItem request)
+      throws ProtocolException {
+    Set<UserId> userIds = request.getUsers();
+    Set<String> optionalActivityIds = ImmutableSet.copyOf(request.getListParameter("activityEntryId"));
+
+    CollectionOptions options = new CollectionOptions(request);
+
+    // Preconditions
+    HandlerPreconditions.requireNotEmpty(userIds, "No userId specified");
+    if (userIds.size() > 1 && !optionalActivityIds.isEmpty()) {
+      throw new IllegalArgumentException("Cannot fetch same activityEntryIds for multiple userIds");
+    }
+
+    if (!optionalActivityIds.isEmpty()) {
+      if (optionalActivityIds.size() == 1) {
+        return service.getActivityEntry(userIds.iterator().next(), request.getGroup(),
+            request.getAppId(), request.getFields(), optionalActivityIds.iterator().next(),
+            request.getToken());
+      } else {
+        return service.getActivityEntries(userIds.iterator().next(), request.getGroup(),
+            request.getAppId(), request.getFields(), options, optionalActivityIds, request.getToken());
+      }
+    }
+
+    return service.getActivityEntries(userIds, request.getGroup(),
+        request.getAppId(),
+        // TODO: add pagination and sorting support
+        // getSortBy(params), getFilterBy(params), getStartIndex(params), getCount(params),
+        request.getFields(), options, request.getToken());
+  }
+
+  @Operation(httpMethods = "GET", path="/@supportedFields")
+  public List<Object> supportedFields(RequestItem request) {
+    // TODO: Would be nice if name in config matched name of service.
+    String container = firstNonNull(request.getToken().getContainer(), ContainerConfig.DEFAULT_CONTAINER);
+    return config.getList(container,
+        "${Cur['gadgets.features'].opensocial.supportedFields.activitystream}");
+  }
+
+  private static <T> T firstNonNull(T first, T second) {
+    return first != null ? first : Preconditions.checkNotNull(second);
+  }
+}

Added: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/spi/ActivityStreamService.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/spi/ActivityStreamService.java?rev=944438&view=auto
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/spi/ActivityStreamService.java (added)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/opensocial/spi/ActivityStreamService.java Fri May 14 20:07:08 2010
@@ -0,0 +1,111 @@
+/*
+ * 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.opensocial.spi;
+
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.social.opensocial.model.ActivityEntry;
+import org.apache.shindig.social.opensocial.model.ActivityStream;
+
+/**
+ * The ActivityService interface defines the service provider interface to retrieve activities from
+ * the underlying SNS.
+ */
+public interface ActivityStreamService {
+
+  /**
+   * Returns a list of activities that correspond to the passed in users and group.
+   *
+   * @param userIds The set of ids of the people to fetch activities for.
+   * @param groupId Indicates whether to fetch activities for a group.
+   * @param appId   The app id.
+   * @param fields  The fields to return. Empty set implies all
+   * @param options The sorting/filtering/pagination options
+   * @param token   A valid SecurityToken
+   * @return a response item with the list of activities.
+   */
+  Future<RestfulCollection<ActivityEntry>> getActivityEntries(Set<UserId> userIds,
+      GroupId groupId, String appId, Set<String> fields, CollectionOptions options, SecurityToken token)
+      throws ProtocolException;
+
+  /**
+   * Returns a set of activities for the passed in user and group that corresponds to a list of
+   * activityIds.
+   *
+   * @param userId      The set of ids of the people to fetch activities for.
+   * @param groupId     Indicates whether to fetch activities for a group.
+   * @param appId       The app id.
+   * @param fields      The fields to return. Empty set implies all
+   * @param options The sorting/filtering/pagination options
+   * @param activityIds The set of activity ids to fetch.
+   * @param token       A valid SecurityToken
+   * @return a response item with the list of activities.
+   */
+  Future<RestfulCollection<ActivityEntry>> getActivityEntries(UserId userId, GroupId groupId,
+      String appId, Set<String> fields, CollectionOptions options, Set<String> activityIds, SecurityToken token)
+      throws ProtocolException;
+
+
+  /**
+   * Returns an activity for the passed in user and group that corresponds to a single
+   * activityId.
+   *
+   * @param userId     The set of ids of the people to fetch activities for.
+   * @param groupId    Indicates whether to fetch activities for a group.
+   * @param appId      The app id.
+   * @param fields     The fields to return. Empty set implies all
+   * @param activityId The activity id to fetch.
+   * @param token      A valid SecurityToken
+   * @return a response item with the list of activities.
+   */
+  Future<ActivityEntry> getActivityEntry(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, String activityId, SecurityToken token)
+      throws ProtocolException;
+
+  /**
+   * Deletes the activity for the passed in user and group that corresponds to the activityId.
+   *
+   * @param userId      The user.
+   * @param groupId     The group.
+   * @param appId       The app id.
+   * @param activityIds A list of activity ids to delete.
+   * @param token       A valid SecurityToken.
+   * @return a response item containing any errors
+   */
+  Future<Void> deleteActivityEntries(UserId userId, GroupId groupId, String appId,
+      Set<String> activityIds, SecurityToken token) throws ProtocolException;
+
+  /**
+   * Creates the passed in activity for the passed in user and group. Once createActivity is called,
+   * getActivities will be able to return the Activity.
+   *
+   * @param userId   The id of the person to create the activity for.
+   * @param groupId  The group.
+   * @param appId    The app id.
+   * @param fields   The fields to return.
+   * @param activity The activity to create.
+   * @param token    A valid SecurityToken
+   * @return a response item containing any errors
+   */
+  Future<Void> createActivityEntry(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, ActivityEntry activity, SecurityToken token) throws ProtocolException;
+}

Modified: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java?rev=944438&r1=944437&r2=944438&view=diff
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java (original)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java Fri May 14 20:07:08 2010
@@ -19,6 +19,7 @@ package org.apache.shindig.social.sample
 
 import org.apache.shindig.social.opensocial.oauth.OAuthDataStore;
 import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.ActivityStreamService;
 import org.apache.shindig.social.opensocial.spi.AppDataService;
 import org.apache.shindig.social.opensocial.spi.MessageService;
 import org.apache.shindig.social.opensocial.spi.PersonService;
@@ -43,6 +44,7 @@ public class SampleModule extends Abstra
     bind(String.class).annotatedWith(Names.named("shindig.canonical.json.db"))
         .toInstance("sampledata/canonicaldb.json");
     bind(ActivityService.class).to(JsonDbOpensocialService.class);
+    bind(ActivityStreamService.class).to(JsonDbOpensocialService.class);
     bind(AppDataService.class).to(JsonDbOpensocialService.class);
     bind(PersonService.class).to(JsonDbOpensocialService.class);
     bind(MessageService.class).to(JsonDbOpensocialService.class);

Copied: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java.orig (from r944421, shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java)
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java.orig?p2=shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java.orig&p1=shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/SampleModule.java&r1=944421&r2=944438&rev=944438&view=diff
==============================================================================
    (empty)

Modified: shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java
URL: http://svn.apache.org/viewvc/shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java?rev=944438&r1=944437&r2=944438&view=diff
==============================================================================
--- shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java (original)
+++ shindig/branches/activitystreams-prototype/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java Fri May 14 20:07:08 2010
@@ -18,6 +18,16 @@
 
 package org.apache.shindig.social.sample.spi;
 
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.common.util.ImmediateFuture;
@@ -28,10 +38,14 @@ import org.apache.shindig.protocol.Restf
 import org.apache.shindig.protocol.conversion.BeanConverter;
 import org.apache.shindig.protocol.model.SortOrder;
 import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.ActivityEntry;
+import org.apache.shindig.social.opensocial.model.ActivityObject;
+import org.apache.shindig.social.opensocial.model.ActivityStream;
 import org.apache.shindig.social.opensocial.model.Message;
 import org.apache.shindig.social.opensocial.model.MessageCollection;
 import org.apache.shindig.social.opensocial.model.Person;
 import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.ActivityStreamService;
 import org.apache.shindig.social.opensocial.spi.AppDataService;
 import org.apache.shindig.social.opensocial.spi.CollectionOptions;
 import org.apache.shindig.social.opensocial.spi.GroupId;
@@ -42,16 +56,6 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import javax.servlet.http.HttpServletResponse;
-
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -64,7 +68,7 @@ import com.google.inject.name.Named;
  * Implementation of supported services backed by a JSON DB.
  */
 @Singleton
-public class JsonDbOpensocialService implements ActivityService, PersonService, AppDataService,
+public class JsonDbOpensocialService implements ActivityService, ActivityStreamService, PersonService, AppDataService,
     MessageService {
 
   private static final Comparator<Person> NAME_COMPARATOR = new Comparator<Person>() {
@@ -94,6 +98,11 @@ public class JsonDbOpensocialService imp
    * db["people"] -> Map<Person.Id, Array<Activity>>
    */
   private static final String ACTIVITIES_TABLE = "activities";
+  
+  /**
+   * db["people"] -> Map<Person.Id, Array<ActivityEntry>>
+   */
+  private static final String ACTIVITYSTREAMS_TABLE = "activityEntries";
 
   /**
    * db["data"] -> Map<Person.Id, Map<String, String>>
@@ -254,6 +263,143 @@ public class JsonDbOpensocialService imp
           je);
     }
   }
+  
+  // Are fields really needed here?
+  public Future<Void> createActivityEntry(UserId userId, GroupId groupId, String appId,
+	      Set<String> fields, ActivityEntry activityEntry, SecurityToken token) throws ProtocolException {
+	try {
+	  JSONObject jsonObject = convertFromActivityEntry(activityEntry, fields);
+	  if (!jsonObject.has(ActivityEntry.Field.ID.toString())) {
+	    jsonObject.put(ActivityEntry.Field.ID.toString(), System.currentTimeMillis());
+	  }
+	  // TODO: bug fixed: jsonArray will not be null; will throw exception!
+	  // Fix in createActivity()
+	  JSONArray jsonArray;
+	  if(db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(userId.getUserId(token))) {
+		  jsonArray = db.getJSONObject(ACTIVITYSTREAMS_TABLE)
+	      				.getJSONArray(userId.getUserId(token));
+	  } else {
+		  jsonArray = new JSONArray();
+		  db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(userId.getUserId(token), jsonArray);
+	  }
+	  jsonArray.put(jsonObject);
+	  return ImmediateFuture.newInstance(null);
+	} catch (JSONException je) {
+	  throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
+	      je);
+	}
+  }
+
+  public Future<Void> deleteActivityEntries(UserId userId, GroupId groupId,
+		  String appId, Set<String> activityIds, SecurityToken token)
+		  throws ProtocolException {
+	try {
+	  String user = userId.getUserId(token);
+	  if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
+	    JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
+	    if (activityEntries != null) {
+	      JSONArray newList = new JSONArray();
+	      for (int i = 0; i < activityEntries.length(); i++) {
+	        JSONObject activityEntry = activityEntries.getJSONObject(i);
+	        if (!activityIds.contains(activityEntry.getString(ActivityEntry.Field.ID.toString()))) {
+	          newList.put(activityEntry);
+	        }
+	      }
+	      db.getJSONObject(ACTIVITYSTREAMS_TABLE).put(user, newList);
+	      // TODO: This seems very odd that we return no useful response in this
+	      // case
+	      // There is no way to represent not-found
+	      // if (found) { ??
+	      // }
+        }
+	  }
+	  // What is the appropriate response here??
+	  return ImmediateFuture.newInstance(null);
+      } catch (JSONException je) {
+	      throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
+	          je);
+	  }
+  }
+	
+  public Future<ActivityEntry> getActivityEntry(UserId userId, GroupId groupId,
+		  String appId, Set<String> fields, String activityId, SecurityToken token)
+		  throws ProtocolException {
+    try {
+      String user = userId.getUserId(token);
+      if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
+        JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
+        for (int i = 0; i < activityEntries.length(); i++) {
+          JSONObject activityEntry = activityEntries.getJSONObject(i);
+          JSONObject actor = new JSONObject(activityEntry.get(ActivityEntry.Field.ACTOR.toString()).toString());
+          String actorId = actor.get(ActivityObject.Field.ID.toString()).toString(); 
+          if (actorId.equals(user)
+              && activityEntry.get(ActivityEntry.Field.ID.toString()).equals(activityId)) {
+            return ImmediateFuture.newInstance(filterFields(activityEntry, fields, ActivityEntry.class));
+         }
+        }
+      }
+
+      throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST, "ActivityEntry not found");
+    } catch (JSONException je) {
+      throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
+          je);
+    }
+  }
+	
+  public Future<RestfulCollection<ActivityEntry>> getActivityEntries(
+		  Set<UserId> userIds, GroupId groupId, String appId, Set<String> fields,
+		  CollectionOptions options, SecurityToken token)
+		  throws ProtocolException {
+      List<ActivityEntry> result = Lists.newArrayList();
+      try {
+        Set<String> idSet = getIdSet(userIds, groupId, token);
+        for (String id : idSet) {
+          if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(id)) {
+            JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(id);
+            for (int i = 0; i < activityEntries.length(); i++) {
+              JSONObject activityEntry = activityEntries.getJSONObject(i);
+              result.add(filterFields(activityEntry, fields, ActivityEntry.class));
+              // TODO: ActivityStreams don't have appIds
+//	              if (appId == null || !activitystream.has(ActivityStream.Field.APP_ID.toString())) {
+//	                result.add(filterFields(activitystream, fields, ActivityStream.class));
+//	              } else if (activitystream.get(ActivityStream.Field.APP_ID.toString()).equals(appId)) {
+//	                result.add(filterFields(activitystream, fields, ActivityStream.class));
+//	              }
+            }
+          }
+        }
+        return ImmediateFuture.newInstance(new RestfulCollection<ActivityEntry>(result));
+    } catch (JSONException je) {
+      throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
+          je);
+    }
+  }
+	
+  public Future<RestfulCollection<ActivityEntry>> getActivityEntries(
+		  UserId userId, GroupId groupId, String appId, Set<String> fields,
+		  CollectionOptions options, Set<String> activityIds, SecurityToken token)
+		  throws ProtocolException {
+	  List<ActivityEntry> result = Lists.newArrayList();
+      try {
+        String user = userId.getUserId(token);
+        if (db.getJSONObject(ACTIVITYSTREAMS_TABLE).has(user)) {
+          JSONArray activityEntries = db.getJSONObject(ACTIVITYSTREAMS_TABLE).getJSONArray(user);
+          for (int i = 0; i < activityEntries.length(); i++) {
+            JSONObject activityEntry = activityEntries.getJSONObject(i);
+            JSONObject actor = new JSONObject(activityEntry.get(ActivityEntry.Field.ACTOR.toString()));
+            String actorId = actor.get(ActivityObject.Field.ID.toString()).toString();
+            if (actorId.equals(user)
+              && activityIds.contains(activityEntry.getString(ActivityEntry.Field.ID.toString()))) {
+            result.add(filterFields(activityEntry, fields, ActivityEntry.class));
+          }
+        }
+      }
+      return ImmediateFuture.newInstance(new RestfulCollection<ActivityEntry>(result));
+    } catch (JSONException je) {
+      throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(),
+          je);
+    }
+  }
 
   public Future<RestfulCollection<Person>> getPeople(Set<UserId> userIds, GroupId groupId,
       CollectionOptions options, Set<String> fields, SecurityToken token) throws ProtocolException {
@@ -629,6 +775,13 @@ public class JsonDbOpensocialService imp
     // TODO Not using fields yet
     return new JSONObject(converter.convertToString(activity));
   }
+  
+  private JSONObject convertFromActivityEntry(ActivityEntry activityEntry, Set<String> fields)
+  throws JSONException {
+	// TODO Not using fields yet
+	return new JSONObject(converter.convertToString(activityEntry));
+  }
+
 
   private <T> T filterFields(JSONObject object, Set<String> fields, Class<T> clz)
       throws JSONException {