Author: ieb
Date: Wed Sep 17 04:08:15 2008
New Revision: 696239

URL: http://svn.apache.org/viewvc?rev=696239&view=rev
Log:
Added in the start of the SPI implementations, focusing on person and the more 
complex queries.
Trying to get all queries down to the underlying storage and avoiding 
performing sorting and filtering in
the SPI implementation. It is expected that the JPA implementation will pass 
these queries onto the DB and not
perform the queries in memory, assuming the JPA implementation is configured to 
point to a relational store.

Added:
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/DbObject.java
      - copied, changed from r696238, 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/DbObject.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterCapability.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterSpecification.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/
    
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
Removed:
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/DbObject.java
Modified:
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AccountDb.java
    
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/AddressDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/BodyTypeDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ListFieldDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MediaItemDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MessageDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/NameDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/OrganizationDb.java
    
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/PersonDb.java

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AccountDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AccountDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AccountDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AccountDb.java
 Wed Sep 17 04:08:15 2008
@@ -17,6 +17,7 @@
  */
 package org.apache.shindig.social.opensocial.jpa;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Account;
 
 import javax.persistence.Basic;
@@ -153,7 +154,7 @@
 
   /**
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

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=696239&r1=696238&r2=696239&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
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Activity;
 import org.apache.shindig.social.opensocial.model.MediaItem;
 
@@ -536,7 +537,7 @@
 
   /** 
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AddressDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AddressDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AddressDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/AddressDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Address;
 import org.apache.shindig.social.opensocial.model.Person;
 

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/BodyTypeDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/BodyTypeDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/BodyTypeDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/BodyTypeDb.java
 Wed Sep 17 04:08:15 2008
@@ -21,6 +21,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.BodyType;
 import org.apache.shindig.social.opensocial.model.Person;
 

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ListFieldDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ListFieldDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ListFieldDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/ListFieldDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.ListField;
 
 import javax.persistence.Basic;
@@ -152,7 +153,7 @@
 
   /** 
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MediaItemDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MediaItemDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MediaItemDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MediaItemDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Activity;
 import org.apache.shindig.social.opensocial.model.MediaItem;
 
@@ -167,7 +168,7 @@
 
   /** 
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MessageDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MessageDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MessageDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/MessageDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Message;
 
 import javax.persistence.Basic;
@@ -161,7 +162,7 @@
 
   /**
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/NameDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/NameDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/NameDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/NameDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Name;
 import org.apache.shindig.social.opensocial.model.Person;
 
@@ -233,7 +234,7 @@
   /**
    * [EMAIL PROTECTED]
    * 
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/OrganizationDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/OrganizationDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/OrganizationDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/OrganizationDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,7 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
 import org.apache.shindig.social.opensocial.model.Address;
 import org.apache.shindig.social.opensocial.model.Organization;
 
@@ -388,7 +389,7 @@
 
   /**
    * [EMAIL PROTECTED]
-   * @see org.apache.shindig.social.opensocial.jpa.DbObject#getObjectId()
+   * @see org.apache.shindig.social.opensocial.jpa.api.DbObject#getObjectId()
    */
   public long getObjectId() {
     return objectId;

Modified: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/PersonDb.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/PersonDb.java?rev=696239&r1=696238&r2=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/PersonDb.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/PersonDb.java
 Wed Sep 17 04:08:15 2008
@@ -19,6 +19,9 @@
 
 import static javax.persistence.GenerationType.IDENTITY;
 
+import org.apache.shindig.social.opensocial.jpa.api.FilterCapability;
+import org.apache.shindig.social.opensocial.jpa.api.DbObject;
+import org.apache.shindig.social.opensocial.jpa.api.FilterSpecification;
 import org.apache.shindig.social.opensocial.model.Account;
 import org.apache.shindig.social.opensocial.model.Address;
 import org.apache.shindig.social.opensocial.model.BodyType;
@@ -32,6 +35,7 @@
 import org.apache.shindig.social.opensocial.model.Enum.LookingFor;
 import org.apache.shindig.social.opensocial.model.Enum.NetworkPresence;
 import org.apache.shindig.social.opensocial.model.Enum.Smoker;
+import org.apache.shindig.social.opensocial.spi.PersonService.FilterOperation;
 
 import com.google.common.collect.Lists;
 
@@ -114,6 +118,78 @@
 
   private static final String TVSHOWS_PROPERTY = "tvshow";
 
+  private static final Map<String, FilterSpecification> FILTER_COLUMNS = 
+      new HashMap<String, FilterSpecification>();
+
+  private static final FilterOperation[] ALL_FILTEROPTIONS = new 
FilterOperation[] {
+      FilterOperation.equals, FilterOperation.contains, 
FilterOperation.present,
+      FilterOperation.startsWith };
+  private static final FilterOperation[] NUMERIC_FILTEROPTIONS = new 
FilterOperation[] {
+      FilterOperation.equals, FilterOperation.present };
+  private static final FilterOperation[] EQUALS_FILTEROPTIONS = new 
FilterOperation[] { 
+    FilterOperation.equals };
+
+  
+  static {
+    FILTER_COLUMNS.put("aboutMe", new 
FilterSpecification("aboutMe",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("age",new 
FilterSpecification("age",NUMERIC_FILTEROPTIONS));
+    FILTER_COLUMNS.put("birthday",new 
FilterSpecification("birthday",NUMERIC_FILTEROPTIONS));
+    FILTER_COLUMNS.put("children",new 
FilterSpecification("children",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("displayName",new 
FilterSpecification("displayName",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("drinker",new 
FilterSpecification("drinkerDb",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("ethnicity",new 
FilterSpecification("ethnicity",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("fashion",new 
FilterSpecification("fashion",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("gender",new 
FilterSpecification("gender",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("happiestWhen",new 
FilterSpecification("happiestWhen",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("humor",new 
FilterSpecification("humor",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("jobInterests",new 
FilterSpecification("jobInterests",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("livingArrangement",
+        new FilterSpecification("livingArrangement",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("movies",new 
FilterSpecification("movies",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("networkPresenceDb",
+        new FilterSpecification("networkPresenceDb",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("nickname",new 
FilterSpecification("nickname",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("pets",new 
FilterSpecification("pets",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("politicalViews",
+        new FilterSpecification("politicalViews",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("relationshipStatus",
+        new FilterSpecification("relationshipStatus",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("religion",new 
FilterSpecification("religion",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("romance",new 
FilterSpecification("romance",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("scaredOf",new 
FilterSpecification("scaredOf",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("sexualOrientation",
+        new FilterSpecification("sexualOrientation",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("smokerDb",new 
FilterSpecification("smokerDb",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("status",new 
FilterSpecification("status",ALL_FILTEROPTIONS));
+    FILTER_COLUMNS.put("utcOffset",new 
FilterSpecification("utcOffset",NUMERIC_FILTEROPTIONS));
+    
+    // the following are special operations which are accepted, but work 
differently
+    FILTER_COLUMNS.put("topFriends",new FilterSpecification());
+    FILTER_COLUMNS.put("hasApp",new FilterSpecification());
+  }
+
+  private static final FilterCapability FILTER_CAPABILITY = new 
FilterCapability() {
+    /**
+     * [EMAIL PROTECTED]
+     */
+    public String getFilterableProperty(String fieldName, FilterOperation 
filterOperation) {
+      FilterSpecification spec = FILTER_COLUMNS.get(fieldName);
+      if (spec != null) {
+        return spec.translateProperty(filterOperation);
+      }
+      return null;
+    }
+
+  };
+
+  public static final String JPQL_FINDALLPERSON = null;
+
+  public static final String JPQL_FINDPERSON_BY_FRIENDS = null;
+
+  public static final Object JPQL_FINDPERSON_BY_GROUP = null;
+
+  public static final Object JPQL_FINDPERSON = null;
+
   /**
    * The internal object ID used for references to this object. Should be 
generated by the
    * underlying storage mechanism
@@ -495,6 +571,7 @@
   @Transient
   private boolean isViewer = false;
 
+
   public PersonDb() {
   }
 
@@ -1184,4 +1261,9 @@
   public void setDisplayName(String displayName) {
     this.displayName = displayName;
   }
+
+  public static FilterCapability getFilterCapability() {
+    return FILTER_CAPABILITY;
+
+  }
 }

Copied: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/DbObject.java
 (from r696238, 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/DbObject.java)
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/DbObject.java?p2=incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/DbObject.java&p1=incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/DbObject.java&r1=696238&r2=696239&rev=696239&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/DbObject.java
 (original)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/DbObject.java
 Wed Sep 17 04:08:15 2008
@@ -15,12 +15,12 @@
  * 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;
+package org.apache.shindig.social.opensocial.jpa.api;
 
 
 /**
  * All Database objects should implement this, mainly to ensure that each has 
an
- * object ID. The object ID cant be set, its generated.
+ * object ID. The object ID can't be set, its generated.
  */
 public interface DbObject {
   /**

Added: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterCapability.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterCapability.java?rev=696239&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterCapability.java
 (added)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterCapability.java
 Wed Sep 17 04:08:15 2008
@@ -0,0 +1,37 @@
+/*
+ * 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.api;
+
+import org.apache.shindig.social.opensocial.spi.PersonService;
+
+/**
+ * Specifies the ability to filter an object
+ */
+public interface FilterCapability {
+  /**
+   * Check to see if the property is filterable on an operation. The final 
property that is returned
+   * must not be directly based on the fieldName passed in and must be 
suitable for direct use
+   * within a JPQL statement. (ie don't trust the passed in parameter)
+   * 
+   * @param fieldName the field name that is being filtered, value is not to 
be trusted.
+   * @param filterOperation the operation being applied to the field.
+   * @return the final property that is being filtered or null is the filter 
operation specified is
+   *         not applicable
+   */
+  String getFilterableProperty(String fieldName, PersonService.FilterOperation 
filterOperation);
+}

Added: 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterSpecification.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterSpecification.java?rev=696239&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterSpecification.java
 (added)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/api/FilterSpecification.java
 Wed Sep 17 04:08:15 2008
@@ -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.api;
+
+import org.apache.shindig.social.opensocial.spi.PersonService.FilterOperation;
+
+/**
+ * A FilterSpecifiation encapsulates the Filter operation for a specific 
field. Name of the target
+ * property based on the operation.
+ */
+public class FilterSpecification {
+
+  public static final String SPECIAL_OPERATION = "special operation";
+  private String finalProperty;
+  private FilterOperation[] filterOptions;
+  private boolean special;
+
+  /**
+   * Create a FilterSpecification with a target final property name and a set 
of acceptable
+   * operations.
+   *
+   * @param finalProperty the name of the final property on the class as used 
by JPQL
+   * @param filterOptions an array of operations that may be applied to this 
property
+   */
+  public FilterSpecification(String finalProperty, FilterOperation[] 
filterOptions) {
+    this.finalProperty = finalProperty;
+    this.filterOptions = filterOptions;
+    this.special = false;
+  }
+
+  /**
+   * Create a default filter operation that operates on special terms, ie that 
is has no filter
+   * mapping and is handled as a special case in the processing. Im this case 
the finalProperty is
+   * set to a reserved value.
+   */
+  public FilterSpecification() {
+    this.special = true;
+  }
+
+  /**
+   * Convert the property into the final property.
+   *
+   * @param operation the operation that is being used.
+   * @return returns the final property name, or null if the operation is not 
applicable
+   */
+  public String translateProperty(FilterOperation operation) {
+    if (special) {
+      return SPECIAL_OPERATION;
+    } else {
+      for (FilterOperation fo : filterOptions) {
+        if (fo.equals(operation)) {
+          return finalProperty;
+        }
+      }
+      return null;
+    }
+  }
+
+  /**
+   * If the final property is special, then return true.
+   * @param finalProp the final property
+   * @return true if special
+   */
+  public static final boolean isSpecial(String finalProp) {
+    return SPECIAL_OPERATION.equals(finalProp);
+  }
+
+  /**
+   * If the final property is valid, return true.
+   * @param finalProp the final property
+   * @return true if valid.
+   */
+  public static final boolean isValid(String finalProp) {
+    return (finalProp != null);
+  }
+
+}

Added: 
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=696239&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java
 (added)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/ActivityServiceDb.java
 Wed Sep 17 04:08:15 2008
@@ -0,0 +1,82 @@
+/*
+ * 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.model.Activity;
+import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.RestfulCollection;
+import org.apache.shindig.social.opensocial.spi.SocialSpiException;
+import org.apache.shindig.social.opensocial.spi.UserId;
+
+import java.util.Set;
+import java.util.concurrent.Future;
+
+/**
+ *
+ */
+public class ActivityServiceDb implements ActivityService {
+
+  /* (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 
SocialSpiException {
+    // TODO Auto-generated method stub
+    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 SocialSpiException {
+    // 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.auth.SecurityToken)
+   */
+  public Future<RestfulCollection<Activity>> getActivities(Set<UserId> 
userIds, GroupId groupId,
+      String appId, Set<String> fields, SecurityToken token) throws 
SocialSpiException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /* (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, java.util.Set, org.apache.shindig.auth.SecurityToken)
+   */
+  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;
+  }
+
+  /* (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 
SocialSpiException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+}

Added: 
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=696239&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java
 (added)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/AppDataServiceDb.java
 Wed Sep 17 04:08:15 2008
@@ -0,0 +1,64 @@
+/*
+ * 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.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 java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+/**
+ *
+ */
+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)
+   */
+  public Future<Void> deletePersonData(UserId userId, GroupId groupId, String 
appId,
+      Set<String> fields, SecurityToken token) throws SocialSpiException {
+    // TODO Auto-generated method stub
+    return 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)
+   */
+  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;
+  }
+
+  /* (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)
+   */
+  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;
+  }
+
+}

Added: 
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=696239&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java
 (added)
+++ 
incubator/shindig/trunk/java/samples/src/main/java/org/apache/shindig/social/opensocial/jpa/spi/PersonServiceDb.java
 Wed Sep 17 04:08:15 2008
@@ -0,0 +1,315 @@
+/*
+ * 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.ResponseError;
+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.RestfulCollection;
+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.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * 
+ */
+public class PersonServiceDb implements PersonService {
+
+  private EntityManager entiyManager;
+
+  /**
+   * 
+   */
+  @Inject
+  public PersonServiceDb(EntityManager entityManager) {
+    this.entiyManager = entityManager;
+  }
+
+  /**
+   * [EMAIL PROTECTED]
+   * 
+   * @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 {
+    // 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.
+
+    return new Future<RestfulCollection<Person>>() {
+
+      private boolean cancel = false;
+
+      public boolean cancel(boolean cancel) {
+        this.cancel = this.cancel || cancel;
+        return this.cancel;
+      }
+
+      public RestfulCollection<Person> get() throws InterruptedException, 
ExecutionException {
+
+        // 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>();
+        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.
+          }
+        }
+        // select the group Id as this will drive the query
+        switch (groupId.getType()) {
+        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);
+
+          List<Person> plist = getListQuery(sb.toString(), paramList, 
collectionOptions);
+          return new RestfulCollection<Person>(plist);
+        }
+        case friends: {
+          // select all friends
+          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);
+
+          List<Person> plist = getListQuery(sb.toString(), paramList, 
collectionOptions);
+          return new RestfulCollection<Person>(plist);
+        }
+        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);
+
+          List<Person> plist = getListQuery(sb.toString(), params, 
collectionOptions);
+          return new RestfulCollection<Person>(plist);
+        }
+        case deleted:
+          // ???
+          break;
+        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);
+
+          List<Person> plist = getListQuery(sb.toString(), paramList, 
collectionOptions);
+          return new RestfulCollection<Person>(plist);
+
+        }
+
+        }
+        throw new SocialSpiException(ResponseError.BAD_REQUEST, "Group ID not 
recognized");
+      }
+
+      public RestfulCollection<Person> get(long arg0, TimeUnit arg1) throws 
InterruptedException,
+          ExecutionException, TimeoutException {
+        return get();
+      }
+
+      public boolean isCancelled() {
+        return false;
+      }
+
+      public boolean isDone() {
+        return true;
+      }
+
+    };
+
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @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 {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /**
+   * 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
+   * @return
+   */
+  private int addFilterClause(StringBuilder sb, FilterCapability filterable,
+      CollectionOptions collectionOptions, int lastPos) {
+    // this makes the filter value safe
+    String filter = 
filterable.getFilterableProperty(collectionOptions.getFilter(),
+        collectionOptions.getFilterOperation());
+    String filterValue = collectionOptions.getFilterValue();
+    int filterPos = 0;
+    if (FilterSpecification.isValid(filter)) {
+      if (FilterSpecification.isSpecial(filter)) {
+        if ("hasApp".equals(filter)) {
+        } else if ("topFriends".equals(filter)) {
+        }
+      } else {
+        sb.append("p.").append(filter);
+        switch (collectionOptions.getFilterOperation()) {
+        case contains:
+          filterPos = lastPos + 1;
+          sb.append(" like ").append(" ?").append(filterPos);
+          filterValue = "%" + 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 + "%";
+          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) {
+      sb.append(" order by p.").append(sortBy);
+      switch (collectionOptions.getSortOrder()) {
+      case ascending:
+        sb.append(" asc ");
+        break;
+      case descending:
+        sb.append(" desc ");
+        break;
+      }
+    }
+  }
+}


Reply via email to