Author: doll
Date: Fri Apr 25 09:49:09 2008
New Revision: 651645

URL: http://svn.apache.org/viewvc?rev=651645&view=rev
Log:
Added an initial restful based container. 

Note: this probably doesn't work at all yet because i don't have a restful json 
container to work with. However, this is a start and hopefully isnt too far off 
from the real thing.


Added:
    incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js
Modified:
    incubator/shindig/trunk/features/core.io/io.js

Modified: incubator/shindig/trunk/features/core.io/io.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/core.io/io.js?rev=651645&r1=651644&r2=651645&view=diff
==============================================================================
--- incubator/shindig/trunk/features/core.io/io.js (original)
+++ incubator/shindig/trunk/features/core.io/io.js Fri Apr 25 09:49:09 2008
@@ -35,7 +35,7 @@
    * Holds configuration-related data such as proxy urls.
    */
   var config = {};
-  
+
   /**
    * Holds state for OAuth.
    */
@@ -184,10 +184,9 @@
    * @param processResponseFunction The function that should process the
    *     response from the sever before calling the callback
    */
-  function makeXhrRequest(realUrl, proxyUrl, callback, paramData, params,
-      processResponseFunction) {
+  function makeXhrRequest(realUrl, proxyUrl, callback, paramData, method,
+      params, processResponseFunction) {
     var xhr = makeXhr();
-    var method = (paramData != null) ? "POST" : "GET";
 
     xhr.open(method, proxyUrl, true);
     if (callback) {
@@ -308,19 +307,21 @@
       };
 
       if (!respondWithPreload(paramData, params, callback, processResponse)) {
-
         var refreshInterval = params.REFRESH_INTERVAL || 0;
-  
+
         if (refreshInterval > 0) {
           // this content should be cached
           // Add paramData to the URL
-          var extraparams = "&refresh=" + refreshInterval + '&' + 
gadgets.io.encodeValues(paramData);
+          var extraparams = "&refresh=" + refreshInterval + '&'
+              + gadgets.io.encodeValues(paramData);
 
-          makeXhrRequest(url, config.jsonProxyUrl + extraparams, callback, 
null, params, processResponse);
+          makeXhrRequest(url, config.jsonProxyUrl + extraparams, callback,
+              null, "GET", params, processResponse);
 
         } else {
           makeXhrRequest(url, config.jsonProxyUrl, callback,
-              gadgets.io.encodeValues(paramData), params, processResponse);
+              gadgets.io.encodeValues(paramData), "POST", params,
+              processResponse);
         }
       }
     },
