You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ie...@apache.org on 2008/09/19 10:52:06 UTC

svn commit: r696991 - in /incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa: ActivityDb.java spi/ActivityServiceDb.java spi/AppDataServiceDb.java spi/JPQLUtils.java spi/PersonServiceDb.java spi/SPIUtils.java

Author: ieb
Date: Fri Sep 19 01:52:05 2008
New Revision: 696991

URL: http://svn.apache.org/viewvc?rev=696991&view=rev
Log:
Clarified implementation of the PersonService which was not honoring the group resolution correctly.
Implemented AppDataService in the process moving shared functionality into util classes.
Started implementation of Activity service.

Added:
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java
Modified:
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ActivityDb.java
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java
    incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java

Modified: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ActivityDb.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ActivityDb.java?rev=696991&r1=696990&r2=696991&view=diff
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ActivityDb.java (original)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ActivityDb.java Fri Sep 19 01:52:05 2008
@@ -56,6 +56,14 @@
 @Table(name = "activity")
 public class ActivityDb implements Activity, DbObject {
 
+  public static final String FINDBY_ACTIVITY_ID = null;
+
+  public static final String PARAM_USERID = null;
+
+  public static final String PARAM_ACTIVITYID = null;
+
+  public static final String JPQL_FINDBY_ACTIVITIES = null;
+
   /**
    * The internal object ID used for references to this object. Should be generated by the
    * underlying storage mechanism

Modified: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java?rev=696991&r1=696990&r2=696991&view=diff
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java (original)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java Fri Sep 19 01:52:05 2008
@@ -18,6 +18,10 @@
 package org.apache.shindig.social.opensocial.jpa.spi;
 
 import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.social.ResponseError;
+import org.apache.shindig.social.opensocial.jpa.ActivityDb;
+import org.apache.shindig.social.opensocial.jpa.ApplicationDataMapDb;
 import org.apache.shindig.social.opensocial.model.Activity;
 import org.apache.shindig.social.opensocial.spi.ActivityService;
 import org.apache.shindig.social.opensocial.spi.GroupId;
@@ -25,6 +29,13 @@
 import org.apache.shindig.social.opensocial.spi.SocialSpiException;
 import org.apache.shindig.social.opensocial.spi.UserId;
 
+import com.google.inject.Inject;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Future;
 
@@ -33,6 +44,13 @@
  */
 public class ActivityServiceDb implements ActivityService {
 
+  private EntityManager entityManager;
+
+  @Inject
+  public ActivityServiceDb(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
   /* (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)
    */
@@ -66,8 +84,7 @@
   public Future<RestfulCollection<Activity>> getActivities(UserId userId, GroupId groupId,
       String appId, Set<String> fields, Set<String> activityIds, SecurityToken token)
       throws SocialSpiException {
-    // TODO Auto-generated method stub
-    return null;
+    return ImmediateFuture.newInstance(new RestfulCollection<Activity>(getActivities(userId, activityIds, token)));
   }
 
   /* (non-Javadoc)
@@ -75,8 +92,56 @@
    */
   public Future<Activity> getActivity(UserId userId, GroupId groupId, String appId,
       Set<String> fields, String activityId, SecurityToken token) throws SocialSpiException {
-    // TODO Auto-generated method stub
+    Activity activity = getActivities(userId, activityId,  token);
+    if ( activity != null  ) {
+      return ImmediateFuture.newInstance(activity);
+    }
+    throw new SocialSpiException(ResponseError.BAD_REQUEST,"Cant find activity");
+  }
+
+  
+  /**
+   * @param userId
+   * @param groupId
+   * @param appId
+   * @param token
+   * @return
+   */
+  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(1);
+    q.setMaxResults(1);
+    List<?> activities = q.getResultList();
+    if ( activities != null && activities.size() > 0 ) {
+      return (Activity) activities.get(1);
+    }
     return null;
   }
 
+
+  /**
+   * @param userId
+   * @param groupId
+   * @param appId
+   * @param token
+   * @return
+   */
+  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;
+  }
+
 }

