]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
NOJIRA - added handler callbacks (prepare, handle, complete) for delete. Needed to...
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 30 Apr 2010 23:20:10 +0000 (23:20 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 30 Apr 2010 23:20:10 +0000 (23:20 +0000)
test: services tests

services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java

index ef756c263af39724a3d85a38dc6b6f31d983d1f2..9582978bd7215ec902434005b707649f13838e1c 100644 (file)
@@ -80,7 +80,6 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
 //     DocumentFilter docFilter = this.createDocumentFilter(ctx);
 //     this.setDocumentFilter(docFilter);
 //    }
-    
     @Override
     public abstract DocumentFilter createDocumentFilter();
 
@@ -121,6 +120,10 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                 prepareGetAll();
                 break;
 
+            case DELETE:
+                prepareDelete();
+                break;
+
         }
     }
 
@@ -140,6 +143,10 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
     public void prepareGetAll() throws Exception {
     }
 
+    @Override
+    public void prepareDelete() throws Exception {
+    }
+
     @Override
     final public void handle(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
         switch (action) {
@@ -159,6 +166,10 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                 handleGetAll((DocumentWrapper<WTL>) wrapDoc);
                 break;
 
+            case DELETE:
+                handleDelete((DocumentWrapper<WT>) wrapDoc);
+                break;
+
         }
     }
 
@@ -174,6 +185,11 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
     @Override
     public abstract void handleGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception;
 
+    @Override
+    public void handleDelete(DocumentWrapper<WT> wrapDoc) throws Exception {
+        
+    }
+
     @Override
     final public void complete(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
         switch (action) {
@@ -192,14 +208,13 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
             case GET_ALL:
                 completeGetAll((DocumentWrapper<WTL>) wrapDoc);
                 break;
+
+            case DELETE:
+                completeDelete((DocumentWrapper<WT>) wrapDoc);
+                break;
         }
     }
 
-    /**
-     * completeCreate is called by the client to indicate completion of the create call.
-     * @param wrapDoc
-     * @throws Exception
-     */
     @Override
     public void completeCreate(DocumentWrapper<WT> wrapDoc) throws Exception {
     }
@@ -217,6 +232,10 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
     public void completeGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception {
     }
 
+    @Override
+    public void completeDelete(DocumentWrapper<WT> wrapDoc) throws Exception {
+    }
+
     @Override
     public abstract T extractCommonPart(DocumentWrapper<WT> wrapDoc)
             throws Exception;
