From 57a3b860178ba531c56cda4f4d88ff899bbe107b Mon Sep 17 00:00:00 2001
From: kaloyane <kaloyane>
Date: Wed, 16 Nov 2011 12:45:53 +0000
Subject: [PATCH] [LMS-2640] fixed + tested

SVN: 23688
---
 .../server/business/bo/EntityTypeBO.java      | 13 ++++
 .../server/dataaccess/IDeletionDAO.java       |  9 +++
 .../server/dataaccess/db/DeletionDAO.java     | 30 ++++++++
 .../openbis/generic/shared/basic/TechId.java  | 13 ++++
 .../generic/shared/dto/DeletedSamplePE.java   |  2 +-
 .../server/business/bo/EntityTypeBOTest.java  | 75 +++++++++++++++++++
 .../server/dataaccess/db/DeletionDAOTest.java | 32 ++++++++
 7 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBOTest.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBO.java
index 981e09aff45..3ffd440bfca 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBO.java
@@ -16,10 +16,13 @@
 
 package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
+import java.util.List;
+
 import org.springframework.dao.DataAccessException;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
@@ -131,6 +134,16 @@ public final class EntityTypeBO extends AbstractBusinessObject implements IEntit
         assert entityTypePE != null : "Type not loaded";
         try
         {
+            List<TechId> entitiesInTrash =
+                    getDeletionDAO().listDeletedEntitiesForType(entityKind,
+                            new TechId(entityTypePE.getId()));
+            if (false == entitiesInTrash.isEmpty())
+            {
+                throw UserFailureException.fromTemplate(
+                        "'%s' is referred from entities in the trash can. "
+                                + "Please empty the trash can and try deleting it again.",
+                        entityTypePE.getCode());
+            }
             getEntityTypeDAO(entityKind).deleteEntityType(entityTypePE);
         } catch (final DataAccessException e)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDeletionDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDeletionDAO.java
index e46db729683..bb1ca091499 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDeletionDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDeletionDAO.java
@@ -77,5 +77,14 @@ public interface IDeletionDAO extends IGenericDAO<DeletionPE>
     /** Returns list of deletions with given ids */
     List<DeletionPE> findAllById(List<Long> ids);
 
+    /**
+     * Returns a list of all deleted entites by their IDs.
+     */
     List<? extends IDeletablePE> listDeletedEntities(EntityKind entityKind, List<TechId> entityIds);
+
+    /**
+     * Returns a list of all deleted entities for a given type id.
+     */
+    List<TechId> listDeletedEntitiesForType(EntityKind entityKind, TechId entityTypeId);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAO.java
index 0c2be91e575..b70533e81ef 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAO.java
@@ -324,4 +324,34 @@ final class DeletionDAO extends AbstractGenericEntityDAO<DeletionPE> implements
         criteria.add(Restrictions.in(ID, ids));
         return cast(getHibernateTemplate().findByCriteria(criteria));
     }
+
+    public List<TechId> listDeletedEntitiesForType(EntityKind entityKind, TechId entityTypeId)
+    {
+        String typeId = null;
+        switch (entityKind)
+        {
+            case EXPERIMENT:
+                typeId = "experimentType.id";
+                break;
+
+            case SAMPLE:
+                typeId = "sampleType.id";
+                break;
+
+            case DATA_SET:
+                typeId = "dataSetType.id";
+                break;
+
+            default:
+                // entities of these types cannot be in the trash can
+                return Collections.emptyList();
+        }
+
+        DetachedCriteria criteria = DetachedCriteria.forClass(entityKind.getDeletedEntityClass());
+        criteria.setProjection(Projections.id());
+        criteria.add(Restrictions.eq(typeId, entityTypeId.getId()));
+
+        List<Long> result = cast(getHibernateTemplate().findByCriteria(criteria));
+        return TechId.createList(result);
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TechId.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TechId.java
index 309027b6cb1..5683b4a8a4d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TechId.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TechId.java
@@ -84,6 +84,19 @@ public class TechId implements IIdHolder, Serializable
         return result;
     }
 
