From 7b718f4f77b80a1ce559ebd7bfe4834b46172e8c Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Tue, 17 Nov 2009 14:38:33 +0000
Subject: [PATCH] [LMS-1263] added dataset tracking (simple version - without
 loading of sample properties, is complete)

SVN: 13429
---
 .../generic/server/TrackingServer.java        | 14 ++++++-------
 .../entity/ISecondaryEntityListingQuery.java  |  8 +++++++
 .../bo/common/entity/SecondaryEntityDAO.java  | 13 ++++++++++++
 .../bo/datasetlister/DatasetLister.java       | 10 +++++++++
 .../bo/datasetlister/IDatasetLister.java      |  8 ++++++-
 .../datasetlister/IDatasetListingQuery.java   |  9 ++++++++
 .../bo/samplelister/ISampleListingQuery.java  | 10 +++++----
 .../bo/samplelister/SampleListingWorker.java  | 21 +++----------------
 .../basic/dto/TrackingDataSetCriteria.java    |  1 +
 .../basic/dto/TrackingSampleCriteria.java     |  1 +
 .../openbis/generic/OpenbisClientTest.java    |  4 ++--
 11 files changed, 67 insertions(+), 32 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
index 65e5de11533..8c45863eda1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.ITrackingServer;
@@ -47,11 +48,6 @@ public final class TrackingServer extends AbstractServer<ITrackingServer> implem
         return businessObjectFactory;
     }
 
-    // private static UserFailureException createUserFailureException(final DataAccessException ex)
-    // {
-    // return new UserFailureException(ex.getMostSpecificCause().getMessage(), ex);
-    // }
-
     //
     // IInvocationLoggerFactory
     //
@@ -71,13 +67,17 @@ public final class TrackingServer extends AbstractServer<ITrackingServer> implem
 
     public List<ExternalData> listDataSets(String sessionToken, TrackingDataSetCriteria criteria)
     {
-        // TODO 2009-11-06, Piotr Buczek: implement
-        return null;
+        final Session session = getSession(sessionToken);
+
+        final IDatasetLister datasetLister =
+                businessObjectFactory.createDatasetLister(session, getDataStoreBaseURL());
+        return datasetLister.listByTrackingCriteria(criteria);
     }
 
     public List<Sample> listSamples(String sessionToken, TrackingSampleCriteria criteria)
     {
         final Session session = getSession(sessionToken);
+
         final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session);
         return sampleLister.list(new ListOrSearchSampleCriteria(criteria));
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
index 0c5d253f357..d59f389c85c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
@@ -96,4 +96,12 @@ public interface ISecondaryEntityListingQuery extends TransactionQuery
      */
     @Select("select id from groups where code=?{1}")
     public long getGroupIdForCode(String groupCode);
+
+    /**
+     * Returns the technical id of a sample type for given <var>sampleTypeCode</code> or
+     * <code>null</code> if such sample type doesn't exist.
+     */
+    @Select("select id from sample_types where code=?{1} and dbin_id=?{2}")
+    public Long getSampleTypeIdForSampleTypeCode(String sampleTypeCode, long dbInstanceId);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
index 7390a887b4d..a836194d7f3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
@@ -29,6 +29,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
 
 import ch.rinn.restrictions.Friend;
 import ch.rinn.restrictions.Private;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.DatabaseContextUtils;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
@@ -141,6 +142,18 @@ public class SecondaryEntityDAO
         return registrator;
     }
 