index 3e8874a9dc45d331bad79e8790cc896537973bd6..c6f88aeeb1025c0cd709feeaeea0bb9946dcabc2 100644 (file)
@@ -86,19 +86,25 @@ public interface DocumentHandler<T, TL, WT, WTL> {
     public void prepareUpdate() throws Exception;
 
     /**
-     * prepareGet processes query from repository before retrieving document from
+     * prepareGet processes query before retrieving document from
      * repository
      * @throws Exception
      */
     public void prepareGet() throws Exception;
 
     /**
-     * prepareGetAll processes query from repository before retrieving document(s) from
+     * prepareGetAll processes query before retrieving document(s) from
      * repository
      * @throws Exception
      */
     public void prepareGetAll() throws Exception;
 
+    /**
+     * prepareDelete processes delete before deleting document from repository
+     * @throws Exception
+     */
+    public void prepareDelete() throws Exception;
+
     /**
      * prepare is called by the client to hand over the document processing task
      * @param action 
@@ -135,6 +141,13 @@ public interface DocumentHandler<T, TL, WT, WTL> {
      */
     public void handleGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception;
 
+    /**
+     * handleDelete processes documents for the deletion of document in repository
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void handleDelete(DocumentWrapper<WT> wrapDoc) throws Exception;
+
     /**
      * complete is called by the client to provide an opportunity to the handler
      * to take care of stuff before closing session with the repository. example
@@ -172,6 +185,13 @@ public interface DocumentHandler<T, TL, WT, WTL> {
      */
     public void completeGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception;
 
+    /**
+     * completeDelete is called by the client to indicate completion of the delete call.
+     * @param wrapDoc
+     * @throws Exception
+     */
+    public void completeDelete(DocumentWrapper<WT> wrapDoc) throws Exception;
+
     /**
      * extractCommonPart extracts common part of a CS object from given document.
      * this is usually called AFTER the get operation is invoked on the repository.
@@ -224,7 +244,7 @@ public interface DocumentHandler<T, TL, WT, WTL> {
      * @param properties
      */
     public void setProperties(Map<String, Object> properties);
-    
+
     /**
      * createDocumentFilter is a factory method to create a document
      * filter that is relevant to be used with this document handler
index 8142c0bf150c54fb3f430e58cd30c06c484b5ef2..05f4d386df436e7a1313e7ea978359d5390ab371 100644 (file)
@@ -50,6 +50,18 @@ public interface StorageClient {
      */
     void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException;
 
+
+    /**
+     * delete a entity from the persistence store
+     * @param ctx service context under which this method is invoked
+     * @param id of the entity
+     * @param handler to perform additional operations such as pre and post processing
+     * @throws DocumentNotFoundException if entity not found
+     * @throws DocumentException
+     */
+    void delete(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
+
     /**
      * get entity from the persistence store
      * @param ctx service context under which this method is invoked
index 3e8a5bf61ad87022164fec8d09d9c29d00192939..e4adc202a944397fe5aee68d08272c8f8874b9a0 100644 (file)
@@ -294,15 +294,7 @@ public class JpaStorageClientImpl implements StorageClient {
             emf = JpaStorageUtils.getEntityManagerFactory();
             em = emf.createEntityManager();
             em.getTransaction().begin();
-            Object entityFound = em.find(entityReceived.getClass(), id);
-            if (entityFound == null) {
-                if (em != null && em.getTransaction().isActive()) {
-                    em.getTransaction().rollback();
-                }
-                String msg = "could not find entity with id=" + id;
-                logger.error(msg);
-                throw new DocumentNotFoundException(msg);
-            }
+            Object entityFound = getEntity(em, id, entityReceived.getClass());
             DocumentWrapper<Object> wrapDoc = new DocumentWrapperImpl<Object>(entityFound);
             handler.handle(Action.UPDATE, wrapDoc);
             em.getTransaction().commit();
@@ -326,7 +318,9 @@ public class JpaStorageClientImpl implements StorageClient {
         }
     }
 
-    /* delete use delete to remove parent entityReceived along with child entities
+    /* 
+     * delete removes entity and its child entities
+     * cost: a get before delete
      * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String)
      */
     @Override
@@ -334,14 +328,14 @@ public class JpaStorageClientImpl implements StorageClient {
             throws DocumentNotFoundException,
             DocumentException {
 
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleting entity with id=" + id);
+        }
+
         if (ctx == null) {
             throw new IllegalArgumentException(
                     "JpaStorageClient.delete: ctx is missing");
         }
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("deleting entity with id=" + id);
-        }
         EntityManagerFactory emf = null;
         EntityManager em = null;
         try {
@@ -383,7 +377,7 @@ public class JpaStorageClientImpl implements StorageClient {
      * deleteWhere uses the where clause to delete an entityReceived represented by the csidReceived
      * it does not delete any child entities.
      * @param ctx
-     * @param csidReceived
+     * @param id
      * @throws DocumentNotFoundException
      * @throws DocumentException
      */
@@ -442,6 +436,43 @@ public class JpaStorageClientImpl implements StorageClient {
         }
     }
 
+    @Override
+    public void delete(ServiceContext ctx, String id, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
+        if (ctx == null) {
+            throw new IllegalArgumentException(
+                    "JpaStorageClient.delete: ctx is missing");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "JpaStorageClient.delete: handler is missing");
+        }
+        EntityManagerFactory emf = null;
+        EntityManager em = null;
+        try {
+            handler.prepare(Action.DELETE);
+            Object entity = handler.getCommonPart();
+            DocumentWrapper<Object> wrapDoc = new DocumentWrapperImpl<Object>(entity);
+
+            handler.handle(Action.DELETE, wrapDoc);
+            handler.complete(Action.DELETE, wrapDoc);
+        } catch (DocumentException de) {
+            throw de;
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            throw new DocumentException(e);
+        } finally {
+            if (emf != null) {
+                JpaStorageUtils.releaseEntityManagerFactory(emf);
+            }
+        }
+    }
+
     /**
      * Gets the entityReceived name.
      * 
@@ -452,8 +483,8 @@ public class JpaStorageClientImpl implements StorageClient {
     protected String getEntityName(ServiceContext ctx) {
         Object o = ctx.getProperty(ServiceContextProperties.ENTITY_NAME);
         if (o == null) {
-            throw new IllegalArgumentException(ServiceContextProperties.ENTITY_NAME +
-                    "property is missing in context "
+            throw new IllegalArgumentException(ServiceContextProperties.ENTITY_NAME
+                    "property is missing in context "
                     + ctx.toString());
         }
 
@@ -462,25 +493,35 @@ public class JpaStorageClientImpl implements StorageClient {
 
     /**
      * getEntity returns persistent entity for given id. it assumes that
-     * JpaStorageClientImpl is implemented using the JpaStorageClientImpl(entityClazz)
-     * constructor
+     * service context has property ServiceContextProperties.ENTITY_CLASS set
      * @param ctx service context
      * @param em entity manager
      * @param csid received
      * @return
-     * @throws DocumentNotFoundException
-     * @throws UnsupportedOperationException if JpaStorageClientImpl is not implemented
-     * using the JpaStorageClientImpl(entityClazz)
-     * constructor
+     * @throws DocumentNotFoundException and rollsback the transaction if active
      */
-    protected Object getEntity(ServiceContext ctx, EntityManager em, String id) throws DocumentNotFoundException {
+    protected Object getEntity(ServiceContext ctx, EntityManager em, String id)
+            throws DocumentNotFoundException {
         Class entityClazz = (Class) ctx.getProperty(ServiceContextProperties.ENTITY_CLASS);
         if (entityClazz == null) {
-            String msg = ServiceContextProperties.ENTITY_CLASS +
-                    " property is missing in the context";
+            String msg = ServiceContextProperties.ENTITY_CLASS
+                    " property is missing in the context";
             logger.error(msg);
             throw new IllegalArgumentException(msg);
         }
+        return getEntity(em, id, entityClazz);
+    }
+
+    /**
+     * getEntity retrieves the persistent entity of given class for given id
+     * @param em
+     * @param id entity id
+     * @param entityClazz
+     * @return
+     * @throws DocumentNotFoundException and rollsback the transaction if active
+     */
+    protected Object getEntity(EntityManager em, String id, Class entityClazz)
+            throws DocumentNotFoundException {
         Object entityFound = JpaStorageUtils.getEntity(em, id, entityClazz);
         if (entityFound == null) {
             if (em != null && em.getTransaction().isActive()) {
index d9d033033aa119682cb6691ace5b8d090f05b775..422569706d28f8235c2e80c743d4cb615921e247 100644 (file)
@@ -123,7 +123,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
 
     }
-    
+
     /**
      * get document from the Nuxeo repository
      * @param ctx service context under which this method is invoked
@@ -196,15 +196,15 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         DocumentFilter docFilter = handler.getDocumentFilter();
         if (docFilter == null) {
             throw new IllegalArgumentException(
-                   "RepositoryJavaClient.get: handler has no Filter specified");
+                    "RepositoryJavaClient.get: handler has no Filter specified");
         }
-        if(docFilter.getPageSize()!= 1) {
+        if (docFilter.getPageSize() != 1) {
             logger.warn("RepositoryJavaClient.get: forcing docFilter pagesize to 1.");
         }
         String docType = ctx.getDocumentType();
         if (docType == null) {
             throw new DocumentNotFoundException(
-                   "Unable to find DocumentType for service " + ctx.getServiceName());
+                    "Unable to find DocumentType for service " + ctx.getServiceName());
         }
         String domain = ctx.getRepositoryDomainName();
         if (domain == null) {
@@ -216,20 +216,20 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         try {
             handler.prepare(Action.GET);
             repoSession = getRepositorySession();
-            
+
             DocumentModelList docList = null;
             // force limit to 1, and ignore totalSize
-            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain ); 
-            docList = repoSession.query( query, null, 1, 0, false);
-            if(docList.size()!=1) {
+            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain);
+            docList = repoSession.query(query, null, 1, 0, false);
+            if (docList.size() != 1) {
                 throw new DocumentNotFoundException("No document found matching filter params.");
             }
             DocumentModel doc = docList.get(0);
-            
+
             if (logger.isDebugEnabled()) {
                 logger.debug("Executed NXQL query: " + query);
             }
-            
+
             //set reposession to handle the document
             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
             DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
@@ -260,7 +260,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
      */
     @Override
     public DocumentWrapper<DocumentModel> getDoc(
-               ServiceContext ctx, String id)
+            ServiceContext ctx, String id)
             throws DocumentNotFoundException, DocumentException {
         RepositoryInstance repoSession = null;
         DocumentWrapper<DocumentModel> wrapDoc = null;
@@ -302,16 +302,16 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
      */
     @Override
     public DocumentWrapper<DocumentModel> findDoc(
-               ServiceContext ctx, String where)
+            ServiceContext ctx, String where)
             throws DocumentNotFoundException, DocumentException {
         RepositoryInstance repoSession = null;
         DocumentWrapper<DocumentModel> wrapDoc = null;
 
         try {
-               String docType = ctx.getDocumentType();
+            String docType = ctx.getDocumentType();
             if (docType == null) {
                 throw new DocumentNotFoundException(
-                       "Unable to find DocumentType for service " + ctx.getServiceName());
+                        "Unable to find DocumentType for service " + ctx.getServiceName());
             }
             String domain = ctx.getRepositoryDomainName();
             if (domain == null) {
@@ -321,11 +321,11 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             repoSession = getRepositorySession();
             DocumentModelList docList = null;
             // force limit to 1, and ignore totalSize
-            String query = buildNXQLQuery(docType, where, domain ); 
-            docList = repoSession.query( query, null, 1, 0, false);
-            if(docList.size()!=1) {
+            String query = buildNXQLQuery(docType, where, domain);
+            docList = repoSession.query(query, null, 1, 0, false);
+            if (docList.size() != 1) {
                 if (logger.isDebugEnabled()) {
-                    logger.debug("findDoc: Query found: "+docList.size()+" items.");
+                    logger.debug("findDoc: Query found: " + docList.size() + " items.");
                     logger.debug(" Query: " + query);
                 }
                 throw new DocumentNotFoundException("No document found matching filter params.");
@@ -348,7 +348,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
         return wrapDoc;
     }
-    
+
     /**
      * find doc and return CSID from the Nuxeo repository
      * @param ctx service context under which this method is invoked
@@ -356,26 +356,26 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
      * @throws DocumentException
      */
     public String findDocCSID(
-               ServiceContext ctx, String where)
+            ServiceContext ctx, String where)
             throws DocumentNotFoundException, DocumentException {
-       String csid = null;
-       try {
-               DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, where);
-               DocumentModel docModel = wrapDoc.getWrappedObject();
+        String csid = null;
+        try {
+            DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, where);
+            DocumentModel docModel = wrapDoc.getWrappedObject();
             csid = NuxeoUtils.extractId(docModel.getPathAsString());
-               } catch (DocumentNotFoundException dnfe) {
+        } catch (DocumentNotFoundException dnfe) {
             throw dnfe;
         } catch (IllegalArgumentException iae) {
             throw iae;
         } catch (DocumentException de) {
             throw de;
-               } catch (Exception e) {
+        } catch (Exception e) {
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
             throw new DocumentException(e);
         }
-               return csid;
+        return csid;
     }
 
     /**
@@ -387,16 +387,16 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
      */
     @Override
     public DocumentWrapper<DocumentModelList> findDocs(
-               List<String> docTypes, String where, String domain,
-               int pageSize, int pageNum, boolean computeTotal )
+            List<String> docTypes, String where, String domain,
+            int pageSize, int pageNum, boolean computeTotal)
             throws DocumentNotFoundException, DocumentException {
         RepositoryInstance repoSession = null;
         DocumentWrapper<DocumentModelList> wrapDoc = null;
 
         try {
-            if (docTypes == null || docTypes.size()<1) {
+            if (docTypes == null || docTypes.size() < 1) {
                 throw new DocumentNotFoundException(
-                       "findDocs must specify at least one DocumentType.");
+                        "findDocs must specify at least one DocumentType.");
             }
             if (domain == null) {
                 throw new DocumentNotFoundException("findDocs must specify Domain.");
@@ -404,8 +404,8 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             repoSession = getRepositorySession();
             DocumentModelList docList = null;
             // force limit to 1, and ignore totalSize
-            String query = buildNXQLQuery(docTypes, where, domain ); 
-            docList = repoSession.query( query, null, pageSize, pageNum, computeTotal);
+            String query = buildNXQLQuery(docTypes, where, domain);
+            docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
             wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
         } catch (IllegalArgumentException iae) {
             throw iae;
@@ -422,10 +422,9 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         return wrapDoc;
     }
 
-    
     @Override
     public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
-               throws DocumentNotFoundException, DocumentException {
+            throws DocumentNotFoundException, DocumentException {
         if (handler == null) {
             throw new IllegalArgumentException(
                     "RepositoryJavaClient.getAll: handler is missing");
@@ -462,7 +461,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             }
         }
     }
-    
+
     /**
      * getAll get all documents for an entity entity service from the Nuxeo
      * repository
@@ -547,7 +546,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             handler.prepare(Action.GET_ALL);
             repoSession = getRepositorySession();
             DocumentModelList docList = null;
-            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain );
+            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain);
 
             // If we have limit and/or offset, then pass true to get totalSize
             // in returned DocumentModelList.
@@ -557,11 +556,11 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             } else {
                 docList = repoSession.query(query);
             }
-            
+
             if (logger.isDebugEnabled()) {
                 logger.debug("Executed NXQL query: " + query.toString());
             }
-            
+
             //set repoSession to handle the document
             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
             DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
@@ -676,6 +675,12 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
     }
 
+    @Override
+    public void delete(ServiceContext ctx, String id, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public String createWorkspace(String tenantDomain, String workspaceName) throws Exception {
         RepositoryInstance repoSession = null;
@@ -737,38 +742,38 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
         return workspaceId;
     }
-    
-    private final void appendNXQLWhere(StringBuilder query, String where, String domain ) {
+
+    private final void appendNXQLWhere(StringBuilder query, String where, String domain) {
         // TODO This is a slow method for tenant-filter
         // We should make this a property that is indexed.
         query.append(" WHERE ecm:path STARTSWITH '/" + domain + "'");
         if ((null != where) && (where.length() > 0)) {
-               // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
-               // into SQL, we need to parenthesize our 'where' clause
-            query.append(" AND " + "(" + where +")");
+            // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
+            // into SQL, we need to parenthesize our 'where' clause
+            query.append(" AND " + "(" + where + ")");
         }
         query.append(" AND ecm:isProxy = 0");
     }
 
-    private final String buildNXQLQuery(String docType, String where, String domain ) {
+    private final String buildNXQLQuery(String docType, String where, String domain) {
         StringBuilder query = new StringBuilder("SELECT * FROM ");
         query.append(docType);
-        appendNXQLWhere(query, where, domain );
+        appendNXQLWhere(query, where, domain);
         return query.toString();
     }
 
-    private final String buildNXQLQuery(List<String> docTypes, String where, String domain ) {
+    private final String buildNXQLQuery(List<String> docTypes, String where, String domain) {
         StringBuilder query = new StringBuilder("SELECT * FROM ");
         boolean fFirst = true;
-        for(String docType:docTypes) {
-               if(fFirst) {
+        for (String docType : docTypes) {
+            if (fFirst) {
                 fFirst = false;
-               } else {
-                       query.append(",");
-               }
+            } else {
+                query.append(",");
+            }
             query.append(docType);
         }
-        appendNXQLWhere(query, where, domain );
+        appendNXQLWhere(query, where, domain);
         return query.toString();
     }