You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by do...@apache.org on 2008/03/06 12:46:29 UTC

svn commit: r634230 - in /incubator/shindig/trunk: features/opensocial-0.7/ java/gadgets/src/main/java/org/apache/shindig/social/ java/gadgets/src/main/java/org/apache/shindig/social/file/ java/gadgets/src/main/java/org/apache/shindig/social/http/

Author: doll
Date: Thu Mar  6 03:46:28 2008
New Revision: 634230

URL: http://svn.apache.org/viewvc?rev=634230&view=rev
Log:
Further improvements to the opensocial-0.7 feature. The basic file implementation of the people apis now actually reads from a file. (The file is hardcoded right now but we be pulled out in another change)

Added a jsonperson object and cleaned up some todos in the js.

Tons of todos left.



Added:
    incubator/shindig/trunk/features/opensocial-0.7/jsonperson.js
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/XmlStateFileFetcher.java
Modified:
    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/DataHandler.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/PeopleHandler.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicDataHandler.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicPeopleHandler.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java

Modified: 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=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/feature.xml (original)
+++ incubator/shindig/trunk/features/opensocial-0.7/feature.xml Thu Mar  6 03:46:28 2008
@@ -22,6 +22,7 @@
   <dependency>opensocial-reference</dependency>
   <dependency>caja</dependency>
   <gadget>
+    <script src="jsonperson.js"></script>
     <script src="jsoncontainer.js"></script>
     <script src="batchrequest.js"></script>
     <script>

Modified: 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=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js (original)
+++ incubator/shindig/trunk/features/opensocial-0.7/jsoncontainer.js Thu Mar  6 03:46:28 2008
@@ -75,13 +75,14 @@
     var globalError = false;
 
     var responseMap = {};
+
     for (var i = 0; i < responses.length; i++) {
       var response = responses[i];
       var rawData = response['response'];
       var error = response['error'];
 
-      var processedData = requestObjects[i].request.processResponse(rawData,
-          error);
+      var processedData = requestObjects[i].request.processResponse(
+          requestObjects[i].request, rawData, error);
       globalError = globalError || processedData.hadError();
       responseMap[requestObjects[i].key] = processedData;
     }
@@ -93,73 +94,69 @@
   new BatchRequest(jsonText, sendResponse, this.baseUrl_).send();
 };
 
-JsonContainer.prototype.newFetchPersonRequest = function(id,
-    opt_params) {
-  var me = this;
+JsonContainer.prototype.newFetchPersonRequest = function(id, opt_params) {
   var peopleRequest = this.newFetchPeopleRequest(id, opt_params);
-  peopleRequest.processResponse = function(rawJson, error) {
-    return new opensocial.ResponseItem(null,
-        me.createPersonFromJson(rawJson[0]), error);
-  };
-  return peopleRequest;
+
+  var me = this;
+  return new RequestItem(peopleRequest.jsonParams,
+      function(rawJson) {
+        return me.createPersonFromJson(rawJson[0]);
+      });
 };
 
-JsonContainer.prototype.newFetchPeopleRequest = function(idSpec,
-    opt_params) {
+JsonContainer.prototype.newFetchPeopleRequest = function(idSpec, opt_params) {
   var me = this;
   return new RequestItem(
       {'type' : 'FETCH_PEOPLE', 'idSpec' : idSpec, 'params': opt_params},
-      function(rawJson, error) {
+      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), error);
+        return 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});
+  // TODO: isOwner, isViewer
+  return new JsonPerson(serverJson);
 }
 
