Author: doll
Date: Fri May  9 08:54:06 2008
New Revision: 654862

URL: http://svn.apache.org/viewvc?rev=654862&view=rev
Log:
Added support for the restful appdata urls. This required: 

- adding a new adapter
- fixing a url typo to turn self and friends into @self and @friends
- improving the BeanJsonConverter to handle maps directly (which essentially 
just meant switching the recursion around)
- changing the js slightly

These urls don't quite follow the spec exactly yet. We need to fix our json 
handling before we can make this all compliant. However, all of the js calls 
work in read only mode now!


Added:
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataServiceAdapter.java
Modified:
    incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RouteManagerTest.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java

Modified: 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=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js 
(original)
+++ incubator/shindig/trunk/features/opensocial-0.7/restfulcontainer.js Fri May 
 9 08:54:06 2008
@@ -185,7 +185,7 @@
        + "?fields=" + keys.join(',');
   return new RestfulRequestItem(url, "GET", null,
       function (appData) {
-        return gadgets.util.escape(appData, true);
+        return gadgets.util.escape(appData[0], true);
       });
 };
 

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/GadgetDataServlet.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
 Fri May  9 08:54:06 2008
@@ -94,7 +94,8 @@
     }
     resp.setContentType("application/json; charset=utf-8");
     PrintWriter writer = resp.getWriter();
-    writer.write(beanJsonConverter.convertToJson(response).toString());
+    Object json = beanJsonConverter.convertToJson(response);
+    writer.write(json.toString());
   }
 
   private List<ResponseItem> createResponse(String requestParam, String token)

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataServiceAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataServiceAdapter.java?rev=654862&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataServiceAdapter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/DataServiceAdapter.java
 Fri May  9 08:54:06 2008
@@ -0,0 +1,94 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.shindig.social.abdera;
+
+import org.apache.shindig.social.opensocial.DataService;
+
+import com.google.inject.Inject;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.ResponseContext;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Date;
+
+/**
+ * All "data" requests are processed here.
+ *
+ */
[EMAIL PROTECTED]("unchecked")
+public class DataServiceAdapter extends RestServerCollectionAdapter {
+  private DataService dataService;
+
+  // TODO get these from the config files like in feedserver
+  private static final String TITLE = "Data Collection title";
+  private static final String AUTHOR = "TODO";
+
+  @Inject
+  public DataServiceAdapter(DataService dataService) {
+    this.dataService = dataService;
+  }
+
+  /**
+   * Handles the following URL
+   *    /appdata/{uid}/@friends/{aid}
+   */
+  public ResponseContext getFeed(RequestContext request) {
+    String uid = request.getTarget().getParameter("uid");
+    String aid = request.getTarget().getParameter("aid");
+    List<String> ids = getFriendIds(request, uid);
+
+    Map<String, Map<String, String>> dataMap = dataService.getPersonData(ids,
+        getKeys(request), getGadgetToken(request, uid)).getResponse();
+
+    // TODO: This return type is not quite right. We should fix this to
+    // match the spec once we have a full json format in place.
+    List dataList = new ArrayList();
+    dataList.add(dataMap);
+
+    return returnFeed(request, TITLE, AUTHOR, dataList);
+  }
+
+  /**
+   *  Handles the following URL
+   *    /appdata/{uid}/@self/{aid}
+   */
+  public ResponseContext getEntry(RequestContext request) {
+    String uid = request.getTarget().getParameter("uid");
+    String appId = request.getTarget().getParameter("aid");
+
+    List<String> ids = new ArrayList<String>();
+    ids.add(uid);
+
+    Map<String, String> data = dataService.getPersonData(ids,
+        getKeys(request), getGadgetToken(request, uid)).getResponse().get(uid);
+
+    // TODO: how is entry id determined. check.
+    String entryId = request.getUri().toString();
+    return returnEntry(request, data == null ? new HashMap() : data,
+        entryId, new Date());
+  }
+
+  private List<String> getKeys(RequestContext request) {
+    String[] keyArray = request.getTarget().getParameter("fields").split(",");
+    return Arrays.asList(keyArray);
+  }
+}
\ No newline at end of file

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
 Fri May  9 08:54:06 2008