Modified: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java?rev=696991&r1=696990&r2=696991&view=diff
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java (original)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java Fri Sep 19 01:52:05 2008
@@ -18,47 +18,190 @@
 package org.apache.shindig.social.opensocial.jpa.spi;
 
 import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.social.opensocial.jpa.ApplicationDataMapDb;
 import org.apache.shindig.social.opensocial.spi.AppDataService;
 import org.apache.shindig.social.opensocial.spi.DataCollection;
 import org.apache.shindig.social.opensocial.spi.GroupId;
 import org.apache.shindig.social.opensocial.spi.SocialSpiException;
 import org.apache.shindig.social.opensocial.spi.UserId;
 
+import com.google.inject.Inject;
+
+import javax.persistence.EntityManager;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Future;
 
 /**
- *
+ * 
  */
-public class AppDataServiceDb implements AppDataService{
+public class AppDataServiceDb implements AppDataService {
 
-  /* (non-Javadoc)
-   * @see org.apache.shindig.social.opensocial.spi.AppDataService#deletePersonData(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)
+  private EntityManager entityManager;
+
+  @Inject
+  public AppDataServiceDb(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
+  /**
+   * {@inheritDoc}
    */
   public Future<Void> deletePersonData(UserId userId, GroupId groupId, String appId,
       Set<String> fields, SecurityToken token) throws SocialSpiException {
-    // TODO Auto-generated method stub
-    return null;
+
+    List<ApplicationDataMapDb> dataMaps = getDataMap(userId, groupId, appId, token);
+    for (ApplicationDataMapDb adm : dataMaps) {
+      for (String f : fields) {
+        adm.remove(f);
+      }
+    }
+
+    entityManager.flush();
+
+    return ImmediateFuture.newInstance(null);
   }
 
-  /* (non-Javadoc)
-   * @see org.apache.shindig.social.opensocial.spi.AppDataService#getPersonData(java.util.Set, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, org.apache.shindig.auth.SecurityToken)
+  /**
+   * @param userId
+   * @param groupId
+   * @param appId
+   * @param token
+   * @return
+   */
+  private List<ApplicationDataMapDb> getDataMap(UserId userId, GroupId groupId, String appId,
+      SecurityToken token) {
+    List<String> paramList = new ArrayList<String>();
+    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(" and am.personId = ?").append(lastParam);
+      lastParam++;
+      break;
+
+    }
+    sb.append(" and a.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 SocialSpiException {
-    // TODO Auto-generated method stub
-    return null;
+    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, "am", "personId", lastParam, paramList.size());
+      // 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 a.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.size() == 0) {
+      for (ApplicationDataMapDb adm : dataMaps) {
+        results.put(adm.getPersonId(), adm);
+      }
+    } else {
+      for (ApplicationDataMapDb adm : dataMaps) {
+        Map<String, String> m = new HashMap<String, String>();
+        for (String f : fields) {
+          m.put(f, adm.get(f));
+        }
+        results.put(adm.getPersonId(), m);
+      }
+    }
+    DataCollection dc = new DataCollection(results);
+    return ImmediateFuture.newInstance(dc);
   }
 
-  /* (non-Javadoc)
-   * @see org.apache.shindig.social.opensocial.spi.AppDataService#updatePersonData(org.apache.shindig.social.opensocial.spi.UserId, org.apache.shindig.social.opensocial.spi.GroupId, java.lang.String, java.util.Set, java.util.Map, org.apache.shindig.auth.SecurityToken)
+  /**
+   * {@inheritDoc}
    */
   public Future<Void> updatePersonData(UserId userId, GroupId groupId, String appId,
       Set<String> fields, Map<String, String> values, SecurityToken token)
       throws SocialSpiException {
-    // TODO Auto-generated method stub
-    return null;
+    List<ApplicationDataMapDb> dataMaps = getDataMap(userId, groupId, appId, token);
+    for (ApplicationDataMapDb adm : dataMaps) {
+      for (String f : fields) {
+        adm.put(f, values.get(f));
+      }
+    }
+
+    entityManager.flush();
+
+    return ImmediateFuture.newInstance(null);
   }
 
 }