@@ -331,7 +332,7 @@
     makeNonProxiedRequest : function (relativeUrl, callback, opt_params) {
       var params = opt_params || {};
       makeXhrRequest(relativeUrl, relativeUrl, callback, params.POST_DATA,
-          params, processNonProxiedResponse);
+          params.METHOD, params, processNonProxiedResponse);
     },
 
     /**

Added: incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js?rev=651645&view=auto
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js (added)
+++ incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js Fri Apr 
25 09:49:09 2008
@@ -0,0 +1,224 @@
+/*
+ * 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 RESTful based opensocial container.
+ */
+
+RestfulContainer = function(baseUrl, domain, supportedFieldsArray) {
+  opensocial.Container.call(this);
+
+  var supportedFieldsMap = {};
+  for (var objectType in supportedFieldsArray) {
+    if (supportedFieldsArray.hasOwnProperty(objectType)) {
+      supportedFieldsMap[objectType] = {};
+      for (var i = 0; i < supportedFieldsArray[objectType].length; i++) {
+        var supportedField = supportedFieldsArray[objectType][i];
+        supportedFieldsMap[objectType][supportedField] = true;
+      }
+    }
+  }
+
+  this.environment_ = new opensocial.Environment(domain, supportedFieldsMap);
+  this.baseUrl_ = baseUrl;
+
+  this.securityToken_ = gadgets.util.getUrlParameters().st;
+  this.parseSecurityToken();
+};
+RestfulContainer.inherits(opensocial.Container);
+
+// Hopefully we can get rid of these with special @viewer and @owner tokens
+// in the restful spec.
+RestfulContainer.prototype.parseSecurityToken = function() {
+  var parts = this.securityToken_.split(":");
+  this.ownerId_ = parts[0];
+  this.viewerId_ = parts[1];
+  this.appId_ = parts[2];
+};
+
+RestfulContainer.prototype.getEnvironment = function() {
+  return this.environment_;
+};
+
+RestfulContainer.prototype.requestCreateActivity = function(activity,
+    priority, opt_callback) {
+  opt_callback = opt_callback || {};
+  // TODO: Implement this
+};
+
+RestfulContainer.prototype.requestData = function(dataRequest, callback) {
+  callback = callback || {};
+
+  var requestObjects = dataRequest.getRequestObjects();
+  var totalRequests = requestObjects.length;
+
+  if (totalRequests == 0) {
+    callback(new opensocial.DataResponse({}, true));
+    return;
+  }
+
+  var responseMap = {};
+  var globalError = false;
+  var responsesReceived = 0;
+
+  // may need multiple urls for one response but lets ignore that for now
+  for (var i = 0; i < totalRequests; i++) {
+    var requestObject = requestObjects[i];
+
+    var makeRequestParams = {
+      "CONTENT_TYPE" : "JSON",
+      "METHOD" : requestObject.request.method
+      // TODO: Handle post data
+    };
+
+    // TODO: Use batching instead of doing this one by one
+    gadgets.io.makeNonProxiedRequest(
+        requestObject.request.url + "st=" + this.securityToken,
+        function(result) {
+          result = result.data;
+
+          // TODO: handle errors
+          var processedData = requestObject.request.processResponse(
+              requestObject.request, result, null, null);
+          globalError = globalError || processedData.hadError();
+          responseMap[requestObject.key] = processedData;
+
+          responsesReceived++;
+          if (responsesReceived == totalRequests) {
+            var dataResponse = new opensocial.DataResponse(responseMap,
+                globalError);
+            callback(dataResponse);
+          }
+        },
+        makeRequestParams);
+  }
+
+};
+
+RestfulContainer.prototype.newFetchPersonRequest = function(id, opt_params) {
+  var peopleRequest = this.newFetchPeopleRequest(id, opt_params);
+
+  var me = this;
+  return new RequestItem(peopleRequest.url, peopleRequest.method, null,
+      function(rawJson) {
+        return me.createPersonFromJson(rawJson['items'][0]);
+      });
+};
+
+RestfulContainer.prototype.translateIdSpec = function(idSpec) {
+  // This will get cleaner in 0.8 because idSpec will be an object
+  if (idSpec == "VIEWER") {
+    return this.viewerId_ + "/@self";
+  } else if (idSpec == "VIEWER_FRIENDS") {
+    return this.viewerId_ + "/@friends";
+  } else if (idSpec == "OWNER") {
+    return this.ownerId_ + "/@self";
+  } else if (idSpec == "OWNER_FRIENDS") {
+    return this.ownerId_ + "/@friends";
+  } else if (this.isArray(idSpec)) {
+    for (var i = 0; i < idSpec.length; i++) {
+      // TODO: We will need multiple urls here....don't want to think about
+      // that yet
+    }
+  } else {
+    return idSpec + "/@self";
+  }
+};
+
+RestfulContainer.prototype.newFetchPeopleRequest = function(idSpec,
+    opt_params) {
+  var url = "/people/" + this.translateIdSpec(idSpec);
+
+  // TODO: Add sortOrder, filter
+  //    'sortOrder': opt_params['sortOrder'] || 'topFriends',
+  //    'filter': opt_params['filter'] || 'all',
+
+  url += "fields=" + (opt_params['profileDetail'].join(','));
+  url += "startPage=" + (opt_params['first'] || 0);
+  url += "count=" + (opt_params['max'] || 20);
+
+  var me = this;
+  return new RequestItem(url, "GET", null,
+      function(rawJson) {
+        var jsonPeople = rawJson['items'];
+        var people = [];
+        for (var i = 0; i < jsonPeople.length; i++) {
+          people.push(me.createPersonFromJson(jsonPeople[i]));
+        }
+        return new opensocial.Collection(people, rawJson['offset'],
+            rawJson['totalSize']);
+      });
+};
+
+RestfulContainer.prototype.createPersonFromJson = function(serverJson) {
+  return new JsonPerson(serverJson);
+}
+
+RestfulContainer.prototype.newFetchPersonAppDataRequest = function(idSpec,
+    keys) {
+   var url = "/appdata/" + this.translateIdSpec(idSpec) + "/" + this.appId_
+       + "?fields=" + keys.join(',');
+  return new RequestItem(url, "GET", null,
+      function (appData) {
+        return gadgets.util.escape(appData, true);
+      });
+};
+
+RestfulContainer.prototype.newUpdatePersonAppDataRequest = function(id, key,
+    value) {
+  var url = "/appdata/" + this.translateIdSpec(idSpec) + "/" + this.appId_
+       + "?fields=" + key;
+  // TODO: Or should we use POST?
+  return new RequestItem(url, "PUT", {key: value});
+};
+
+RestfulContainer.prototype.newFetchActivitiesRequest = function(idSpec,
+    opt_params) {
+  var url = "/activities/" + this.translateIdSpec(idSpec)
+      + "?app=" + this.appId_;
+  return new RequestItem(url, "GET", null,
+      function(rawJson) {
+        var activities = [];
+        for (var i = 0; i < rawJson.length; i++) {
+          activities.push(new JsonActivity(rawJson[i]));
+        }
+        return {'activities' : new opensocial.Collection(activities)};
+      });
+};
+
+RestfulContainer.prototype.newCreateActivityRequest = function(idSpec,
+    activity) {
+   // TODO: no idea how to do this yet
+  return new RequestItem("TODO", "POST", {});
+};
+
+RequestItem = function(url, method, postData, processData) {
+  this.url = url;
+  this.method = method;
+  this.postData = postData;
+  this.processData = processData ||
+    function (rawJson) {
+      return rawJson;
+    };
+
+  this.processResponse = function(originalDataRequest, rawJson, error,
+      errorMessage) {
+    return new opensocial.ResponseItem(originalDataRequest,
+        error ? null : this.processData(rawJson), error, errorMessage);
+  }
+};
\ No newline at end of file


Reply via email to