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 50644afd58f751dc1ae2ea3c0b0d6987bd08ec82..bf61d70e73ce1dfdac3500f56a75aaf97cc780a7 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 @@ -23,6 +23,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleUtils; import ch.systemsx.cisd.openbis.generic.server.dataaccess.RelationshipUtils; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.DAOFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; +import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; @@ -144,21 +145,17 @@ public class RelationshipService implements IRelationshipService public void assignDataSetToExperiment(IAuthSession session, DataPE data, ExperimentPE experimentOrNull) { RelationshipUtils.setExperimentForDataSet(data, experimentOrNull, session); - if (experimentOrNull != null) - { - RelationshipUtils.setSampleForDataSet(data, null, session); - } } @Override - public void assignDataSetToSample(IAuthSession session, DataPE data, SamplePE sampleOrNull) + public void assignDataSetToSample(IAuthSession session, DataPE data, SamplePE sample) { - if (sampleOrNull != null) + SamplePE currentSample = data.tryGetSample(); + if (equalEntities(currentSample, sample)) { - ExperimentPE experiment = sampleOrNull.getExperiment(); - RelationshipUtils.setExperimentForDataSet(data, experiment, session); + return; } - RelationshipUtils.setSampleForDataSet(data, sampleOrNull, session); + RelationshipUtils.setSampleForDataSet(data, sample, session); } @Override @@ -281,4 +278,16 @@ public class RelationshipService implements IRelationshipService return RelationshipUtils.getParentChildRelationshipType(daoFactory.getRelationshipTypeDAO()); } + private static <T extends IIdHolder >boolean equalEntities(T entity1OrNull, T entity2OrNull) + { + Long id1 = getIdOrNull(entity1OrNull); + Long id2 = getIdOrNull(entity2OrNull); + return id1 == null ? id1 == id2 : id1.equals(id2); + } + + private static Long getIdOrNull(IIdHolder idHolderOrNull) + { + return idHolderOrNull == null ? null : idHolderOrNull.getId(); + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java index c3c0c44ee1fbab34cfb651dfac762693a61aaecc..d9e66090a2a4088c8aa7024b3affb07108d8f5d8 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java @@ -34,6 +34,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetTypeWitho import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityPropertiesConverter; +import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE; @@ -118,30 +119,99 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti { throw createWrongSampleException(data, newSample, "the new sample is shared"); } - ExperimentPE experiment = newSample.getExperiment(); - String dataSetTypeCode = data.getDataSetType().getCode(); + assignDataSetToSampleAndExperiment(data, newSample, newSample.getExperiment()); + } + + private void assignDataSetToSampleAndExperiment(DataPE data, SamplePE newSample, ExperimentPE experiment) + { + List<DataSetSampleExperiment> assignments = new ArrayList<DataSetSampleExperiment>(); + gatherNewAssigments(assignments, data, data, newSample, experiment); + for (DataSetSampleExperiment assignment : assignments) + { + assignment.assignDataSet(relationshipService, session); + } + } + + private void gatherNewAssigments(List<DataSetSampleExperiment> assignments, + DataPE dataSet, DataPE rootDataSet, SamplePE sample, ExperimentPE experiment) + { + String dataSetTypeCode = dataSet.getDataSetType().getCode(); if (experiment == null && dataSetTypeChecker.isDataSetTypeWithoutExperiment(dataSetTypeCode) == false) { - throw createWrongSampleException(data, newSample, - "the new sample is not connected to any experiment"); + throw createWrongSampleException(dataSet, sample, + "the new sample is not connected to any experiment and the data set type (" + + dataSetTypeCode + ") doesn't match one of the following regular expressions: " + + dataSetTypeChecker.getRegularExpressions()); + } + if (rootDataSet == dataSet) + { + assignments.add(new DataSetSampleExperiment(dataSet, sample, experiment)); + } + SamplePE rootSample = rootDataSet.tryGetSample(); + ExperimentPE rootExperiment = getExperimentOf(rootDataSet); + List<DataPE> components = dataSet.getContainedDataSets(); + for (DataPE component : components) + { + SamplePE componentSample = component.tryGetSample(); + ExperimentPE componentExperiment = getExperimentOf(component); + if ((equalEntities(rootSample, componentSample) || componentSample == null) + && equalEntities(rootExperiment, componentExperiment)) + { + SamplePE newSample = componentSample == null && rootSample != null ? null : sample; + assignments.add(new DataSetSampleExperiment(component, newSample, experiment)); + gatherNewAssigments(assignments, component, rootDataSet, sample, experiment); + } } - - relationshipService.assignDataSetToSample(session, data, newSample); + } + + private ExperimentPE getExperimentOf(DataPE data) + { + SamplePE sample = data.tryGetSample(); + return sample == null ? data.getExperiment() : sample.getExperiment(); + } + + private static <T extends IIdHolder >boolean equalEntities(T entity1OrNull, T entity2OrNull) + { + Long id1 = getIdOrNull(entity1OrNull); + Long id2 = getIdOrNull(entity2OrNull); + return id1 == null ? id1 == id2 : id1.equals(id2); } - protected void updateExperiment(DataPE data, ExperimentIdentifier experimentIdentifier) + private static Long getIdOrNull(IIdHolder idHolderOrNull) { - assert experimentIdentifier != null; - ExperimentPE experiment = getExperimentByIdentifier(experimentIdentifier); - updateExperiment(data, experiment); + return idHolderOrNull == null ? null : idHolderOrNull.getId(); } - protected void updateExperiment(DataPE data, ExperimentPE experiment) + private static final class DataSetSampleExperiment { - if (experiment.equals(data.getExperiment()) == false) + private DataPE dataSet; + private SamplePE sample; + private ExperimentPE experiment; + + DataSetSampleExperiment(DataPE dataSet, SamplePE sample, ExperimentPE experiment) { - relationshipService.assignDataSetToExperiment(session, data, experiment); + this.dataSet = dataSet; + this.sample = sample; + this.experiment = experiment; } + + public void assignDataSet(IRelationshipService relationshipService, Session session) + { + if (equalEntities(dataSet.tryGetSample(), sample) == false) + { + relationshipService.assignDataSetToSample(session, dataSet, sample); + } + if (equalEntities(dataSet.getExperiment(), experiment) == false) + { + relationshipService.assignDataSetToExperiment(session, dataSet, experiment); + } + } + } + + protected void updateExperiment(DataPE data, ExperimentIdentifier experimentIdentifier) + { + assert experimentIdentifier != null; + assignDataSetToSampleAndExperiment(data, null, getExperimentByIdentifier(experimentIdentifier)); } protected ExperimentPE getExperimentByIdentifier(final ExperimentIdentifier identifier) @@ -155,9 +225,7 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti throw new UserFailureException("Unkown experiment because of unkown project: " + identifier); } - final ExperimentPE exp = - getExperimentDAO().tryFindByCodeAndProject(project, identifier.getExperimentCode()); - return exp; + return getExperimentDAO().tryFindByCodeAndProject(project, identifier.getExperimentCode()); } protected void setContainedDataSets(final DataPE container, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java index a4fd29fa9df561024c87aeddaf9bc30720345d73..fe6956e8ba1d67ba758954763a1dcf5be9419fff 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java @@ -616,10 +616,10 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO { // update sample and indirectly experiment updateSample(data, sampleIdentifierOrNull); - } else + } else if (updates.getExperimentIdentifierOrNull() != null) { - relationshipService.assignDataSetToSample(session, data, null); updateExperiment(data, updates.getExperimentIdentifierOrNull()); + relationshipService.assignDataSetToSample(session, data, null); } setParents(data, asListOrNull(updates.getModifiedParentDatasetCodesOrNull())); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetTypeWithoutExperimentChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetTypeWithoutExperimentChecker.java index 0841024ff0d99858e04a6904338b8765ba5fe6cf..fc9d912efb045eb3049639e8a549084465595337 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetTypeWithoutExperimentChecker.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetTypeWithoutExperimentChecker.java @@ -35,11 +35,13 @@ public class DataSetTypeWithoutExperimentChecker { public static final String PROPERTY_KEY = "data-set-types-with-no-experiment-needed"; - private List<Pattern> patternsForDataSetTypesWithoutExperiment = new ArrayList<Pattern>(); + private final String regularExpressions; + private List<Pattern> patternsForDataSetTypesWithoutExperiment = new ArrayList<Pattern>(); + public DataSetTypeWithoutExperimentChecker(Properties properties) { - String regularExpressions = properties.getProperty(PROPERTY_KEY); + regularExpressions = properties.getProperty(PROPERTY_KEY); if (StringUtils.isNotBlank(regularExpressions)) { String[] splittedRegexes = regularExpressions.split(","); @@ -57,6 +59,11 @@ public class DataSetTypeWithoutExperimentChecker } } + public String getRegularExpressions() + { + return regularExpressions; + } + public boolean isDataSetTypeWithoutExperiment(String dataSetTypeCode) { for (Pattern pattern : patternsForDataSetTypesWithoutExperiment) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java index ebff4c49f5e8cd1e8bd9c9afceeb34ec5c97aff4..b0f030f8903b9e7ab57382698eb9a0996f85c5e4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java @@ -637,13 +637,6 @@ public class DataPE extends AbstractIdAndCodeHolder<DataPE> implements if (experiment != null) { experiment.addDataSet(this); - for (DataPE contained : getContainedDataSets()) - { - if (false == contained.equals(this)) - { - contained.setExperiment(experiment); - } - } } else { ExperimentPE previous = getExperiment(); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/DataSetNode.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/DataSetNode.java index 7e6e22ea9dc1e7ec4e4e3474db666dd632c39456..a4e25ff5e772f160d2c036485a8b112cf3626d35 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/DataSetNode.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/DataSetNode.java @@ -103,7 +103,7 @@ public final class DataSetNode extends EntityNode @Override public String toString() { - StringBuilder builder = new StringBuilder(getCode()); + StringBuilder builder = new StringBuilder(super.toString()); if (deletable == false) { builder.append(" (non deletable)"); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/EntityNode.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/EntityNode.java index a049dd9cfe4616048458d5a183801035c729837a..dfa18463e03ef45c61612f98a6bc3112d85424d3 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/EntityNode.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/EntityNode.java @@ -18,7 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder; -public class EntityNode implements IIdHolder +public class EntityNode implements IIdHolder, Comparable<EntityNode> { private final long id; @@ -47,9 +47,32 @@ public class EntityNode implements IIdHolder { return type; } + + public String getCodeAndType() + { + StringBuilder builder = new StringBuilder(code); + if (type != null) + { + builder.append("[").append(type).append("]"); + } + return builder.toString(); + } public void setType(String type) { this.type = type; } + + @Override + public int compareTo(EntityNode that) + { + return this.getCode().compareTo(that.getCode()); + } + + @Override + public String toString() + { + return getCodeAndType(); + } + } \ No newline at end of file diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/ExperimentNode.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/ExperimentNode.java index d904a9513b61d5b791e1bacf2e2193ac8d06de42..5072c31effc24e9deeb3d6e521c19c761f3bc7a3 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/ExperimentNode.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/ExperimentNode.java @@ -60,7 +60,7 @@ public final class ExperimentNode extends EntityNode @Override public String toString() { - StringBuilder builder = new StringBuilder(getCode()); + StringBuilder builder = new StringBuilder(super.toString()); Utils.appendTo(builder, "samples", samples); Utils.appendTo(builder, "data sets", dataSets); return builder.toString(); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/SampleNode.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/SampleNode.java index 6a106977b85d922ad3dfe847811f557084391beb..b8fee0d01ee12211e453f62dfea73f89c8a15559 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/SampleNode.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/entitygraph/SampleNode.java @@ -98,7 +98,7 @@ public final class SampleNode extends EntityNode public String toString() { - StringBuilder builder = new StringBuilder(getCode()); + StringBuilder builder = new StringBuilder(super.toString()); Utils.appendTo(builder, "experiment", experiment); Utils.appendTo(builder, "children", children); Utils.appendTo(builder, "parents", parents); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignDataSetToSampleTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignDataSetToSampleTest.java index f0b54bb7a9f7ebd7e5f23ecf4b9bc96c42b393d0..cee14dbe3d7c4acf388ab3298e46d6499b50e43c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignDataSetToSampleTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignDataSetToSampleTest.java @@ -63,134 +63,234 @@ public class AssignDataSetToSampleTest extends BaseTest Space destinationSpace; @Test - public void dataSetReassignedFromExperimentToExperiment() + public void containerWithSomeComponentsReassignedFromExperimentToExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n" - + "E2, samples: S2\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2 DS4\n" + + "E2, samples: S2\n" + + "E3, data sets: DS3\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4"); reassignToExperiment(g.ds(1), g.e(2)); assertEquals("E1, samples: S1\n" - + "E2, samples: S2, data sets: DS1\n", renderGraph(g)); + + "E2, samples: S2, data sets: DS1 DS2 DS4\n" + + "E3, data sets: DS3\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4\n", renderGraph(g)); repository.assertModified(g.e(1), g.e(2)); - repository.assertModified(g.ds(1)); - repository.assertUnmodified(g.s(1), g.s(2)); + repository.assertModified(g.ds(1), g.ds(2), g.ds(4)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromExperimentToSampleWithExperiment() + public void containerWithSomeComponentsReassignedFromExperimentToSampleWithExperiment() + { + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2 DS4\n" + + "E2, samples: S2\n" + + "E3, data sets: DS3\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4"); + + reassignToSample(g.ds(1), g.s(2)); + + assertEquals("E1, samples: S1\n" + + "E2, samples: S2, data sets: DS1 DS2 DS4\n" + + "E3, data sets: DS3\n" + + "S2, data sets: DS1 DS2 DS4\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4\n", renderGraph(g)); + repository.assertModified(g.e(1), g.e(2)); + repository.assertModified(g.ds(1), g.ds(2), g.ds(4)); + repository.assertModified(g.s(2)); + repository.assertUnmodified(g); + } + + @Test + public void containerWithSomeComponentsReassignedFromExperimentToSampleWithExperiment2() { - EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS1\nE2, samples: S2\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2 DS4\n" + + "E2, samples: S2\n" + + "E3, data sets: DS3\n" + + "S1, data sets: DS2\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4"); + + reassignToSample(g.ds(1), g.s(2)); + + assertEquals("E1, samples: S1, data sets: DS2 DS4\n" + + "E2, samples: S2, data sets: DS1\n" + + "E3, data sets: DS3\n" + + "S1, data sets: DS2\n" + + "S2, data sets: DS1\n" + + "DS1, components: DS2 DS3\n" + + "DS2, components: DS4\n", renderGraph(g)); + repository.assertModified(g.e(1), g.e(2)); + repository.assertModified(g.s(2)); + repository.assertModified(g.ds(1)); + repository.assertUnmodified(g); + } + + @Test + public void containerWithAllItsComponentsReassignedFromExperimentToExperiment() + { + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2\n" + + "E2, samples: S2\n" + + "DS1, components: DS2\n"); + + reassignToExperiment(g.ds(1), g.e(2)); + + assertEquals("E1, samples: S1\n" + + "E2, samples: S2, data sets: DS1 DS2\n" + + "DS1, components: DS2\n", renderGraph(g)); + repository.assertModified(g.e(1), g.e(2)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); + } + + @Test + public void containerWithAllItsComponentsReassignedFromExperimentToSampleWithExperiment() + { + EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS1 DS2\n" + + "E2, samples: S2\n" + + "DS1, components: DS2\n"); reassignToSample(g.ds(1), g.s(2)); - assertEquals("E2, samples: S2, data sets: DS1\nS2, data sets: DS1\n", renderGraph(g)); + assertEquals("E2, samples: S2, data sets: DS1 DS2\n" + + "S2, data sets: DS1 DS2\n" + + "DS1, components: DS2\n", renderGraph(g)); repository.assertModified(g.e(1), g.e(2)); repository.assertModified(g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromExperimentToSampleWithoutExperiment() + public void containerWithAllItsComponentsReassignedFromExperimentToSampleWithoutExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1[NEXP-TYPE]\n" - + "S2\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1[NECT] DS2[NET]\n" + + "S2\n" + + "DS1[NECT], components: DS2[NET]\n"); reassignToSample(g.ds(1), g.s(2)); - assertEquals("E1, samples: S1\nS2, data sets: DS1[NEXP-TYPE]\n", renderGraph(g)); + assertEquals("E1, samples: S1\n" + + "S2, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n", renderGraph(g)); repository.assertModified(g.e(1)); - repository.assertUnmodified(g.s(1)); repository.assertModified(g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithExperimentToExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithExperimentToExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n" - + "E2, samples: S2\nS1, data sets: DS1\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2\n" + + "E2, samples: S2\n" + + "S1, data sets: DS1\n" + + "DS1, components: DS2"); reassignToExperiment(g.ds(1), g.e(2)); assertEquals("E1, samples: S1\n" - + "E2, samples: S2, data sets: DS1\n", renderGraph(g)); + + "E2, samples: S2, data sets: DS1 DS2\n" + + "DS1, components: DS2\n", renderGraph(g)); repository.assertModified(g.e(1), g.e(2)); repository.assertModified(g.s(1)); - repository.assertModified(g.ds(1)); - repository.assertUnmodified(g.s(2)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithExperimentToSampleWithExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithExperimentToSampleWithExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n" - + "E2, samples: S2\nS1, data sets: DS1\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1 DS2\n" + + "E2, samples: S2\n" + + "S1, data sets: DS1\n" + + "DS1, components: DS2"); reassignToSample(g.ds(1), g.s(2)); assertEquals("E1, samples: S1\n" - + "E2, samples: S2, data sets: DS1\nS2, data sets: DS1\n", renderGraph(g)); + + "E2, samples: S2, data sets: DS1 DS2\n" + + "S2, data sets: DS1\n" + + "DS1, components: DS2\n", renderGraph(g)); repository.assertModified(g.e(1), g.e(2)); repository.assertModified(g.s(1), g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithExperimentToSampleWithoutExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithExperimentToSampleWithoutExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1[NEXP-TYPE]\n" - + "S1, data sets: DS1[NEXP-TYPE]\nS2\n"); + EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1[NECT] DS2[NET]\n" + + "S1, data sets: DS1[NECT] DS2[NET]\n" + + "S2\n" + + "DS1[NECT], components: DS2[NET]\n"); reassignToSample(g.ds(1), g.s(2)); assertEquals("E1, samples: S1\n" - + "S2, data sets: DS1[NEXP-TYPE]\n", renderGraph(g)); + + "S2, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n", renderGraph(g)); repository.assertModified(g.e(1)); repository.assertModified(g.s(1), g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithoutExperimentToExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithoutExperimentToExperiment() { EntityGraphGenerator g = parseAndCreateGraph("E1\n" - + "S1, data sets: DS1[NEXP-TYPE]\n"); + + "S1, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n"); reassignToExperiment(g.ds(1), g.e(1)); - assertEquals("E1, data sets: DS1[NEXP-TYPE]\n", renderGraph(g)); + assertEquals("E1, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n", renderGraph(g)); repository.assertModified(g.e(1)); repository.assertModified(g.s(1)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithoutExperimentToSampleWithExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithoutExperimentToSampleWithExperiment() { EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1\n" - + "S2, data sets: DS1[NEXP-TYPE]\n"); + + "S2, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n"); reassignToSample(g.ds(1), g.s(1)); - assertEquals("E1, samples: S1, data sets: DS1[NEXP-TYPE]\n" - + "S1, data sets: DS1[NEXP-TYPE]\n", renderGraph(g)); + assertEquals("E1, samples: S1, data sets: DS1[NECT] DS2[NET]\n" + + "S1, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n", renderGraph(g)); repository.assertModified(g.e(1)); repository.assertModified(g.s(1), g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test - public void dataSetReassignedFromSampleWithoutExperimentToSampleWithoutExperiment() + public void containerWithAllItsComponentsReassignedFromSampleWithoutExperimentToSampleWithoutExperiment() { - EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NO-EXP-TYPE]\n" - + "S2\n"); + EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NECT] DS2[NET]\n" + + "S2\n" + + "DS1[NECT], components: DS2[NET]\n"); reassignToSample(g.ds(1), g.s(2)); - assertEquals("S2, data sets: DS1[NO-EXP-TYPE]\n", renderGraph(g)); + assertEquals("S2, data sets: DS1[NECT] DS2[NET]\n" + + "DS1[NECT], components: DS2[NET]\n", renderGraph(g)); repository.assertModified(g.s(1), g.s(2)); - repository.assertModified(g.ds(1)); + repository.assertModified(g.ds(1), g.ds(2)); + repository.assertUnmodified(g); } @Test(expectedExceptions = diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java index e2fb6d78a1195de85261e2cedcfd089f7685150e..570825d19f59ea83b953d72f45adb8572c0bb4e1 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java @@ -20,11 +20,17 @@ import static org.hamcrest.CoreMatchers.is; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -62,6 +68,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeWithRegistrationAndModificationDate; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; @@ -165,7 +172,7 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT System.setProperty("hibernate.search.index-mode", IndexMode.INDEX_FROM_SCRATCH.name()); System.setProperty("hibernate.search.index-base", "../openbis/targets/lucene/cleandb"); System.setProperty("hibernate.search.worker.execution", "sync"); - System.setProperty(DataSetTypeWithoutExperimentChecker.PROPERTY_KEY, " NO-EXP-.* , NEXP-.* "); + System.setProperty(DataSetTypeWithoutExperimentChecker.PROPERTY_KEY, " NO-EXP-.* , NE.* "); } private void setContext() throws Exception @@ -485,8 +492,9 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT { EntityGraphGenerator g = new EntityGraphGenerator(); g.parse(graphDefinition); - prepare(g); - assertEquals(removeSolitaryNodes(graphDefinition), renderGraph(g)); + createGraph(g); + assertEquals(removeSolitaryNodes(graphDefinition), renderGraph(g, true)); + repository.gatherModifictaionInfos(); return g; } @@ -506,31 +514,44 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT protected String renderGraph(EntityGraphGenerator g) { - repository.refreshGraph(); + return renderGraph(g, false); + } + + private String renderGraph(EntityGraphGenerator g, boolean showWhereIAm) + { + repository.refreshGraph(showWhereIAm); StringBuilder builder = new StringBuilder(); for (ExperimentNode experimentNode : g.getExperiments().values()) { StringBuilder builder2 = new StringBuilder(); render(builder2, "samples", repository.getSampleNode(experimentNode)); render(builder2, "data sets", repository.getDataSetNodes(experimentNode)); - if (builder2.length() > 0) - { - builder.append(experimentNode.getCode()); - builder.append(builder2).append("\n"); - } + appendNodeTo(builder, experimentNode, builder2); } for (SampleNode sampleNode : g.getSamples().values()) { StringBuilder builder2 = new StringBuilder(); render(builder2, "data sets", repository.getDataSetNodes(sampleNode)); - if (builder2.length() > 0) - { - builder.append(sampleNode.getCode()); - builder.append(builder2).append("\n"); - } + appendNodeTo(builder, sampleNode, builder2); + } + for (DataSetNode dataSetNode : g.getDataSets().values()) + { + StringBuilder builder2 = new StringBuilder(); + render(builder2, "components", repository.getComponentDataSetNodes(dataSetNode)); + appendNodeTo(builder, dataSetNode, builder2); } return builder.toString(); } + + private void appendNodeTo(StringBuilder builder, EntityNode entityNode, StringBuilder builder2) + { + if (builder2.length() > 0) + { + builder.append(entityNode.getCodeAndType()); + + builder.append(builder2).append("\n"); + } + } private void render(StringBuilder builder, String name, Collection<? extends EntityNode> nodes) { @@ -541,22 +562,18 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT builder.append(", ").append(name).append(":"); for (EntityNode node : nodes) { - builder.append(' ').append(node.getCode()); - if (node.getType() != null) - { - builder.append("[").append(node.getType()).append("]"); - } + builder.append(' ').append(node.getCodeAndType()); } } - private void prepare(EntityGraphGenerator g) + private void createGraph(EntityGraphGenerator g) { repository = new EntityRepository(); Space space = create(aSpace()); Project project = create(aProject().inSpace(space)); for (ExperimentNode experimentNode : g.getExperiments().values()) { - repository.put(experimentNode, create(anExperiment().inProject(project))); + addToRepository(experimentNode, create(anExperiment().inProject(project))); } for (SampleNode sampleNode : g.getSamples().values()) { @@ -566,9 +583,11 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT { sample.inExperiment(repository.getExperiment(experimentNode)); } - repository.put(sampleNode, create(sample)); + addToRepository(sampleNode, sample); } - for (DataSetNode dataSetNode : g.getDataSets().values()) + List<DataSetNode> dataSetNodes = new ArrayList<DataSetNode>(g.getDataSets().values()); + Collections.reverse(dataSetNodes); + for (DataSetNode dataSetNode : dataSetNodes) { ExternalDataBuilder dataSet = aDataSet().withType(dataSetNode.getType()); if (dataSetNode.getSample() != null) @@ -578,10 +597,62 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT { dataSet.inExperiment(repository.getExperiment(dataSetNode.getExperiment())); } + List<DataSetNode> components = dataSetNode.getComponents(); + if (components.isEmpty() == false) + { + dataSet.asContainer(); + for (DataSetNode component : components) + { + AbstractExternalData componentDataSet = repository.getDataSet(component); + if (componentDataSet == null) + { + throw new IllegalStateException("Data set " + component.getCode() + + " is specified as component of " + dataSetNode.getCode() + + " but hasn't yet created."); + } + dataSet.withComponent(componentDataSet); + } + } + addToRepository(dataSetNode, dataSet); + } + } + + private void addToRepository(ExperimentNode experimentNode, Experiment experiment) + { + try + { + repository.put(experimentNode, experiment); + } catch (Exception ex) + { + throw new RuntimeException("Error while creating experiment for node " + experimentNode.getCode() + + ": " + ex.getMessage(), ex); + } + } + + private void addToRepository(SampleNode sampleNode, SampleBuilder sample) + { + try + { + repository.put(sampleNode, create(sample)); + } catch (Exception ex) + { + throw new RuntimeException("Error while creating sample for node " + sampleNode.getCode() + + ": " + ex.getMessage(), ex); + } + } + + private void addToRepository(DataSetNode dataSetNode, ExternalDataBuilder dataSet) + { + try + { repository.put(dataSetNode, create(dataSet)); + } catch (Exception ex) + { + throw new RuntimeException("Error while creating data set for node " + dataSetNode.getCodeAndType() + + ": " + ex.getMessage(), ex); } } - + public static ExperimentIdentifier id(Experiment experiment) { return new ExperimentIdentifier(id(experiment.getProject()), experiment.getCode()); @@ -680,18 +751,48 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT private Map<Long, Experiment> experimentsNodeToDtoMap = new TreeMap<Long, Experiment>(); private Map<Long, ExperimentNode> experimentDtoToNodeMap = new TreeMap<Long, ExperimentNode>(); private Map<Long, ModificationInfo> experimentModificationInfoByNodeId = new HashMap<Long, ModificationInfo>(); + private Set<ExperimentNode> modifiedExperimentNodes = new HashSet<ExperimentNode>(); private Map<Long, Sample> samplesNodeToDtoMap = new TreeMap<Long, Sample>(); private Map<Long, SampleNode> samplesDtoToNodeMap = new TreeMap<Long, SampleNode>(); private Map<Long, ModificationInfo> sampleModificationInfoByNodeId = new HashMap<Long, ModificationInfo>(); + private Set<SampleNode> modifiedSampleNodes = new HashSet<SampleNode>(); private Map<Long, AbstractExternalData> dataSetsNodeToDtoMap = new TreeMap<Long, AbstractExternalData>(); private Map<Long, DataSetNode> dataSetsDtoToNodeMap = new TreeMap<Long, DataSetNode>(); private Map<Long, ModificationInfo> dataSetModificationInfoByNodeId = new HashMap<Long, ModificationInfo>(); - + private Set<DataSetNode> modifiedDataSetNodes = new HashSet<DataSetNode>(); + private Map<Long, Set<Long>> experimentSamplesMap = new HashMap<Long, Set<Long>>(); private Map<Long, Set<Long>> experimentDataSetsMap = new HashMap<Long, Set<Long>>(); private Map<Long, Set<Long>> sampleDataSetsMap = new HashMap<Long, Set<Long>>(); + private Map<Long, Set<Long>> componentDataSetsMap = new HashMap<Long, Set<Long>>(); + + public String renderNodeToDtoMapping() + { + StringBuilder builder = new StringBuilder(); + for (Entry<Long, Experiment> entry : experimentsNodeToDtoMap.entrySet()) + { + render(builder, "E", entry.getKey(), entry.getValue()); + } + for (Entry<Long, Sample> entry : samplesNodeToDtoMap.entrySet()) + { + render(builder, "S", entry.getKey(), entry.getValue()); + } + for (Entry<Long, AbstractExternalData> entry : dataSetsNodeToDtoMap.entrySet()) + { + render(builder, "DS", entry.getKey(), entry.getValue()); + } + return builder.toString(); + } + + private void render(StringBuilder builder, String prefix, Long id, + CodeWithRegistrationAndModificationDate<?> entity) + { + builder.append(prefix).append(id).append(" -> ").append(entity.getCode()).append(" ("); + builder.append(entity.getModifier().getUserId()).append(", "); + builder.append(entity.getModificationDate()).append(")\n"); + } public Experiment getExperiment(ExperimentNode experimentNode) { @@ -708,19 +809,19 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT return dataSetsNodeToDtoMap.get(dataSetNode.getId()); } - void refreshGraph() + void refreshGraph(boolean showWhereIAm) { for (Long id : experimentsNodeToDtoMap.keySet()) { - experimentsNodeToDtoMap.put(id, refresh(experimentsNodeToDtoMap.get(id))); + experimentsNodeToDtoMap.put(id, refresh(experimentsNodeToDtoMap.get(id))); } for (Long id : samplesNodeToDtoMap.keySet()) { - samplesNodeToDtoMap.put(id, refresh(samplesNodeToDtoMap.get(id))); + samplesNodeToDtoMap.put(id, refresh(samplesNodeToDtoMap.get(id))); } for (Long id : dataSetsNodeToDtoMap.keySet()) { - dataSetsNodeToDtoMap.put(id, refresh(dataSetsNodeToDtoMap.get(id))); + dataSetsNodeToDtoMap.put(id, refresh(dataSetsNodeToDtoMap.get(id))); } experimentSamplesMap.clear(); for (Sample sample : samplesNodeToDtoMap.values()) @@ -744,12 +845,34 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT addToDataSetsMap(experimentDataSetsMap, dataSet, dataSet.getExperiment()); } sampleDataSetsMap.clear(); + componentDataSetsMap.clear(); for (AbstractExternalData dataSet : dataSetsNodeToDtoMap.values()) { addToDataSetsMap(sampleDataSetsMap, dataSet, dataSet.getSample()); + List<ContainerDataSet> containerDataSets = dataSet.getContainerDataSets(); + for (ContainerDataSet containerDataSet : containerDataSets) + { + addToDataSetsMap(componentDataSetsMap, dataSet, containerDataSet); + } } + if (showWhereIAm) + { + printWhereIAm(); + } + System.out.println("Entities mapping:\n" + renderNodeToDtoMapping()); } + private void printWhereIAm() + { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + for (int i = 5, n = Math.min(stackTrace.length, 9); i < n; i++) + { + StackTraceElement element = stackTrace[i]; + System.out.print(element.getMethodName() + " <- "); + } + System.out.println("..."); + } + private void addToDataSetsMap(Map<Long, Set<Long>> holderDataSetsMap, AbstractExternalData dataSet, IIdHolder idHolder) { @@ -766,57 +889,101 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT } } + void gatherModifictaionInfos() + { + for (Entry<Long, Experiment> entry : experimentsNodeToDtoMap.entrySet()) + { + experimentModificationInfoByNodeId.put(entry.getKey(), new ModificationInfo(entry.getValue())); + } + for (Entry<Long, Sample> entry : samplesNodeToDtoMap.entrySet()) + { + sampleModificationInfoByNodeId.put(entry.getKey(), new ModificationInfo(entry.getValue())); + } + for (Entry<Long, AbstractExternalData> entry : dataSetsNodeToDtoMap.entrySet()) + { + dataSetModificationInfoByNodeId.put(entry.getKey(), new ModificationInfo(entry.getValue())); + } + } + void put(ExperimentNode experimentNode, Experiment experiment) { experimentsNodeToDtoMap.put(experimentNode.getId(), experiment); experimentDtoToNodeMap.put(experiment.getId(), experimentNode); - experimentModificationInfoByNodeId.put(experimentNode.getId(), new ModificationInfo(experiment)); } public void assertModified(ExperimentNode...experimentNodes) { - assertModificationInfo(true, experimentModificationInfoByNodeId, experimentsNodeToDtoMap, experimentNodes); - } - - public void assertUnmodified(ExperimentNode...experimentNodes) - { - assertModificationInfo(false, experimentModificationInfoByNodeId, experimentsNodeToDtoMap, experimentNodes); + assertModificationInfo(true, experimentModificationInfoByNodeId, experimentsNodeToDtoMap, + Arrays.<EntityNode>asList(experimentNodes)); + modifiedExperimentNodes.addAll(Arrays.asList(experimentNodes)); } void put(SampleNode sampleNode, Sample sample) { samplesNodeToDtoMap.put(sampleNode.getId(), sample); samplesDtoToNodeMap.put(sample.getId(), sampleNode); - sampleModificationInfoByNodeId.put(sampleNode.getId(), new ModificationInfo(sample)); } public void assertModified(SampleNode...sampleNodes) { - assertModificationInfo(true, sampleModificationInfoByNodeId, samplesNodeToDtoMap, sampleNodes); - } - - public void assertUnmodified(SampleNode...sampleNodes) - { - assertModificationInfo(false, sampleModificationInfoByNodeId, samplesNodeToDtoMap, sampleNodes); + assertModificationInfo(true, sampleModificationInfoByNodeId, samplesNodeToDtoMap, + Arrays.<EntityNode>asList(sampleNodes)); + modifiedSampleNodes.addAll(Arrays.asList(sampleNodes)); } void put(DataSetNode dataSetNode, AbstractExternalData dataSet) { dataSetsNodeToDtoMap.put(dataSetNode.getId(), dataSet); dataSetsDtoToNodeMap.put(dataSet.getId(), dataSetNode); - dataSetModificationInfoByNodeId.put(dataSetNode.getId(), new ModificationInfo(dataSet)); } - + public void assertModified(DataSetNode...dataSetNodes) { - assertModificationInfo(true, dataSetModificationInfoByNodeId, dataSetsNodeToDtoMap, dataSetNodes); + assertModificationInfo(true, dataSetModificationInfoByNodeId, dataSetsNodeToDtoMap, + Arrays.<EntityNode>asList(dataSetNodes)); + modifiedDataSetNodes.addAll(Arrays.asList(dataSetNodes)); } - public void assertUnmodified(DataSetNode...dataSetNodes) + public void assertUnmodified(EntityGraphGenerator g) { - assertModificationInfo(false, dataSetModificationInfoByNodeId, dataSetsNodeToDtoMap, dataSetNodes); + Set<EntityNode> unmodifiedExperimentNodes = new HashSet<EntityNode>(g.getExperiments().values()); + unmodifiedExperimentNodes.removeAll(modifiedExperimentNodes); + assertModificationInfo(false, experimentModificationInfoByNodeId, experimentsNodeToDtoMap, unmodifiedExperimentNodes); + Set<EntityNode> unmodifiedSampleNodes = new HashSet<EntityNode>(g.getSamples().values()); + unmodifiedSampleNodes.removeAll(modifiedSampleNodes); + assertModificationInfo(false, sampleModificationInfoByNodeId, samplesNodeToDtoMap, unmodifiedSampleNodes); + Set<EntityNode> unmodifiedDataSetNodes = new HashSet<EntityNode>(g.getDataSets().values()); + unmodifiedDataSetNodes.removeAll(modifiedDataSetNodes); + assertModificationInfo(false, dataSetModificationInfoByNodeId, dataSetsNodeToDtoMap, unmodifiedDataSetNodes); } + private void assertModificationInfo(boolean modified, Map<Long, ModificationInfo> previousInfos, + Map<Long, ? extends CodeWithRegistrationAndModificationDate<?>> nodeToDtoMap, + Collection<EntityNode> entityNodes) + { + for (EntityNode node : entityNodes) + { + ModificationInfo previous = previousInfos.get(node.getId()); + assertNotNull(node.getCode() + " no previous modification info", previous); + CodeWithRegistrationAndModificationDate<?> entity = nodeToDtoMap.get(node.getId()); + assertNotNull(node.getCode() + " unknown", entity); + ModificationInfo current = new ModificationInfo(entity); + if (modified) + { + assertEquals(node.getCode() + " has unexpectedly still the old modifier: " + current.modifier, + false, current.modifier.equals(previous.modifier)); + assertEquals(node.getCode() + " has unexpectedly still the old modification date: " + current.modificationDate, + true, current.modificationDate.getTime() > previous.modificationDate.getTime()); + } else + { + assertEquals(node.getCode() + " has unexpectedly a new modifier: ", + previous.modifier, current.modifier); + assertEquals(node.getCode() + " has unexpectedly a new modification date:", + previous.modificationDate, current.modificationDate); + } + } + } + Set<SampleNode> getSampleNode(ExperimentNode experimentNode) { Set<SampleNode> result = new LinkedHashSet<SampleNode>(); @@ -845,9 +1012,14 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT return getDataSetNodes(sampleDataSetsMap, samplesNodeToDtoMap.get(sampleNode.getId())); } + Set<DataSetNode> getComponentDataSetNodes(DataSetNode containerDataSetNode) + { + return getDataSetNodes(componentDataSetsMap, dataSetsNodeToDtoMap.get(containerDataSetNode.getId())); + } + private Set<DataSetNode> getDataSetNodes(Map<Long, Set<Long>> idHolderDataSetsMap, IIdHolder experiment) { - Set<DataSetNode> result = new LinkedHashSet<DataSetNode>(); + Set<DataSetNode> result = new TreeSet<DataSetNode>(); if (experiment != null) { Set<Long> dataSetDtoIds = idHolderDataSetsMap.get(experiment.getId()); @@ -861,33 +1033,6 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT } return result; } - - private void assertModificationInfo(boolean modified, Map<Long, ModificationInfo> previousInfos, - Map<Long, ? extends CodeWithRegistrationAndModificationDate<?>> nodeToDtoMap, EntityNode...entityNodes) - { - for (EntityNode node : entityNodes) - { - ModificationInfo previous = previousInfos.get(node.getId()); - assertNotNull(node.getCode() + " no previous modification info", previous); - CodeWithRegistrationAndModificationDate<?> entity = nodeToDtoMap.get(node.getId()); - assertNotNull(node.getCode() + " unknown", entity); - ModificationInfo current = new ModificationInfo(entity); - if (modified) - { - assertEquals(node.getCode() + " still same modifier: " + current.modifier, false, - current.modifier.equals(previous.modifier)); - assertEquals(node.getCode() + " still same modification date: " + current.modificationDate, - true, current.modificationDate.getTime() > previous.modificationDate.getTime()); - } else - { - assertEquals(node.getCode() + " different modifiers: " + previous.modifier + " " + previous.modifier, - previous.modifier, current.modifier); - assertEquals(node.getCode() + " different modification date: " + previous.modificationDate - + " " + current.modificationDate, previous.modificationDate, current.modificationDate); - } - } - } - } private static final class ModificationInfo diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java index b15d7e0cfeccef056bd580ca21709054ed0b2c39..ecaacc7e6984a9f6745191ddbb8f008487a660bd 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java @@ -131,9 +131,13 @@ public class ExternalDataBuilder extends Builder<AbstractExternalData> if (this.sampleIdentifier != null) { etlService.registerDataSet(systemSession, sampleIdentifier, data); - } else + } else if (experimentIdentifier != null) { etlService.registerDataSet(systemSession, experimentIdentifier, data); + } else + { + throw new IllegalStateException("Neither sample nor experiment has been specified for data set " + + data.getCode()); } return etlService.tryGetDataSet(systemSession, this.code); @@ -151,7 +155,7 @@ public class ExternalDataBuilder extends Builder<AbstractExternalData> { dataSetType.setDataSetKind(DataSetKind.PHYSICAL); } - commonServer.registerDataSetType(systemSession, dataSetType); + registerDataSetType(dataSetType); NewExternalData data; if (this.container) @@ -175,4 +179,17 @@ public class ExternalDataBuilder extends Builder<AbstractExternalData> data.setParentDataSetCodes(this.parentCodes); return data; } + + private void registerDataSetType(DataSetType dataSetType) + { + List<DataSetType> dataSetTypes = commonServer.listDataSetTypes(systemSession); + for (DataSetType type : dataSetTypes) + { + if (type.getCode().equals(dataSetType.getCode())) + { + return; + } + } + commonServer.registerDataSetType(systemSession, dataSetType); + } } \ No newline at end of file