-JsonContainer.prototype.newFetchPersonAppDataRequest = function(
-    idSpec, keys) {
+JsonContainer.prototype.newFetchPersonAppDataRequest = function(idSpec, keys) {
   return new RequestItem({'type' : 'FETCH_PERSON_APP_DATA', 'idSpec' : idSpec,
       'keys' : keys},
-      function (appData, error) {
-        return new opensocial.ResponseItem(null,
-            gadgets.util.escape(appData, true), error); // TODO: Original request
+      function (appData) {
+        return gadgets.util.escape(appData, true);
       });
 };
 
-JsonContainer.prototype.newUpdatePersonAppDataRequest = function(
-    id, key, value) {
+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) {
+JsonContainer.prototype.newFetchActivitiesRequest = function(idSpec,
+    opt_params) {
   return new RequestItem({'type' : 'FETCH_ACTIVITIES', 'idSpec' : idSpec},
-      function(rawJson, error) {
+      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)}, error);
+        return {'activities' : new opensocial.Collection(activities)};
       });
 };
 
-RequestItem = function(jsonParams, processResponse) {
+RequestItem = function(jsonParams, processData) {
   this.jsonParams = jsonParams;
-  this.processResponse = processResponse ||
-    function (rawJson, error) {
-      return new opensocial.ResponseItem(null, rawJson, error); // TODO: Original request
+  this.processData = processData ||
+    function (rawJson) {
+      return rawJson;
     };
+
+  this.processResponse = function(originalDataRequest, rawJson, error) {
+    return new opensocial.ResponseItem(originalDataRequest,
+        this.processData(rawJson), error);
+  }
 };

Added: incubator/shindig/trunk/features/opensocial-0.7/jsonperson.js
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-0.7/jsonperson.js?rev=634230&view=auto
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/jsonperson.js (added)
+++ incubator/shindig/trunk/features/opensocial-0.7/jsonperson.js Thu Mar  6 03:46:28 2008
@@ -0,0 +1,63 @@
+/*
+ * 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 interface for json based person objects.
+ *
+ * @private
+ * @constructor
+ */
+JsonPerson = function(opt_params, opt_isOwner, opt_isViewer) {
+  opt_params = opt_params || {};
+
+  // TODO: doesn't handle dateOfBirth, drinker, smoker, or gender yet
+  JsonPerson.constructObject(opt_params, "bodyType", opensocial.BodyType);
+  JsonPerson.constructObject(opt_params, "currentLocation", opensocial.Address);
+  JsonPerson.constructObject(opt_params, "name", opensocial.Name);
+  JsonPerson.constructObject(opt_params, "profileSong", opensocial.Url);
+  JsonPerson.constructObject(opt_params, "profileVideo", opensocial.Url);
+
+  JsonPerson.constructArrayObject(opt_params, "addresses", opensocial.Address);
+  JsonPerson.constructArrayObject(opt_params, "emails", opensocial.Email);
+  JsonPerson.constructArrayObject(opt_params, "jobs", opensocial.Organization);
+  JsonPerson.constructArrayObject(opt_params, "phoneNumbers", opensocial.Phone);
+  JsonPerson.constructArrayObject(opt_params, "schools",
+      opensocial.Organization);
+  JsonPerson.constructArrayObject(opt_params, "urls", opensocial.Url);
+
+  
+  opensocial.Person.call(this, opt_params, opt_isOwner, opt_isViewer);
+};
+JsonPerson.inherits(opensocial.Person);
+
+JsonPerson.constructObject = function(map, fieldName, className) {
+  var fieldValue = map[fieldName];
+  if (fieldValue) {
+    map[fieldName] = new className(fieldValue);
+  }
+}
+
+JsonPerson.constructArrayObject = function(map, fieldName, className) {
+  var fieldValue = map[fieldName];
+  if (fieldValue) {
+    for (var i = 0; i < fieldValue.length; i++) {
+      fieldValue[i] = new className(fieldValue[i]);
+    }
+  }
+}

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/DataHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/DataHandler.java?rev=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/DataHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/DataHandler.java Thu Mar  6 03:46:28 2008
@@ -17,11 +17,9 @@
  */
 package org.apache.shindig.social;
 
-import org.json.JSONException;
-
+import java.util.List;
 import java.util.Map;
 
 public interface DataHandler {
-  public Map<String, Map<String, String>> getPersonData(IdSpec idSpec)
-      throws JSONException;
+  public Map<String, Map<String, String>> getPersonData(List<String> ids);
 }

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/PeopleHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/PeopleHandler.java?rev=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/PeopleHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/PeopleHandler.java Thu Mar  6 03:46:28 2008
@@ -22,5 +22,20 @@
 import java.util.List;
 
 public interface PeopleHandler {
-  public List<Person> getPeople(IdSpec idSpec) throws JSONException;
+  /**
+   * Returns a list of people ids that the other handlers (currently data
+   * and activities) can use to fetch their own objects
+   *
+   * @param idSpec The idSpec to translate into ids
+   * @return a list of person ids
+   * @throws JSONException If the idSpec is malformed
+   */
+  public List<String> getIds(IdSpec idSpec) throws JSONException;
+
+  /**
+   * Returns a list of people that correspond to the passed in person ids.
+   * @param ids The ids of the people to fetch.
+   * @return a list of people.
+   */
+  public List<Person> getPeople(List<String> ids);
 }

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicDataHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicDataHandler.java?rev=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicDataHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicDataHandler.java Thu Mar  6 03:46:28 2008
@@ -18,47 +18,92 @@
 package org.apache.shindig.social.file;
 
 import org.apache.shindig.social.DataHandler;
-import org.apache.shindig.social.IdSpec;
-import org.json.JSONException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
 
-import java.util.Map;
-import java.util.List;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class BasicDataHandler implements DataHandler {
-  public Map<String, Map<String, String>> getPersonData(IdSpec idSpec)
-      throws JSONException {
-    // TODO: Actually read from file
+  Map<String, Map<String, String>> allData
+      = new HashMap<String, Map<String, String>>();
+
+  public BasicDataHandler() {
+    // TODO: Should use guice here for one global thingy and get url from web ui
+    String stateFile = "http://localhost:8080/gadgets/files/samplecontainer/state-basicfriendlist.xml";
+    XmlStateFileFetcher fetcher = new XmlStateFileFetcher(stateFile);
+    Document doc = fetcher.fetchStateDocument(true);
+    setupData(doc);
+  }
+
+  private void setupData(Document stateDocument) {
+    Element root = stateDocument.getDocumentElement();
+
+    NodeList elements = root.getElementsByTagName("personAppData");
+    NodeList personDataNodes = elements.item(0).getChildNodes();
+
+    for (int i = 0; i < personDataNodes.getLength(); i++) {
+      Node personDataNode = personDataNodes.item(i);
+      NamedNodeMap attributes = personDataNode.getAttributes();
+      if (attributes == null) {
+        continue;
+      }
+
+      String id = attributes.getNamedItem("person").getNodeValue();
+      String field = attributes.getNamedItem("field").getNodeValue();
+      String value = personDataNode.getTextContent();
+
+      Map<String, String> currentData = allData.get(id);
+      if (currentData == null) {
+        currentData = new HashMap<String, String>();
+        allData.put(id, currentData);
+      }
+      currentData.put(field, value);
+    }
+  }
+
+  public Map<String, Map<String, String>> getPersonData(List<String> ids) {
     // TODO: Use the opensource Collections library
-    Map<String, Map<String, String>> map =
+    Map<String, Map<String, String>> data =
         new HashMap<String, Map<String, String>>();
 
-    switch (idSpec.getType()) {
-      case VIEWER:
-      case OWNER:
-        Map<String, String> data = new HashMap<String, String>();
-        data.put("count", "3");
-
-        map.put("john.doe", data);
-        break;
-      case VIEWER_FRIENDS:
-      case OWNER_FRIENDS:
-        Map<String, String> janeData = new HashMap<String, String>();
-        janeData.put("count", "7");
-        Map<String, String> georgeData = new HashMap<String, String>();
-        georgeData.put("count", "2");
-
-        map.put("jane.doe", janeData);
-        map.put("george.doe", georgeData);
-        break;
-      case USER_IDS:
-        List<String> userIds = idSpec.fetchUserIds();
-        for (String userId : userIds) {
-          Map<String, String> userData = new HashMap<String, String>();
-          userData.put("count", "1");
-          map.put(userId, userData);
-        }
+    for (String id : ids) {
+      data.put(id, allData.get(id));
+    }
+
+    return data;
+  }
+
+  /**
+   * Determines whether the input is a valid key. Valid keys match the regular
+   * expression [\w\-\.]+. The logic is not done using java.util.regex.* as
+   * that is 20X slower.
+   *
+   * @param key the key to validate.
+   * @return true if the key is a valid appdata key, false otherwise.
+   */
+  // TODO: Use this method
+  public static boolean isValidKey(String key) {
+    if (key == null || key.length() == 0) {
+      return false;
     }
-    return map;
+    for (int i = 0; i < key.length(); ++i) {
+      char c = key.charAt(i);
+      if ((c >= 'a' && c <= 'z') ||
+          (c >= 'A' && c <= 'Z') ||
+          (c >= '0' && c <= '9') ||
+          (c == '-') ||
+          (c == '_') ||
+          (c == '.')) {
+        continue;
+      }
+      return false;
+    }
+    return true;
   }
+
 }

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicPeopleHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicPeopleHandler.java?rev=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicPeopleHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/BasicPeopleHandler.java Thu Mar  6 03:46:28 2008
@@ -17,37 +17,99 @@
  */
 package org.apache.shindig.social.file;
 
+import org.apache.shindig.social.IdSpec;
+import org.apache.shindig.social.Name;
 import org.apache.shindig.social.PeopleHandler;
 import org.apache.shindig.social.Person;
-import org.apache.shindig.social.Name;
-import org.apache.shindig.social.IdSpec;
 import org.json.JSONException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.NodeList;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class BasicPeopleHandler implements PeopleHandler {
-  public List<Person> getPeople(IdSpec idSpec) throws JSONException {
-    // TODO: Actually read from file
+  private Map<IdSpec.Type, List<String>> idMap
+      = new HashMap<IdSpec.Type, List<String>>();
+  private Map<String, Person> allPeople
+      = new HashMap<String, Person>();
+
+  public BasicPeopleHandler() {
+    // TODO: Get file from user in web ui
+    String stateFile = "http://localhost:8080/gadgets/files/samplecontainer/state-basicfriendlist.xml";
+    XmlStateFileFetcher fetcher = new XmlStateFileFetcher(stateFile);
+    Document doc = fetcher.fetchStateDocument(true);
+    setupData(doc);
+  }
+
+  private void setupData(Document stateDocument) {
+    Element root = stateDocument.getDocumentElement();
+
+    // TODO: Eventually the viewer and owner shouldn't be hardcoded. You should
+    // be able to visit other allPeople's "profile" pages in the sample container
+    setupPeopleInXmlTag(root, "viewer", IdSpec.Type.VIEWER);
+    setupPeopleInXmlTag(root, "owner", IdSpec.Type.OWNER);
+    setupPeopleInXmlTag(root, "viewerFriends", IdSpec.Type.VIEWER_FRIENDS);
+    setupPeopleInXmlTag(root, "ownerFriends", IdSpec.Type.OWNER_FRIENDS);
+
+    // Handle empty people
+    if (idMap.get(IdSpec.Type.OWNER).isEmpty()) {
+      idMap.put(IdSpec.Type.OWNER, idMap.get(IdSpec.Type.VIEWER));
+    }
+
+    if (idMap.get(IdSpec.Type.OWNER_FRIENDS).isEmpty()) {
+      idMap.put(IdSpec.Type.OWNER_FRIENDS,
+          idMap.get(IdSpec.Type.VIEWER_FRIENDS));
+    }
+  }
+
+  // Adds all people in the xml tag to the allPeople map.
+  // Also returns the relevant ids
+  private void setupPeopleInXmlTag(Element root, String tagName,
+      IdSpec.Type idType) {
     // TODO: Use the opensource Collections library
-    ArrayList<Person> people = new ArrayList<Person>();
+    List<String> ids = new ArrayList<String>();
+
+    NodeList elements = root.getElementsByTagName(tagName);
+    if (elements == null || elements.item(0) == null) {
+      idMap.put(idType, ids);
+      return;
+    }
+
+    NodeList personNodes = elements.item(0).getChildNodes();
+
+    for (int i = 0; i < personNodes.getLength(); i++) {
+      NamedNodeMap attributes = personNodes.item(i).getAttributes();
+      if (attributes == null) {
+        continue;
+      }
 
-    switch (idSpec.getType()) {
-      case VIEWER:
-      case OWNER:
-        people.add(new Person("john.doe", new Name("John Doe")));
-        break;
-      case VIEWER_FRIENDS:
-      case OWNER_FRIENDS:
-        people.add(new Person("jane.doe", new Name("Jane Doe")));
-        people.add(new Person("jane.doe", new Name("George Doe")));
-        break;
-      case USER_IDS:
-        List<String> userIds = idSpec.fetchUserIds();
-        for (String userId : userIds) {
-          people.add(new Person(userId, new Name(userId)));
-        }
+      String name = attributes.getNamedItem("name").getNodeValue();
+      String id = attributes.getNamedItem("id").getNodeValue();
+      allPeople.put(id, new Person(id, new Name(name)));
+      ids.add(id);
+    }
+
+    idMap.put(idType, ids);
+  }
+
+  public List<Person> getPeople(List<String> ids) {
+    List<Person> people = new ArrayList<Person>();
+    for (String id : ids) {
+      people.add(allPeople.get(id));
     }
     return people;
+  }
+
+  public List<String> getIds(IdSpec idSpec) throws JSONException {
+    if (idSpec.getType() == IdSpec.Type.USER_IDS) {
+      return idSpec.fetchUserIds();
+    } else {
+      return idMap.get(idSpec.getType());
+    }
   }
 }

Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/XmlStateFileFetcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/XmlStateFileFetcher.java?rev=634230&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/XmlStateFileFetcher.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/file/XmlStateFileFetcher.java Thu Mar  6 03:46:28 2008
@@ -0,0 +1,68 @@
+package org.apache.shindig.social.file;
+
+import org.w3c.dom.Document;
+import org.apache.shindig.gadgets.RemoteContentFetcher;
+import org.apache.shindig.gadgets.BasicRemoteContentFetcher;
+import org.apache.shindig.gadgets.RemoteContent;
+import org.apache.shindig.gadgets.RemoteContentRequest;
+import org.apache.shindig.gadgets.ProcessingOptions;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.StringReader;
+import java.io.IOException;
+
+/**
+ * @author Cassandra Doll <do...@google.com>
+ */
+public class XmlStateFileFetcher {
+  private String stateFile;
+  private Document document;
+
+  // TODO: Prob change to a Uri param, let the stateFile setter deal
+  // with the exception.
+  public XmlStateFileFetcher(String stateFile) {
+    this.stateFile = stateFile;
+  }
+
+  public Document fetchStateDocument(boolean useCache) {
+    if (useCache && document != null) {
+      return document;
+    }
+
+    URI uri;
+    try {
+      uri = new URI(stateFile);
+    } catch (URISyntaxException e) {
+      throw new RuntimeException("The state file " + stateFile
+          + " does not point to a valid uri", e);
+    }
+
+    // TODO: Eventually get the fetcher and processing options from a
+    // config file, just like the GadgetServer
+    RemoteContentFetcher fetcher = new BasicRemoteContentFetcher(1024 * 1024);
+    RemoteContent xml = fetcher.fetch(new RemoteContentRequest(uri),
+        new ProcessingOptions());
+
+    InputSource is = new InputSource(new StringReader(
+        xml.getResponseAsString()));
+
+    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+    String errorMessage = "The state file " + stateFile
+        + " could not be fetched and parsed.";
+    try {
+      document = factory.newDocumentBuilder().parse(is);
+      return document;
+    } catch (SAXException e) {
+      throw new RuntimeException(errorMessage, e);
+    } catch (IOException e) {
+      throw new RuntimeException(errorMessage, e);
+    } catch (ParserConfigurationException e) {
+      throw new RuntimeException(errorMessage, e);
+    }
+  }
+}

Modified: 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=634230&r1=634229&r2=634230&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/http/SocialDataServlet.java Thu Mar  6 03:46:28 2008
@@ -26,6 +26,7 @@
 import org.apache.shindig.social.Person;
 import org.apache.shindig.social.IdSpec;
 import org.apache.shindig.social.DataHandler;
+import static org.apache.shindig.social.IdSpec.*;
 import org.apache.shindig.social.file.BasicPeopleHandler;
 import org.apache.shindig.social.file.BasicDataHandler;
 
@@ -83,17 +84,21 @@
       String jsonData = "{}";
 
       JSONObject requestItem = requestItems.getJSONObject(i);
-      SocialDataType type = SocialDataType.valueOf(
-          requestItem.getString("type"));
 
       try {
+        SocialDataType type = SocialDataType.valueOf(
+            requestItem.getString("type"));
+
+        String jsonSpec = requestItem.getString("idSpec");
+        List<String> peopleIds = peopleHandler.getIds(fromJson(jsonSpec));
+
         switch (type) {
           case FETCH_PEOPLE :
-            jsonData = handleFetchPeople(requestItem);
+            jsonData = handleFetchPeople(peopleIds);
             break;
 
           case FETCH_PERSON_APP_DATA :
-            jsonData = handleFetchData(requestItem);
+            jsonData = handleFetchData(peopleIds);
             break;
         }
 
@@ -111,21 +116,21 @@
     return jsonResponse;
   }
 
-  private String handleFetchData(JSONObject requestItem) throws JSONException {
-    String jsonSpec = requestItem.getString("idSpec");
+  private String handleFetchData(List<String> peopleIds) {
     Map<String, Map<String,String>> people
-        = dataHandler.getPersonData(IdSpec.fromJson(jsonSpec));
+        = dataHandler.getPersonData(peopleIds);
 
     String jsonData = "{";
 
     for (String userId : people.keySet()) {
       Map<String, String> userData = people.get(userId);
-
       jsonData += "'" + userId + "' : {";
 
-      for (String dataKey : userData.keySet()) {
-        String dataValue = userData.get(dataKey);
-        jsonData += "'" + dataKey + "' : '" + dataValue + "' ";
+      if (userData != null) {
+        for (String dataKey : userData.keySet()) {
+          String dataValue = userData.get(dataKey);
+          jsonData += "'" + dataKey + "' : '" + dataValue + "' ";
+        }
       }
 
       jsonData += "}, ";
@@ -136,11 +141,8 @@
     return jsonData;
   }
 
-  private String handleFetchPeople(JSONObject requestItem)
-      throws JSONException {
-    String jsonSpec = requestItem.getString("idSpec");
-
-    List<Person> people = peopleHandler.getPeople(IdSpec.fromJson(jsonSpec));
+  private String handleFetchPeople(List<String> peopleIds) {
+    List<Person> people = peopleHandler.getPeople(peopleIds);
     if (people.isEmpty()) {
       return "{}";
     }
@@ -153,4 +155,5 @@
 
     return jsonData;
   }
+
 }