From ee7e5cf21a7a45ff45cf21c3f4fc5eb42079a873 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Wed, 5 Oct 2011 11:48:38 +0000
Subject: [PATCH] LMS-2551 implemented and test written

SVN: 23202
---
 .../bo/datasetlister/DatasetLister.java       |   1 +
 .../bo/datasetlister/DatasetRecord.java       |   2 +
 .../basic/dto/builders/DataSetBuilder.java    |   7 +
 ...DataSetInfoExtractorForProteinResults.java |  31 +++-
 ...ProteinResultDataSetParentLinkingTask.java | 175 ++++++++++++++++++
 ...einResultDataSetParentLinkingTaskTest.java | 174 +++++++++++++++++
 6 files changed, 382 insertions(+), 8 deletions(-)
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTask.java
 create mode 100644 rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTaskTest.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
index b73ca486c10..738ee3c1334 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
@@ -723,6 +723,7 @@ public class DatasetLister extends AbstractLister implements IDatasetLister
         dataSet.setProductionDate(record.production_timestamp);
         dataSet.setRegistrationDate(record.registration_timestamp);
         dataSet.setRegistrator(getOrCreateRegistrator(record.pers_id_registerer));
+        dataSet.setModificationDate(record.modification_timestamp);
         dataSet.setDataSetProperties(new ArrayList<IEntityProperty>());
 
         if (record.ctnr_id != null)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetRecord.java
index 7477f825aff..542fa893781 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetRecord.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetRecord.java
@@ -27,6 +27,8 @@ public class DatasetRecord extends CodeRecord
 
     public Date registration_timestamp;
 
+    public Date modification_timestamp;
+
     public Long pers_id_registerer;
 
     public boolean is_placeholder;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/builders/DataSetBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/builders/DataSetBuilder.java
index 14ed412a2c3..195caac5945 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/builders/DataSetBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/builders/DataSetBuilder.java
@@ -27,6 +27,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStore;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 
@@ -93,6 +94,12 @@ public class DataSetBuilder
         return this;
     }
 
+    public DataSetBuilder fileFormat(String fileFormatType)
+    {
+        dataSet.setFileFormatType(new FileFormatType(fileFormatType));
+        return this;
+    }
+
     public DataSetBuilder status(DataSetArchivingStatus status)
     {
         dataSet.setStatus(status);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/DataSetInfoExtractorForProteinResults.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/DataSetInfoExtractorForProteinResults.java
index 95564639f79..b68ab4c4b2b 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/DataSetInfoExtractorForProteinResults.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/DataSetInfoExtractorForProteinResults.java
@@ -100,31 +100,46 @@ public class DataSetInfoExtractorForProteinResults extends AbstractDataSetInfoEx
         DataSetInformation info = new DataSetInformation();
         info.setExperimentIdentifier(experimentIdentifier);
         String parentDataSetCodesOrNull = getProperty(properties, PARENT_DATA_SET_CODES);
+        String baseExperimentIdentifier = getProperty(properties, EXPERIMENT_IDENTIFIER_KEY);
+        List<String> parentDataSetCodes =
+                getParentDataSetCodes(parentDataSetCodesOrNull, baseExperimentIdentifier, service);
+        info.setParentDataSetCodes(parentDataSetCodes);
+        return info;
+    }
+
+    /**
+     * Returns data set codes either from the first argument or if <code>null</code> from
+     * the data sets of the specified experiment. 
+     */
+    static List<String> getParentDataSetCodes(String parentDataSetCodesOrNull,
+            String baseExperimentIdentifier, IEncapsulatedOpenBISService service)
+    {
+        List<String> parentDataSetCodes = new ArrayList<String>();
         if (parentDataSetCodesOrNull != null)
         {
-            info.setParentDataSetCodes(Arrays.asList(StringUtils.split(parentDataSetCodesOrNull, ", ")));
-        } else 
+            parentDataSetCodes = Arrays.asList(StringUtils.split(parentDataSetCodesOrNull, ", "));
+        } else
         {
-            String baseExperimentIdentifier = getProperty(properties, EXPERIMENT_IDENTIFIER_KEY);
             if (baseExperimentIdentifier != null)
             {
-                ExperimentIdentifier identifier = new ExperimentIdentifierFactory(baseExperimentIdentifier).createIdentifier();
+                ExperimentIdentifier identifier =
+                        new ExperimentIdentifierFactory(baseExperimentIdentifier)
+                                .createIdentifier();
                 Experiment baseExperiment = service.tryToGetExperiment(identifier);
                 if (baseExperiment == null)
                 {
                     throw new UserFailureException("Property " + EXPERIMENT_IDENTIFIER_KEY
                             + " specifies an unknown experiment: " + baseExperimentIdentifier);
                 }
-                List<ExternalData> dataSets = service.listDataSetsByExperimentID(baseExperiment.getId());
-                List<String> parentDataSetCodes = new ArrayList<String>();
+                List<ExternalData> dataSets =
+                        service.listDataSetsByExperimentID(baseExperiment.getId());
                 for (ExternalData dataSet : dataSets)
                 {
                     parentDataSetCodes.add(dataSet.getCode());
                 }
-                info.setParentDataSetCodes(parentDataSetCodes);
             }
         }