@@ -150,8 +150,8 @@
             "application/xml");
         break;
       case JSON:
-        entry.setContent(beanJsonConverter.convertToJson(obj).toString(),
-            "application/json");
+        Object json = beanJsonConverter.convertToJson(obj);
+        entry.setContent(json.toString(), "application/json");
         break;
     }
 

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/SocialApiProvider.java
 Fri May  9 08:54:06 2008
@@ -30,6 +30,7 @@
   private Provider<PeopleServiceAdapter> peopleAdapterProvider;
   private Provider<ActivitiesServiceAdapter> activitiesAdapterProvider;
   private Provider<FriendsServiceAdapter> friendsAdapterProvider;
+  private Provider<DataServiceAdapter> dataAdapterProvider;
 
   /**
    * The CollectionAdapter enum standardizes the names and descriptions of the
@@ -73,21 +74,15 @@
   }
 
   @Inject
-  public void setPeopleAdapter(Provider<PeopleServiceAdapter>
-      peopleAdapterProvider) {
+  public void setAdapters(
+      Provider<PeopleServiceAdapter> peopleAdapterProvider,
+      Provider<FriendsServiceAdapter> friendsAdapterProvider,
+      Provider<ActivitiesServiceAdapter> activitiesAdapterProvider,
+      Provider<DataServiceAdapter> dataAdapterProvider) {
     this.peopleAdapterProvider = peopleAdapterProvider;
-  }
-
-  @Inject
-  public void setFriendsAdapter(Provider<FriendsServiceAdapter>
-      friendsAdapterProvider) {
     this.friendsAdapterProvider = friendsAdapterProvider;
-  }
-
-  @Inject
-  public void setActivitiesAdapter(Provider<ActivitiesServiceAdapter>
-      activitiesAdapterProvider) {
     this.activitiesAdapterProvider = activitiesAdapterProvider;
+    this.dataAdapterProvider = dataAdapterProvider;
   }
 
   /**
@@ -112,6 +107,7 @@
     FriendsServiceAdapter friendsAdapter = friendsAdapterProvider.get();
     ActivitiesServiceAdapter activitiesAdapter
         = activitiesAdapterProvider.get();
+    DataServiceAdapter dataAdapter = dataAdapterProvider.get();
 
     // Add the RouteManager that parses incoming and builds outgoing URLs
     // {uid} is assumed to be a deterministic GUID for the service
@@ -179,16 +175,16 @@
         // AppData
 
         // Individual App Data record for a given user+app, consisting 
primarily
-        // of a bag of key/value pairs. -- /appdata/{uid}/self/{aid}
+        // of a bag of key/value pairs. -- /appdata/{uid}/@self/{aid}
         .addRoute(CollectionAdapter.APPDATA_OF_APP_OF_USER.toString(),
-            BASE + "appdata/:uid/self/:aid",
-            TargetType.TYPE_ENTRY, null)
+            BASE + "appdata/:uid/@self/:aid",
+            TargetType.TYPE_ENTRY, dataAdapter)
 
         // Collection of App Data records for friends of {uid}
-        // /appdata/{uid}/friends/{aid}
+        // /appdata/{uid}/@friends/{aid}
         .addRoute(CollectionAdapter.APPDATA_OF_FRIENDS_OF_USER.toString(),
-            BASE + "appdata/:uid/friends/:aid",
-            TargetType.TYPE_COLLECTION, null)
+            BASE + "appdata/:uid/@friends/:aid",
+            TargetType.TYPE_COLLECTION, dataAdapter)
 
         ;
 

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
 Fri May  9 08:54:06 2008
@@ -40,18 +40,71 @@
   private static final Pattern GETTER = Pattern.compile("^get([a-zA-Z]+)$");
 
   /**
+   * Convert the passed in object to a json object
+   *
+   * @param pojo The object to convert
+   * @return An object whos toString method will return json
+   */
+  public Object convertToJson(Object pojo) {
+    try {
+      return translateObjectToJson(pojo);
+    } catch (JSONException e) {
+      throw new RuntimeException("Could not translate " + pojo + " to json", 
e);
+    }
+  }
+
+  private Object translateObjectToJson(Object val) throws JSONException {
+    if (val instanceof Object[]) {
+      JSONArray array = new JSONArray();
+      for (Object asd : (Object[]) val) {
+        array.put(translateObjectToJson(asd));
+      }
+      return array;
+
+    } else if (val instanceof List) {
+      JSONArray list = new JSONArray();
+      for (Object item : (List) val) {
+        list.put(translateObjectToJson(item));
+      }
+      return list;
+
+    } else if (val instanceof Map) {
+      JSONObject map = new JSONObject();
+      Map originalMap = (Map) val;
+
+      for (Object item : originalMap.keySet()) {
+        map.put(item.toString(), translateObjectToJson(originalMap.get(item)));
+      }
+      return map;
+
+    } else if (val instanceof String
+        || val instanceof Boolean
+        || val instanceof Integer
+        || val instanceof Date
+        || val instanceof Long
+        || val instanceof Enum
+        || val instanceof Float
+        || val instanceof JSONObject
+        || val instanceof JSONArray) {
+      return val;
+    }
+
+    return convertMethodsToJson(val);
+  }
+
+  /**
    * Convert the object to [EMAIL PROTECTED] JSONObject} reading Pojo 
properties
    *
    * @param pojo The object to convert
    * @return A JSONObject representing this pojo
    */