+    public Long getSampleTypeIdForSampleTypeCode(String sampleTypeCode)
+    {
+        Long id = query.getSampleTypeIdForSampleTypeCode(sampleTypeCode, databaseInstance.getId());
+        if (id == null)
+        {
+            throw UserFailureException
+                    .fromTemplate("No sample type with code '%s' could be found in the database.",
+                            sampleTypeCode);
+        }
+        return id;
+    }
+
     public Group[] getAllGroups(long databaseInstanceId)
     {
         return query.getAllGroups(databaseInstanceId);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
index 7f6e4a76f71..70ac7f59eee 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
@@ -50,6 +50,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Invalidation;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LocatorType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataStoreTranslator;
 
 /**
@@ -174,6 +175,15 @@ public class DatasetLister implements IDatasetLister
         return enrichDatasets(query.getDatasets(new LongOpenHashSet(datasetIds)));
     }
 
+    public List<ExternalData> listByTrackingCriteria(TrackingDataSetCriteria criteria)
+    {
+        Long sampleTypeId =
+                referencedEntityDAO.getSampleTypeIdForSampleTypeCode(criteria
+                        .getConnectedSampleTypeCode());
+        return enrichDatasets(query.getNewDataSetsForSampleType(sampleTypeId, criteria
+                .getLastSeenDataSetId()));
+    }
+
     private List<ExternalData> enrichDatasets(Iterable<DatasetRecord> datasets)
     {
         loadSmallConnectedTables();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
index 10c9ebc7b7d..0418e32ed69 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
 
 /**
  * A class for fast dataset listing.
@@ -33,6 +34,7 @@ public interface IDatasetLister
     List<ExternalData> listByExperimentTechId(TechId experimentId);
 
     // TODO 2009-09-10, Piotr Buczek: write tests
+
     /**
      * @return datasets connected to the sample with the specified id
      * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also
@@ -45,8 +47,12 @@ public interface IDatasetLister
 
     /** @return datasets that are parents of a dataset with the specified id */
     List<ExternalData> listByParentTechId(TechId parentDatasetId);
-	//
+
+    //
 
     /** @return datasets with given ids */
     List<ExternalData> listByDatasetIds(Collection<Long> datasetIds);
+
+    /** @return datasets specified by given criteria */
+    List<ExternalData> listByTrackingCriteria(TrackingDataSetCriteria criteria);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
index 741b4076aa3..bacfdadb935 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
@@ -58,6 +58,15 @@ public interface IDatasetListingQuery extends TransactionQuery, IPropertyListing
     @Select(sql = "select * from data join external_data on data.id = external_data.data_id where data.samp_id=?{1}", fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRecord> getDatasetsForSample(long sampleId);
 
+    /**
+     * Returns datasets that are newer than dataset with given id (<var>lastSeenDatasetId</var>) and
+     * are directly connected with samples of sample type with given <var>sampleTypeId</var>.
+     */
+    @Select(sql = "SELECT * FROM data JOIN external_data ON data.id = external_data.data_id"
+            + "    WHERE data.id > ?{2} AND data.samp_id IN (SELECT id FROM samples s WHERE s.saty_id=?{1})", fetchSize = FETCH_SIZE)
+    public DataIterator<DatasetRecord> getNewDataSetsForSampleType(long sampleTypeId,
+            int lastSeenDatasetId);
+
     /**
      * Returns the directly connected dataset ids for the given sample id.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
index 5d54cbaa5c1..c203a16118f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
@@ -159,17 +159,19 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
     public DataIterator<SampleRecord> getSamplesForContainer(long sampleContainerId);
 
     //
-    // Samples of type
+    // New samples of type
     //
 
     /**
-     * Returns all samples for the given <var>sampleTypeId</var>.
+     * Returns all samples of sample type with given <var>sampleTypeId</var> that are newer than
+     * sample with given id (<var>lastSeenSampleId</var>).
      */
     @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, s.dbin_id, "
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
-            + "   from samples s where s.saty_id=?{1} order by s.code", fetchSize = FETCH_SIZE)
-    public DataIterator<SampleRecord> getSamplesForSampleType(long sampleTypeId);
+            + "   from samples s where s.saty_id=?{1} and s.id > ?{2} order by s.code", fetchSize = FETCH_SIZE)
+    public DataIterator<SampleRecord> getNewSamplesForSampleType(long sampleTypeId,
+            int lastSeenSampleId);
 
     //
     // Shared samples
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
index ff3dab63cbf..f164ae69487 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
@@ -31,7 +31,6 @@ import org.apache.commons.lang.time.StopWatch;
 import org.apache.log4j.Logger;
 
 import ch.rinn.restrictions.Friend;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.EntityPropertiesEnricher;
@@ -395,23 +394,9 @@ final class SampleListingWorker
         {
             return null;
         }
-        SampleType sampleTypeOrNull = null;
-        for (SampleType sampleType : sampleTypes.values())
-        {
-            if (sampleType.getCode().equals(sampleTypeCode))
-            {
-                sampleTypeOrNull = sampleType;
-            }
-        }
-        if (sampleTypeOrNull != null)
-        {
-            return query.getSamplesForSampleType(sampleTypeOrNull.getId());
-        } else
-        {
-            throw UserFailureException
-                    .fromTemplate("No sample type with code '%s' could be found in the database.",
-                            sampleTypeCode);
-        }
+        Long sampleTypeId =
+                referencedEntityDAO.getSampleTypeIdForSampleTypeCode(criteria.getSampleTypeCode());
+        return query.getNewSamplesForSampleType(sampleTypeId, criteria.getLastSeenSampleId());
     }
 
     private void retrievePrimaryBasicSamples(final Iterable<SampleRecord> sampleIteratorOrNull)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingDataSetCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingDataSetCriteria.java
index 7eb7f31088c..723124b6688 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingDataSetCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingDataSetCriteria.java
@@ -40,6 +40,7 @@ public class TrackingDataSetCriteria implements IsSerializable, Serializable
 
     public TrackingDataSetCriteria(String connectedSampleTypeCode, int lastSeenDataSetId)
     {
+        assert connectedSampleTypeCode != null;
         this.lastSeenDataSetId = lastSeenDataSetId;
         this.connectedSampleTypeCode = connectedSampleTypeCode;
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingSampleCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingSampleCriteria.java
index a5d5191cf85..49afa5e79df 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingSampleCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/TrackingSampleCriteria.java
@@ -38,6 +38,7 @@ public class TrackingSampleCriteria implements Serializable
 
     public TrackingSampleCriteria(String sampleTypeCode, int lastSeenSampleId)
     {
+        assert sampleTypeCode != null;
         this.sampleTypeCode = sampleTypeCode;
         this.lastSeenSampleId = lastSeenSampleId;
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/OpenbisClientTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/OpenbisClientTest.java
index 75b4dbbdaa2..4cd7442c7ab 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/OpenbisClientTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/OpenbisClientTest.java
@@ -100,8 +100,8 @@ public class OpenbisClientTest
         SessionContextDTO session = trackingServer.tryToAuthenticate(USER_ID, USER_PASSWORD);
 
         final String sampleTypeCode = "CELL_PLATE";
-        final int lastSeenSampleId = 0;
-        final int lastSeenDataSetId = 0;
+        final int lastSeenSampleId = 1000; // compare with 0
+        final int lastSeenDataSetId = 3; // compare with 0
 
         final TrackingSampleCriteria sampleCriteria =
                 new TrackingSampleCriteria(sampleTypeCode, lastSeenSampleId);
-- 
GitLab