To add on to this implementation, here is what I am thinking some of the
next steps are:

1. Change the social data servlet from returning hardcoded data to querying
interfaces for data. These interfaces can simply be file backed for shindig,
and in a real container would be backed by mysql or whatever.
  1.5 Once we have a file backed version we may want to change the
samplecontainer to use it, rather than having a completely separate
implementation. Perhaps the sample container could just have some code for
writing to that file.

2. Obviously amp up the javascript to support the rest of opensocial.

3. Start handling error messages and codes in the js and java.

4. Implement the ifpc based calls, requestPermission and such.

5. Remove all todos, general refactoring, and tests.


I'm sure there are plenty more tasks that we will run into. For now, I will
be working on #1 with the help of Vincent's patch. I'll probably do some of
#2 in parallel.

Let me know if you think there are any horrible design flaws, its all a wip
so we have plenty to do.

- Cassie


On Thu, Feb 21, 2008 at 6:50 PM, <[EMAIL PROTECTED]> wrote:

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

Reply via email to