-  public JSONObject convertToJson(Object pojo) {
+  private JSONObject convertMethodsToJson(Object pojo) {
     JSONObject toReturn = new JSONObject();
     Method[] methods = pojo.getClass().getMethods();
     for (Method method : methods) {
       String errorMessage = "Could not encode the " + method + " method.";
       try {
-        putAttribute(pojo, toReturn, method);
+        addMethodValue(pojo, toReturn, method);
       } catch (JSONException e) {
         throw new RuntimeException(errorMessage, e);
       } catch (IllegalAccessException e) {
@@ -74,7 +127,7 @@
    * @throws IllegalAccessException thrown exception
    * @throws InvocationTargetException thrown exception
    */
-  private void putAttribute(Object pojo, JSONObject object,
+  private void addMethodValue(Object pojo, JSONObject object,
       Method method) throws JSONException, IllegalAccessException,
       InvocationTargetException {
     Matcher matcher = GETTER.matcher(method.getName());
@@ -93,43 +146,4 @@
       object.put(fieldName, translateObjectToJson(val));
     }
   }
-
-  private Object translateObjectToJson(Object val) throws JSONException {
-    if (val instanceof Object[]) {
-      JSONArray array = new JSONArray();
-      for (Object asd : (Object[]) val) {
-        array.put(translateObjectToJson(asd));
-      }
-      return array;
-
-    } else if (val instanceof List) {
-      JSONArray list = new JSONArray();
-      for (Object item : (List) val) {
-        list.put(translateObjectToJson(item));
-      }
-      return list;
-
-    } else if (val instanceof Map) {
-      JSONObject map = new JSONObject();
-      Map originalMap = (Map) val;
-
-      for (Object item : originalMap.keySet()) {
-        map.put(item.toString(), translateObjectToJson(originalMap.get(item)));
-      }
-      return map;
-
-    } else if (val instanceof String
-        || val instanceof Boolean
-        || val instanceof Integer
-        || val instanceof Date
-        || val instanceof Long
-        || val instanceof Enum
-        || val instanceof Float
-        || val instanceof JSONObject
-        || val instanceof JSONArray) {
-      return val;
-    }
-
-    return convertToJson(val);
-  }
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RouteManagerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RouteManagerTest.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RouteManagerTest.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/RouteManagerTest.java
 Fri May  9 08:54:06 2008
@@ -44,8 +44,8 @@
     mockAndResolve("activities/x/y");
     mockAndResolve("activities/x/@self/y");
 
-    mockAndResolve("appdata/x/friends/y");
-    mockAndResolve("appdata/x/self/y");
+    mockAndResolve("appdata/x/@friends/y");
+    mockAndResolve("appdata/x/@self/y");
   }
 
   private void mockAndResolve(String path){

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/abdera/SocialApiProviderTestFixture.java
 Fri May  9 08:54:06 2008
@@ -36,18 +36,21 @@
     mock(Provider.class);
   public final Provider<FriendsServiceAdapter> friendsProvider =
     mock(Provider.class);
+  public final Provider<DataServiceAdapter> dataProvider =
+    mock(Provider.class);
   public final SocialApiProvider provider = new SocialApiProvider();
 
   public SocialApiProviderTestFixture() {
-    provider.setActivitiesAdapter(activitiesProvider);
+    provider.setAdapters(peopleProvider, friendsProvider, activitiesProvider,
+        dataProvider);
     expect(activitiesProvider.get()).andReturn(null);
-    provider.setPeopleAdapter(peopleProvider);
     expect(peopleProvider.get()).andReturn(null);
-    provider.setFriendsAdapter(friendsProvider);
     expect(friendsProvider.get()).andReturn(null);
+    expect(dataProvider.get()).andReturn(null);
     org.easymock.EasyMock.replay(activitiesProvider);
     org.easymock.EasyMock.replay(peopleProvider);
     org.easymock.EasyMock.replay(friendsProvider);
+    org.easymock.EasyMock.replay(dataProvider);
     provider.initialize();
   }
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java?rev=654862&r1=654861&r2=654862&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java
 Fri May  9 08:54:06 2008
@@ -86,13 +86,13 @@
   public void testToJsonOnInheritedClass() throws Exception {
     SpecialPerson cassie = new SpecialPerson("5", "robot", "nonsense");
 
-    JSONObject result = beanJsonConverter.convertToJson(cassie);
+    JSONObject result = (JSONObject) beanJsonConverter.convertToJson(cassie);
     assertEquals(cassie.getId(), result.getString("id"));
     assertEquals(cassie.getNewfield(), result.getString("newfield"));
   }
 
   public void testPersonToJson() throws Exception {
-    JSONObject result = beanJsonConverter.convertToJson(johnDoe);
+    JSONObject result = (JSONObject) beanJsonConverter.convertToJson(johnDoe);
 
     assertEquals(johnDoe.getId(), result.getString("id"));
 
@@ -126,7 +126,7 @@
   }
 
   public void testActivityToJson() throws Exception {
-    JSONObject result = beanJsonConverter.convertToJson(activity);
+    JSONObject result = (JSONObject) beanJsonConverter.convertToJson(activity);
 
     assertEquals(activity.getUserId(), result.getString("userId"));
     assertEquals(activity.getId(), result.getString("id"));
@@ -155,13 +155,27 @@
     item2Map.put("value", "2");
     map.put("item2", item2Map);
 
-    ResponseItem response
-        = new ResponseItem<Map<String, Map<String, String>>>(map);
-    JSONObject result = beanJsonConverter.convertToJson(response);
+    JSONObject jsonMap = (JSONObject) beanJsonConverter.convertToJson(map);
 
-    JSONObject jsonMap = result.getJSONObject("response");
     assertEquals("1", jsonMap.getJSONObject("item1").getString("value"));
     assertEquals("2", jsonMap.getJSONObject("item2").getString("value"));
   }
 
+  public void testListsToJson() throws Exception {
+    List<Map<String, String>> list = new ArrayList<Map<String, String>>();
+
+    Map<String, String> item1Map = new HashMap<String, String>();
+    item1Map.put("value", "1");
+    list.add(item1Map);
+
+    Map<String, String> item2Map = new HashMap<String, String>();
+    item2Map.put("value", "2");
+    list.add(item2Map);
+
+    JSONArray jsonArray = (JSONArray) beanJsonConverter.convertToJson(list);
+
+    assertEquals("1", ((JSONObject) jsonArray.get(0)).getString("value"));
+    assertEquals("2", ((JSONObject) jsonArray.get(1)).getString("value"));
+  }
+
 }


Reply via email to