diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java index 2625f69ab15ef513ed5cf9f9de140d27d20e2662..0863f2b12a2acc7e71a8dc76c738a1dd3c65063a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/RelationshipService.java @@ -65,6 +65,7 @@ public class RelationshipService implements IRelationshipService RelationshipUtils.updateModificationDateAndModifier(previousProject, session); experiment.setProject(project); RelationshipUtils.updateModificationDateAndModifier(project, session); + RelationshipUtils.updateModificationDateAndModifier(experiment, session); } @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java index b82887f6119a75af309da02fee3bf39a8e65a7ed..f0a40adb4a5cee950f0c478e07ebb74374848b1b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java @@ -17,8 +17,11 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.Collection; +import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.hibernate.SessionFactory; @@ -72,7 +75,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Identifier; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder; import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityWithMetaprojects; +import ch.systemsx.cisd.openbis.generic.shared.dto.IModifierAndModificationDateBean; +import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE; import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE; import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; @@ -516,4 +522,58 @@ abstract class AbstractBusinessObject implements IDAOFactory { return daoFactory.getMetaprojectDAO(); } + + protected void updateProperties(EntityTypePE entityType, List<IEntityProperty> properties, + IEntityPropertiesHolder entityAsPropertiesHolder, + IModifierAndModificationDateBean entityAsModifiableBean) + { + Set<? extends EntityPropertyPE> existingProperties = + entityAsPropertiesHolder.getProperties(); + Map<String, Object> existingPropertyValuesByCode = new HashMap<String, Object>(); + for (EntityPropertyPE existingProperty : existingProperties) + { + String propertyCode = + existingProperty.getEntityTypePropertyType().getPropertyType().getCode(); + existingPropertyValuesByCode.put(propertyCode, getValue(existingProperty)); + } + Set<? extends EntityPropertyPE> convertedProperties = + convertProperties(entityType, existingProperties, properties); + if (isEquals(existingPropertyValuesByCode, convertedProperties) == false) + { + entityAsPropertiesHolder.setProperties(convertedProperties); + entityAsModifiableBean.setModifier(findPerson()); + entityAsModifiableBean.setModificationDate(new Date()); + } + } + + private boolean isEquals(Map<String, Object> existingPropertyValuesByCode, + Set<? extends EntityPropertyPE> properties) + { + for (EntityPropertyPE property : properties) + { + Object existingValue = + existingPropertyValuesByCode.remove(property.getEntityTypePropertyType() + .getPropertyType().getCode()); + if (existingValue == null || existingValue.equals(getValue(property)) == false) + { + return false; + } + } + return existingPropertyValuesByCode.isEmpty(); + } + + private Object getValue(EntityPropertyPE property) + { + String value = property.getValue(); + if (value != null) + { + return value; + } + MaterialPE materialValue = property.getMaterialValue(); + if (materialValue != null) + { + return materialValue; + } + return property.getVocabularyTerm(); + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java index 46c03fedb53e85a58fc7974530241bd04ac53708..710d07404c3929a5c5240b95e1497e75b7ce6f90 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java @@ -19,7 +19,6 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -30,6 +29,7 @@ import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.collection.CollectionUtils; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService; +import ch.systemsx.cisd.openbis.generic.server.business.bo.util.RelationshipUtils; import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleUtils; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAttachmentDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; @@ -203,6 +203,10 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper + identifier); } final ExperimentPE exp = tryGetExperiment(identifier, project); + if (exp == null) + { + throw new UserFailureException("Unkown experiment: " + identifier); + } return exp; } @@ -341,6 +345,7 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper newExperiment.getProperties(), registrator); defineExperimentProject(newExperiment, experimentIdentifier); experiment.setPermId(getOrCreatePermID(newExperiment)); + RelationshipUtils.updateModificationDateAndModifier(experiment, session); setMetaprojects(experiment, newExperiment.getMetaprojectsOrNull()); dataChanged = true; } @@ -370,9 +375,8 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper { throw UserFailureException.fromTemplate(ERR_PROJECT_NOT_FOUND, newExperiment); } - project.setModificationDate(new Date()); - project.setModifier(findPerson()); experiment.setProject(project); + RelationshipUtils.updateModificationDateAndModifier(project, session); } private void defineExperimentType(NewExperiment newExperiment) @@ -457,7 +461,8 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper { throwModifiedEntityException("Experiment"); } - updateProperties(updates.getProperties()); + updateProperties(experiment.getEntityType(), updates.getProperties(), experiment, + experiment); ProjectPE project = findProject(updates.getProjectIdentifier()); ProjectPE previousProject = experiment.getProject(); @@ -612,14 +617,6 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper return project; } - @Private - void updateProperties(List<IEntityProperty> properties) - { - final Set<ExperimentPropertyPE> existingProperties = experiment.getProperties(); - final ExperimentTypePE type = experiment.getExperimentType(); - experiment.setProperties(convertProperties(type, existingProperties, properties)); - } - @Override public void updateManagedProperty(IManagedProperty managedProperty) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java index 35e4f5d9819b69e857bf1148d77f8eb9e7339fe3..be444b4859fc14a29f71042a6319f32449de8260 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java @@ -36,7 +36,6 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.sample.SampleIdenti import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.sample.SamplePermIdId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.sample.SampleTechIdId; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedProperty; @@ -316,7 +315,7 @@ public final class SampleBO extends AbstractSampleBusinessObject implements ISam { throwModifiedEntityException("Sample"); } - updateProperties(updates.getProperties()); + updateProperties(sample.getSampleType(), updates.getProperties(), sample, sample); spaceUpdated = updateSpace(sample, updates.getSampleIdentifier(), null); if (updates.isUpdateExperimentLink()) { @@ -334,13 +333,6 @@ public final class SampleBO extends AbstractSampleBusinessObject implements ISam dataChanged = true; } - private void updateProperties(List<IEntityProperty> properties) - { - final Set<SamplePropertyPE> existingProperties = sample.getProperties(); - final SampleTypePE type = sample.getSampleType(); - sample.setProperties(convertProperties(type, existingProperties, properties)); - } - private void updateParents(SampleUpdatesDTO updates) { String[] parentCodes = updates.getModifiedParentCodesOrNull(); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java index d495a6a4d22de86a4188ff635058ec530fd8b0ab..16626f5983c5540d6ff96ba92b3ad7b5799d6711 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java @@ -19,7 +19,6 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Set; @@ -422,23 +421,9 @@ public class ExperimentDAO extends AbstractGenericEntityWithPropertiesDAO<Experi { assert experiment != null : "Missing experiment."; experiment.setCode(CodeConverter.tryToDatabase(experiment.getCode())); - if (experiment.getModificationDate() == null) - { - experiment.setModificationDate(new Date()); - } validatePE(experiment); final HibernateTemplate template = getHibernateTemplate(); template.saveOrUpdate(experiment); - // Hibernate behaves as follows: If a PE bean property annotated with - // @OptimisticLock(excluded = true) (as it is the case for modifier and modification date) - // has changed the version will only be increased if a direct - // bean property (like project, but not properties or meta-projects) has also changed. This - // sounds like a bug. Thus, modifier and modification date is changed after the following - // flush in order to increase the version in case of changed properties or meta-projects. - template.flush(); - experiment.setModifier(modifier); - experiment.setModificationDate(new Date()); - template.saveOrUpdate(experiment); if (operationLog.isDebugEnabled()) { operationLog.debug(String.format("ADD: experiment '%s'.", experiment)); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java index 49c44a317d9a82b6c6ad96f4edcfe311e18aa93a..01c9cfcaca94532c84ce604fe85425ec984d67d0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java @@ -86,16 +86,8 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE> { sample.setModificationDate(new Date()); } - hibernateTemplate.saveOrUpdate(sample); - // Hibernate behaves as follows: If a PE bean property annotated with - // @OptimisticLock(excluded = true) (as it is the case for modifier and modification date) - // has changed the version will only be increased if a direct - // bean property (like space, but not properties or meta-projects) has also changed. This - // sounds like a bug. Thus, modifier and modification date is changed after the following - // flush in order to increase the version in case of changed properties or meta-projects. - hibernateTemplate.flush(); - sample.setModifier(modifier); - sample.setModificationDate(new Date()); + // sample.setModifier(modifier); + // sample.setModificationDate(new Date()); hibernateTemplate.saveOrUpdate(sample); if (doLog && operationLog.isInfoEnabled()) { diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java index 70a950cf9f313e02a9a0e26f92e995a24a6a09b9..8ddb532349aca86efe496353f9a0ec7b13263947 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java @@ -22,6 +22,7 @@ import static ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool.E import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -29,12 +30,14 @@ import java.util.Set; import org.jmock.Expectations; import org.springframework.dao.DataIntegrityViolationException; import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.test.AssertionUtil; import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; +import ch.systemsx.cisd.openbis.generic.server.util.TimeIntervalChecker; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; @@ -50,6 +53,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession; +import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder; +import ch.systemsx.cisd.openbis.generic.shared.dto.IModifierAndModificationDateBean; import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; @@ -82,11 +87,22 @@ public final class ExperimentBOTest extends AbstractBOTest private static final String EXP_CODE = "EXP-CODE"; + private IEntityPropertiesHolder entityAsPropertiesHolder; + + private IModifierAndModificationDateBean entityAsModifiableBean; + private final ExperimentBO createExperimentBO() { return new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, relationshipService); } + @BeforeMethod + public void setUp() + { + entityAsPropertiesHolder = context.mock(IEntityPropertiesHolder.class); + entityAsModifiableBean = context.mock(IModifierAndModificationDateBean.class); + } + @Test public void testLoadByExperimentIdentifier() throws Exception { @@ -100,13 +116,21 @@ public final class ExperimentBOTest extends AbstractBOTest private void prepareUpdateProperties(final Set<ExperimentPropertyPE> oldProperties, final List<IEntityProperty> newProperties, final EntityTypePE entityType, final PersonPE registrator, final List<ExperimentPropertyPE> updated) + { + final Set<ExperimentPropertyPE> newProps = new HashSet<ExperimentPropertyPE>(updated); + prepareUpdateProperties(oldProperties, newProperties, entityType, registrator, newProps); + } + + private void prepareUpdateProperties(final Set<ExperimentPropertyPE> oldProperties, + final List<IEntityProperty> newProperties, final EntityTypePE entityType, + final PersonPE registrator, final Set<ExperimentPropertyPE> newProps) { context.checking(new Expectations() { { one(propertiesConverter).updateProperties(oldProperties, entityType, newProperties, registrator, Collections.<String> emptySet()); - will(returnValue(new HashSet<ExperimentPropertyPE>(updated))); + will(returnValue(newProps)); } }); @@ -205,6 +229,7 @@ public final class ExperimentBOTest extends AbstractBOTest final ProjectPE project = createProject(dbCode, groupCode, projectCode); final ExperimentTypePE type = createExperimentType(expTypeCode); final ExperimentPE experiment = createExperiment(project, expCode, type); + TimeIntervalChecker timeIntervalChecker = new TimeIntervalChecker(); prepareAnyDaoCreation(); context.checking(new Expectations() @@ -233,6 +258,12 @@ public final class ExperimentBOTest extends AbstractBOTest experimentBO.define(newExperiment); experimentBO.save(); + assertEquals(EXAMPLE_PERSON, experimentBO.getExperiment().getModifier()); + assertEquals(EXAMPLE_PERSON, experimentBO.getExperiment().getProject().getModifier()); + timeIntervalChecker + .assertDateInInterval(experimentBO.getExperiment().getModificationDate()); + timeIntervalChecker.assertDateInInterval(experimentBO.getExperiment().getProject() + .getModificationDate()); context.assertIsSatisfied(); } @@ -423,23 +454,223 @@ public final class ExperimentBOTest extends AbstractBOTest new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); bo.loadByExperimentIdentifier(identifier); - assertTrue(bo.getExperiment().getProperties().contains(changedProperty)); - assertTrue(bo.getExperiment().getProperties().contains(deletedProperty)); - assertFalse(bo.getExperiment().getProperties().contains(addedProperty)); + ExperimentPE experiment = bo.getExperiment(); + assertTrue(experiment.getProperties().contains(changedProperty)); + assertTrue(experiment.getProperties().contains(deletedProperty)); + assertFalse(experiment.getProperties().contains(addedProperty)); final List<IEntityProperty> newProperties = createDummyProperties(); prepareUpdateProperties(exp.getProperties(), newProperties, experimentType, ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), Arrays.asList(changedProperty, addedProperty)); - bo.updateProperties(newProperties); + bo.updateProperties(experiment.getEntityType(), newProperties, experiment, experiment); + + assertTrue(experiment.getProperties().contains(changedProperty)); + assertFalse(experiment.getProperties().contains(deletedProperty)); + assertTrue(experiment.getProperties().contains(addedProperty)); + + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesWithSameProperties() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createNotesProperty(entityType); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), + Arrays.asList(materialProp, stringProp, termProp)); + prepareEntity(existingProperties, null); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); - assertTrue(bo.getExperiment().getProperties().contains(changedProperty)); - assertFalse(bo.getExperiment().getProperties().contains(deletedProperty)); - assertTrue(bo.getExperiment().getProperties().contains(addedProperty)); + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesOfUnchangedProperties() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE materialProp2 = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createNotesProperty(entityType); + ExperimentPropertyPE stringProp2 = CommonTestUtils.createNotesProperty(entityType); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + ExperimentPropertyPE termProp2 = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), + Arrays.asList(stringProp2, materialProp2, termProp2)); + prepareEntity(existingProperties, null); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); context.assertIsSatisfied(); } + @Test + public void testUpdatePropertiesOfChangedStringProperty() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createStringProperty(entityType, "alpha"); + ExperimentPropertyPE changedStringProp = + CommonTestUtils.createStringProperty(entityType, "beta"); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + final Set<ExperimentPropertyPE> newConvertedProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, changedStringProp, + termProp)); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), newConvertedProperties); + prepareEntity(existingProperties, newConvertedProperties); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); + + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesOfChangedMaterialProperty() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE changedMaterialProp = + CommonTestUtils.createMaterialProperty(entityType, "BETA"); + ExperimentPropertyPE stringProp = CommonTestUtils.createStringProperty(entityType, "alpha"); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + final Set<ExperimentPropertyPE> newConvertedProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(changedMaterialProp, stringProp, + termProp)); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), newConvertedProperties); + prepareEntity(existingProperties, newConvertedProperties); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); + + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesOfChangedTermProperty() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createStringProperty(entityType, "alpha"); + ExperimentPropertyPE termProp = + CommonTestUtils.createTermProperty(entityType, CommonTestUtils.BRAIN); + ExperimentPropertyPE changedTermProp = + CommonTestUtils.createTermProperty(entityType, CommonTestUtils.LEG); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + final Set<ExperimentPropertyPE> newConvertedProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, + changedTermProp)); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), newConvertedProperties); + prepareEntity(existingProperties, newConvertedProperties); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); + + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesOfWithAddedTermProperty() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createStringProperty(entityType, "alpha"); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + final Set<ExperimentPropertyPE> newConvertedProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), newConvertedProperties); + prepareEntity(existingProperties, newConvertedProperties); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); + + context.assertIsSatisfied(); + } + + @Test + public void testUpdatePropertiesOfWithRemovedMaterialProperty() + { + ExperimentTypePE entityType = CommonTestUtils.createExperimentType(); + ExperimentPropertyPE materialProp = CommonTestUtils.createMaterialProperty(entityType); + ExperimentPropertyPE stringProp = CommonTestUtils.createStringProperty(entityType, "alpha"); + ExperimentPropertyPE termProp = CommonTestUtils.createOrganProperty(entityType); + final Set<ExperimentPropertyPE> existingProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(materialProp, stringProp, termProp)); + List<IEntityProperty> newProperties = createDummyProperties(); + final Set<ExperimentPropertyPE> newConvertedProperties = + new HashSet<ExperimentPropertyPE>(Arrays.asList(stringProp, termProp)); + prepareUpdateProperties(existingProperties, newProperties, entityType, + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(), newConvertedProperties); + prepareEntity(existingProperties, newConvertedProperties); + ExperimentBO bo = + new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, propertiesConverter); + + bo.updateProperties(entityType, newProperties, entityAsPropertiesHolder, + entityAsModifiableBean); + + context.assertIsSatisfied(); + } + + private void prepareEntity(final Set<ExperimentPropertyPE> existingProperties, + final Set<ExperimentPropertyPE> newConvertedPropertiesOrNull) + { + context.checking(new Expectations() + { + { + one(entityAsPropertiesHolder).getProperties(); + will(returnValue(existingProperties)); + + if (newConvertedPropertiesOrNull != null) + { + one(entityAsPropertiesHolder).setProperties(newConvertedPropertiesOrNull); + one(entityAsModifiableBean).setModifier( + ManagerTestTool.EXAMPLE_SESSION.tryGetPerson()); + one(entityAsModifiableBean).setModificationDate(with(any(Date.class))); + } + } + }); + } + private List<IEntityProperty> createDummyProperties() { return new ArrayList<IEntityProperty>(); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java index dca8068f337b4ec050e76ac951b770a66bd68d10..1178c05c2fc5afbe6d6e0add0d7376864de4947c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.generic.shared; +import static ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool.EXAMPLE_SESSION; + import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -68,9 +70,9 @@ public class CommonTestUtils { public static final VocabularyTermPE BRAIN = createVocabularyTerm("BRAIN"); - private static final VocabularyTermPE LEG = createVocabularyTerm("LEG"); + public static final VocabularyTermPE LEG = createVocabularyTerm("LEG"); - private static final VocabularyTermPE HEAD = createVocabularyTerm("HEAD"); + public static final VocabularyTermPE HEAD = createVocabularyTerm("HEAD"); public static final TechId TECH_ID = new TechId(1L); @@ -137,26 +139,52 @@ public class CommonTestUtils } public static ExperimentPropertyPE createNotesProperty(ExperimentTypePE experimentType) + { + return createStringProperty(experimentType, "Check the impact on the hand on 03/04/2008."); + } + + public static ExperimentPropertyPE createStringProperty(ExperimentTypePE experimentType, + String value) { ExperimentTypePropertyTypePE notesAssignment = createAssignment(ExamplePropertyTypes.NOTES, experimentType); ExperimentPropertyPE deleted = new ExperimentPropertyPE(); deleted.setEntityTypePropertyType(notesAssignment); - deleted.setValue("Check the impact on the hand on 03/04/2008."); + deleted.setValue(value); return deleted; } public static ExperimentPropertyPE createOrganProperty(ExperimentTypePE experimentType) { + return createTermProperty(experimentType, BRAIN); + } + public static ExperimentPropertyPE createTermProperty(ExperimentTypePE experimentType, + VocabularyTermPE term) + { ExperimentTypePropertyTypePE organAssignment = createAssignment(ExamplePropertyTypes.INFECTED_ORGAN, experimentType); ExperimentPropertyPE changed = new ExperimentPropertyPE(); changed.setEntityTypePropertyType(organAssignment); - changed.setVocabularyTerm(CommonTestUtils.BRAIN); + changed.setVocabularyTerm(term); return changed; } + public static ExperimentPropertyPE createMaterialProperty(ExperimentTypePE experimentType) + { + return createMaterialProperty(experimentType, "ABCD"); + } + + public static ExperimentPropertyPE createMaterialProperty(ExperimentTypePE experimentType, + String materialCode) + { + ExperimentPropertyPE property = new ExperimentPropertyPE(); + property.setEntityTypePropertyType(createAssignment(ExamplePropertyTypes.INFECTING_VIRUS, + experimentType)); + property.setMaterialValue(createMaterial(VIRUS, materialCode)); + return property; + } + public static ExperimentTypePropertyTypePE createAssignment(PropertyTypePE propertyType, ExperimentTypePE type) { @@ -371,6 +399,16 @@ public class CommonTestUtils return attachmentContentPE; } + public static MaterialPE createMaterial(MaterialTypePE materialType, String code) + { + final MaterialPE material = new MaterialPE(); + material.setCode(code); + material.setMaterialType(materialType); + material.setDatabaseInstance(CommonTestUtils.createHomeDatabaseInstance()); + material.setRegistrator(EXAMPLE_SESSION.tryGetPerson()); + return material; + } + public static MaterialTypePE createMaterialType() { return createMaterialType(MATERIAL_TYPE_VIRUS); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/optimistic_locking/ExperimentOptimisticLockingTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/optimistic_locking/ExperimentOptimisticLockingTest.java index 6e259f5358857806302da62a7ae307fa28ab2296..3f027e6a971e1581f1cabd702f85bfb0aba64f8d 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/optimistic_locking/ExperimentOptimisticLockingTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/optimistic_locking/ExperimentOptimisticLockingTest.java @@ -214,6 +214,7 @@ public class ExperimentOptimisticLockingTest extends OptimisticLockingTestCase Experiment experiment = toolBox.createAndLoadExperiment(1); toolBox.createAndLoadSample(1, experiment); ExperimentUpdatesDTO update = new ExperimentUpdatesDTO(); + update.setVersion(toolBox.loadExperiment(experiment).getVersion()); update.setExperimentId(new TechId(experiment)); update.setSampleCodes(new String[0]); update.setProperties(ToolBox.NO_PROPERTIES);