rave-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zh...@apache.org
Subject svn commit: r1104678 [4/4] - in /incubator/rave/trunk: ./ rave-portal/ rave-shindig/ rave-shindig/src/main/java/ rave-shindig/src/main/java/org/ rave-shindig/src/main/java/org/apache/ rave-shindig/src/main/java/org/apache/rave/ rave-shindig/src/main/ja...
Date Wed, 18 May 2011 03:42:11 GMT
Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java Wed May 18 03:42:09 2011
@@ -0,0 +1,280 @@
+/*
+ * 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.jpa.spi;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+
+import org.apache.rave.os.DatabasePopulateContextListener;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.social.opensocial.jpa.ActivityDb;
+import org.apache.shindig.social.opensocial.jpa.MediaItemDb;
+import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.MediaItem;
+import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.UserId;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The Class ActivityServiceDb.
+ */
+public class ActivityServiceDb implements ActivityService {
+
+  /** The entity manager. */
+  private EntityManager entityManager;
+
+  /**
+   * Instantiates a new activity service db.
+   * 
+   * @param entityManager the entity manager
+   */
+//  @Inject
+  public ActivityServiceDb(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
+  public ActivityServiceDb() {
+      this.entityManager = DatabasePopulateContextListener.getEntityManager();
+  }
+  /* (non-Javadoc)
+   * @see org.apache.shindig.social.opensocial.spi.ActivityService#createActivity(org.apache.shindig.social.opensocial.spi.UserId, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, org.apache.shindig.social.opensocial.model.Activity, org.apache.shindig.auth.SecurityToken)
+   */
+  public Future<Void> createActivity(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, Activity activity, SecurityToken token) throws ProtocolException {
+    String uid = SPIUtils.getUserList(userId, token);
+
+    try {
+      // Map activity into a new ActivityDb instance
+      // TODO Could we use dozer to do this mapping instead, for future-proofing reasons?
+      ActivityDb activityDb = new ActivityDb();
+      activityDb.setPostedTime(new Date().getTime());
+      activityDb.setAppId(appId);
+      activityDb.setUserId(uid);
+      activityDb.setId(activity.getId());
+      activityDb.setBodyId(activity.getBodyId());
+      activityDb.setBody(activity.getBody());
+      activityDb.setExternalId(activity.getExternalId());
+      activityDb.setTitleId(activity.getTitleId());
+      activityDb.setTitle(activity.getTitle());
+      activityDb.setUpdated(new Date());
+      activityDb.setPriority(activity.getPriority());
+      activityDb.setStreamFaviconUrl(activity.getStreamFaviconUrl());
+      activityDb.setStreamSourceUrl(activity.getStreamSourceUrl());
+      activityDb.setStreamTitle(activity.getStreamTitle());
+      activityDb.setStreamUrl(activity.getStreamUrl());
+      activityDb.setUrl(activity.getUrl());
+      if(activity.getMediaItems() != null) {
+        List<MediaItem> mediaItems = new ArrayList<MediaItem>();
+        for(MediaItem m : activity.getMediaItems()) {
+          MediaItemDb mediaItem = new MediaItemDb();
+          mediaItem.setMimeType(m.getMimeType());
+          mediaItem.setType(m.getType());
+          mediaItem.setUrl(m.getUrl());
+          mediaItems.add(mediaItem);
+        }
+        activityDb.setMediaItems(mediaItems);
+      }
+      if (activity.getTemplateParams() != null) {
+        activityDb.setTemplateParams(activity.getTemplateParams());
+      }
+
+      // TODO How should transactions be managed? Should samples be using warp-persist instead?
+      if (!entityManager.getTransaction().isActive()) {
+        entityManager.getTransaction().begin();
+      }
+      entityManager.persist(activityDb);
+      entityManager.getTransaction().commit();
+
+    } catch (Exception e) {
+      throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to create activity", e);
+    }
+
+    return null;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.shindig.social.opensocial.spi.ActivityService#deleteActivities(org.apache.shindig.social.opensocial.spi.UserId, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, org.apache.shindig.auth.SecurityToken)
+   */
+  public Future<Void> deleteActivities(UserId userId, GroupId groupId, String appId,
+      Set<String> activityIds, SecurityToken token) throws ProtocolException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.shindig.social.opensocial.spi.ActivityService#getActivities(java.util.Set, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, org.apache.shindig.social.opensocial.spi.CollectionOptions, org.apache.shindig.auth.SecurityToken)
+   */
+  public Future<RestfulCollection<Activity>> getActivities(Set<UserId> userIds,
+      GroupId groupId, String appId, Set<String> fields,
+      CollectionOptions options, SecurityToken token) throws ProtocolException {
+
+    // TODO currently the implementation of this method ignores the fields variable. Is this correct?
+
+    List<Activity> plist = null;
+    int lastPos = 1;
+
+    StringBuilder sb = new StringBuilder();
+    // sanitize the list to get the uid's and remove duplicates
+    List<String> paramList = SPIUtils.getUserList(userIds, token);
+    // select the group Id as this will drive the query
+    switch (groupId.getType()) {
+    case all:
+      // select all contacts
+      sb.append("");
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
+    case friends:
+      // select all friends (subset of contacts)
+      sb.append(ActivityDb.JPQL_FINDACTIVITY_BY_FRIENDS);
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      sb.append(")) ");
+      // TODO Group by doesn't work in HSQLDB or Derby - causes a "Not in aggregate function or group by clause" jdbc exception
+      // sb.append(" group by p ");
+      break;
+    case groupId:
+      // select those in the group
+      // TODO Needs implementing and then have a unit test created to test it.
+      sb.append("");
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      sb.append(" and g.id = ?").append(lastPos);
+      lastPos++;
+      break;
+    case deleted:
+      // ???
+      break;
+    case self:
+      // select self
+      sb.append(ActivityDb.JPQL_FINDACTIVITY);
+      lastPos = JPQLUtils.addInClause(sb, "a", "userId", lastPos, paramList.size());
+      break;
+    default:
+      throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST, "Group ID not recognized");
+
+    }
+    
+    // Get total results, that is count the total number of rows for this query
+    Long totalResults = JPQLUtils.getTotalResults(entityManager, sb.toString(), paramList);
+    
+    // Execute paginated query
+    if (totalResults > 0) {
+      plist = JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, options);
+    }
+
+    if (plist == null) {
+      plist = Lists.newArrayList();
+    }
+
+    plist = JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, null);
+
+    if (plist == null) {
+      plist = new ArrayList<Activity>();
+    }
+
+    // all of the above could equally have been placed into a thread to overlay the
+    // db wait times.
+    RestfulCollection<Activity> restCollection = new RestfulCollection<Activity>(
+        plist, options.getFirst(), totalResults.intValue(), options.getMax());
+    return ImmediateFuture.newInstance(restCollection);
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.shindig.social.opensocial.spi.ActivityService#getActivities(org.apache.shindig.social.opensocial.spi.UserId, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, org.apache.shindig.social.opensocial.spi.CollectionOptions, java.util.Set, org.apache.shindig.auth.SecurityToken)
+   */
+  public Future<RestfulCollection<Activity>> getActivities(UserId userId,
+      GroupId groupId, String appId, Set<String> fields,
+      CollectionOptions options, Set<String> activityIds, SecurityToken token)
+      throws ProtocolException {
+    return ImmediateFuture.newInstance(new RestfulCollection<Activity>(getActivities(userId, activityIds, token)));
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.shindig.social.opensocial.spi.ActivityService#getActivity(org.apache.shindig.social.opensocial.spi.UserId, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, java.lang.String, org.apache.shindig.auth.SecurityToken)
+   */
+  public Future<Activity> getActivity(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, String activityId, SecurityToken token) throws ProtocolException {
+    Activity activity = getActivities(userId, activityId,  token);
+    if ( activity != null  ) {
+      return ImmediateFuture.newInstance(activity);
+    }
+    throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST,"Cant find activity");
+  }
+
+
+  /**
+   * Gets the activities.
+   * 
+   * @param userId the user id
+   * @param token the token
+   * @param activityId the activity id
+   * 
+   * @return the activities
+   */
+  private Activity getActivities(UserId userId, String activityId,
+      SecurityToken token) {
+    Query q = entityManager.createNamedQuery(ActivityDb.FINDBY_ACTIVITY_ID);
+    String uid = SPIUtils.getUserList(userId, token);
+    q.setParameter(ActivityDb.PARAM_USERID, uid);
+    q.setParameter(ActivityDb.PARAM_ACTIVITYID, activityId);
+    q.setFirstResult(0);
+    q.setMaxResults(1);
+    List<?> activities = q.getResultList();
+    if ( activities != null && !activities.isEmpty()) {
+      return (Activity) activities.get(0);
+    }
+    return null;
+  }
+
+
+  /**
+   * Gets the activities.
+   * 
+   * @param userId the user id
+   * @param token the token
+   * @param activityIds the activity ids
+   * 
+   * @return the activities
+   */
+  private List<Activity> getActivities(UserId userId, Set<String> activityIds,
+      SecurityToken token) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(ActivityDb.JPQL_FINDBY_ACTIVITIES);
+    List<String> paramList = SPIUtils.toList(activityIds);
+    String uid = SPIUtils.getUserList(userId, token);
+    int lastPos = JPQLUtils.addInClause(sb, "a", "id", 1, paramList.size());
+    sb.append(" and a.userid = ?").append(lastPos);
+    lastPos++;
+    paramList.add(uid);
+    List<Activity> a = JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, null);
+    return a;
+  }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java Wed May 18 03:42:09 2011
@@ -0,0 +1,227 @@
+/*
+ * 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.jpa.spi;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+
+import org.apache.rave.os.DatabasePopulateContextListener;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.protocol.DataCollection;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.social.opensocial.jpa.ApplicationDataMapDb;
+import org.apache.shindig.social.opensocial.spi.AppDataService;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.UserId;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.persistence.EntityManager;
+
+/**
+ *
+ */
+public class AppDataServiceDb implements AppDataService {
+
+  private EntityManager entityManager;
+
+//  @Inject
+  public AppDataServiceDb(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+  public AppDataServiceDb() {
+      this.entityManager = DatabasePopulateContextListener.getEntityManager();
+  }
+  
+
+  /**
+   * {@inheritDoc}
+   */
+  public Future<Void> deletePersonData(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, SecurityToken token) throws ProtocolException {
+
+    List<ApplicationDataMapDb> dataMaps = getDataMap(userId, groupId, appId, token);
+    for (ApplicationDataMapDb adm : dataMaps) {
+      for (String f : fields) {
+        adm.getValues().remove(f);
+      }
+    }
+     // TODO How should transactions be managed? Should samples be using warp-persist instead?
+     if (!entityManager.getTransaction().isActive()) {
+       entityManager.getTransaction().begin();
+     }
+
+    entityManager.flush();
+    entityManager.getTransaction().commit();
+
+    return ImmediateFuture.newInstance(null);
+  }
+
+  /**
+   * @param userId
+   * @param groupId
+   * @param appId
+   * @param token
+   * @return
+   */
+  private List<ApplicationDataMapDb> getDataMap(UserId userId, GroupId groupId, String appId,
+      SecurityToken token) {
+    List<String> paramList = Lists.newArrayList();
+    paramList.add(SPIUtils.getUserList(userId, token));
+    int lastParam = 1;
+    StringBuilder sb = new StringBuilder();
+
+    switch (groupId.getType()) {
+    case all:
+      // userId translates into all contacts
+      sb.append(ApplicationDataMapDb.FINDBY_ALL_GROUP);
+      sb.append(" and am.personId = ?").append(lastParam);
+      lastParam++;
+      break;
+    case deleted:
+      // ignored
+      break;
+    case friends:
+      sb.append(ApplicationDataMapDb.FINDBY_FRIENDS_GROUP);
+      sb.append(" and am.personId = ?").append(lastParam);
+      lastParam++;
+      // userId translates into all friends
+      break;
+    case groupId:
+      sb.append(ApplicationDataMapDb.FINDBY_GROUP_GROUP);
+      sb.append(" and am.personId = ?").append(lastParam);
+      lastParam++;
+      sb.append(" and g.id = ?").append(lastParam);
+      paramList.add(groupId.getGroupId());
+      lastParam++;
+      // userId translates into friends within a group
+      break;
+    default: // including self
+      // userId is the user Id
+      sb.append(ApplicationDataMapDb.FINDBY_SELF_GROUP);
+      sb.append(" am.personId = ?").append(lastParam);
+      lastParam++;
+      break;
+
+    }
+    sb.append(" and am.application.id = ?").append(lastParam);
+    lastParam++;
+    paramList.add(appId);
+    return JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, null);
+
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Future<DataCollection> getPersonData(Set<UserId> userIds, GroupId groupId, String appId,
+      Set<String> fields, SecurityToken token) throws ProtocolException {
+    List<String> paramList = SPIUtils.getUserList(userIds, token);
+    int lastParam = 1;
+    StringBuilder sb = new StringBuilder();
+
+    switch (groupId.getType()) {
+    case all:
+      // userId translates into all contacts
+      sb.append(ApplicationDataMapDb.FINDBY_ALL_GROUP);
+      lastParam = JPQLUtils.addInClause(sb, "am", "personId", lastParam, paramList.size());
+      break;
+    case deleted:
+      // ignored
+      break;
+    case friends:
+      sb.append(ApplicationDataMapDb.FINDBY_FRIENDS_GROUP);
+      lastParam = JPQLUtils.addInClause(sb, "p", "id", lastParam, paramList.size());
+      sb.append(')');
+      // userId translates into all friends
+      break;
+    case groupId:
+      sb.append(ApplicationDataMapDb.FINDBY_GROUP_GROUP);
+      lastParam = JPQLUtils.addInClause(sb, "am", "personId", lastParam, paramList.size());
+      sb.append(" and g.id = ?").append(lastParam);
+      paramList.add(groupId.getGroupId());
+      lastParam++;
+      // userId translates into friends within a group
+      break;
+    default: // including self
+      // userId is the user Id
+      sb.append(ApplicationDataMapDb.FINDBY_SELF_GROUP);
+      lastParam = JPQLUtils.addInClause(sb, "am", "personId", lastParam, paramList.size());
+      break;
+
+    }
+    sb.append(" and am.application.id = ?").append(lastParam);
+    lastParam++;
+    paramList.add(appId);
+
+    // load the map up
+    List<ApplicationDataMapDb> dataMaps = JPQLUtils.getListQuery(entityManager, sb.toString(),
+        paramList, null);
+    Map<String, Map<String, String>> results = new HashMap<String, Map<String, String>>();
+
+    // only add in the fields
+    if (fields == null || fields.isEmpty()) {
+      for (ApplicationDataMapDb adm : dataMaps) {
+        results.put(adm.getPersonId(), adm.getValues());
+      }
+    } else {
+      for (ApplicationDataMapDb adm : dataMaps) {
+        Map<String, String> m = Maps.newHashMap();
+        for (String f : fields) {
+          String value = adm.getValues().get(f);
+          if (null != value) {
+            m.put(f, value);
+          }
+        }
+        results.put(adm.getPersonId(), m);
+      }
+    }
+    DataCollection dc = new DataCollection(results);
+    return ImmediateFuture.newInstance(dc);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Future<Void> updatePersonData(UserId userId, GroupId groupId, String appId,
+      Set<String> fields, Map<String, String> values, SecurityToken token)
+      throws ProtocolException {
+    List<ApplicationDataMapDb> dataMaps = getDataMap(userId, groupId, appId, token);
+    for (ApplicationDataMapDb adm : dataMaps) {
+      for (String f : fields) {
+        adm.getValues().put(f, values.get(f));
+      }
+    }
+
+    // TODO How should transactions be managed? Should samples be using warp-persist instead?
+    if (!entityManager.getTransaction().isActive()) {
+      entityManager.getTransaction().begin();
+    }
+    entityManager.flush();
+    entityManager.getTransaction().commit();
+
+    return ImmediateFuture.newInstance(null);
+  }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPASocialModule.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPASocialModule.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPASocialModule.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPASocialModule.java Wed May 18 03:42:09 2011
@@ -0,0 +1,92 @@
+/*
+ * 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.jpa.spi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.rave.os.JPAOpenSocialService;
+import org.apache.shindig.social.opensocial.jpa.openjpa.OpenJPAEntityManagerProvider;
+import org.apache.shindig.social.opensocial.oauth.OAuthDataStore;
+import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.ActivityStreamService;
+import org.apache.shindig.social.opensocial.spi.AlbumService;
+import org.apache.shindig.social.opensocial.spi.AppDataService;
+import org.apache.shindig.social.opensocial.spi.MediaItemService;
+import org.apache.shindig.social.opensocial.spi.MessageService;
+import org.apache.shindig.social.opensocial.spi.PersonService;
+import org.apache.shindig.social.sample.oauth.SampleOAuthDataStore;
+
+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;
+
+/**
+ *
+ */
+public class JPASocialModule extends AbstractModule {
+
+  private EntityManager entityManager;
+
+  /**
+   *
+   */
+  public JPASocialModule() {
+      this(null);
+  }
+
+  /**
+   *
+   */
+  public JPASocialModule(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @see com.google.inject.AbstractModule#configure()
+   */
+  @Override
+  protected void configure() {
+    if (entityManager == null) {
+      bind(EntityManager.class).toProvider(OpenJPAEntityManagerProvider.class)
+          .in(Scopes.SINGLETON);
+    } else {
+      bind(EntityManager.class).toInstance(this.entityManager);
+    }
+    bind(PersonService.class).to(PersonServiceDb.class);
+    bind(ActivityService.class).to(ActivityServiceDb.class);
+    bind(ActivityStreamService.class).to(JPAOpenSocialService.class);
+    bind(AlbumService.class).to(JPAOpenSocialService.class);
+    bind(MediaItemService.class).to(JPAOpenSocialService.class);
+    bind(AppDataService.class).to(AppDataServiceDb.class);
+    bind(MessageService.class).to(JPAOpenSocialService.class);
+    bind(OAuthDataStore.class).to(SampleOAuthDataStore.class);
+    
+    bind(String.class).annotatedWith(Names.named("shindig.canonical.json.db"))
+    .toInstance("sampledata/canonicaldb.json");
+  }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java Wed May 18 03:42:09 2011
@@ -0,0 +1,121 @@
+/*
+ * 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.jpa.spi;
+
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ */
+public class JPQLUtils {
+
+  /**
+   * Append an in clause to the query builder buffer, using positional parameters.
+   *
+   * @param sb the query builder buffer
+   * @param alias the alias to use for the property
+   * @param inField the infield name
+   * @param nfields the number of infields
+   */
+  public static int addInClause(StringBuilder sb, String alias, String inField, int firstField,
+      int nfields) {
+    sb.append(alias).append('.').append(inField).append(" in (");
+    for (int i = firstField; i < (firstField + nfields); i++) {
+      if (i != firstField) {
+        sb.append(", ");
+      }
+      sb.append('?').append(i);
+    }
+    sb.append(')');
+    return firstField + nfields;
+  }
+
+  /**
+   * Perform a JPAQ, and return a typed list.
+   *
+   * @param <T> The type of list
+   * @param query the JPQL Query with positional parameters
+   * @param parametersValues a list of parameters
+   * @param collectionOptions the options used for paging.
+   * @return a typed list of objects
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> List<T> getListQuery(EntityManager entityManager, String query,
+      List<?> parametersValues, CollectionOptions collectionOptions) {
+    Query q = createQuery(entityManager, query, parametersValues);
+    if (collectionOptions != null) {
+      q.setFirstResult(collectionOptions.getFirst());
+      q.setMaxResults(collectionOptions.getMax());
+    }
+    return (List<T>) q.getResultList();
+  }
+
+
+  /**
+   * Performs a 'select count(*)' on the given query
+   *
+   * @param entityManager
+   * @param query
+   * @param parametersValues
+   * @return
+   */
+  public static Long getTotalResults(EntityManager entityManager, String query,
+      List<?> parametersValues) {
+    int fromIndex = 0;
+    String queryInUpperCase = query.toUpperCase();
+    // If JPA query starts with FROM then fromIndex as 0 is correct,
+    // otherwise find where FROM keyword starts in the query string and set the fromIndex.
+    if (!queryInUpperCase.startsWith("FROM ")) {
+      fromIndex = queryInUpperCase.indexOf(" FROM ");
+      if (fromIndex == -1) {
+        // Couldn't find the FROM keyword in the query
+        throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid query [" + query + ']');
+      }
+    }
+    query = "select count(*) " + query.substring(fromIndex, query.length());
+    Query q = createQuery(entityManager, query, parametersValues);
+    return (Long) q.getSingleResult();
+  }
+
+  /**
+   * Create JPA Query
+   *
+   * @param entityManager
+   * @param query
+   * @param parametersValues
+   * @return
+   */
+  private static Query createQuery(EntityManager entityManager, String query,
+      List<?> parametersValues) {
+    Query q = entityManager.createQuery(query);
+    int i = 1;
+    for (Object p : parametersValues) {
+      q.setParameter(i, p);
+      i++;
+    }
+    return q;
+  }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java Wed May 18 03:42:09 2011
@@ -0,0 +1,297 @@
+/*
+ * 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.jpa.spi;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.rave.os.DatabasePopulateContextListener;
+import org.apache.rave.os.ShindigUtil;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.protocol.conversion.BeanConverter;
+import org.apache.shindig.social.opensocial.jpa.PersonDb;
+import org.apache.shindig.social.opensocial.jpa.api.FilterCapability;
+import org.apache.shindig.social.opensocial.jpa.api.FilterSpecification;
+import org.apache.shindig.social.opensocial.model.Person;
+import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.PersonService;
+import org.apache.shindig.social.opensocial.spi.UserId;
+import org.json.JSONObject;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+/**
+ * Implements the PersonService from the SPI binding to the JPA model and providing queries to
+ * support the OpenSocial implementation.
+ */
+public class PersonServiceDb implements PersonService {
+
+  /**
+   * This is the JPA entity manager, shared by all threads accessing this service (need to check
+   * that its really thread safe).
+   */
+  private EntityManager entityManager;
+
+  /**
+   * Create the PersonServiceDb, injecting an entity manager that is configured with the social
+   * model.
+   *
+   * @param entityManager the entity manager containing the social model.
+   */
+//  @Inject
+  public PersonServiceDb(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+  
+  public PersonServiceDb() {
+      this.entityManager = DatabasePopulateContextListener.getEntityManager();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Future<RestfulCollection<Person>> getPeople(Set<UserId> userIds,
+       GroupId groupId, CollectionOptions collectionOptions, Set<String> fields,
+       SecurityToken token) throws ProtocolException {
+    // for each user id get the filtered userid using the token and then, get the users identified
+    // by the group id, the final set is filtered
+    // using the collectionOptions and return the fields requested.
+
+    // not dealing with the collection options at the moment, and not the fields because they are
+    // either lazy or at no extra costs, the consumer will either access the properties or not
+    List<Person> plist = null;
+    int lastPos = 1;
+    Long totalResults = null;
+
+    StringBuilder sb = new StringBuilder();
+    // sanitize the list to get the uid's and remove duplicates
+    List<String> paramList = SPIUtils.getUserList(userIds, token);
+    // select the group Id as this will drive the query
+    switch (groupId.getType()) {
+    case all:
+      // select all contacts
+      sb.append(PersonDb.JPQL_FINDALLPERSON);
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
+    case friends:
+      // select all friends (subset of contacts)
+      sb.append(PersonDb.JPQL_FINDPERSON_BY_FRIENDS);
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      sb.append(") ");
+      // TODO Group by doesn't work in HSQLDB or Derby - causes a "Not in aggregate function or group by clause" jdbc exception
+      // sb.append(" group by p ");
+      break;
+    case groupId:
+      // select those in the group
+      sb.append(PersonDb.JPQL_FINDPERSON_BY_GROUP);
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      sb.append(" and g.id = ?").append(lastPos);
+      lastPos++;
+      break;
+    case deleted:
+      // ???
+      break;
+    case self:
+      // select self
+      sb.append(PersonDb.JPQL_FINDPERSON);
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
+    default:
+      throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST, "Group ID not recognized");
+
+    }
+
+    if (GroupId.Type.self.equals(groupId.getType())) {
+      plist = JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, collectionOptions);
+      totalResults = Long.valueOf(1);
+      if (plist.isEmpty()) {
+        throw new ProtocolException(HttpServletResponse.SC_BAD_REQUEST, "Person not found");
+      }
+    } else {
+      int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions,
+          lastPos);
+      if (filterPos > 0) {
+        paramList.add(collectionOptions.getFilterValue());
+      }
+
+      // Get total results, that is count the total number of rows for this query
+      totalResults = JPQLUtils.getTotalResults(entityManager, sb.toString(), paramList);
+
+      // Execute ordered and paginated query
+      if (totalResults > 0) {
+        addOrderClause(sb, collectionOptions);
+        plist = JPQLUtils.getListQuery(entityManager, sb.toString(), paramList, collectionOptions);
+      }
+
+      if (plist == null) {
+        plist = Lists.newArrayList();
+      }
+    }
+
+    // all of the above could equally have been placed into a thread to overlay the
+    // db wait times.
+    RestfulCollection<Person> restCollection = new RestfulCollection<Person>(
+        plist, collectionOptions.getFirst(), totalResults.intValue(), collectionOptions.getMax());
+    return ImmediateFuture.newInstance(restCollection);
+
+  }
+  
+  private ShindigUtil shindigUtil = new ShindigUtil();
+  private BeanConverter beanConverter = shindigUtil.getBeanConverter();
+  
+  /**
+   * {@inheritDoc}
+   */
+  public Future<Person> getPerson(UserId id, Set<String> fields, SecurityToken token)
+      throws ProtocolException {
+    try {
+        String uid = id.getUserId(token);
+        Query q = entityManager.createNamedQuery(PersonDb.FINDBY_PERSONID);
+        q.setParameter(PersonDb.PARAM_PERSONID, uid);
+        q.setFirstResult(0);
+        q.setMaxResults(1);
+        List<?> plist = q.getResultList();
+        Person person = null;
+        if (plist != null && !plist.isEmpty()) {
+            person = (Person) plist.get(0);
+        }
+        String jsonStrRep = beanConverter.convertToString(person);
+        JSONObject jsonRep = new JSONObject(jsonStrRep);
+        if (!fields.isEmpty()) {
+            if (fields.size() != 1 || !fields.contains("id"))
+                jsonRep = new JSONObject(jsonRep, fields.toArray(new String[fields.size()]));
+        }
+        person = beanConverter.convertToObject(jsonRep.toString(), Person.class);
+        return ImmediateFuture.newInstance(person);
+    } catch (Exception je) {
+        throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, je.getMessage(), je);
+    }
+  }
+
+
+
+  /**
+   * Add a filter clause specified by the collection options.
+   *
+   * @param sb the query builder buffer
+   * @param collectionOptions the options
+   * @param lastPos the last positional parameter that was used so far in the query
+   * @return
+   */
+  private int addFilterClause(StringBuilder sb, FilterCapability filterable,
+      CollectionOptions collectionOptions, int lastPos) {
+    // this makes the filter value saf
+    String filter = filterable.findFilterableProperty(collectionOptions.getFilter(),
+        collectionOptions.getFilterOperation());
+    String filterValue = collectionOptions.getFilterValue();
+    int filterPos = 0;
+    if (FilterSpecification.isValid(filter)) {
+      if (FilterSpecification.isSpecial(filter)) {
+        if (PersonService.HAS_APP_FILTER.equals(filter)) {
+          // Retrieves all friends with any data for this application.
+          // TODO: how do we determine which application is being talked about,
+          // the assumption below is wrong
+          filterPos = lastPos + 1;
+          sb.append(" f.application_id  = ?").append(filterPos);
+        } else if (PersonService.TOP_FRIENDS_FILTER.equals(filter)) {
+          // Retrieves only the user's top friends, this is defined here by the implementation
+          // and there is an assumption that the sort order has already been applied.
+          // to do this we need to modify the collections options
+          // there will only ever b x friends in the list and it will only ever start at 1
+
+          collectionOptions.setFirst(1);
+          collectionOptions.setMax(20);
+
+        } else if (PersonService.ALL_FILTER.equals(filter)) {
+           // select all, ie no filtering
+        } else if (PersonService.IS_WITH_FRIENDS_FILTER.equals(filter)) {
+          filterPos = lastPos + 1;
+          sb.append(" f.friend  = ?").append(filterPos);
+        }
+      } else {
+        sb.append("p.").append(filter);
+        switch (collectionOptions.getFilterOperation()) {
+        case contains:
+          filterPos = lastPos + 1;
+          sb.append(" like ").append(" ?").append(filterPos);
+          filterValue = '%' + filterValue + '%';
+          collectionOptions.setFilter(filterValue);
+          break;
+        case equals:
+          filterPos = lastPos + 1;
+          sb.append(" = ").append(" ?").append(filterPos);
+          break;
+        case present:
+          sb.append(" is not null ");
+          break;
+        case startsWith:
+          filterPos = lastPos + 1;
+          sb.append(" like ").append(" ?").append(filterPos);
+          filterValue = '%' + filterValue + '%';
+          collectionOptions.setFilter(filterValue);
+          break;
+        }
+      }
+    }
+    return filterPos;
+  }
+
+  /**
+   * Add an order clause to the query string.
+   *
+   * @param sb the buffer for the query string
+   * @param collectionOptions the options to use for the order.
+   */
+  private void addOrderClause(StringBuilder sb, CollectionOptions collectionOptions) {
+    String sortBy = collectionOptions.getSortBy();
+    if (sortBy != null && sortBy.length() > 0) {
+      if (PersonService.TOP_FRIENDS_SORT.equals(sortBy)) {
+        // TODO sorting by friend.score doesn't work right now because of group by issue (see above TODO)
+        // this assumes that the query is a join with the friends store.
+        sb.append(" order by f.score ");
+      } else {
+        if ("name".equals(sortBy)) {
+          // TODO Is this correct?
+          // If sortBy is name then order by p.name.familyName, p.name.givenName.
+          sb.append(" order by p.name.familyName, p.name.givenName ");
+        } else {
+          sb.append(" order by p.").append(sortBy);
+        }
+        switch (collectionOptions.getSortOrder()) {
+        case ascending:
+          sb.append(" asc ");
+          break;
+        case descending:
+          sb.append(" desc ");
+          break;
+        }
+      }
+    }
+  }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java Wed May 18 03:42:09 2011
@@ -0,0 +1,74 @@
+/*
+ * 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.jpa.spi;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.social.opensocial.spi.UserId;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ */
+public class SPIUtils {
+
+  /**
+   * @param userIds
+   * @param token
+   * @return
+   */
+  public static List<String> getUserList(Set<UserId> userIds, SecurityToken token) {
+    // TODO What's the use of userIdMap?
+    HashMap<String, String> userIdMap = Maps.newHashMap();
+    List<String> paramList = Lists.newArrayList();
+    for (UserId u : userIds) {
+      try {
+        String uid = u.getUserId(token);
+        if (uid != null) {
+          userIdMap.put(uid, uid);
+          paramList.add(uid);
+        }
+      } catch (IllegalStateException istate) {
+        // ignore the user id.
+      }
+    }
+    return paramList;
+  }
+
+  /**
+   * @param userId
+   * @param token
+   * @return
+   */
+  public static String getUserList(UserId userId, SecurityToken token) {
+    return userId.getUserId(token);
+  }
+
+  public static <T> List<T> toList(Set<T> s) {
+    List<T> l = new ArrayList<T>(s.size());
+    l.addAll(s);
+    return l;
+  }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/orm.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/orm.xml?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/orm.xml (added)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/orm.xml Wed May 18 03:42:09 2011
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
+  version="1.0"> 
+  <entity class="org.apache.shindig.social.opensocial.jpa.AccountDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ActivityDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.AddressDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.BodyTypeDb">
+  </entity>
+  <entity
+    class="org.apache.shindig.social.opensocial.jpa.MediaItemDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.NameDb">
+  </entity>
+  <entity class="org.apache.rave.os.model.RaveNameImpl">
+  </entity>
+  <entity
+    class="org.apache.shindig.social.opensocial.jpa.OrganizationDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PersonDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.UrlDb">
+  </entity>
+  <entity
+    class="org.apache.shindig.social.opensocial.jpa.ListFieldDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.MessageDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ActivityTemplateParamsDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.OrganizationAddressDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.EmailDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ImDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PersonAccountDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PersonAddressDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PersonOrganizationDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PhoneDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PhotoDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.PersonPropertyDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.FriendDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.FriendPropertyDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.GroupDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.GroupPropertyDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ApplicationDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ApplicationPropertyDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ApplicationDataMapDb">
+  </entity>
+  <entity class="org.apache.shindig.social.opensocial.jpa.ApplicationDataMapValueDb">
+  </entity>
+</entity-mappings>

Added: incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml (added)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml Wed May 18 03:42:09 2011
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+	version="2.0">
+	<persistence-unit name="raveShindigPersistenceUnit"
+		transaction-type="RESOURCE_LOCAL">
+		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+		<properties>
+			<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
+			<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" />
+			<property name="openjpa.ConnectionDriverName" value="org.h2.Driver" />
+			<property name="openjpa.ConnectionURL" value="jdbc:h2:mem:portal;DB_CLOSE_DELAY=-1" />
+			<property name="openjpa.ConnectionUserName" value="sa" />
+			<property name="openjpa.ConnectionPassword" value="sa" />
+		</properties>
+	</persistence-unit>
+	
+	
+	 <persistence-unit name="raveShindigOpenJPATest" transaction-type="RESOURCE_LOCAL">
+    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+    <properties>
+      <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" />
+      <property name="openjpa.ConnectionDriverName" value="org.h2.Driver" />
+      <property name="openjpa.ConnectionURL" value="jdbc:h2:mem:portal;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=10000" />
+      <property name="openjpa.ConnectionUserName" value="sa" />
+      <property name="openjpa.ConnectionPassword" value="sa" />
+    </properties>
+  </persistence-unit>
+</persistence>

Added: incubator/rave/trunk/rave-shindig/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/webapp/WEB-INF/web.xml?rev=1104678&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/webapp/WEB-INF/web.xml (added)
+++ incubator/rave/trunk/rave-shindig/src/main/webapp/WEB-INF/web.xml Wed May 18 03:42:09 2011
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="Shindig"
+         version="2.5">
+  <display-name>Shindig</display-name>
+  <!-- configuration -->
+  <!-- If you have your own Guice module(s), put them here as a colon-separated list. -->
+  <!-- Note that any extras modules are optional -->
+  <context-param>
+    <param-name>guice-modules</param-name>
+    <param-value>
+      org.apache.shindig.common.PropertiesModule:
+      org.apache.shindig.gadgets.DefaultGuiceModule:
+      org.apache.shindig.social.core.config.SocialApiGuiceModule:
+      org.apache.rave.os.JPAOpenSocialModule:
+      org.apache.shindig.gadgets.oauth.OAuthModule:
+      org.apache.shindig.common.cache.ehcache.EhCacheModule:
+      org.apache.shindig.sample.shiro.ShiroGuiceModule:
+      org.apache.shindig.sample.container.SampleContainerGuiceModule:
+      org.apache.shindig.extras.ShindigExtrasGuiceModule:
+      org.apache.shindig.sample.commoncontainer.auth.CommonContainerAuthGuiceModule
+    </param-value>
+  </context-param>
+
+  <!-- 
+  Syntax: <key>=<value> separated by a newline
+  
+  system.properties specifies the environmental variables that will be set to the JVM System Properties at server startup time.
+  Alternatively, you may add these values in your app server (ex: Tomcat) as
+  VM arguments like this: -Dshindig.host="my.production.shindig.server.com".
+  
+  Here are a few properties that can be set for Shindig:
+  shindig.host: the server name that Shindig is deployed and running on
+  shindig.port: the port number of shindig.host server
+  
+  Make sure you escape all HTML values for the web.xml to be parsed correctly.
+  -->
+   <context-param>
+  	<param-name>system.properties</param-name>
+     <param-value>
+    	shindig.host=localhost
+    	
+    	aKey=/shindig/gadgets/proxy?container=default&amp;url=
+    	shindig.port=
+    	
+     </param-value>
+  </context-param>  
+
+    <filter>
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
+        <init-param>
+            <param-name>config</param-name>
+            <param-value>
+                # The ShiroFilter configuration is very powerful and flexible, while still remaining succinct.
+                # Please read the comprehensive example, with full comments and explanations, in the JavaDoc:
+                #
+                # http://www.jsecurity.org/api/org/jsecurity/web/servlet/JSecurityFilter.html
+                [main]
+                shindigSampleRealm = org.apache.shindig.sample.shiro.SampleShiroRealm
+                securityManager.realm = $shindigSampleRealm
+                authc.loginUrl = /login.jsp
+
+                [urls]
+                # The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
+                # the 'authc' filter must still be specified for it so it can process that url's
+                # login submissions. It is 'smart' enough to allow those requests through as specified by the
+                # shiro.loginUrl above.
+                /login.jsp = authc
+
+                /oauth/authorize/** = authc
+
+            </param-value>
+        </init-param>
+    </filter>
+
+  <filter>
+    <filter-name>authFilter</filter-name>
+    <filter-class>org.apache.shindig.auth.AuthenticationServletFilter</filter-class>
+  </filter>
+  
+  <filter>
+    <filter-name>etagFilter</filter-name>
+    <filter-class>org.apache.shindig.gadgets.servlet.ETagFilter</filter-class>
+  </filter>
+
+
+  <filter-mapping>
+      <filter-name>ShiroFilter</filter-name>
+      <url-pattern>/oauth/authorize</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+      <filter-name>ShiroFilter</filter-name>
+      <url-pattern>*.jsp</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>authFilter</filter-name>
+    <url-pattern>/social/*</url-pattern>
+    <url-pattern>/gadgets/ifr</url-pattern>
+    <url-pattern>/gadgets/makeRequest</url-pattern>
+    <url-pattern>/gadgets/api/rpc/*</url-pattern>
+    <url-pattern>/gadgets/api/rest/*</url-pattern>
+    <url-pattern>/rpc/*</url-pattern>
+    <url-pattern>/rest/*</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>etagFilter</filter-name>
+    <url-pattern>*</url-pattern>
+  </filter-mapping>
+
+	<context-param>
+	    <param-name>db.url</param-name>
+	    <param-value>jdbc:h2:mem:portal</param-value>
+	</context-param>
+	<context-param>
+	    <param-name>db.user</param-name>
+	    <param-value>sa</param-value>
+	</context-param>
+	<context-param>
+	    <param-name>db.password</param-name>
+	    <param-value>sa</param-value>
+	</context-param>
+	<context-param>
+	    <param-name>db.tcpServer</param-name>
+	    <param-value>-tcpAllowOthers</param-value>
+	</context-param>
+
+  <listener>
+    <listener-class>org.apache.shindig.common.servlet.GuiceServletContextListener</listener-class>
+  </listener>
+  <listener>
+    <listener-class>org.apache.rave.os.DatabasePopulateContextListener</listener-class>
+  </listener>
+  <listener>
+    <listener-class>org.h2.server.web.DbStarter</listener-class>
+  </listener>
+
+  <!-- Render a Gadget -->
+  <servlet>
+    <servlet-name>xml-to-html</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.GadgetRenderingServlet
+    </servlet-class>
+  </servlet>
+
+  <servlet>
+    <servlet-name>accel</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.HtmlAccelServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- Proxy -->
+  <servlet>
+    <servlet-name>proxy</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.ProxyServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- makeRequest -->
+  <servlet>
+    <servlet-name>makeRequest</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.MakeRequestServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- Concat -->
+  <servlet>
+    <servlet-name>concat</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.ConcatProxyServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- OAuth callback -->
+  <servlet>
+    <servlet-name>oauthCallback</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.OAuthCallbackServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- Metadata RPC -->
+  <servlet>
+    <servlet-name>metadata</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.RpcServlet
+    </servlet-class>
+  </servlet>
+
+  <!-- javascript serving -->
+  <servlet>
+    <servlet-name>js</servlet-name>
+    <servlet-class>org.apache.shindig.gadgets.servlet.JsServlet</servlet-class>
+  </servlet>
+
+  <servlet>
+    <servlet-name>restapiServlet</servlet-name>
+    <servlet-class>
+      org.apache.shindig.protocol.DataServiceServlet
+    </servlet-class>
+    <init-param>
+      <param-name>handlers</param-name>
+      <param-value>org.apache.shindig.handlers</param-value>
+    </init-param>
+  </servlet>
+
+  <!-- Serve social RPC api -->
+  <servlet>
+    <servlet-name>jsonRpcServlet</servlet-name>
+    <servlet-class>
+      org.apache.shindig.protocol.JsonRpcServlet
+    </servlet-class>
+    <init-param>
+      <param-name>handlers</param-name>
+      <param-value>org.apache.shindig.handlers</param-value>
+    </init-param>
+  </servlet>
+
+  <!-- Serve sample OAuth apis -->
+  <servlet>
+    <servlet-name>sampleOAuth</servlet-name>
+    <servlet-class>
+      org.apache.shindig.social.sample.oauth.SampleOAuthServlet
+    </servlet-class>
+  </servlet>
+
+  <servlet>
+    <servlet-name>rpcSwf</servlet-name>
+    <servlet-class>
+      org.apache.shindig.gadgets.servlet.RpcSwfServlet
+    </servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>js</servlet-name>
+    <url-pattern>/gadgets/js/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>proxy</servlet-name>
+    <url-pattern>/gadgets/proxy/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>makeRequest</servlet-name>
+    <url-pattern>/gadgets/makeRequest</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>jsonRpcServlet</servlet-name>
+    <url-pattern>/rpc/*</url-pattern>
+    <url-pattern>/gadgets/api/rpc/*</url-pattern>
+    <url-pattern>/social/rpc/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>restapiServlet</servlet-name>
+    <url-pattern>/rest/*</url-pattern>
+    <url-pattern>/gadgets/api/rest/*</url-pattern>
+    <url-pattern>/social/rest/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>concat</servlet-name>
+    <url-pattern>/gadgets/concat</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>oauthCallback</servlet-name>
+    <url-pattern>/gadgets/oauthcallback</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>xml-to-html</servlet-name>
+    <url-pattern>/gadgets/ifr</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>accel</servlet-name>
+    <url-pattern>/gadgets/accel</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>metadata</servlet-name>
+    <url-pattern>/gadgets/metadata</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>sampleOAuth</servlet-name>
+    <url-pattern>/oauth/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>rpcSwf</servlet-name>
+    <url-pattern>/xpc*</url-pattern>
+  </servlet-mapping>
+  
+  
+  
+  <servlet>
+		<servlet-name>H2Console</servlet-name>
+		<servlet-class>org.h2.server.web.WebServlet</servlet-class>
+		<!-- <init-param> <param-name>webAllowOthers</param-name> <param-value></param-value> 
+			</init-param> <init-param> <param-name>trace</param-name> <param-value></param-value> 
+			</init-param> -->
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>H2Console</servlet-name>
+		<url-pattern>/console/*</url-pattern>
+	</servlet-mapping>
+	
+</web-app>



Mime
View raw message