+    /**
+     * Convenience method for getting a list of technical ids from collection of longs.
+     */
+    public static List<TechId> createList(List<Long> ids)
+    {
+        List<TechId> result = new ArrayList<TechId>();
+        for (Long id : ids)
+        {
+            result.add(new TechId(id));
+        }
+        return result;
+    }
+
     /**
      * Convenience method for getting a list of technical ids from given list of objects with
      * identifiers.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DeletedSamplePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DeletedSamplePE.java
index 5fc7702fbba..98eb9eac7ae 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DeletedSamplePE.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DeletedSamplePE.java
@@ -53,7 +53,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.util.EqualsHashUtils;
 
 /**
- * Persistence Entity representing deleted experiment.
+ * Persistence Entity representing deleted sample.
  * 
  * @author Piotr Buczek
  */
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBOTest.java
new file mode 100644
index 00000000000..2d0ba67e532
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/EntityTypeBOTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.server.business.bo;
+
+import static ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool.EXAMPLE_SESSION;
+
+import java.util.Arrays;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.builders.SampleTypePEBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * @author Kaloyan Enimanev
+ */
+public class EntityTypeBOTest extends AbstractBOTest
+{
+
+    @Test
+    public void testDeleteReferencedFromTrashCan()
+    {
+        final String sampleTypeCode = "SAMPLE_TYPE";
+        final IEntityTypeBO entityTypeBO = new EntityTypeBO(daoFactory, EXAMPLE_SESSION);
+        final EntityKind entityKind = EntityKind.SAMPLE;
+        final SampleTypePE sampleType =
+                new SampleTypePEBuilder().id(1).code(sampleTypeCode).getSampleType();
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(daoFactory).getEntityTypeDAO(entityKind);
+                    will(returnValue(entityTypeDAO));
+
+                    one(entityTypeDAO).tryToFindEntityTypeByCode(sampleType.getCode());
+                    will(returnValue(sampleType));
+
+                    one(deletionDAO).listDeletedEntitiesForType(entityKind,
+                            new TechId(sampleType.getId()));
+                    will(returnValue(Arrays.asList(1L, 2L)));
+                }
+            });
+
+        entityTypeBO.load(entityKind, sampleTypeCode);
+        try
+        {
+            entityTypeBO.delete();
+            fail("UserFailureException expected");
+        } catch (UserFailureException ufe)
+        {
+            assertEquals("'SAMPLE_TYPE' is referred from entities in the trash can. Please empty "
+                    + "the trash can and try deleting it again.", ufe.getMessage());
+        }
+
+        context.assertIsSatisfied();
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAOTest.java
index 393998f325d..9b7f11ddd5c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DeletionDAOTest.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 
 import java.util.Collections;
@@ -28,13 +29,16 @@ import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDeletionDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
  * @author Piotr Buczek
@@ -125,6 +129,34 @@ public class DeletionDAOTest extends AbstractDAOTest
                 .getRegistrationDate().getTime() < dateAfterRegistration.getTime());
     }
 
+    @Test
+    public void testFindDeletedEntities()
+    {
+        assertExistsDeletedEntity(EntityKind.EXPERIMENT, "SIRNA_HCS");
+        assertExistsDeletedEntity(EntityKind.SAMPLE, "WELL");
+        assertExistsDeletedEntity(EntityKind.DATA_SET, "HCS_IMAGE");
+    }
+
+    private void assertExistsDeletedEntity(EntityKind entityKind, String entityTypeCode)
+    {
+        IDeletionDAO deletionDAO = daoFactory.getDeletionDAO();
+
+        IEntityTypeDAO entityTypeDAO = daoFactory.getEntityTypeDAO(entityKind);
+        EntityTypePE entityType = entityTypeDAO.tryToFindEntityTypeByCode(entityTypeCode);
+
+        assertNotNull(
+                String.format("%s '%s' does not exist", entityKind.getLabel(), entityTypeCode),
+                entityType);
+
+        final List<TechId> deletedEntities =
+                deletionDAO.listDeletedEntitiesForType(entityKind, new TechId(entityType.getId()));
+
+        assertTrue(String.format("At least one deleted %s of type '%s'"
+                + " must exist in the test database", entityKind.getLabel(), entityTypeCode),
+                deletedEntities.size() > 0);
+
+    }
+
     @Test
     public void testRevertDeletion()
     {
-- 
GitLab