]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
cspace-789 partial search on account. query parameters are sn for screenname, uid...
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Tue, 26 Jan 2010 17:27:05 +0000 (17:27 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Tue, 26 Jan 2010 17:27:05 +0000 (17:27 +0000)
test: added search tests on account

M    services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClient.java
M    services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java
M    services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java
M    services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java
A    services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java
A    services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageConstants.java
M    services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java
M    services/account/client/src/main/java/org/collectionspace/services/client/AccountClient.java
M    services/account/client/src/main/java/org/collectionspace/services/client/AccountProxy.java
_M   services/organization/client

services/account/client/src/main/java/org/collectionspace/services/client/AccountClient.java
services/account/client/src/main/java/org/collectionspace/services/client/AccountProxy.java
services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java [new file with mode: 0644]
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageConstants.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClient.java

index 286108e79d8b7e480bf3f0997f141c2ee48dca25..05175be33f772cea70fad6dc9dd5293d5bcd414e 100644 (file)
@@ -88,8 +88,8 @@ public class AccountClient extends BaseServiceClient {
 
     }
 
-    public ClientResponse<AccountsCommonList> readSearchList(String screenName) {
-        return accountProxy.readSearchList(screenName);
+    public ClientResponse<AccountsCommonList> readSearchList(String screenName, String uid, String email) {
+        return accountProxy.readSearchList(screenName, uid, email);
 
     }
 
index 940d701a8fe3dcdc64072f78e7aa6bba09b90ff9..ce724ff2cb082b9e275306426c6c64f6aa249316 100644 (file)
@@ -58,7 +58,7 @@ public interface AccountProxy {
 
         @GET
     @Produces({"application/xml"})
-    ClientResponse<AccountsCommonList> readSearchList(@QueryParam("sn") String screenName);
+    ClientResponse<AccountsCommonList> readSearchList(@QueryParam("sn") String screenName, @QueryParam("uid") String uid, @QueryParam("email") String email);
 
     //(C)reate
     @POST
index 810a99b606fad287de4c6b33094f9c37132d1e36..09bb984ada704a94f390ec9a070d11235b252de8 100644 (file)
@@ -58,10 +58,11 @@ public class AccountServiceTest extends AbstractServiceTest {
     private String knownResourceId = null;
     private String resource1Id = null;
     private String resource2Id = null;
-
+    private String resource3Id = null;
     /*
      * This method is called only by the parent class, AbstractServiceTest
      */
+
     @Override
     protected String getServicePathComponent() {
         return client.getServicePathComponent();
@@ -173,6 +174,15 @@ public class AccountServiceTest extends AbstractServiceTest {
                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
         resource2Id = extractId(res);
+
+        AccountsCommon account3 =
+                createAccountInstance("dj", "hithere10", "dj@dinoland.com", true, true, true);
+        res = client.create(account3);
+        statusCode = res.getStatus();
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        resource3Id = extractId(res);
     }
 
     // Failure outcomes
@@ -277,13 +287,69 @@ public class AccountServiceTest extends AbstractServiceTest {
 
     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
     dependsOnMethods = {"createList", "read"})
-    public void readSearchList(String testName) throws Exception {
+    public void searchScreenName(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadList(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<AccountsCommonList> res = client.readSearchList("tom", null, null);
+        AccountsCommonList list = res.getEntity();
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        Assert.assertEquals(1, list.getAccountListItem().size());
+        // Optionally output additional data about list members for debugging.
+        boolean iterateThroughList = true;
+        if (iterateThroughList && logger.isDebugEnabled()) {
+            printList(testName, list);
+        }
+    }
+
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"createList", "read"})
+    public void searchUserId(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadList(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<AccountsCommonList> res = client.readSearchList(null, "tom", null);
+        AccountsCommonList list = res.getEntity();
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        Assert.assertEquals(1, list.getAccountListItem().size());
+        // Optionally output additional data about list members for debugging.
+        boolean iterateThroughList = true;
+        if (iterateThroughList && logger.isDebugEnabled()) {
+            printList(testName, list);
+        }
+    }
+
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"createList", "read"})
+    public void searchEmail(String testName) throws Exception {
 
         // Perform setup.
         setupReadList(testName);
 
         // Submit the request to the service and store the response.
-        ClientResponse<AccountsCommonList> res = client.readSearchList("tom");
+        ClientResponse<AccountsCommonList> res = client.readSearchList(null, null, "dinoland");
         AccountsCommonList list = res.getEntity();
         int statusCode = res.getStatus();
 
@@ -295,7 +361,35 @@ public class AccountServiceTest extends AbstractServiceTest {
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        Assert.assertEquals(2, list.getAccountListItem().size());
+        // Optionally output additional data about list members for debugging.
+        boolean iterateThroughList = true;
+        if (iterateThroughList && logger.isDebugEnabled()) {
+            printList(testName, list);
+        }
+    }
 
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"createList", "read"})
+    public void searchScreenNameEmail(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadList(testName);
+
+        // Submit the request to the service and store the response.
+        ClientResponse<AccountsCommonList> res = client.readSearchList("tom", null, "jerry");
+        AccountsCommonList list = res.getEntity();
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        Assert.assertEquals(1, list.getAccountListItem().size());
         // Optionally output additional data about list members for debugging.
         boolean iterateThroughList = true;
         if (iterateThroughList && logger.isDebugEnabled()) {
@@ -632,6 +726,12 @@ public class AccountServiceTest extends AbstractServiceTest {
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+        res = client.delete(resource3Id);
+        statusCode = res.getStatus();
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     // Failure outcomes
index 6863aca45b64b11e2f5a3b72e58f694d9e3c1071..ec11b7dd971abf868d4a0c4e4242d90fbd00bf1b 100644 (file)
@@ -33,7 +33,6 @@ import org.collectionspace.services.common.document.AbstractDocumentHandler;
 import org.collectionspace.services.common.document.BadRequestException;
 import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentWrapper;
-import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -161,26 +160,15 @@ public class AccountDocumentHandler
 
     @Override
     public DocumentFilter createDocumentFilter() {
-        return new JpaDocumentFilter();
+        return new AccountJpaFilter();
     }
-    private void setWhereForGetAll(StringBuilder strBld) {
-        DocumentFilter filter = getDocumentFilter();
-        String screenName = null;
-        if (screenName != null && !screenName.isEmpty()) {
-            String ptClause =
-                    "WHERE UPPER(a.screenName)"
-                    + " LIKE "
-                    + ":sn";
-            filter.addQueryParam("sn", "%" + screenName.toUpperCase() + "%");
-            filter.setWhereClause(ptClause);
-        }
 
-    }
     /**
      * sanitize removes data not needed to be sent to the consumer
      * @param account
      */
     private void sanitize(AccountsCommon account) {
         account.setPassword(null);
+
     }
 }
diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java
new file mode 100644 (file)
index 0000000..1763585
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  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.
+ *//**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author 
+ */
+public class AccountJpaFilter extends JpaDocumentFilter {
+
+    private final Logger logger = LoggerFactory.getLogger(AccountJpaFilter.class);
+
+    @Override
+    public List<ParamBinding> buildWhereForSearch(StringBuilder queryStrBldr) {
+
+        List<ParamBinding> paramList = new ArrayList<ParamBinding>();
+        boolean hasWhere = false;
+        //TODO: add tenant id
+
+        String screenName = null;
+        List<String> snvals = getQueryParam(AccountStorageConstants.Q_SCREEN_NAME);
+        if (snvals != null) {
+            screenName = snvals.get(0);
+        }
+        if (null != screenName && !screenName.isEmpty()) {
+            hasWhere = true;
+            queryStrBldr.append(" WHERE");
+            queryStrBldr.append(" UPPER(a." + AccountStorageConstants.SCREEN_NAME + ")");
+            queryStrBldr.append(" LIKE");
+            queryStrBldr.append(" :" + AccountStorageConstants.Q_SCREEN_NAME);
+            paramList.add(new ParamBinding(AccountStorageConstants.Q_SCREEN_NAME, "%"
+                    + screenName.toUpperCase() + "%"));
+        }
+
+        String uid = null;
+        List<String> uidvals = getQueryParam(AccountStorageConstants.Q_USER_ID);
+        if (uidvals != null) {
+            uid = uidvals.get(0);
+        }
+        if (null != uid && !uid.isEmpty()) {
+            if (hasWhere) {
+                queryStrBldr.append(" AND");
+            } else {
+                queryStrBldr.append(" WHERE");
+            }
+            queryStrBldr.append(" UPPER(a." + AccountStorageConstants.USER_ID + ")");
+            queryStrBldr.append(" LIKE");
+            queryStrBldr.append(" :" + AccountStorageConstants.Q_USER_ID);
+            paramList.add(new ParamBinding(AccountStorageConstants.Q_USER_ID, "%"
+                    + uid.toUpperCase() + "%"));
+            hasWhere = true;
+        }
+
+                String email = null;
+        List<String> emailvals = getQueryParam(AccountStorageConstants.Q_EMAIL);
+        if (emailvals != null) {
+            email = emailvals.get(0);
+        }
+        if (null != email && !email.isEmpty()) {
+            if (hasWhere) {
+                queryStrBldr.append(" AND");
+            } else {
+                queryStrBldr.append(" WHERE");
+            }
+            queryStrBldr.append(" UPPER(a." + AccountStorageConstants.EMAIL + ")");
+            queryStrBldr.append(" LIKE");
+            queryStrBldr.append(" :" + AccountStorageConstants.Q_EMAIL);
+            paramList.add(new ParamBinding(AccountStorageConstants.Q_EMAIL, "%"
+                    + email.toUpperCase() + "%"));
+            hasWhere = true;
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("query=" + queryStrBldr.toString());
+        }
+
+        return paramList;
+    }
+
+    @Override
+    public List<ParamBinding> buildWhere(StringBuilder queryStrBldr) {
+        return new ArrayList<ParamBinding>();
+    }
+}
index 0e1dcd8f0839406d9a3019aa6536db424031b312..f0d479ca574dbdddb994102b05305791ec584961 100644 (file)
@@ -23,8 +23,6 @@
  */
 package org.collectionspace.services.account.storage;
 
-import java.util.ArrayList;
-import java.util.List;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Query;
diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageConstants.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageConstants.java
new file mode 100644 (file)
index 0000000..35b8e25
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  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.
+ *//**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ *  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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.collectionspace.services.account.storage;
+
+/**
+ * AccountStorageConstants declares query params, etc.
+ * @author
+ */
+public class AccountStorageConstants {
+
+    final public static String Q_SCREEN_NAME = "sn";
+    final public static String Q_USER_ID= "uid";
+    final public static String Q_EMAIL = "email";
+
+
+    final public static String SCREEN_NAME = "screenName";
+    final public static String USER_ID = "userId";
+    final public static String EMAIL = "email";
+}
index 971b8a423601081c541f434a63a6657ee5b7fca4..72fb4d30ae90a3dedbcad168cfcca1120bf93c1c 100644 (file)
  */\r
 package org.collectionspace.services.common.document;\r
 \r
-import java.util.HashMap;\r
+import java.util.ArrayList;\r
 import java.util.List;\r
-import java.util.Map;\r
 import javax.ws.rs.core.MultivaluedMap;\r
 import org.collectionspace.services.common.query.IQueryManager;\r
 \r
+//TODO: would be great to not rely on resteasy directly\r
+import org.jboss.resteasy.specimpl.MultivaluedMapImpl;\r
+\r
 /**\r
  * DocumentFilter bundles simple query filtering parameters. \r
  * It is designed to be used with filtered get and search calls to RepositoryClient.\r
@@ -38,8 +40,51 @@ public class DocumentFilter {
     protected String whereClause;      // Filtering clause. Omit the "WHERE".\r
     protected int startPage;           // Pagination offset for list results\r
     protected int pageSize;                    // Pagination limit for list results\r
-    private MultivaluedMap<String, String> queryParams;\r
+    private MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl<String, String>();\r
+\r
+\r
+    /**\r
+     * ParamBinding encapsulates parameter binding for query\r
+     */\r
+    public static class ParamBinding {\r
+\r
+        private String name;\r
+        private Object value;\r
+\r
+        public ParamBinding(String name, Object value) {\r
+            this.name = name;\r
+            this.value = value;\r
+        }\r
+\r
+        /**\r
+         * @return the name\r
+         */\r
+        public String getName() {\r
+            return name;\r
+        }\r
+\r
+        /**\r
+         * @param name the name to set\r
+         */\r
+        public void setName(String name) {\r
+            this.name = name;\r
+        }\r
 \r
+        /**\r
+         * @return the value\r
+         */\r
+        public Object getValue() {\r
+            return value;\r
+        }\r
+\r
+        /**\r
+         * @param value the value to set\r
+         */\r
+        public void setValue(Object value) {\r
+            this.value = value;\r
+        }\r
+    }\r
+    \r
     public DocumentFilter() {\r
         this("", 0, defaultPageSize);                  // Use empty string for easy concatenation\r
     }\r
@@ -114,6 +159,24 @@ public class DocumentFilter {
         }\r
     }\r
 \r
+    /**\r
+     * buildWhereClause builds where clause for search query\r
+     * @param queryStrBldr query string to append with where clause\r
+     * @return parameter binding\r
+     */\r
+    public List<ParamBinding> buildWhereForSearch(StringBuilder queryStrBldr) {\r
+        return new ArrayList<ParamBinding>();\r
+    }\r
+\r
+    /**\r
+     * buildWhereClause builds where clause for get, update or delete\r
+     * @param queryStrBldr query string to append with where clause\r
+     * @return parameter binding\r
+     */\r
+    public List<ParamBinding> buildWhere(StringBuilder queryStrBldr) {\r
+        return new ArrayList<ParamBinding>();\r
+    }\r
+\r
     /**\r
      * @return the specified (0-based) page offset\r
      */\r
index 4438049eedab76f5bdfbf7ed6eba1327201b5b91..9e71d811cf4224c52f895c7b201168cfc46aa4d4 100644 (file)
@@ -121,18 +121,19 @@ public class JpaStorageClient implements StorageClient {
         EntityManager em = null;
         try {
             handler.prepare(Action.GET);
-            StringBuilder queryStr = new StringBuilder("SELECT a FROM ");
-            queryStr.append(getEntityName(ctx));
-            queryStr.append(" a");
-            queryStr.append(" WHERE csid = :csid");
+            StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
+            queryStrBldr.append(getEntityName(ctx));
+            queryStrBldr.append(" a");
+            queryStrBldr.append(" WHERE csid = :csid");
             //TODO: add tenant id
             String where = docFilter.getWhereClause();
             if ((null != where) && (where.length() > 0)) {
-                queryStr.append(" AND " + where);
+                queryStrBldr.append(" AND " + where);
             }
             emf = getEntityManagerFactory();
             em = emf.createEntityManager();
-            Query q = em.createQuery(queryStr.toString());
+            String queryStr = queryStrBldr.toString(); //for debugging
+            Query q = em.createQuery(queryStr);
             q.setParameter("csid", id);
             //TODO: add tenant id
 
@@ -201,18 +202,18 @@ public class JpaStorageClient implements StorageClient {
         try {
             handler.prepare(Action.GET_ALL);
 
-            StringBuilder strBld = new StringBuilder("SELECT a FROM ");
-            strBld.append(getEntityName(ctx));
-            strBld.append(" a");
+            StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
+            queryStrBldr.append(getEntityName(ctx));
+            queryStrBldr.append(" a");
+            List<DocumentFilter.ParamBinding> params = docFilter.buildWhereForSearch(queryStrBldr);
             //TODO: add tenant id
             emf = getEntityManagerFactory();
             em = emf.createEntityManager();
-            String queryStr = strBld.toString(); //for debugging
+            String queryStr = queryStrBldr.toString(); //for debugging
             Query q = em.createQuery(queryStr);
-            //TODO: add tenant id
-            String where = docFilter.getWhereClause();
-            if ((null != where) && (where.length() > 0)) {
-                strBld.append(where);
+            //bind parameters
+            for(DocumentFilter.ParamBinding p : params) {
+                q.setParameter(p.getName(), p.getValue());
             }
             if (docFilter.getOffset() > 0) {
                 q.setFirstResult(docFilter.getOffset());