-        return info;
+        return parentDataSetCodes;
     }
     
     private String getProperty(Properties properties, String key)
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTask.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTask.java
new file mode 100644
index 00000000000..1c33685a076
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTask.java
@@ -0,0 +1,175 @@
+/*
+ * 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.etlserver.phosphonetx;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.maintenance.IMaintenanceTask;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class ProteinResultDataSetParentLinkingTask implements IMaintenanceTask
+{
+    private static final Pattern DATA_SET_CODE_PATTERN = Pattern.compile("\\d{17}-\\d+");
+
+    private static final String PARENT_DATA_SET_CODES_KEY =
+            DataSetInfoExtractorForProteinResults.PARENT_DATA_SET_CODES.toUpperCase();
+
+    private static final String BASE_EXPERIMENT_KEY =
+            DataSetInfoExtractorForProteinResults.EXPERIMENT_IDENTIFIER_KEY.toUpperCase();
+    
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            ProteinResultDataSetParentLinkingTask.class);
+
+    private final IEncapsulatedOpenBISService service;
+
+    public ProteinResultDataSetParentLinkingTask()
+    {
+        this(ServiceProvider.getOpenBISService());
+    }
+
+    ProteinResultDataSetParentLinkingTask(IEncapsulatedOpenBISService service)
+    {
+        this.service = service;
+
+    }
+
+    public void setUp(String pluginName, Properties properties)
+    {
+    }
+
+    public void execute()
+    {
+        List<DataSetUpdatesDTO> dataSetUpdates = new ArrayList<DataSetUpdatesDTO>();
+        List<Project> projects = service.listProjects();
+        for (Project project : projects)
+        {
+            List<Experiment> experiments =
+                    service.listExperiments(new ProjectIdentifier(project.getSpace().getCode(),
+                            project.getCode()));
+            for (Experiment experiment : experiments)
+            {
+                Map<String, IEntityProperty> propertiesMap = getPropertiesMap(experiment);
+                String baseExperimentIdentifier =
+                        tryGetProperty(propertiesMap, BASE_EXPERIMENT_KEY);
+                String parentDataSetCodes =
+                        tryGetProperty(propertiesMap, PARENT_DATA_SET_CODES_KEY);
+                List<String> codes =
+                        filter(DataSetInfoExtractorForProteinResults.getParentDataSetCodes(
+                                parentDataSetCodes, baseExperimentIdentifier, service));
+                if (codes.isEmpty())
+                {
+                    continue;
+                }
+                List<ExternalData> dataSets =
+                        service.listDataSetsByExperimentID(experiment.getId());
+                if (dataSets.isEmpty())
+                {
+                    continue;
+                }
+                for (ExternalData ds : dataSets)
+                {
+                    if (ds instanceof DataSet == false)
+                    {
+                        continue;
+                    }
+                    DataSet dataSet = (DataSet) ds;
+                    DataSetUpdatesDTO update = new DataSetUpdatesDTO();
+                    update.setDatasetId(new TechId(dataSet.getId()));
+                    update.setVersion(dataSet.getModificationDate());
+                    update.setExperimentIdentifierOrNull(ExperimentIdentifierFactory.parse(dataSet
+                            .getExperiment().getIdentifier()));
+                    update.setModifiedParentDatasetCodesOrNull(codes.toArray(new String[0]));
+                    update.setFileFormatTypeCode(dataSet.getFileFormatType().getCode());
+                    update.setProperties(dataSet.getProperties());
+                    operationLog.info("Parent data set links of data set " + dataSet.getCode()
+                            + " from experiment " + experiment.getIdentifier()
+                            + " will be updated.");
+                    dataSetUpdates.add(update);
+                }
+            }
+        }
+        service.performEntityOperations(new AtomicEntityOperationDetails(null, Collections
+                .<NewSpace> emptyList(), Collections.<NewProject> emptyList(), Collections
+                .<NewExperiment> emptyList(), Collections.<SampleUpdatesDTO> emptyList(),
+                Collections.<NewSample> emptyList(), Collections
+                        .<String, List<NewMaterial>> emptyMap(), Collections
+                        .<NewExternalData> emptyList(), dataSetUpdates));
+        operationLog.info("Parent data set links for " + dataSetUpdates.size()
+                + " data sets have been updated.");
+    }
+
+    private Map<String, IEntityProperty> getPropertiesMap(Experiment experiment)
+    {
+        List<IEntityProperty> properties = experiment.getProperties();
+        Map<String, IEntityProperty> propertiesMap = new HashMap<String, IEntityProperty>();
+        for (IEntityProperty property : properties)
+        {
+            propertiesMap.put(property.getPropertyType().getCode(), property);
+        }
+        return propertiesMap;
+    }
+
+    private String tryGetProperty(Map<String, IEntityProperty> propertiesMap, String key)
+    {
+        IEntityProperty property = propertiesMap.get(key);
+        return property == null ? null : property.tryGetAsString();
+    }
+
+    private List<String> filter(List<String> codes)
+    {
+        List<String> result = new ArrayList<String>();
+        for (String code : codes)
+        {
+            if (DATA_SET_CODE_PATTERN.matcher(code).matches())
+            {
+                result.add(code);
+            }
+        }
+        return result;
+    }
+}
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTaskTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTaskTest.java
new file mode 100644
index 00000000000..53aff1de1eb
--- /dev/null
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/etlserver/phosphonetx/ProteinResultDataSetParentLinkingTaskTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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.etlserver.phosphonetx;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Level;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.logging.BufferedAppender;
+import ch.systemsx.cisd.common.test.RecordingMatcher;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataSetBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class ProteinResultDataSetParentLinkingTaskTest extends AssertJUnit
+{
+    private static final String PARENT_DATA_SET_CODES_KEY =
+            DataSetInfoExtractorForProteinResults.PARENT_DATA_SET_CODES.toUpperCase();
+
+    private static final String BASE_EXPERIMENT_KEY =
+            DataSetInfoExtractorForProteinResults.EXPERIMENT_IDENTIFIER_KEY.toUpperCase();
+
+    private BufferedAppender logRecorder;
+
+    private Mockery context;
+
+    private IEncapsulatedOpenBISService service;
+
+    private ProteinResultDataSetParentLinkingTask task;
+
+    @BeforeMethod
+    public void beforeMethod()
+    {
+        logRecorder = new BufferedAppender("%-5p %c - %m%n", Level.DEBUG);
+        context = new Mockery();
+        service = context.mock(IEncapsulatedOpenBISService.class);
+        task = new ProteinResultDataSetParentLinkingTask(service);
+    }
+
+    @AfterMethod
+    public void afterMethod()
+    {
+        logRecorder.reset();
+        // To following line of code should also be called at the end of each test method.
+        // Otherwise one do not known which test failed.
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void test()
+    {
+        final Experiment e1 =
+                new ExperimentBuilder().id(1).identifier("/S/P1/E1").property("ABC", "non-sense")
+                        .getExperiment();
+        final Experiment e2 =
+                new ExperimentBuilder().id(2).identifier("/A/P2/E2")
+                        .property(PARENT_DATA_SET_CODES_KEY, "non-sense").getExperiment();
+        final Experiment e3 =
+                new ExperimentBuilder()
+                        .id(3)
+                        .identifier("/A/P2/E3")
+                        .property(PARENT_DATA_SET_CODES_KEY,
+                                "20100930111833087-297733, 20100511163311581-25265")
+                        .getExperiment();
+        final Experiment e4 =
+                new ExperimentBuilder().id(4).identifier("/S/P1/E4")
+                        .property(BASE_EXPERIMENT_KEY, "/S/P1/E1").getExperiment();
+        final DataSet ds1 =
+                new DataSetBuilder(1).code("20100930111811581-25265").fileFormat("A")
+                        .experiment(e1).modificationDate(new Date(11)).getDataSet();
+        final DataSet ds2 =
+                new DataSetBuilder(2).code("20100930111811087-29765").fileFormat("B")
+                        .experiment(e4).modificationDate(new Date(22)).getDataSet();
+        final DataSet ds3 =
+                new DataSetBuilder(3).code("20100530111833087-297733").fileFormat("C")
+                        .experiment(e3).modificationDate(new Date(33)).property("ALPHA", "3.1")
+                        .getDataSet();
+        final RecordingMatcher<AtomicEntityOperationDetails> operationRecorder =
+                new RecordingMatcher<AtomicEntityOperationDetails>();
+        context.checking(new Expectations()
+            {
+                {
+                    one(service).listProjects();
+                    will(returnValue(Arrays.asList(e1.getProject(), e2.getProject())));
+
+                    one(service).listExperiments(new ProjectIdentifier("S", "P1"));
+                    will(returnValue(Arrays.asList(e1, e4)));
+
+                    one(service).listExperiments(new ProjectIdentifier("A", "P2"));
+                    will(returnValue(Arrays.asList(e2, e3)));
+
+                    one(service).tryToGetExperiment(ExperimentIdentifierFactory.parse("/S/P1/E1"));
+                    will(returnValue(e1));
+
+                    one(service).listDataSetsByExperimentID(e1.getId());
+                    will(returnValue(Arrays.asList(ds1)));
+
+                    one(service).listDataSetsByExperimentID(e3.getId());
+                    will(returnValue(Arrays.asList(ds3)));
+
+                    one(service).listDataSetsByExperimentID(e4.getId());
+                    will(returnValue(Arrays.asList(ds2)));
+
+                    one(service).performEntityOperations(with(operationRecorder));
+                }
+            });
+        
+        task.execute();
+
+        assertEquals("INFO  OPERATION.ProteinResultDataSetParentLinkingTask - "
+                + "Parent data set links of data set 20100930111811087-29765 "
+                + "from experiment /S/P1/E4 will be updated.\n"
+                + "INFO  OPERATION.ProteinResultDataSetParentLinkingTask - "
+                + "Parent data set links of data set 20100530111833087-297733 "
+                + "from experiment /A/P2/E3 will be updated.\n"
+                + "INFO  OPERATION.ProteinResultDataSetParentLinkingTask - "
+                + "Parent data set links for 2 data sets have been updated.",
+                logRecorder.getLogContent());
+        List<DataSetUpdatesDTO> dataSetUpdates =
+                operationRecorder.recordedObject().getDataSetUpdates();
+        assertEquals(2L, dataSetUpdates.get(0).getDatasetId().getId().longValue());
+        assertEquals(22L, dataSetUpdates.get(0).getVersion().getTime());
+        assertEquals("B", dataSetUpdates.get(0).getFileFormatTypeCode());
+        assertEquals("[]", dataSetUpdates.get(0).getProperties().toString());
+        assertEquals(e4.getIdentifier(), dataSetUpdates.get(0).getExperimentIdentifierOrNull()
+                .toString());
+        assertEquals("[20100930111811581-25265]",
+                Arrays.asList(dataSetUpdates.get(0).getModifiedParentDatasetCodesOrNull())
+                        .toString());
+        assertEquals(3L, dataSetUpdates.get(1).getDatasetId().getId().longValue());
+        assertEquals(33L, dataSetUpdates.get(1).getVersion().getTime());
+        assertEquals("C", dataSetUpdates.get(1).getFileFormatTypeCode());
+        assertEquals("[ALPHA: 3.1]", dataSetUpdates.get(1).getProperties().toString());
+        assertEquals(e3.getIdentifier(), dataSetUpdates.get(1).getExperimentIdentifierOrNull()
+                .toString());
+        assertEquals("[20100930111833087-297733, 20100511163311581-25265]",
+                Arrays.asList(dataSetUpdates.get(1).getModifiedParentDatasetCodesOrNull())
+                        .toString());
+        assertEquals(2, dataSetUpdates.size());
+        context.assertIsSatisfied();
+    }
+
+}
-- 
GitLab