From 7c09059e9933daefc6c02612cd8413e3103b93d5 Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Tue, 6 Oct 2009 12:28:33 +0000
Subject: [PATCH] [LMS-1191] extended data set upload form and cifex extractor

SVN: 12854
---
 .../cifex/CifexDataSetInfoExtractor.java      |  33 ++++-
 .../ui/data/DataSetUploadForm.java            | 117 ++++++++++++++++--
 .../application/ui/widget/FieldUtil.java      |   6 +-
 .../shared/basic/DataSetUploadInfo.java       | 102 +++++++++++++--
 .../dataset/DataSetParentsArea.java           |   2 +-
 .../GenericSampleBatchRegistrationForm.java   |   8 +-
 .../generic/shared/DataSetInfoHelperTest.java |  86 ++++++++++---
 7 files changed, 304 insertions(+), 50 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
index 11d07ab2bb4..623f80e3960 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.etlserver.cifex;
 import static ch.systemsx.cisd.etlserver.AbstractDataSetInfoExtractor.extractDataSetProperties;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.Properties;
 
 import ch.rinn.restrictions.Private;
@@ -28,13 +29,16 @@ import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
 import ch.systemsx.cisd.openbis.generic.shared.basic.DataSetUploadInfo;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
 
 /**
- * {@link IDataSetInfoExtractor} extracting group and sample from CIFEX comment.
+ * {@link IDataSetInfoExtractor} extracting data from CIFEX comment.
  * 
  * @author Izabela Adamczyk
+ * @author Piotr Buczek
  */
 public class CifexDataSetInfoExtractor implements IDataSetInfoExtractor
 {
@@ -59,12 +63,26 @@ public class CifexDataSetInfoExtractor implements IDataSetInfoExtractor
 
         DataSetUploadInfo info = CifexExtratorHelper.getDataSetUploadInfo(incomingDataSetPath);
         final DataSetInformation dataSetInformation = new DataSetInformation();
-        SampleIdentifier identifier = SampleIdentifierFactory.parse(info.getSample());
-        dataSetInformation.setSampleCode(identifier.getSampleCode());
-        if (identifier.isGroupLevel())
+
+        // either sample is specified or experiment (with optional data set parents)
+
+        SampleIdentifier sampleIdentifierOrNull = tryGetSampleIdentifier(info);
+        if (sampleIdentifierOrNull != null)
         {
-            dataSetInformation.setGroupCode(identifier.getGroupLevel().getGroupCode());
+            dataSetInformation.setSampleCode(sampleIdentifierOrNull.getSampleCode());
+            if (sampleIdentifierOrNull.isGroupLevel())
+            {
+                dataSetInformation.setGroupCode(sampleIdentifierOrNull.getGroupLevel()
+                        .getGroupCode());
+            }
+        } else
+        {
+            ExperimentIdentifier experimentIdentifier =
+                    new ExperimentIdentifierFactory(info.getExperiment()).createIdentifier();
+            dataSetInformation.setGroupCode(experimentIdentifier.getGroupCode());
+            dataSetInformation.setParentDataSetCodes(Arrays.asList(info.getParents()));
         }
+
         dataSetInformation.setUploadingUserEmail(CifexExtratorHelper
                 .getUploadingUserEmail(incomingDataSetPath));
         dataSetInformation.setDataSetProperties(extractDataSetProperties(incomingDataSetPath,
@@ -72,4 +90,9 @@ public class CifexDataSetInfoExtractor implements IDataSetInfoExtractor
         return dataSetInformation;
     }
 
+    private SampleIdentifier tryGetSampleIdentifier(DataSetUploadInfo info)
+    {
+        return (info.getSample() == null) ? null : SampleIdentifierFactory.parse(info.getSample());
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetUploadForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetUploadForm.java
index 72facb08740..e2603aab96d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetUploadForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetUploadForm.java
@@ -16,6 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data;
 
+import com.extjs.gxt.ui.client.Events;
+import com.extjs.gxt.ui.client.event.FieldEvent;
+import com.extjs.gxt.ui.client.event.Listener;
 import com.google.gwt.http.client.URL;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
@@ -26,15 +29,20 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.CheckBoxField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.SampleChooserField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField.ExperimentChooserFieldAdaptor;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.SampleChooserField.SampleChooserFieldAdaptor;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.StringUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WindowUtils;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.DataSetUploadInfo;
 import ch.systemsx.cisd.openbis.generic.shared.basic.URLMethodWithParameters;
 import ch.systemsx.cisd.openbis.generic.shared.basic.DataSetUploadInfo.DataSetUploadInfoHelper;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.DataSetParentsArea;
 
 /**
  * Panel that allows to specify information necessary to upload data sets and redirects user to
@@ -49,15 +57,26 @@ public class DataSetUploadForm extends AbstractRegistrationForm
 
     public static final String ID = GenericConstants.ID_PREFIX + ID_SUFFIX;
 
-    private String cifexURL;
+    private final String cifexURL;
 
-    private String cifexRecipient;
+    private final String cifexRecipient;
 
-    private DataSetTypeSelectionWidget dataSetTypeSelectionWidget;
+    private final DataSetTypeSelectionWidget dataSetTypeSelectionWidget;
 
-    private SampleChooserFieldAdaptor sampleChooser;
+    private final FileFormatTypeSelectionWidget fileTypeSelectionWidget;
 
-    private FileFormatTypeSelectionWidget fileTypeSelectionWidget;
+    private final CheckBoxField connectedWithSampleCheckbox;
+
+    // two options:
+    // 1. connected with sample
+    private final SampleChooserFieldAdaptor sampleChooser;
+
+    // 2. not connected with sample
+    private final ExperimentChooserFieldAdaptor experimentChooser;
+
+    private final DataSetParentsArea parentsArea;
+
+    //
 
     public DataSetUploadForm(IViewContext<ICommonClientServiceAsync> viewContext)
     {
@@ -65,10 +84,31 @@ public class DataSetUploadForm extends AbstractRegistrationForm
         cifexURL = viewContext.getModel().getApplicationInfo().getCIFEXURL();
         cifexRecipient = viewContext.getModel().getApplicationInfo().getCifexRecipient();
         saveButton.setText(viewContext.getMessage(Dict.BUTTON_UPLOAD_DATA_VIA_CIFEX));
+
+        connectedWithSampleCheckbox = new CheckBoxField("Connected with Sample", false);
+        connectedWithSampleCheckbox.setValue(true);
+        formPanel.add(connectedWithSampleCheckbox);
+
+        // both sample and experiment choosers are mandatory but only one will be shown
         sampleChooser =
                 SampleChooserField.create(viewContext.getMessage(Dict.SAMPLE), true, null, false,
                         true, viewContext);
         formPanel.add(sampleChooser.getField());
+        experimentChooser =
+                ExperimentChooserField.create(viewContext.getMessage(Dict.EXPERIMENT), true, null,
+                        viewContext);
+        formPanel.add(experimentChooser.getField());
+        formPanel.add(parentsArea = new DataSetParentsArea(viewContext, ID_SUFFIX));
+
+        connectedWithSampleCheckbox.addListener(Events.Change, new Listener<FieldEvent>()
+            {
+                public void handleEvent(FieldEvent be)
+                {
+                    updateFieldsVisibility();
+                }
+            });
+        updateFieldsVisibility();
+
         formPanel.add(dataSetTypeSelectionWidget =
                 new DataSetTypeSelectionWidget(viewContext, ID_SUFFIX));
         FieldUtil.markAsMandatory(dataSetTypeSelectionWidget);
@@ -82,6 +122,14 @@ public class DataSetUploadForm extends AbstractRegistrationForm
         }
     }
 
+    private void updateFieldsVisibility()
+    {
+        boolean connectedWithSample = connectedWithSampleCheckbox.getValue();
+        FieldUtil.setVisibility(connectedWithSample, sampleChooser.getField());
+        FieldUtil.setVisibility(connectedWithSample == false, experimentChooser.getField(),
+                parentsArea);
+    }
+
     public static DatabaseModificationAwareComponent create(
             IViewContext<ICommonClientServiceAsync> viewContext)
     {
@@ -102,17 +150,64 @@ public class DataSetUploadForm extends AbstractRegistrationForm
     @Override
     protected void submitValidForm()
     {
-        String comment =
-                encodeDataSetInfo(sampleChooser.getValue(), dataSetTypeSelectionWidget
-                        .tryGetSelected().getCode(), fileTypeSelectionWidget.tryGetSelected()
-                        .getCode());
+        final String sample = extractSampleIdentifier();
+        final String experiment = extractExperimentIdentifier();
+        final String dataSetType = extractDataSetTypeCode();
+        final String fileType = extractFileTypeCode();
+        final String[] parents = extractParentDatasetCodes();
+        String comment;
+        if (isConnectedWithSample())
+        {
+            comment = encodeDataSetInfo(sample, dataSetType, fileType);
+        } else
+        {
+            comment = encodeDataSetInfo(experiment, parents, dataSetType, fileType);
+        }
         WindowUtils.openWindow(encodeCifexRequest(cifexURL, cifexRecipient, comment));
     }
 
+    private Boolean isConnectedWithSample()
+    {
+        return connectedWithSampleCheckbox.getValue();
+    }
+
+    private String extractSampleIdentifier()
+    {
+        return sampleChooser.getValue();
+    }
+
+    private String extractExperimentIdentifier()
+    {
+        ExperimentIdentifier identifierOrNull = experimentChooser.tryToGetValue();
+        return identifierOrNull == null ? null : identifierOrNull.getIdentifier();
+    }
+
+    private String extractDataSetTypeCode()
+    {
+        return dataSetTypeSelectionWidget.tryGetSelected().getCode();
+    }
+
+    private String extractFileTypeCode()
+    {
+        return fileTypeSelectionWidget.tryGetSelected().getCode();
+    }
+
+    protected String[] extractParentDatasetCodes()
+    {
+        return parentsArea.tryGetModifiedParentCodes();
+    }
+
     private String encodeDataSetInfo(String sample, String dataSetType, String fileType)
     {
-        return DataSetUploadInfoHelper.encodeAsCifexComment(new DataSetUploadInfo(sample,
-                dataSetType, fileType));
+        return DataSetUploadInfoHelper.encodeAsCifexComment(new DataSetUploadInfo(sample, null,
+                null, dataSetType, fileType));
+    }
+
+    private String encodeDataSetInfo(String experiment, String[] parents, String dataSetType,
+            String fileType)
+    {
+        return DataSetUploadInfoHelper.encodeAsCifexComment(new DataSetUploadInfo(null, experiment,
+                parents, dataSetType, fileType));
     }
 
     private static String encodeCifexRequest(String cifexUrl, String recipient, String comment)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/FieldUtil.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/FieldUtil.java
index 68f59e06f42..922a763e7c3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/FieldUtil.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/FieldUtil.java
@@ -72,10 +72,14 @@ public class FieldUtil
     {
         field.setEnabled(visible);
         field.setVisible(visible);
-        // invalidation mark is not removed automatically when we make field invisible
         if (visible == false)
         {
+            // invalidation mark is not removed automatically when we make field invisible
             field.clearInvalid();
+        } else if (field.isDirty())
+        {
+            // validate only if something have been modified and field is shown
+            field.validate();
         }
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/DataSetUploadInfo.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/DataSetUploadInfo.java
index 2e9ed4e4068..4bffbd944c7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/DataSetUploadInfo.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/DataSetUploadInfo.java
@@ -22,7 +22,15 @@ package ch.systemsx.cisd.openbis.generic.shared.basic;
 public class DataSetUploadInfo
 {
 
-    String sample;
+    private static final String PARENT_SEPARATOR = "|";
+
+    private static final String SEPARATOR = ",";
+
+    String sample; // may be null
+
+    String experiment; // may be null
+
+    String[] parents; // may be null
 
     String dataSetType;
 
@@ -32,9 +40,12 @@ public class DataSetUploadInfo
     {
     }
 
-    public DataSetUploadInfo(String sample, String dataSetType, String fileType)
+    public DataSetUploadInfo(String sample, String experiment, String[] parents,
+            String dataSetType, String fileType)
     {
         setSample(sample);
+        setExperiment(experiment);
+        setParents(parents);
         setDataSetType(dataSetType);
         setFileType(fileType);
     }
@@ -69,42 +80,107 @@ public class DataSetUploadInfo
         this.fileType = fileType;
     }
 
+    public String getExperiment()
+    {
+        return experiment;
+    }
+
+    public void setExperiment(String experiment)
+    {
+        this.experiment = experiment;
+    }
+
+    public String[] getParents()
+    {
+        return parents;
+    }
+
+    public void setParents(String[] parents)
+    {
+        this.parents = parents;
+    }
+
     public static class DataSetUploadInfoHelper
     {
-        private static final String SEPARATOR = ",";
 
         enum CommentElements
         {
-            SAMPLE, DATA_SET_TYPE, FILE_TYPE;
+            SAMPLE, EXPERIMENT, PARENTS, DATA_SET_TYPE, FILE_TYPE;
         }
 
         public static String encodeAsCifexComment(DataSetUploadInfo info)
         {
             String[] commentElements = new String[CommentElements.values().length];
             commentElements[CommentElements.SAMPLE.ordinal()] = info.getSample();
+            commentElements[CommentElements.EXPERIMENT.ordinal()] = info.getExperiment();
+            commentElements[CommentElements.PARENTS.ordinal()] = tryEncodeParentsAsString(info);
             commentElements[CommentElements.DATA_SET_TYPE.ordinal()] = info.getDataSetType();
             commentElements[CommentElements.FILE_TYPE.ordinal()] = info.getFileType();
-            String comment = "";
+            StringBuilder commentBuilder = new StringBuilder();
             for (String el : commentElements)
             {
-                if (comment.length() != 0)
-                {
-                    comment += SEPARATOR;
-                }
-                comment += el;
+                commentBuilder.append(el);
+                commentBuilder.append(SEPARATOR);
             }
-            return comment;
+            return cutOffLastSeparator(commentBuilder, SEPARATOR);
         }
 
         public static DataSetUploadInfo extractFromCifexComment(String comment)
         {
-            String[] commentElements = comment.split(SEPARATOR);
+            String[] commentElements = comment.split(asEscapedRegexp(SEPARATOR));
             DataSetUploadInfo result = new DataSetUploadInfo();
-            result.setSample(commentElements[CommentElements.SAMPLE.ordinal()]);
+            result.setSample(nullify(commentElements[CommentElements.SAMPLE.ordinal()]));
+            result.setExperiment(nullify(commentElements[CommentElements.EXPERIMENT.ordinal()]));
+            result
+                    .setParents(tryExtractParentsFromString(nullify(commentElements[CommentElements.PARENTS
+                            .ordinal()])));
             result.setDataSetType(commentElements[CommentElements.DATA_SET_TYPE.ordinal()]);
             result.setFileType(commentElements[CommentElements.FILE_TYPE.ordinal()]);
             return result;
         }
+
+        private static String nullify(String string)
+        {
+            return string.equals("null") ? null : string;
+        }
+
+        private static String[] tryExtractParentsFromString(String parents)
+        {
+            return parents == null ? null : parents.split(asEscapedRegexp(PARENT_SEPARATOR));
+        }
+
+        private static String tryEncodeParentsAsString(DataSetUploadInfo info)
+        {
+            if (info.getParents() == null)
+            {
+                return null;
+            }
+            StringBuilder sb = new StringBuilder();
+            for (String parent : info.getParents())
+            {
+                sb.append(parent);
+                sb.append(PARENT_SEPARATOR);
+            }
+            return cutOffLastSeparator(sb, PARENT_SEPARATOR);
+        }
+
+        private static String asEscapedRegexp(String str)
+        {
+            return "\\Q" + str + "\\E";
+        }
+
+        private static String cutOffLastSeparator(StringBuilder builder, String sep)
+        {
+            // either builder is empty or it should end with separator
+            if (builder.length() == 0)
+            {
+                return "";
+            } else
+            {
+                assert builder.lastIndexOf(sep) == builder.length() - sep.length();
+                return builder.substring(0, builder.length() - sep.length());
+            }
+        }
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetParentsArea.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetParentsArea.java
index fb9c7ddaa5a..8d062ee3649 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetParentsArea.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetParentsArea.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
  * 
  * @author Piotr Buczek
  */
-final class DataSetParentsArea extends TextArea
+public final class DataSetParentsArea extends TextArea
 {
 
     public static final String ID_SUFFIX_PARENTS = "_parents";
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java
index f9fd36e8a9f..8ceebccab43 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java
@@ -76,9 +76,9 @@ public final class GenericSampleBatchRegistrationForm extends AbstractRegistrati
 
     private final SampleType sampleType;
 
-    private CheckBoxField generateCodesCheckbox;
+    private final CheckBoxField generateCodesCheckbox;
 
-    private GroupSelectionWidget groupSelector;
+    private final GroupSelectionWidget groupSelector;
 
     public GenericSampleBatchRegistrationForm(
             final IViewContext<IGenericClientServiceAsync> viewContext, final SampleType sampleType)
@@ -100,9 +100,7 @@ public final class GenericSampleBatchRegistrationForm extends AbstractRegistrati
                 public void handleEvent(FieldEvent be)
                 {
                     boolean selected = (Boolean) be.value;
-                    groupSelector.setVisible(selected);
-                    groupSelector.setEnabled(selected);
-                    groupSelector.validate();
+                    FieldUtil.setVisibility(selected, groupSelector);
                 }
             });
         addUploadFeatures(SESSION_KEY);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/DataSetInfoHelperTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/DataSetInfoHelperTest.java
index 7d712552087..4866c47dc09 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/DataSetInfoHelperTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/DataSetInfoHelperTest.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.shared;
 
+import org.apache.commons.lang.StringUtils;
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
@@ -27,36 +28,93 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.DataSetUploadInfo.DataSetUp
  */
 public class DataSetInfoHelperTest extends AssertJUnit
 {
-
     @Test
-    public void testDataSetUploadInfoContructor()
+    public void testDataSetUploadInfoContructorWithSample()
     {
+        // sample but no experiment and parents
         String sample = "sampleA";
-        String dataSetType = "dataSetTypeB";
-        String fileType = "fileTypeC";
-        DataSetUploadInfo info = new DataSetUploadInfo(sample, dataSetType, fileType);
+        String experiment = null;
+        String dataSetType = "dataSetTypeC";
+        String fileType = "fileTypeD";
+        String[] parents = null;
+        DataSetUploadInfo info =
+                new DataSetUploadInfo(sample, experiment, parents, dataSetType, fileType);
+        checkInfo(info, sample, experiment, parents, dataSetType, fileType);
+    }
+
+    @Test
+    public void testDataSetUploadInfoConstructorNoSample()
+    {
+        // no sample but experiment and parents
+        String sample = null;
+        String experiment = "experimentB";
+        String dataSetType = "dataSetTypeC";
+        String fileType = "fileTypeD";
+        String[] parents =
+            { "p1", "p2", "p3" };
+        DataSetUploadInfo info =
+                new DataSetUploadInfo(sample, experiment, parents, dataSetType, fileType);
+        checkInfo(info, sample, experiment, parents, dataSetType, fileType);
+    }
+
+    private void checkInfo(DataSetUploadInfo info, String sample, String experiment,
+            String[] parents, String dataSetType, String fileType)
+    {
         assertEquals(info.getSample(), sample);
+        assertEquals(info.getExperiment(), experiment);
+        assertEquals(StringUtils.join(info.getParents(), ";"), StringUtils.join(parents, ";"));
         assertEquals(info.getFileType(), fileType);
         assertEquals(info.getDataSetType(), dataSetType);
     }
 
     @Test
-    public void testExtractFromComment() throws Exception
+    public void testExtractFromCommentWithSample() throws Exception
     {
-        DataSetUploadInfo info = DataSetUploadInfoHelper.extractFromCifexComment("sA,dsB,ftC");
+        DataSetUploadInfo info =
+                DataSetUploadInfoHelper.extractFromCifexComment("sA,null,null,dsC,ftD");
         assertEquals("sA", info.getSample());
-        assertEquals("ftC", info.getFileType());
-        assertEquals("dsB", info.getDataSetType());
+        assertNull(info.getExperiment());
+        assertNull(info.getParents());
+        assertEquals("dsC", info.getDataSetType());
+        assertEquals("ftD", info.getFileType());
     }
 
     @Test
-    public void testEncodeAsComment()
+    public void testExtractFromCommentNoSample() throws Exception
+    {
+        DataSetUploadInfo info =
+                DataSetUploadInfoHelper.extractFromCifexComment("null,eB,p1|p2|p3,dsC,ftD");
+        assertNull(info.getSample());
+        assertEquals("eB", info.getExperiment());
+        assertEquals("p1;p2;p3", StringUtils.join(info.getParents(), ";"));
+        assertEquals("dsC", info.getDataSetType());
+        assertEquals("ftD", info.getFileType());
+    }
+
+    @Test
+    public void testEncodeAsCommentWithSample()
     {
         String sample = "sA";
-        String dataSetType = "dsB";
-        String fileType = "ftC";
-        DataSetUploadInfo info = new DataSetUploadInfo(sample, dataSetType, fileType);
-        assertEquals("sA,dsB,ftC", DataSetUploadInfoHelper.encodeAsCifexComment(info));
+        String experiment = null;
+        String[] parents = null;
+        String dataSetType = "dsC";
+        String fileType = "ftD";
+        DataSetUploadInfo info =
+                new DataSetUploadInfo(sample, experiment, parents, dataSetType, fileType);
+        assertEquals("sA,null,null,dsC,ftD", DataSetUploadInfoHelper.encodeAsCifexComment(info));
+    }
 
+    @Test
+    public void testEncodeAsCommentNoSample()
+    {
+        String sample = null;
+        String experiment = "eB";
+        String[] parents =
+            { "p1", "p2", "p3" };
+        String dataSetType = "dsC";
+        String fileType = "ftD";
+        DataSetUploadInfo info =
+                new DataSetUploadInfo(sample, experiment, parents, dataSetType, fileType);
+        assertEquals("null,eB,p1|p2|p3,dsC,ftD", DataSetUploadInfoHelper.encodeAsCifexComment(info));
     }
 }
-- 
GitLab