From ad3c6fd26476d61bd6f9d8f89d6b36335e1a41d6 Mon Sep 17 00:00:00 2001
From: gakin <gakin>
Date: Thu, 17 Dec 2015 10:35:41 +0000
Subject: [PATCH] SSDMSSDM-2898 : Automatically created sample codes should
 form a continuous sequence (working  prototype)

SVN: 35356
---
 .../business/bo/EntityCodeGenerator.java      | 60 ++++++++++++++++++-
 .../server/dataaccess/db/DAOFactory.java      |  5 ++
 .../openbis/generic/shared/Constants.java     |  2 +
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityCodeGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityCodeGenerator.java
index 7daa170219b..809473b63e9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityCodeGenerator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityCodeGenerator.java
@@ -22,8 +22,11 @@ import java.util.List;
 import net.lemnik.eodsql.BaseQuery;
 import net.lemnik.eodsql.QueryTool;
 import net.lemnik.eodsql.Select;
-
+import ch.systemsx.cisd.common.properties.PropertyUtils;
+import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.DAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.Constants;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
 
@@ -38,10 +41,15 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
  */
 public class EntityCodeGenerator
 {
+
     private final IDAOFactory daoFactory;
 
     private final CountQuery countQuery;
 
+    private final MaxQuery maxQuery;
+
+    private boolean isCreateContinuousSampleCodes;
+
     public static interface CountQuery extends BaseQuery
     {
         public final static String PREFIX = "SELECT count(*) FROM ";
@@ -61,10 +69,27 @@ public class EntityCodeGenerator
         public int getMaterialsCount(String code);
     }
 
+    public static interface MaxQuery extends BaseQuery
+    {
+        @Select(sql = "SELECT max(substr(code, length(?{1})+1)::int) "
+                + "FROM samples WHERE code similar to ?{1} || '[1234567890]+'")
+        public int getMaxCode(String prefix);
+    }
+
     public EntityCodeGenerator(IDAOFactory daoFactory)
     {
         this.daoFactory = daoFactory;
+        if (daoFactory instanceof DAOFactory)
+        {
+            ExposablePropertyPlaceholderConfigurer configurer = ((DAOFactory) daoFactory).getExposablePropertyPlaceholderConfigurer();
+            this.isCreateContinuousSampleCodes =
+                    PropertyUtils.getBoolean(configurer.getResolvedProps(), Constants.CREATE_CONTINUOUS_SAMPLES_CODES_KEY, false);
+        } else
+        {
+            this.isCreateContinuousSampleCodes = false;
+        }
         this.countQuery = QueryTool.getManagedQuery(CountQuery.class);
+        this.maxQuery = QueryTool.getManagedQuery(MaxQuery.class);
     }
 
     public String generateCode(String codePrefix, EntityKind entityKind)
@@ -82,6 +107,38 @@ public class EntityCodeGenerator
      * @param numberOfCodes Number of codes to be generated.
      */
     public List<String> generateCodes(String codePrefix, EntityKind entityKind, int numberOfCodes)
+    {
+        if (isCreateContinuousSampleCodes && entityKind == EntityKind.SAMPLE)
+        {
+            return generateContinuousSampleCodes(codePrefix, entityKind, numberOfCodes);
+        }
+        else
+        {
+            return generateCodesFromSequence(codePrefix, entityKind, numberOfCodes);
+        }
+    }
+
+    private List<String> generateContinuousSampleCodes(String codePrefix, EntityKind entityKind, int numberOfCodes)
+    {
+        int maxCode = maxQuery.getMaxCode(codePrefix);
+        final String[] codes = new String[numberOfCodes];
+        for (int i = 0; i < numberOfCodes; i++)
+        {
+            String code;
+
+            do
+            {
+                maxCode++;
+                code = codePrefix + maxCode;
+            } while (isCodeUsed(code, entityKind));
+
+            codes[i] = code;
+        }
+
+        return Arrays.asList(codes);
+    }
+
+    private List<String> generateCodesFromSequence(String codePrefix, EntityKind entityKind, int numberOfCodes)
     {
         final String[] codes = new String[numberOfCodes];
         for (int i = 0; i < numberOfCodes; i++)
@@ -125,5 +182,4 @@ public class EntityCodeGenerator
 
         return count > 0;
     }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
index 54c9b591c8a..2d49441052e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
@@ -371,4 +371,9 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
         }
     }
 
+    public ExposablePropertyPlaceholderConfigurer getExposablePropertyPlaceholderConfigurer()
+    {
+        return configurer;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/Constants.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/Constants.java
index 2e04d738d22..7b1f1eddfc9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/Constants.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/Constants.java
@@ -34,4 +34,6 @@ public class Constants
     public static final int DEFAULT_SPEED_HINT = -MAX_SPEED / 2;
 
     public static final String PROJECT_SAMPLES_ENABLED_KEY = "project-samples-enabled";
+
+    public static final String CREATE_CONTINUOUS_SAMPLES_CODES_KEY = "create-continuous-sample-codes";
 }
-- 
GitLab