Author: doll
Date: Wed Apr 30 04:06:59 2008
New Revision: 652321

URL: http://svn.apache.org/viewvc?rev=652321&view=rev
Log:
SHINDIG-210 - Patch from Vasu Nori - adds an initial implementation of some of 
the restful apis to the social code.

Added:
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/SocialApiProvider.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivitiesServiceAdapter.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PeopleServiceAdapter.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestGuiceModule.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/opensocial/util/
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
Modified:
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
    incubator/shindig/trunk/java/social-api/pom.xml
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/ActivitiesService.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
    incubator/shindig/trunk/java/social-api/src/main/webapp/WEB-INF/web.xml

Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml 
(original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml Wed Apr 
30 04:06:59 2008
@@ -71,6 +71,19 @@
     <servlet-class>org.apache.shindig.gadgets.http.JsServlet</servlet-class>
   </servlet>
 
+  <!-- Serve REST api -->
+  <servlet>
+    <servlet-name>restapiServlet</servlet-name>
+    <servlet-class>
+      org.apache.abdera.protocol.server.servlet.AbderaServlet
+    </servlet-class>
+    <init-param>
+      <param-name>org.apache.abdera.protocol.server.Provider</param-name>
+      <param-value>org.apache.shindig.social.SocialApiProvider</param-value>
+    </init-param> 
+  </servlet>
+
+
   <servlet-mapping>
     <servlet-name>js</servlet-name>
     <url-pattern>/gadgets/js/*</url-pattern>
@@ -95,4 +108,9 @@
     <servlet-name>socialdata</servlet-name>
     <url-pattern>/social/data</url-pattern>
   </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>restapiServlet</servlet-name>
+    <url-pattern>/rest/*</url-pattern>
+  </servlet-mapping>
 </web-app>

Modified: incubator/shindig/trunk/java/social-api/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/pom.xml (original)
+++ incubator/shindig/trunk/java/social-api/pom.xml Wed Apr 30 04:06:59 2008
@@ -76,14 +76,6 @@
           <artifactId>maven-eclipse-plugin</artifactId>
       </plugin>
       <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>1.5</source>
-          <target>1.5</target>
-          <fork>true</fork>
-        </configuration>
-      </plugin>
-      <plugin>
         <artifactId>maven-source-plugin</artifactId>
         <executions>
           <execution>
@@ -177,5 +169,10 @@
       <groupId>${pom.groupId}</groupId>
       <artifactId>shindig-common</artifactId>
     </dependency>
+    <dependency>
+      <artifactId>commons-betwixt</artifactId>
+      <version>0.8</version>
+      <groupId>commons-betwixt</groupId>
+    </dependency>
   </dependencies>
 </project>

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/SocialApiProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/SocialApiProvider.java?rev=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/SocialApiProvider.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/SocialApiProvider.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import org.apache.shindig.social.abdera.ActivitiesServiceAdapter;
+import org.apache.shindig.social.abdera.PeopleServiceAdapter;
+
+import org.apache.abdera.protocol.server.TargetType;
+import org.apache.abdera.protocol.server.impl.DefaultProvider;
+import org.apache.abdera.protocol.server.impl.RouteManager;
+
+public class SocialApiProvider extends DefaultProvider {
+  private static final String BASE = "/rest/";
+  private static final String ROUTENAME_NOT_USED = "not_used_right_now";
+
+  public SocialApiProvider() {
+
+    // Create the adapters to handle requests.
+    // TODO @Inject
+    PeopleServiceAdapter peopleAdapter = new PeopleServiceAdapter();
+    ActivitiesServiceAdapter activitiesAdapter = new 
ActivitiesServiceAdapter();
+
+    // Add the RouteManager that parses incoming and builds outgoing URLs
+    routeManager = new RouteManager()
+
+      // Collection of all people connected to user {uid}
+      // /people/{uid}/@all
+      .addRoute(ROUTENAME_NOT_USED,
+            BASE + "people/:uid/@all",
+            TargetType.TYPE_COLLECTION,
+            peopleAdapter)
+
+      // Individual person record. /people/{uid}/@all/{pid}
+      .addRoute(ROUTENAME_NOT_USED,
+          BASE + "people/:uid/@all/:pid",
+          TargetType.TYPE_ENTRY,
+          peopleAdapter)
+
+      // Self Profile record for user {uid} /people/{uid}/@self
+      .addRoute(ROUTENAME_NOT_USED,
+          BASE + "people/:uid/@self",
+          TargetType.TYPE_ENTRY,
+          peopleAdapter)
+
+      // Activities
+      // Collection of activities for given user /activities/{uid}/@self
+      .addRoute(ROUTENAME_NOT_USED,
+          BASE + "activities/:uid/@self",
+          TargetType.TYPE_COLLECTION,
+          activitiesAdapter)
+
+      // Individual activity resource; usually discovered from collection
+      // /activities/{uid}/@self/{aid}
+      .addRoute(ROUTENAME_NOT_USED,
+          BASE + "activities/:uid/@self/:aid",
+          TargetType.TYPE_ENTRY,
+          activitiesAdapter)
+    ;
+
+    targetBuilder = routeManager;
+    targetResolver = routeManager;
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivitiesServiceAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivitiesServiceAdapter.java?rev=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivitiesServiceAdapter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/ActivitiesServiceAdapter.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,87 @@
+/*
+* 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.ActivitiesService;
+import org.apache.shindig.social.opensocial.model.Activity;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.ResponseContext;
+
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.logging.Logger;
+
+/**
+ * All "activity" requests are processed here.
+ *
+ * @author [EMAIL PROTECTED] (Vasu Nori)
+ *
+ */
[EMAIL PROTECTED]("unchecked")
+public class ActivitiesServiceAdapter extends RestServerCollectionAdapter {
+  private static Logger logger =
+    Logger.getLogger(ActivitiesServiceAdapter.class.getName());
+  private ActivitiesService handler;
+
+  // TODO get these from the config files like in feedserver
+  private static final String TITLE = "Acitivity Collection title";
+  private static final String AUTHOR = "TODO";
+
+  public ActivitiesServiceAdapter() {
+    // TODO needs cleanup once injection from AbderaServlet works..
+    Injector injector = null;
+    try {
+       injector = Guice.createInjector(new RestGuiceModule());
+    } catch (Exception e) {
+      logger.severe("injector exception: " + e.getMessage());
+    }
+    handler = injector.getInstance(ActivitiesService.class);
+  }
+
+  @Override
+  public ResponseContext getFeed(RequestContext request) {
+    // get the params from the request
+    String[] paramNames = request.getTarget().getParameterNames();
+    String uid = request.getTarget().getParameter(paramNames[0]);
+
+    List<String> ids = new ArrayList<String>();
+    ids.add(uid);
+    // TODO: Use a real gadget token
+    List<Activity> listOfObj = handler.getActivities(ids, null).getResponse();
+    return returnFeed(request, TITLE, AUTHOR, (List)listOfObj);
+  }
+
+  @Override
+  public ResponseContext getEntry(RequestContext request) {
+    // get the params from the request
+    String[] paramNames = request.getTarget().getParameterNames();
+    String uid = request.getTarget().getParameter(paramNames[0]);
+    String aid = request.getTarget().getParameter(paramNames[1]);
+    // TODO: Use a real gadget token
+    Activity obj = handler.getActivity(uid, aid, null).getResponse();
+
+    // TODO: how is entry id determined. check.
+    String entryId = request.getUri().toString();
+    Date updated = (obj != null) ? obj.getUpdated() : null;
+    return returnEntry(request, obj, entryId, updated);
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PeopleServiceAdapter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PeopleServiceAdapter.java?rev=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PeopleServiceAdapter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/PeopleServiceAdapter.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,103 @@
+/*
+* 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.PeopleService;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.abdera.protocol.server.ProviderHelper;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.ResponseContext;
+
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * All "people" requests are processed here.
+ *
+ * @author [EMAIL PROTECTED] (Vasu Nori)
+ *
+ */
[EMAIL PROTECTED]("unchecked")
+public class PeopleServiceAdapter extends RestServerCollectionAdapter {
+  private static Logger logger =
+    Logger.getLogger(PeopleServiceAdapter.class.getName());
+  private PeopleService handler;
+
+  // TODO get these from the config files like in feedserver
+  private static final String TITLE = "People Collection title";
+  private static final String AUTHOR = "TODO";
+
+  public PeopleServiceAdapter() {
+    // TODO needs cleanup once injection from AbderaServlet works..
+    Injector injector = null;
+    try {
+       injector = Guice.createInjector(new RestGuiceModule());
+    } catch (Exception e) {
+      logger.severe("injector exception: " + e.getMessage());
+    }
+    handler = injector.getInstance(PeopleService.class);
+  }
+
+  @Override
+  public ResponseContext getFeed(RequestContext request) {
+    // get the params from the request
+    String[] paramNames = request.getTarget().getParameterNames();
+    String uid = request.getTarget().getParameter(paramNames[0]);
+    // TODO(doll): Fix the service apis to add a concept of arbitrary friends
+    // Consider whether @all really makes sense... 
+    List<Person> listOfObj = null;
+    return returnFeed(request, TITLE, AUTHOR, (List)listOfObj);
+  }
+
+  @Override
+  public ResponseContext getEntry(RequestContext request) {
+    // get the params from the request
+    String[] paramNames = request.getTarget().getParameterNames();
+
+    //   this method is called with 2 params for /people/{uid}/@all/{pid}
+    // and with 1 param for /people/{uid}/@self
+    // TODO have 2 different Abdera Handlers for the 2 different urls.
+    Person person;
+    switch (paramNames.length) {
+      case 1:
+        String uid = request.getTarget().getParameter(paramNames[0]);
+        // TODO: Pass in the gadget token
+        person = handler.getPerson(uid, null).getResponse();
+        break;
+      case 2:
+        uid = request.getTarget().getParameter(paramNames[0]);
+        String pid = request.getTarget().getParameter(paramNames[1]);
+        // TODO: pass in the gadget token with the uid parameter set. We don't
+        // have different views of people from an aribtrary ids point of view.
+        // Rather, the token is how permissions are done.
+        person = handler.getPerson(pid, null).getResponse();
+        break;
+      default:
+        return ProviderHelper.notsupported(request, "more than 2 params?");
+    }
+    // TODO: how is entry id determined. check.
+    String entryId = request.getUri().toString();
+    Date updated = (person != null) ? person.getUpdated() : null;
+    logger.info("updated = " + updated);
+    return returnEntry(request, person, entryId, updated);
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestGuiceModule.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestGuiceModule.java?rev=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestGuiceModule.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestGuiceModule.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,124 @@
+/*
+ * 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.abdera;
+
+import org.apache.shindig.gadgets.BasicContentCache;
+import org.apache.shindig.gadgets.BasicGadgetBlacklist;
+import org.apache.shindig.gadgets.BasicGadgetTokenDecoder;
+import org.apache.shindig.gadgets.BasicRemoteContentFetcher;
+import org.apache.shindig.gadgets.ContainerConfig;
+import org.apache.shindig.gadgets.ContentCache;
+import org.apache.shindig.gadgets.ContentFetcher;
+import org.apache.shindig.gadgets.ContentFetcherFactory;
+import org.apache.shindig.gadgets.GadgetBlacklist;
+import org.apache.shindig.gadgets.GadgetFeatureRegistry;
+import org.apache.shindig.gadgets.GadgetServer;
+import org.apache.shindig.gadgets.GadgetSpecFetcher;
+import org.apache.shindig.gadgets.GadgetTokenDecoder;
+import org.apache.shindig.gadgets.MessageBundleFetcher;
+import org.apache.shindig.gadgets.RemoteContentFetcherFactory;
+import org.apache.shindig.gadgets.SigningFetcherFactory;
+import org.apache.shindig.gadgets.oauth.OAuthFetcherFactory;
+import org.apache.shindig.social.opensocial.ActivitiesService;
+import org.apache.shindig.social.opensocial.DataService;
+import org.apache.shindig.social.opensocial.PeopleService;
+import org.apache.shindig.social.samplecontainer.BasicActivitiesService;
+import org.apache.shindig.social.samplecontainer.BasicDataService;
+import org.apache.shindig.social.samplecontainer.BasicPeopleService;
+import org.apache.shindig.util.ResourceLoader;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import com.google.inject.Scopes;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Message;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * TODO this is to be removed once I figure out how to get AbderaServlet
+ * to play with Guice.
+ * 
+ * TODO: Also, these extra bindings should really be moved into the
+ * SocialApiGuiceModule if they are needed.
+ */
+public class RestGuiceModule extends AbstractModule {
+  private  Properties properties = null;
+  private final String DEFAULT_PROPERTIES = "gadgets.properties";
+
+  /** [EMAIL PROTECTED] */
+  @Override
+  protected void configure() {
+
+    Names.bindProperties(this.binder(), properties);
+
+    bind(RemoteContentFetcherFactory.class);
+    bind(SigningFetcherFactory.class);
+    // Needed becuase OAuth fetcher factory fetches its config
+    bind(ContentFetcher.class)
+        .annotatedWith(OAuthFetcherFactory.OAuthConfigFetcher.class)
+        .to(BasicRemoteContentFetcher.class);
+    bind(OAuthFetcherFactory.class);
+    bind(ContentFetcherFactory.class);
+
+    bind(ContentFetcher.class)
+        .annotatedWith(GadgetSpecFetcher.class)
+        .toProvider(ContentFetcherFactory.class);
+    bind(ContentFetcher.class)
+        .annotatedWith(MessageBundleFetcher.class)
+        .toProvider(ContentFetcherFactory.class);
+
+    bind(GadgetBlacklist.class).to(BasicGadgetBlacklist.class);
+    bind(Executor.class).toInstance(Executors.newCachedThreadPool());
+
+    bind(ContainerConfig.class).in(Scopes.SINGLETON);
+    bind(GadgetFeatureRegistry.class).in(Scopes.SINGLETON);
+    bind(GadgetServer.class).in(Scopes.SINGLETON);
+
+    bind(PeopleService.class).to(BasicPeopleService.class);
+    bind(DataService.class).to(BasicDataService.class);
+    bind(ActivitiesService.class).to(BasicActivitiesService.class);
+
+    bind(ContentFetcher.class).to(BasicRemoteContentFetcher.class);
+    bind(GadgetTokenDecoder.class).to(BasicGadgetTokenDecoder.class);
+    bind(ContentCache.class).to(BasicContentCache.class);
+  }
+
+  /**
+   * Creates module with standard properties.
+   */
+  public RestGuiceModule() {
+    Properties properties = null;
+    try {
+      InputStream is = ResourceLoader.openResource(DEFAULT_PROPERTIES);
+      properties = new Properties();
+      properties.load(is);
+    } catch (IOException e) {
+      throw new CreationException(Arrays.asList(
+          new Message("Unable to load properties: " + DEFAULT_PROPERTIES)));
+    }
+    this.properties = properties;
+  }
+
+}

Added: 
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=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/abdera/RestServerCollectionAdapter.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,164 @@
+/*
+* 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.model.Activity;
+import org.apache.shindig.social.opensocial.model.Person;
+import org.apache.shindig.social.opensocial.util.BeanXmlConverter;
+
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.protocol.server.ProviderHelper;
+import org.apache.abdera.protocol.server.RequestContext;
+import org.apache.abdera.protocol.server.ResponseContext;
+import org.apache.abdera.protocol.server.context.ResponseContextException;
+import org.apache.abdera.protocol.server.impl.AbstractCollectionAdapter;
+
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * handles logic to create feeds, entries etc.
+ *
+ * @author [EMAIL PROTECTED] (Vasu Nori)
+ *
+ */
[EMAIL PROTECTED]("unchecked")
+public class RestServerCollectionAdapter extends AbstractCollectionAdapter {
+  private static Logger logger =
+    Logger.getLogger(RestServerCollectionAdapter.class.getName());
+
+  protected ResponseContext returnFeed(RequestContext request, String title,
+      String author, List<Object> listOfObj) {
+    Feed feed;
+    try {
+      feed = createFeedBase(request);
+    } catch (ResponseContextException e) {
+      logger.warning(e.getMessage());
+      return null;
+    }
+    feed.setBaseUri(request.getUri());
+    // TODO set these some other way?
+    feed.addAuthor(author);
+    feed.setTitle(title);
+    // TODO updated should be set to the MAX(updated) of all entries
+    feed.setUpdated(new Date());
+    feed.setId(request.getUri().toString());
+
+    if (listOfObj != null) {
+      // make Entries out of the list  of objects returned above
+      for (Object obj : listOfObj) {
+        // TODO: how is entry id determined. check.
+        String entryId = null;
+        Date updated = null;
+        if (obj instanceof Person) {
+          entryId = request.getUri().toString() + "/" + ((Person)obj).getId();
+          updated = ((Person)obj).getUpdated();
+        } else if (obj instanceof Activity) {
+          entryId = request.getUri().toString() + "/" + 
((Activity)obj).getId();
+          updated = ((Activity)obj).getUpdated();
+        }
+        Entry entry = fillEntry(request, obj, entryId, updated);
+        feed.insertEntry(entry);
+      }
+    }
+    return ProviderHelper.returnBase(feed.getDocument(), 200,
+        feed.getUpdated())
+          .setEntityTag(ProviderHelper.calculateEntityTag(feed));
+  }
+
+  private Entry fillEntry(RequestContext request, Object obj,
+      String id, Date updated) {
+    // create entry
+    Entry entry = request.getAbdera().newEntry();
+    entry.setId(id);
+    entry.setContent(BeanXmlConverter.convertToXml(obj), "text/xml");
+    entry.setUpdated(updated);
+    // TODO what should this be?
+    entry.addAuthor("Author TODO");
+    // TODO what should this be?
+    if (obj instanceof Person) {
+      entry.setTitle((((Person)obj).getName().getUnstructured() != null) ?
+          ((Person)obj).getName().getUnstructured() : "title TODO");
+    } else if (obj instanceof Activity) {
+      entry.setTitle(((Activity)obj).getTitle());
+    } else {
+      entry.setTitle("title TODO");
+    }
+
+    // TODO what is this
+    //entry.setSource(feed.getAsSource());
+    return entry;
+  }
+
+  protected ResponseContext returnEntry(RequestContext request, Object obj,
+      String entryId, Date updated) {
+    if (null == obj) {
+      return ProviderHelper.notfound(request);
+    }
+
+    Entry entry = fillEntry(request, obj, entryId, updated);
+    return ProviderHelper.returnBase(entry.getDocument(), 200,
+        entry.getEdited())
+        .setEntityTag(ProviderHelper.calculateEntityTag(entry));
+  }
+
+  @Override
+  public String getAuthor(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public String getId(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+  public ResponseContext deleteEntry(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+
+  public ResponseContext postEntry(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+  public ResponseContext putEntry(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+  public String getTitle(RequestContext arg0) {
+    //  Auto-generated method stub
+    return null;
+  }
+
+  public ResponseContext getEntry(RequestContext request) {
+    // Auto-generated method stub
+    return null;
+  }
+
+  public ResponseContext getFeed(RequestContext request) {
+    // Auto-generated method stub
+    return null;
+  }
+}

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/ActivitiesService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/ActivitiesService.java?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/ActivitiesService.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/ActivitiesService.java
 Wed Apr 30 04:06:59 2008
@@ -44,4 +44,16 @@
    */
   public ResponseItem createActivity(String personId, Activity activity,
       GadgetToken token);
+
+  /**
+   * Returns an activity for the gived user id that matches the passes in
+   * activityId.
+   *
+   * @param id The id of the user to activity belongs to
+   * @param activityId The id of the activity
+   * @param token A valid GadgetToken 
+   * @return a reponse item with the matching activity
+   */
+  public ResponseItem<Activity> getActivity(String id, String activityId,
+      GadgetToken token);
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/PeopleService.java
 Wed Apr 30 04:06:59 2008
@@ -17,12 +17,13 @@
  */
 package org.apache.shindig.social.opensocial;
 
-import org.json.JSONException;
-import org.apache.shindig.social.opensocial.model.Person;
-import org.apache.shindig.social.opensocial.model.IdSpec;
-import org.apache.shindig.social.opensocial.model.ApiCollection;
-import org.apache.shindig.social.ResponseItem;
 import org.apache.shindig.gadgets.GadgetToken;
+import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.opensocial.model.ApiCollection;
+import org.apache.shindig.social.opensocial.model.IdSpec;
+import org.apache.shindig.social.opensocial.model.Person;
+
+import org.json.JSONException;
 
 import java.util.List;
 import java.util.Set;
@@ -33,6 +34,7 @@
    * and activities) can use to fetch their own objects
    *
    * @param idSpec The idSpec to translate into ids
+   * @param token The gadget token
    * @return a list of person ids
    * @throws JSONException If the idSpec is malformed
    */
@@ -54,9 +56,20 @@
    * @param filter How the people should be filtered.
    * @param first The index of the first person to fetch.
    * @param max The max number of people to fetch.
+   * @param profileDetails The profile details to fetch
+   * @param token The gadget token
    * @return a list of people.
    */
   public ResponseItem<ApiCollection<Person>> getPeople(List<String> ids,
       SortOrder sortOrder, FilterType filter, int first, int max,
       Set<String> profileDetails, GadgetToken token);
+
+  /**
+   * Returns a person that corresponds to the passed in person id.
+   *
+   * @param id The id of the person to fetch.
+   * @param token The gadget token
+   * @return a list of people.
+   */
+  public ResponseItem<Person> getPerson(String id, GadgetToken token);
 }

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java?rev=652321&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanXmlConverter.java
 Wed Apr 30 04:06:59 2008
@@ -0,0 +1,69 @@
+/*
+ * 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.opensocial.util;
+
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.logging.Logger;
+import org.apache.commons.betwixt.io.BeanWriter;
+import org.xml.sax.SAXException;
+
+public class BeanXmlConverter {
+  public static Logger logger =
+      Logger.getLogger(BeanXmlConverter.class.getName());
+
+  public static String convertToXml(Object obj) {
+    StringWriter outputWriter = new StringWriter();
+    BeanWriter writer = new BeanWriter(outputWriter);
+    writer.getXMLIntrospector()
+        .getConfiguration()
+        .setAttributesForPrimitives(false);
+    writer.getBindingConfiguration().setMapIDs(false);
+    writer.enablePrettyPrint();
+    writer.setWriteEmptyElements(false);
+    String toReturn = null;
+    try {
+      // get class name in lower letters (w/o package name)
+      String className = obj.getClass().getName();
+      int lastDotIndex = className.lastIndexOf(".");
+      if (lastDotIndex >= 0) {
+        className = className.substring(lastDotIndex + 1);
+      }
+      className = className.toLowerCase();
+      writer.write(className, obj);
+      toReturn = outputWriter.toString();
+      logger.finest("XML is: " + toReturn + "\n **** \n\n");
+    } catch(SAXException e) {
+      System.err.println(e);
+    } catch(IOException e) {
+      System.err.println(e);
+    } catch(IntrospectionException e) {
+      System.err.println(e);
+    }
+
+    try {
+      if (writer != null) {
+        writer.close();
+      }
+    } catch(IOException e) {
+      // ignore this exception. it won't matter
+    }
+    return toReturn;
+  }
+}

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicActivitiesService.java
 Wed Apr 30 04:06:59 2008
@@ -20,6 +20,7 @@
 import org.apache.shindig.gadgets.GadgetToken;
 
 import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.ResponseError;
 import org.apache.shindig.social.opensocial.ActivitiesService;
 import org.apache.shindig.social.opensocial.model.Activity;
 import org.json.JSONObject;
@@ -56,6 +57,21 @@
     return new ResponseItem<List<Activity>>(activities);
   }
 
+  public ResponseItem<Activity> getActivity(String id, String activityId,
+      GadgetToken token) {
+    List<String> ids = new ArrayList<String>();
+    ids.add(id);
+    
+    List<Activity> allActivities = getActivities(ids, null).getResponse();
+    for (Activity activity : allActivities) {
+      if (activity.getId().equals(activityId)) {
+        return new ResponseItem<Activity>(activity);
+      }
+    }
+    return new ResponseItem<Activity>(ResponseError.BAD_REQUEST,
+        "Activity not found", null);
+  }
+
   public ResponseItem createActivity(String personId, Activity activity,
       GadgetToken token) {
     // TODO: Validate the activity and do any template expanding
@@ -65,4 +81,5 @@
     fetcher.createActivity(personId, activity);
     return new ResponseItem<JSONObject>(new JSONObject());
   }
+
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/BasicPeopleService.java
 Wed Apr 30 04:06:59 2008
@@ -51,9 +51,7 @@
     this.fetcher = fetcher;
   }
 
-  public ResponseItem<ApiCollection<Person>> getPeople(List<String> ids,
-      SortOrder sortOrder, FilterType filter, int first, int max,
-      Set<String> profileDetails, GadgetToken token) {
+  private List<Person> getPeople(List<String> ids, GadgetToken token) {
     Map<String, Person> allPeople = fetcher.getAllPeople();
 
     List<Person> people = new ArrayList<Person>();
@@ -69,6 +67,13 @@
         people.add(person);
       }
     }
+    return people;
+  }
+
+  public ResponseItem<ApiCollection<Person>> getPeople(List<String> ids,
+      SortOrder sortOrder, FilterType filter, int first, int max,
+      Set<String> profileDetails, GadgetToken token) {
+    List<Person> people = getPeople(ids, token);
 
     // We can pretend that by default the people are in top friends order
     if (sortOrder.equals(SortOrder.name)) {
@@ -87,6 +92,12 @@
     return new ResponseItem<ApiCollection<Person>>(collection);
   }
 
+  public ResponseItem<Person> getPerson(String id, GadgetToken token) {
+    List<String> ids = new ArrayList<String>();
+    ids.add(id);
+    return new ResponseItem<Person>(getPeople(ids, token).get(0));
+  }
+
   public List<String> getIds(IdSpec idSpec, GadgetToken token)
       throws JSONException {
     Map<String, List<String>> friendIds = fetcher.getFriendIds();
@@ -111,4 +122,5 @@
     }
     return ids;
   }
+
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
 Wed Apr 30 04:06:59 2008
@@ -31,6 +31,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Date;
 
 @Singleton
 public class XmlStateFileFetcher {
@@ -217,6 +218,7 @@
       String name = attributes.getNamedItem("name").getNodeValue();
       String id = attributes.getNamedItem("id").getNodeValue();
       Person person = new Person(id, new Name(turnEvil(name)));
+      person.setUpdated(new Date());
 
       Node phoneItem = attributes.getNamedItem("phone");
       if (phoneItem != null) {
@@ -304,6 +306,7 @@
         activity.setTitle(turnEvil(title));
         activity.setBody(turnEvil(body));
         activity.setMediaItems(getMediaItems(activityItem));
+        activity.setUpdated(new Date());
 
         createActivity(userId, activity);
       }

Modified: 
incubator/shindig/trunk/java/social-api/src/main/webapp/WEB-INF/web.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/webapp/WEB-INF/web.xml?rev=652321&r1=652320&r2=652321&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/webapp/WEB-INF/web.xml 
(original)
+++ incubator/shindig/trunk/java/social-api/src/main/webapp/WEB-INF/web.xml Wed 
Apr 30 04:06:59 2008
@@ -42,9 +42,26 @@
       org.apache.shindig.social.GadgetDataServlet
     </servlet-class>
   </servlet>
-
+  
+  <!-- Serve REST api -->
+  <servlet>
+    <servlet-name>restapiServlet</servlet-name>
+    <servlet-class>
+      org.apache.abdera.protocol.server.servlet.AbderaServlet
+    </servlet-class>
+    <init-param>
+      <param-name>org.apache.abdera.protocol.server.Provider</param-name>
+      <param-value>org.apache.shindig.social.SocialApiProvider</param-value>
+    </init-param> 
+  </servlet>
+  
   <servlet-mapping>
     <servlet-name>socialdata</servlet-name>
     <url-pattern>/data</url-pattern>
   </servlet-mapping>
+  
+  <servlet-mapping>
+    <servlet-name>restapiServlet</servlet-name>
+    <url-pattern>/rest/*</url-pattern>
+  </servlet-mapping>
 </web-app>


Reply via email to