Added: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java?rev=696991&view=auto
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java (added)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/JPQLUtils.java Fri Sep 19 01:52:05 2008
@@ -0,0 +1,75 @@
+/*
+ * 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.social.opensocial.spi.CollectionOptions;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import java.util.List;
+
+/**
+ *
+ */
+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++) {
+      sb.append(" ?").append(i).append(" ");
+    }
+    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 = entityManager.createQuery(query);
+    int i = 1;
+    for (Object p : parametersValues) {
+      q.setParameter(i, p);
+      i++;
+    }
+    if (collectionOptions != null) {
+      q.setFirstResult(collectionOptions.getFirst());
+      q.setMaxResults(collectionOptions.getFirst() + collectionOptions.getMax());
+    }
+    return (List<T>) q.getResultList();
+  }
+
+}

Modified: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java?rev=696991&r1=696990&r2=696991&view=diff
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java (original)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java Fri Sep 19 01:52:05 2008
@@ -37,7 +37,6 @@
 import javax.persistence.Query;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Future;
@@ -57,7 +56,7 @@
   /**
    * Create the PersonServiceDb, injecting an entity manager that is configured with the social
    * model.
-   * 
+   *
    * @param entityManager the entity manager containing the social model.
    */
   @Inject
@@ -67,108 +66,64 @@
 
   /**
    * {@inheritDoc}
-   * 
-   * @see org.apache.shindig.social.opensocial.spi.PersonService#getPeople(java.util.Set,
-   *      org.apache.shindig.social.opensocial.spi.GroupId,
-   *      org.apache.shindig.social.opensocial.spi.CollectionOptions, java.util.Set,
-   *      org.apache.shindig.auth.SecurityToken)
    */
-  public Future<RestfulCollection<Person>> getPeople(final Set<UserId> userIds,
-      final GroupId groupId, final CollectionOptions collectionOptions, final Set<String> fields,
-      final SecurityToken token) throws SocialSpiException {
+  public Future<RestfulCollection<Person>> getPeople(Set<UserId> userIds,
+       GroupId groupId, CollectionOptions collectionOptions, Set<String> fields,
+       SecurityToken token) throws SocialSpiException {
     // 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 proeprties or not
+    // either lazy or at no extra costs, the consumer will either access the properties or not
+    List<Person> plist = null;
+    int lastPos = 1;
 
+    StringBuilder sb = new StringBuilder();
     // sanitize the list to get the uid's and remove duplicates
-    HashMap<String, String> userIdMap = new HashMap<String, String>();
-    List<String> paramList = new ArrayList<String>();
-    List<Person> plist = null;
-    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.
-      }
-    }
+    List<String> paramList = SPIUtils.getUserList(userIds, token);
     // select the group Id as this will drive the query
     switch (groupId.getType()) {
-    case all: {
+    case all:
       // select all contacts
-      StringBuilder sb = new StringBuilder();
       sb.append(PersonDb.JPQL_FINDALLPERSON);
-      addInClause(sb, "id", paramList.size());
-      int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions,
-          paramList.size() + 1);
-      if (filterPos > 0) {
-        paramList.add(collectionOptions.getFilterValue());
-      }
-      addOrderClause(sb, collectionOptions);
-
-      plist = getListQuery(sb.toString(), paramList, collectionOptions);
-    }
-    case friends: {
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
+    case friends:
       // select all friends (subset of contacts)
-      StringBuilder sb = new StringBuilder();
       sb.append(PersonDb.JPQL_FINDPERSON_BY_FRIENDS);
-      addInClause(sb, "id", paramList.size());
-      int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions,
-          paramList.size() + 1);
-      if (filterPos > 0) {
-        paramList.add(collectionOptions.getFilterValue());
-      }
-      addOrderClause(sb, collectionOptions);
-
-      plist = getListQuery(sb.toString(), paramList, collectionOptions);
-    }
-    case groupId: {
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
+    case groupId:
       // select those in the group
-      StringBuilder sb = new StringBuilder();
       sb.append(PersonDb.JPQL_FINDPERSON_BY_GROUP);
-      List<Object> params = new ArrayList<Object>();
-      params.add(groupId.getGroupId());
-      params.addAll(paramList);
-
-      addInClause(sb, "id", paramList.size());
-      int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions, params
-          .size() + 1);
-      if (filterPos > 0) {
-        params.add(collectionOptions.getFilterValue());
-      }
-      addOrderClause(sb, collectionOptions);
-
-      plist = getListQuery(sb.toString(), params, collectionOptions);
-    }
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      sb.append(" and g.id = ?").append(lastPos);
+      lastPos++;
+      break;
     case deleted:
       // ???
       break;
