Author: awiner
Date: Mon Mar 30 23:45:31 2009
New Revision: 760259
URL: http://svn.apache.org/viewvc?rev=760259&view=rev
Log:
SHINDIG-753: Radically simplify the Persistence/AppData API
- Add support for an appData parameter to the fetch-person and fetch-people JS
APIs
- Add person.getAppData(key) API
- Add JsonDbOpensocialService support for appData and appData.key fields on
person objects
- Add Person.get/setAppData() API
- Add end-to-end tests of appdata retrieval
New APIs - data pipelining and OS Lite - and the JSON-RPC and REST protocols
will just use @fields.
No changes have been made to the service APIs (beyond adding the new appData
key to Person)
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-0.8/opensocial8to9.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/fieldtranslations.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/jsonperson.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-jsonrpc/jsonrpccontainer.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/container.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/datarequest.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/person.js
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-rest/restfulcontainer.js
incubator/shindig/trunk/java/server/src/test/resources/endtoend/fetchPersonTest.xml
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/model/PersonImpl.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialServiceTest.java
incubator/shindig/trunk/java/social-api/src/test/resources/org/apache/shindig/social/opensocial/util/opensocial.xsd
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-0.8/opensocial8to9.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-0.8/opensocial8to9.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-0.8/opensocial8to9.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-0.8/opensocial8to9.js
Mon Mar 30 23:45:31 2009
@@ -17,3 +17,30 @@
* under the License.
*/
+opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest_09 =
+ opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest;
+/**
+ * Implementation of 0.8 newUpdatePersonAppDataRequest API
+ */
+opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest = function(id,
+ key, value) {
+ if (id !== opensocial.IdSpec.PersonId.VIEWER) {
+ throw "Cannot update app data for person " + id;
+ }
+ return this.newUpdatePersonAppDataRequest_09(key, value);
+}
+
+opensocial.DataRequest.prototype.newRemovePersonAppDataRequest_09 =
+ opensocial.DataRequest.prototype.newRemovePersonAppDataRequest;
+/**
+ * Implementation of 0.8 newRemovePersonAppDataRequest API
+ */
+opensocial.DataRequest.prototype.newRemovePersonAppDataRequest = function(id,
+ keys) {
+ if (id !== opensocial.IdSpec.PersonId.VIEWER) {
+ throw "Cannot remove app data for person " + id;
+ }
+
+ return this.newRemovePersonAppDataRequest_09(keys);
+}
+
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/fieldtranslations.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/fieldtranslations.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/fieldtranslations.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/fieldtranslations.js
Mon Mar 30 23:45:31 2009
@@ -23,7 +23,7 @@
var FieldTranslations = {};
-FieldTranslations.translateServerPersonToJsPerson = function(serverJson) {
+FieldTranslations.translateServerPersonToJsPerson = function(serverJson,
opt_params) {
if (serverJson.emails) {
for (var i = 0; i < serverJson.emails.length; i++) {
serverJson.emails[i].address = serverJson.emails[i].value;
@@ -88,6 +88,11 @@
if (serverJson.name) {
serverJson.name.unstructured = serverJson.name.formatted;
}
+
+ if (serverJson.appData) {
+ serverJson.appData = opensocial.Container.escape(
+ serverJson.appData, opt_params, true);
+ }
};
@@ -148,3 +153,32 @@
return new Date(Number(time));
}
+
+/**
+ * AppData is provided by the REST and JSON-RPC protocols using
+ * an "appData" or "appData.key" field, but is described by
+ * the JS fetchPerson() API in terms of an appData param. Translate
+ * between the two.
+ */
+FieldTranslations.addAppDataAsProfileFields = function(opt_params) {
+ if (opt_params) {
+ // Push the appData keys in as profileDetails
+ if (opt_params['appData']) {
+ var appDataKeys = opt_params['appData'];
+ if (typeof appDataKeys === 'string') {
+ appDataKeys = [appDataKeys];
+ }
+
+ var profileDetail = opt_params['profileDetail'] || [];
+ for (var i = 0; i < appDataKeys.length; i++) {
+ if (appDataKeys[i] === '*') {
+ profileDetail.push('appData');
+ } else {
+ profileDetail.push('appData.' + appDataKeys[i]);
+ }
+ }
+
+ opt_params['appData'] = appDataKeys;
+ }
+ }
+}
\ No newline at end of file
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/jsonperson.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/jsonperson.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/jsonperson.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-base/jsonperson.js
Mon Mar 30 23:45:31 2009
@@ -99,3 +99,8 @@
JsonPerson.prototype.getDisplayName = function() {
return this.getField("displayName");
};
+
+JsonPerson.prototype.getAppData = function(key) {
+ var appData = this.getField("appData");
+ return appData && appData[key];
+};
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-jsonrpc/jsonrpccontainer.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-jsonrpc/jsonrpccontainer.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-jsonrpc/jsonrpccontainer.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-jsonrpc/jsonrpccontainer.js
Mon Mar 30 23:45:31 2009
@@ -273,7 +273,7 @@
var me = this;
return new JsonRpcRequestItem(peopleRequest.rpc,
function(rawJson) {
- return me.createPersonFromJson(rawJson);
+ return me.createPersonFromJson(rawJson, opt_params);
});
};
@@ -281,6 +281,9 @@
opt_params) {
var rpc = { method : "people.get" };
rpc.params = this.translateIdSpec(idSpec);
+
+ FieldTranslations.addAppDataAsProfileFields(opt_params);
+
if (opt_params['profileDetail']) {
FieldTranslations.translateJsPersonFieldsToServerFields(opt_params['profileDetail']);
rpc.params.fields = opt_params['profileDetail'];
@@ -315,15 +318,15 @@
var people = [];
for (var i = 0; i < jsonPeople.length; i++) {
- people.push(me.createPersonFromJson(jsonPeople[i]));
+ people.push(me.createPersonFromJson(jsonPeople[i], opt_params));
}
return new opensocial.Collection(people,
rawJson['startIndex'], rawJson['totalResults']);
});
};
- JsonRpcContainer.prototype.createPersonFromJson = function(serverJson) {
- FieldTranslations.translateServerPersonToJsPerson(serverJson);
+ JsonRpcContainer.prototype.createPersonFromJson = function(serverJson,
opt_params) {
+ FieldTranslations.translateServerPersonToJsPerson(serverJson, opt_params);
return new JsonPerson(serverJson);
};
@@ -362,10 +365,10 @@
});
};
- JsonRpcContainer.prototype.newUpdatePersonAppDataRequest = function(id, key,
+ JsonRpcContainer.prototype.newUpdatePersonAppDataRequest = function(key,
value) {
var rpc = { method : "appdata.update" };
- rpc.params = this.translateIdSpec(this.makeIdSpec(id));
+ rpc.params = {userId: ["@viewer"], groupId: "@self"};
rpc.params.appId = "@app";
rpc.params.data = {};
rpc.params.data[key] = value;
@@ -373,9 +376,9 @@
return new JsonRpcRequestItem(rpc);
};
- JsonRpcContainer.prototype.newRemovePersonAppDataRequest = function(id,
keys) {
+ JsonRpcContainer.prototype.newRemovePersonAppDataRequest = function(keys) {
var rpc = { method : "appdata.delete" };
- rpc.params = this.translateIdSpec(this.makeIdSpec(id));
+ rpc.params = {userId: ["@viewer"], groupId: "@self"};
rpc.params.appId = "@app";
rpc.params.fields = this.getFieldsList(keys);
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/container.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/container.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/container.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/container.js
Mon Mar 30 23:45:31 2009
@@ -271,33 +271,32 @@
/**
- * Used to request an update of an app field for the given person.
+ * Creates an item to request an update of an app field for the current VIEWER
* When processed, does not return any data.
+ * App Data is stored as a series of key value pairs of strings, scoped per
+ * person, per application. Containers supporting this request SHOULD provide
+ * at least 10KB of space per user per application for this data.
*
- * @param {String} id The id of the person to update. (Right now only the
- * special VIEWER id is allowed.)
* @param {String} key The name of the key
* @param {String} value The value
* @return {Object} a request object
* @private
*/
-opensocial.Container.prototype.newUpdatePersonAppDataRequest = function(id,
+opensocial.Container.prototype.newUpdatePersonAppDataRequest = function(
key, value) {};
/**
- * Deletes the given keys from the datastore for the given person.
+ * Deletes the given keys from the datastore for the current VIEWER.
* When processed, does not return any data.
*
- * @param {String} id The ID of the person to update; only the
- * special <code>VIEWER</code> ID is currently allowed.
* @param {Array.<String> | String} keys The keys you want to delete from
* the datastore; this can be an array of key names, a single key name,
* or "*" to mean "all keys"
* @return {Object} A request object
* @private
*/
-opensocial.Container.prototype.newRemovePersonAppDataRequest = function(id,
+opensocial.Container.prototype.newRemovePersonAppDataRequest = function(
keys) {};
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/datarequest.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/datarequest.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/datarequest.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/datarequest.js
Mon Mar 30 23:45:31 2009
@@ -251,7 +251,24 @@
*
* @member opensocial.DataRequest.PeopleRequestFields
*/
- MAX : 'max'
+ MAX : 'max',
+
+ /**
+ * A string or array of strings, specifying the app data keys to fetch for
+ * each of the Person objects. This field may be used interchangeably with
+ * the string 'appData'. Pass the string '*' to fetch all app data keys.
+ * @member opensocial.DataRequest.PeopleRequestFields
+ */
+ APP_DATA : 'appData',
+
+ /**
+ * How to escape app data returned from the server;
+ * defaults to HTML_ESCAPE. Possible values are defined by
+ * <a href="opensocial.EscapeType.html">EscapeType</a>.
+ * This field may be used interchangeably with the string 'escapeType'.
+ * @member opensocial.DataRequest.PeopleRequestFields
+ */
+ ESCAPE_TYPE : 'escapeType'
};
@@ -368,7 +385,11 @@
* How to escape person data returned from the server; defaults to
HTML_ESCAPE.
* Possible values are defined by
* <a href="opensocial.EscapeType.html">EscapeType</a>.
+ * Use of this function is deprecated in favor of using the
+ * <a href="#opensocial.DataRequest.PeopleRequestFields.ESCAPE_TYPE">
+ * ESCAPE_TYPE</a> request field.
*
+ * @deprecated
* @member opensocial.DataRequest.DataRequestFields
*/
ESCAPE_TYPE : 'escapeType'
@@ -381,7 +402,11 @@
* <a href="opensocial.DataRequest.PersonId.html">PersonId</a>,
* Map<String, String>> object.
* All of the data values returned will be valid json.
+ * Use of this function is deprecated in favor of using the
+ * <a href="#opensocial.DataRequest.PeopleRequestFields.APP_DATA">APP_DATA</a>
+ * request field.
*
+ * @deprecated
* @param {opensocial.IdSpec} idSpec An IdSpec used to specify which people to
* fetch. See also <a href="opensocial.IdSpec.html">IdSpec</a>.
* @param {Array.<String> | String} keys The keys you want data for; this
@@ -401,37 +426,34 @@
/**
- * Creates an item to request an update of an app field for the given person.
+ * Creates an item to request an update of an app field for the current VIEWER
* When processed, does not return any data.
- *
- * @param {String} id The ID of the person to update; only the
- * special <code>VIEWER</code> ID is currently allowed.
+ * App Data is stored as a series of key value pairs of strings, scoped per
+ * person, per application. Containers supporting this request SHOULD provide
+ * at least 10KB of space per user per application for this data.
* @param {String} key The name of the key. This may only contain alphanumeric
* (A-Za-z0-9) characters, underscore(_), dot(.) or dash(-).
* @param {String} value The value, must be valid json
* @return {Object} A request object
*/
-opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest = function(id,
+opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest = function(
key, value) {
- return opensocial.Container.get().newUpdatePersonAppDataRequest(id, key,
+ return opensocial.Container.get().newUpdatePersonAppDataRequest(key,
value);
};
/**
- * Deletes the given keys from the datastore for the given person.
+ * Deletes the given keys from the datastore for the current VIEWER.
* When processed, does not return any data.
*
- * @param {String} id The ID of the person to update; only the
- * special <code>VIEWER</code> ID is currently allowed.
* @param {Array.<String> | String} keys The keys you want to delete from
* the datastore; this can be an array of key names, a single key name,
* or "*" to mean "all keys"
* @return {Object} A request object
*/
-opensocial.DataRequest.prototype.newRemovePersonAppDataRequest = function(id,
- keys) {
- return opensocial.Container.get().newRemovePersonAppDataRequest(id, keys);
+opensocial.DataRequest.prototype.newRemovePersonAppDataRequest =
function(keys) {
+ return opensocial.Container.get().newRemovePersonAppDataRequest(keys);
};
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/person.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/person.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/person.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-reference/person.js
Mon Mar 30 23:45:31 2009
@@ -554,6 +554,17 @@
/**
+ * Gets the app data for this person that is associated with the specified
+ * key.
+ *
+ * @param {String} key The key to get app data for.
+ * @return {String} The corresponding app data.
+ */
+opensocial.Person.prototype.getAppData = function(key) {
+};
+
+
+/**
* Returns true if this person object represents the currently logged in user.
*
* @return {Boolean} True if this is the currently logged in user;
Modified:
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-rest/restfulcontainer.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-rest/restfulcontainer.js?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-rest/restfulcontainer.js
(original)
+++
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-rest/restfulcontainer.js
Mon Mar 30 23:45:31 2009
@@ -209,7 +209,7 @@
var me = this;
return new RestfulRequestItem(peopleRequest.url, peopleRequest.method, null,
function(rawJson) {
- return me.createPersonFromJson(rawJson['entry']);
+ return me.createPersonFromJson(rawJson['entry'], opt_params);
});
};
@@ -217,7 +217,9 @@
opt_params) {
var url = "/people/" + this.translateIdSpec(idSpec);
+ FieldTranslations.addAppDataAsProfileFields(opt_params);
FieldTranslations.translateJsPersonFieldsToServerFields(opt_params['profileDetail']);
+
url += "?fields=" + (opt_params['profileDetail'].join(','));
url += "&startIndex=" + (opt_params['first'] || 0);
url += "&count=" + (opt_params['max'] || 20);
@@ -240,15 +242,15 @@
var people = [];
for (var i = 0; i < jsonPeople.length; i++) {
- people.push(me.createPersonFromJson(jsonPeople[i]));
+ people.push(me.createPersonFromJson(jsonPeople[i], opt_params));
}
return new opensocial.Collection(people,
rawJson['startIndex'], rawJson['totalResults']);
});
};
-RestfulContainer.prototype.createPersonFromJson = function(serverJson) {
- FieldTranslations.translateServerPersonToJsPerson(serverJson);
+RestfulContainer.prototype.createPersonFromJson = function(serverJson,
opt_params) {
+ FieldTranslations.translateServerPersonToJsPerson(serverJson, opt_params);
return new JsonPerson(serverJson);
};
@@ -281,17 +283,17 @@
});
};
-RestfulContainer.prototype.newUpdatePersonAppDataRequest = function(id, key,
+RestfulContainer.prototype.newUpdatePersonAppDataRequest = function(key,
value) {
- var url = "/appdata/" + this.translateIdSpec(this.makeIdSpec(id))
+ var url = "/appdata/@viewer/@self"
+ "/@app?fields=" + key;
var data = {};
data[key] = value;
return new RestfulRequestItem(url, "POST", data);
};
-RestfulContainer.prototype.newRemovePersonAppDataRequest = function(id, keys) {
- var url = "/appdata/" + this.translateIdSpec(this.makeIdSpec(id))
+RestfulContainer.prototype.newRemovePersonAppDataRequest = function(keys) {
+ var url = "/appdata/@viewer/@self"
+ "/@app?" + this.getFieldsList(keys);
return new RestfulRequestItem(url, "DELETE");
};
Modified:
incubator/shindig/trunk/java/server/src/test/resources/endtoend/fetchPersonTest.xml
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/test/resources/endtoend/fetchPersonTest.xml?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/server/src/test/resources/endtoend/fetchPersonTest.xml
(original)
+++
incubator/shindig/trunk/java/server/src/test/resources/endtoend/fetchPersonTest.xml
Mon Mar 30 23:45:31 2009
@@ -125,9 +125,51 @@
// Send the request
req.send(receivedData);
- }
- };
+ },
+
+ /** Test fetching app data */
+ fetchAppData: function() {
+ var req = opensocial.newDataRequest();
+
+ // Request the "canonical" viewer
+ req.add(req.newFetchPersonRequest("canonical",
+ {appData: '*'}), "canonical");
+
+ var receivedData = function(response) {
+ var user = getAndCheckError(response, "canonical");
+ assertEquals("Names don't match",
+ "Shin Digg", user.getDisplayName());
+ assertEquals("Wrong app data returned", "2",
user.getAppData("count"));
+ assertEquals("Wrong app data returned", "100",
user.getAppData("size"));
+ finished();
+ }
+
+ // Send the request
+ req.send(receivedData);
+ },
+ /** Test fetching app data via the array */
+ fetchTwoProperties: function() {
+ var req = opensocial.newDataRequest();
+
+ // Request the "canonical" viewer
+ req.add(req.newFetchPersonRequest("canonical",
+ {appData: ['count', 'notThere']}), "canonical");
+
+ var receivedData = function(response) {
+ var user = getAndCheckError(response, "canonical");
+ assertEquals("Names don't match",
+ "Shin Digg", user.getDisplayName());
+ assertEquals("Wrong app data returned", "2",
user.getAppData("count"));
+ assertEquals("Too much app data returned", undefined,
user.getAppData("size"));
+ assertEquals("App data that shouldn't exist returned",
undefined, user.getAppData("notThere"));
+ finished();
+ }
+
+ // Send the request
+ req.send(receivedData);
+ },
+ };
function getAndCheckError(response, key) {
assertFalse("Data error", response.hadError());
Modified:
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/model/PersonImpl.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/model/PersonImpl.java?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/model/PersonImpl.java
(original)
+++
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/model/PersonImpl.java
Mon Mar 30 23:45:31 2009
@@ -35,6 +35,7 @@
import java.util.Date;
import java.util.List;
+import java.util.Map;
/**
* Default Implementation of the Person object in the model.
@@ -45,6 +46,7 @@
private List<String> activities;
private List<Address> addresses;
private Integer age;
+ private Map<String, ? extends Object> appData;
private Date birthday;
private BodyType bodyType;
private List<String> books;
@@ -158,6 +160,14 @@
this.age = age;
}
+ public Map<String, ? extends Object> getAppData() {
+ return this.appData;
+ }
+
+ public void setAppData(Map<String, ? extends Object> appData) {
+ this.appData = appData;
+ }
+
public BodyType getBodyType() {
return bodyType;
}
@@ -611,8 +621,7 @@
public void setIsViewer(boolean isViewer) {
this.isViewer = isViewer;
}
-
-
+
// Proxied fields
public String getProfileUrl() {
Modified:
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
(original)
+++
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
Mon Mar 30 23:45:31 2009
@@ -79,7 +79,7 @@
}
/**
- * The fields that represent the person object ion json form.
+ * The fields that represent the person object in json form.
*/
public static enum Field {
/** the json field for aboutMe. */
@@ -92,6 +92,8 @@
ADDRESSES("addresses"),
/** the json field for age. */
AGE("age"),
+ /** the json field for appData. */
+ APP_DATA("appData"),
/** the json field for bodyType. */
BODY_TYPE("bodyType"),
/** the json field for books. */
@@ -336,6 +338,20 @@
void setAge(Integer age);
/**
+ * Get app data for the person.
+ *
+ * @return the app data, possibly a subset.
+ */
+ Map<String, ? extends Object> getAppData();
+
+ /**
+ * Sets app data for the person.
+ *
+ * @param appData the app data, possibly a subset
+ */
+ void setAppData(Map<String, ? extends Object> appData);
+
+ /**
* Get the person's date of birth, specified as a {...@link Date} object.
Container support for this
* field is OPTIONAL.
*
@@ -1201,5 +1217,4 @@
* @param thumbnailUrl the person's photo thumbnail URL
*/
void setThumbnailUrl(String thumbnailUrl);
-
}
Modified:
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java
(original)
+++
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialService.java
Mon Mar 30 23:45:31 2009
@@ -262,8 +262,14 @@
if (!idSet.contains(person.get(Person.Field.ID.toString()))) {
continue;
}
+
// Add group support later
- result.add(filterFields(person, fields, Person.class));
+ Person personObj = filterFields(person, fields, Person.class);
+ Map<String, Object> appData = getPersonAppData(
+ person.getString(Person.Field.ID.toString()), fields);
+ personObj.setAppData(appData);
+
+ result.add(personObj);
}
if (GroupId.Type.self == groupId.getType() && result.isEmpty()) {
@@ -302,7 +308,12 @@
JSONObject person = people.getJSONObject(i);
if (id != null && person.get(Person.Field.ID.toString())
.equals(id.getUserId(token))) {
- return ImmediateFuture.newInstance(filterFields(person, fields,
Person.class));
+ Person personObj = filterFields(person, fields, Person.class);
+ Map<String, Object> appData = getPersonAppData(
+ person.getString(Person.Field.ID.toString()), fields);
+ personObj.setAppData(appData);
+
+ return ImmediateFuture.newInstance(personObj);
}
}
throw new SocialSpiException(ResponseError.BAD_REQUEST, "Person not
found");
@@ -311,6 +322,42 @@
}
}
+ private Map<String, Object> getPersonAppData(String id, Set<String> fields) {
+ try {
+ Map<String, Object> appData = null;
+ JSONObject personData = db.getJSONObject(DATA_TABLE).optJSONObject(id);
+ if (personData != null) {
+ if (fields.contains(Person.Field.APP_DATA.toString())) {
+ appData = Maps.newHashMap();
+ @SuppressWarnings("unchecked")
+ Iterator<String> keys = personData.keys();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ appData.put(key, personData.get(key));
+ }
+ } else {
+ String appDataPrefix = Person.Field.APP_DATA.toString() + ".";
+ for (String field : fields) {
+ if (field.startsWith(appDataPrefix)) {
+ if (appData == null) {
+ appData = Maps.newHashMap();
+ }
+
+ String appDataField = field.substring(appDataPrefix.length());
+ if (personData.has(appDataField)) {
+ appData.put(appDataField, personData.get(appDataField));
+ }
+ }
+ }
+ }
+ }
+
+ return appData;
+ } catch (JSONException je) {
+ throw new SocialSpiException(ResponseError.INTERNAL_ERROR,
je.getMessage(), je);
+ }
+ }
+
public Future<DataCollection> getPersonData(Set<UserId> userIds, GroupId
groupId,
String appId, Set<String> fields, SecurityToken token) throws
SocialSpiException {
try {
Modified:
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialServiceTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialServiceTest.java?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialServiceTest.java
(original)
+++
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/sample/spi/JsonDbOpensocialServiceTest.java
Mon Mar 30 23:45:31 2009
@@ -83,6 +83,38 @@
assertNotNull("Canonical user not found", person);
}
+ public void testGetPersonAllAppData() throws Exception {
+ Person person = db
+ .getPerson(CANON_USER, ImmutableSet.of("id", "appData"), token).get();
+
+ assertNotNull("Canonical user not found", person);
+ assertEquals("Canonical user has wrong id", "canonical", person.getId());
+ assertEquals("Canonical user has wrong app data",
+ ImmutableMap.of("count", "2", "size", "100"), person.getAppData());
+ }
+
+ public void testGetPersonOneAppDataField() throws Exception {
+ Person person = db
+ .getPerson(CANON_USER, ImmutableSet.of("id", "appData.size"),
token).get();
+
+ assertNotNull("Canonical user not found", person);
+ assertEquals("Canonical user has wrong id", "canonical", person.getId());
+ assertEquals("Canonical user has wrong app data",
+ ImmutableMap.of("size", "100"), person.getAppData());
+ }
+
+ public void testGetPersonMultipleAppDataFields() throws Exception {
+ Person person = db
+ .getPerson(CANON_USER,
+ ImmutableSet.of("id", "appData.size", "appData.count",
"appData.bogus"),
+ token).get();
+
+ assertNotNull("Canonical user not found", person);
+ assertEquals("Canonical user has wrong id", "canonical", person.getId());
+ assertEquals("Canonical user has wrong app data",
+ ImmutableMap.of("count", "2", "size", "100"), person.getAppData());
+ }
+
public void testGetExpectedFriends() throws Exception {
CollectionOptions options = new CollectionOptions();
options.setSortBy(PersonService.TOP_FRIENDS_SORT);
Modified:
incubator/shindig/trunk/java/social-api/src/test/resources/org/apache/shindig/social/opensocial/util/opensocial.xsd
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/resources/org/apache/shindig/social/opensocial/util/opensocial.xsd?rev=760259&r1=760258&r2=760259&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/test/resources/org/apache/shindig/social/opensocial/util/opensocial.xsd
(original)
+++
incubator/shindig/trunk/java/social-api/src/test/resources/org/apache/shindig/social/opensocial/util/opensocial.xsd
Mon Mar 30 23:45:31 2009
@@ -82,6 +82,7 @@
<xs:element minOccurs="0" maxOccurs="unbounded" name="addresses"
type="tns:Address" />
<xs:element minOccurs="0" name="age" type="xs:string"/>
<xs:element minOccurs="0" name="anniversary" type="xs:dateTime" />
+ <xs:element minOccurs="0" name="appData" type="tns:Appdata"/>
<xs:element minOccurs="0" name="birthday" type="xs:dateTime" />
<xs:element minOccurs="0" name="bodyType" type="tns:BodyType" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="books"
type="xs:string" />