Author: doll
Date: Thu Feb 21 18:50:31 2008
New Revision: 630072
URL: http://svn.apache.org/viewvc?rev=630072&view=rev
Log:
The first part of a very very simple implementation of a sever side backed
opensocial container. This involves creating the opensocial-0.7 feature with a
json based container which talks back to a servlet at /socialdata.
This code is littered with todos and needs tons of fleshing out. However, it
does successfully render the SocialHelloWorld gadget and gets us started down
the path of supporting opensocial for real.
Added:
incubator/shindig/trunk/features/opensocial-0.7/
incubator/shindig/trunk/features/opensocial-0.7/batchrequest.js
incubator/shindig/trunk/features/opensocial-0.7/feature.xml
incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java
Modified:
incubator/shindig/trunk/features/features.txt
incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml
Modified: incubator/shindig/trunk/features/features.txt
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/features.txt?rev=630072&r1=630071&r2=630072&view=diff
==============================================================================
--- incubator/shindig/trunk/features/features.txt (original)
+++ incubator/shindig/trunk/features/features.txt Thu Feb 21 18:50:31 2008
@@ -5,6 +5,7 @@
features/dynamic-height/feature.xml
features/flash/feature.xml
features/minimessage/feature.xml
+features/opensocial-0.7/feature.xml
features/opensocial-reference/feature.xml
features/opensocial-samplecontainer/feature.xml
features/rpc/feature.xml
Added: incubator/shindig/trunk/features/opensocial-0.7/batchrequest.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-0.7/batchrequest.js?rev=630072&view=auto
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/batchrequest.js (added)
+++ incubator/shindig/trunk/features/opensocial-0.7/batchrequest.js Thu Feb 21
18:50:31 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * Base class for sending a JSON request for people data.
+ *
+ * @param {Object} opt_params Key-value pairs of request parameters
+ * @param {String} opt_path Path of data request URL relative to base
+ * path on server. Defaults to /socialdata
+ * @param {Function} opt_callback Function to call when done.
+ * Will be called with the JSON data as the only parameter.
+ * @constructor
+ */
+BatchRequest = function(jsonText, opt_callback, opt_path, opt_params) {
+ this.params_ = opt_params || {};
+ this.params_['request'] = jsonText;
+
+ // TODO: Make the opt_path easy to configure within jsoncontainer
+ this.path_ = opt_path || 'http://localhost:8080/gadgets/socialdata';
+ this.callback_ = opt_callback;
+};
+
+BatchRequest.prototype.send = function() {
+ // TODO: This will likely grow to be a lot more complicated
+ var makeRequestParams = {
+ "CONTENT_TYPE" : "JSON",
+ "METHOD" : "POST",
+ "AUTHORIZATION" : "SIGNED",
+ "POST_DATA" : gadgets.io.encodeValues(this.params_)};
+
+ gadgets.io.makeRequest(this.path_, this.callback_,
+ makeRequestParams);
+};
\ No newline at end of file
Added: incubator/shindig/trunk/features/opensocial-0.7/feature.xml
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-0.7/feature.xml?rev=630072&view=auto
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/feature.xml (added)
+++ incubator/shindig/trunk/features/opensocial-0.7/feature.xml Thu Feb 21
18:50:31 2008
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<feature>
+ <name>opensocial-0.7</name>
+ <dependency>opensocial-reference</dependency>
+ <dependency>caja</dependency>
+ <gadget>
+ <script src="jsoncontainer.js"></script>
+ <script src="batchrequest.js"></script>
+ <script>
+ opensocial.Container.setContainer(new JsonContainer());
+ opensocial.Container.get().enableCaja();
+ </script>
+ </gadget>
+</feature>
Added: incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js?rev=630072&view=auto
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js (added)
+++ incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js Thu Feb 21
18:50:31 2008
@@ -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.
+ */
+
+/**
+ * @fileoverview Json based opensocial container.
+ */
+
+
+JsonContainer = function() {
+ opensocial.Container.call(this);
+};
+JsonContainer.inherits(opensocial.Container);
+
+JsonContainer.prototype.getEnvironment = function() {
+ return this.environment_;
+};
+
+JsonContainer.prototype.createJson = function(requestObjects) {
+ var jsonObjects = [];
+ for (var i = 0; i < requestObjects.length; i++) {
+ jsonObjects[i] = requestObjects[i].request.jsonParams;
+ }
+ return gadgets.json.stringify(jsonObjects);
+};
+
+JsonContainer.prototype.requestData = function(dataRequest, callback) {
+ callback = callback || {};
+
+ var requestObjects = dataRequest.getRequestObjects();
+ if (requestObjects.length == 0) {
+ callback(new opensocial.DataResponse({}, true));
+ return;
+ }
+
+ var jsonText = this.createJson(requestObjects);
+
+ var sendResponse = function(result) {
+ result = result.data;
+
+ if (!result || result['globalError']) {
+ callback(new opensocial.DataResponse({}, true));
+ return;
+ }
+
+ var responses = result['responses'] || [];
+ var globalError = false;
+
+ var responseMap = {};
+ for (var i = 0; i < responses.length; i++) {
+ var response = responses[i];
+ var rawData = response['response'];
+
+ var processedData = requestObjects[i].request.processResponse(rawData);
+ globalError = globalError || processedData.hadError();
+ responseMap[requestObjects[i].key] = processedData;
+ }
+
+ var dataResponse = new opensocial.DataResponse(responseMap, globalError);
+ callback(dataResponse);
+ };
+
+ new BatchRequest(jsonText, sendResponse).send();
+};
+
+JsonContainer.prototype.newFetchPersonRequest = function(id,
+ opt_params) {
+ var me = this;
+ var peopleRequest = this.newFetchPeopleRequest(id, opt_params);
+ peopleRequest.processResponse = function(rawJson) {
+ return new opensocial.ResponseItem(null,
+ me.createPersonFromJson(rawJson[0]));
+ };
+ return peopleRequest;
+};
+
+JsonContainer.prototype.newFetchPeopleRequest = function(idSpec,
+ opt_params) {
+ var me = this;
+ return new RequestItem(
+ {'type' : 'FETCH_PEOPLE', 'idSpec' : idSpec, 'params': opt_params},
+ function(rawJson) {
+ var people = [];
+ for (var i = 0; i < rawJson.length; i++) {
+ people.push(me.createPersonFromJson(rawJson[i]));
+ // TODO: isOwner, isViewer
+ }
+ return new opensocial.ResponseItem(null, // TODO: Original request
+ new opensocial.Collection(people));
+ });
+};
+
+JsonContainer.prototype.createPersonFromJson = function(serverJson) {
+ // TODO: Probably move this into a subclass of person and make it cover
+ // all fields
+ var name = new opensocial.Name(serverJson["name"]);
+ return new opensocial.Person({"id" : serverJson["id"], "name" : name});
+}
+
+JsonContainer.prototype.newFetchPersonAppDataRequest = function(
+ idSpec, keys) {
+ return new RequestItem({'type' : 'FETCH_PERSON_APP_DATA', 'idSpec' : idSpec,
+ 'keys' : keys});
+};
+
+JsonContainer.prototype.newUpdatePersonAppDataRequest = function(
+ id, key, value) {
+ return new RequestItem({'type' : 'UPDATE_PERSON_APP_DATA', 'id' : id,
+ 'key' : key, 'value' : value});
+};
+
+JsonContainer.prototype.newFetchActivitiesRequest = function(
+ idSpec, opt_params) {
+ return new RequestItem({'type' : 'FETCH_ACTIVITIES', 'idSpec' : idSpec},
+ function(rawJson) {
+ var activities = [];
+ for (var i = 0; i < rawJson.length; i++) {
+ activities.push(new opensocial.Activity(rawJson[i]));
+ }
+ return new opensocial.ResponseItem(null, // TODO: Original request
+ {'activities' : new opensocial.Collection(activities)});
+ });
+};
+
+RequestItem = function(jsonParams, processResponse) {
+ this.jsonParams = jsonParams;
+ this.processResponse = processResponse ||
+ function (rawJson) {
+ return new opensocial.ResponseItem(null, rawJson); // TODO: Original
request
+ };
+};
\ No newline at end of file
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java?rev=630072&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java
Thu Feb 21 18:50:31 2008
@@ -0,0 +1,93 @@
+/*
+ * 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.http;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Servlet for serving social data. This is a very basic hardcoded inital file.
+ * This will expand to be more sophisticated as time goes on.
+ */
+public class SocialDataServlet extends HttpServlet {
+ private static final Logger logger
+ = Logger.getLogger("org.apache.shindig.social");
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException {
+ // TODO: Get the security token
+ // TODO: Allow saving data
+ // TODO: Don't use string concatentation for json output
+ // TODO: etc, etc, etc
+
+ String requestParam = req.getParameter("request");
+ try {
+ JSONArray requestItems = new JSONArray(requestParam);
+ String jsonResponse = "{'responses' : [";
+ int length = requestItems.length();
+
+ for (int i = 0; i < length; i++) {
+ String jsonData = "";
+
+ JSONObject requestItem = requestItems.getJSONObject(i);
+ String type = requestItem.getString("type");
+
+ if (type.equals("FETCH_PEOPLE")) {
+ String idSpec = requestItem.getString("idSpec");
+ if (idSpec.equals("VIEWER") || idSpec.equals("OWNER")) {
+ jsonData = "[{'id' : 'john.doe', 'name' : {'unstructured' : 'John
Doe'}}]";
+ } else if (idSpec.equals("VIEWER_FRIENDS")) {
+ jsonData = "[{'id' : 'jane.doe', 'name' : {'unstructured' : 'Jane
Doe'}}, " +
+ "{'id' : 'george.doe', 'name' : {'unstructured' : 'George
Doe'}}]";
+ }
+
+ } else if (type.equals("FETCH_PERSON_APP_DATA")) {
+ String idSpec = requestItem.getString("idSpec");
+ if (idSpec.equals("VIEWER")) {
+ jsonData = "{'john.doe' : {'count' : 3}}";
+ } else if (idSpec.equals("VIEWER_FRIENDS")) {
+ jsonData = "{'jane.doe' : {'count' : 7}, " +
+ "'george.doe' : {'count' : 2}}";
+ }
+ }
+
+ jsonResponse += "{'response' : " + jsonData + "}";
+ if (i < length - 1) {
+ jsonResponse += ",";
+ }
+ }
+ jsonResponse += "]}";
+ PrintWriter writer = resp.getWriter();
+ writer.write(jsonResponse);
+
+ } catch (JSONException e) {
+ // TODO: handle the exception here
+ }
+
+ }
+}
Modified: incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml?rev=630072&r1=630071&r2=630072&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml
(original)
+++ incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml Thu
Feb 21 18:50:31 2008
@@ -9,7 +9,7 @@
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
@@ -60,6 +60,14 @@
</servlet-class>
</servlet>
+ <!-- Serve social data -->
+ <servlet>
+ <servlet-name>socialdata</servlet-name>
+ <servlet-class>
+ org.apache.shindig.social.http.SocialDataServlet
+ </servlet-class>
+ </servlet>
+
<!-- javascript serving -->
<servlet>
<servlet-name>js</servlet-name>
@@ -84,5 +92,10 @@
<servlet-mapping>
<servlet-name>rpc</servlet-name>
<url-pattern>/rpc</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>socialdata</servlet-name>
+ <url-pattern>/socialdata</url-pattern>
</servlet-mapping>
</web-app>