-    case self: {
+    case self:
       // select self
-      StringBuilder sb = new StringBuilder();
       sb.append(PersonDb.JPQL_FINDPERSON);
-      addInClause(sb, "id", paramList.size());
-      int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions,
-          paramList.size() + 1);
-      if (filterPos > 0) {
-        paramList.add(collectionOptions.getFilterValue());
-      }
-      addOrderClause(sb, collectionOptions);
-
-      plist = getListQuery(sb.toString(), paramList, collectionOptions);
-
-    }
+      lastPos = JPQLUtils.addInClause(sb, "p", "id", lastPos, paramList.size());
+      break;
     default:
       throw new SocialSpiException(ResponseError.BAD_REQUEST, "Group ID not recognized");
 
     }
 
+
+    int filterPos = addFilterClause(sb, PersonDb.getFilterCapability(), collectionOptions,
+        lastPos);
+    if (filterPos > 0) {
+      paramList.add(collectionOptions.getFilterValue());
+    }
+    addOrderClause(sb, collectionOptions);
+
+    plist = JPQLUtils.getListQuery(entiyManager, sb.toString(), paramList, collectionOptions);
+
     if (plist == null) {
       plist = new ArrayList<Person>();
     }
@@ -180,9 +135,6 @@
 
   /**
    * {@inheritDoc}
-   * 
-   * @see org.apache.shindig.social.opensocial.spi.PersonService#getPerson(org.apache.shindig.social.opensocial.spi.UserId,
-   *      java.util.Set, org.apache.shindig.auth.SecurityToken)
    */
   public Future<Person> getPerson(UserId id, Set<String> fields, SecurityToken token)
       throws SocialSpiException {
@@ -199,46 +151,11 @@
     return ImmediateFuture.newInstance(person);
   }
 
-  /**
-   * 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
-   */
-  protected <T> List<T> getListQuery(String query, List<?> parametersValues,
-      CollectionOptions collectionOptions) {
-    Query q = entiyManager.createQuery(query);
-    int i = 1;
-    for (Object p : parametersValues) {
-      q.setParameter(i, p);
-      i++;
-    }
-    q.setFirstResult(collectionOptions.getFirst());
-    q.setMaxResults(collectionOptions.getFirst() + collectionOptions.getMax());
-    return q.getResultList();
-  }
 
-  /**
-   * Append an in clause to the query builder buffer, using positional parameters.
-   * 
-   * @param sb the query builder buffer
-   * @param inField the infield name (assumes that this is bound to a p. object)
-   * @param nfields the number of infields
-   */
-  private void addInClause(StringBuilder sb, String inField, int nfields) {
-    sb.append("p.").append(inField).append(" in (");
-    for (int i = 1; i <= nfields; i++) {
-      sb.append(" ?").append(i).append(" ");
-    }
-    sb.append(")");
-  }
 
   /**
    * 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
@@ -255,20 +172,24 @@
       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
+          // 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)) {
-          // all matches must also be friends with the value of the filter.
-
+          filterPos = lastPos + 1;
+          sb.append(" f.friend  = ?").append(filterPos);
         }
       } else {
         sb.append("p.").append(filter);
@@ -277,6 +198,7 @@
           filterPos = lastPos + 1;
           sb.append(" like ").append(" ?").append(filterPos);
           filterValue = "%" + filterValue + "%";
+          collectionOptions.setFilter(filterValue);
           break;
         case equals:
           filterPos = lastPos + 1;
@@ -289,6 +211,7 @@
           filterPos = lastPos + 1;
           sb.append(" like ").append(" ?").append(filterPos);
           filterValue = "%" + filterValue + "%";
+          collectionOptions.setFilter(filterValue);
           break;
         }
       }
@@ -298,7 +221,7 @@
 
   /**
    * 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.
    */

Added: incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java?rev=696991&view=auto
==============================================================================
--- incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java (added)
+++ incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/SPIUtils.java Fri Sep 19 01:52:05 2008
@@ -0,0 +1,70 @@
+/*
+ * 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.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) {
+    HashMap<String, String> userIdMap = new HashMap<String, String>();
+    List<String> paramList = new ArrayList<String>();
+    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>();
+    l.addAll(s);
+    return l;
+  }
+
+}