From ff10cfc8fb24a537ea5369399a776fc11aad2208 Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Tue, 9 Mar 2010 09:11:18 +0000
Subject: [PATCH] LMS-1398 Work on CINA ETL + new tests

SVN: 15072
---
 .../cisd/cina/dss/StorageProcessor.java       |  11 +-
 .../dss/info/CinaDataSetInfoExtractor.java    |   6 +-
 .../info/EntityRegistrationSuccessEmail.java  | 240 ++++++++++++++++++
 .../dss/info/ExperimentMetadataExtractor.java |   8 +-
 .../cisd/cina/dss/info/FolderOracle.java      |   8 +-
 .../dss/info/SampleMetadataExtractor.java     |  70 ++---
 .../info/CinaDataSetInfoExtractorTest.java    | 125 +++++++++
 .../cisd/cina/dss/info/FolderOracleTest.java  |  82 ++++++
 .../ambiguous-data-folder/dataset.properties  |   3 +
 .../ambiguous-data-folder/sample.properties   |   3 +
 .../dataset-data-folder/dataset.properties    |   3 +
 .../dss/info/empty-data-folder/.gitignore     |   0
 .../experiment.properties                     |   3 +
 .../info/sample-data-folder/sample.properties |   3 +
 14 files changed, 519 insertions(+), 46 deletions(-)
 create mode 100644 rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/EntityRegistrationSuccessEmail.java
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractorTest.java
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/FolderOracleTest.java
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/dataset.properties
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/sample.properties
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/dataset-data-folder/dataset.properties
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/empty-data-folder/.gitignore
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder/experiment.properties
 create mode 100644 rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder/sample.properties

diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/StorageProcessor.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/StorageProcessor.java
index e0245ac168f..1c319511cc7 100644
--- a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/StorageProcessor.java
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/StorageProcessor.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.cina.dss;
 import java.io.File;
 import java.util.Properties;
 
+import ch.systemsx.cisd.cina.dss.info.EntityRegistrationSuccessEmail;
 import ch.systemsx.cisd.common.mail.IMailClient;
 import ch.systemsx.cisd.etlserver.AbstractDelegatingStorageProcessor;
 import ch.systemsx.cisd.etlserver.IStorageProcessor;
@@ -58,6 +59,11 @@ public class StorageProcessor extends AbstractDelegatingStorageProcessor
             final ITypeExtractor typeExtractor, final IMailClient mailClient,
             final File incomingDataSetDirectory, final File rootDir)
     {
+        // Create the email first because the email looks into the directory to determine its
+        // content.
+        EntityRegistrationSuccessEmail successEmail =
+                new EntityRegistrationSuccessEmail(dataSetInformation, incomingDataSetDirectory);
+
         File answer =
                 super.storeData(dataSetInformation, typeExtractor, mailClient,
                         incomingDataSetDirectory, rootDir);
@@ -68,9 +74,8 @@ public class StorageProcessor extends AbstractDelegatingStorageProcessor
             emailAddress = defaultEmailAddress;
         }
 
-        mailClient.sendMessage("[CINA] Registered Experiment",
-                "Experment was successfully registered. Use the following properties file : experiment.code="
-                        + dataSetInformation.getExperimentIdentifier(), null, null, emailAddress);
+        mailClient.sendMessage(successEmail.getSubject(), successEmail.getContent(), null, null,
+                emailAddress);
 
         return answer;
     }
diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractor.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractor.java
index 976ff280cec..753b7b8ab2e 100644
--- a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractor.java
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractor.java
@@ -70,14 +70,14 @@ public class CinaDataSetInfoExtractor implements IDataSetInfoExtractor
         switch (folderType)
         {
             case DATA_SET:
-                processDataSetFolder(metadata.tryMetadataFile(), dataSetInformation, openbisService);
+                processDataSetFolder(metadata.tryGetMetadataFile(), dataSetInformation, openbisService);
                 break;
             case EXPERIMENT:
-                processExperimentFolder(metadata.tryMetadataFile(), dataSetInformation,
+                processExperimentFolder(metadata.tryGetMetadataFile(), dataSetInformation,
                         openbisService);
                 break;
             case SAMPLE:
-                processSampleFolder(metadata.tryMetadataFile(), dataSetInformation, openbisService);
+                processSampleFolder(metadata.tryGetMetadataFile(), dataSetInformation, openbisService);
                 break;
             case UNKNOWN:
                 break;
diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/EntityRegistrationSuccessEmail.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/EntityRegistrationSuccessEmail.java
new file mode 100644
index 00000000000..ace867bee77
--- /dev/null
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/EntityRegistrationSuccessEmail.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2010 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.cina.dss.info;
+
+import java.io.File;
+
+import ch.systemsx.cisd.cina.dss.info.FolderOracle.FolderType;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
+
+/**
+ * Create the subject and content for an email that is sent when an experiment or sample is
+ * registered.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class EntityRegistrationSuccessEmail
+{
+    private final DataSetInformation dataSetInformation;
+
+    private final EntityEmailDetails entityEmailDetails;
+
+    private static final String EMAIL_SUBJECT_PREFIX = "[CINA]";
+
+    private static final String SAMPLE_CODE_PREFIX = "S";
+
+    public EntityRegistrationSuccessEmail(DataSetInformation dataSetInformation,
+            File incomingDataSetDirectory)
+    {
+        this.dataSetInformation = dataSetInformation;
+
+        FolderType folderType = new FolderOracle().getTypeForFolder(incomingDataSetDirectory);
+        switch (folderType)
+        {
+            case DATA_SET:
+                entityEmailDetails = new DatasetEmailDetails();
+                break;
+            case EXPERIMENT:
+                entityEmailDetails = new ExperimentEmailDetails();
+                break;
+            case SAMPLE:
+                entityEmailDetails = new SampleEmailDetails();
+                break;
+            case UNKNOWN:
+                entityEmailDetails = new UnknownEmailDetails();
+                break;
+            default:
+                entityEmailDetails = new UnknownEmailDetails();
+                break;
+        }
+    }
+
+    public boolean shouldSendEmail()
+    {
+        return entityEmailDetails.shouldSendEmail();
+    }
+
+    public String getSubject()
+    {
+        StringBuffer subject = new StringBuffer();
+        subject.append(EMAIL_SUBJECT_PREFIX);
+        subject.append(" Registered ");
+        entityEmailDetails.appendEntityName(subject);
+        subject.append(" ");
+        entityEmailDetails.appendSubjectDetails(subject);
+        return subject.toString();
+    }
+
+    public String getContent()
+    {
+        StringBuffer content = new StringBuffer();
+        entityEmailDetails.appendEntityName(content);
+        content.append(" was successfully registered. Use the following metadata file to register");
+        entityEmailDetails.appendFollowOnEntityName(content);
+        content.append(":\n");
+        content.append("------");
+        entityEmailDetails.appendMetadataFileName(content);
+        content.append("------");
+        content.append("\n");
+        entityEmailDetails.appendMetadataFileContent(content);
+
+        return content.toString();
+    }
+
+    private abstract class EntityEmailDetails
+    {
+        boolean shouldSendEmail()
+        {
+            return false;
+        }
+
+        abstract void appendEntityName(StringBuffer sb);
+
+        void appendFollowOnEntityName(StringBuffer sb)
+        {
+        }
+
+        void appendSubjectDetails(StringBuffer subject)
+        {
+        }
+
+        void appendMetadataFileName(StringBuffer sb)
+        {
+        }
+
+        void appendMetadataFileContent(StringBuffer sb)
+        {
+
+        }
+    }
+
+    private class ExperimentEmailDetails extends EntityEmailDetails
+    {
+        @Override
+        boolean shouldSendEmail()
+        {
+            return true;
+        }
+
+        @Override
+        void appendEntityName(StringBuffer sb)
+        {
+            sb.append("Experiment");
+        }
+
+        @Override
+        void appendFollowOnEntityName(StringBuffer sb)
+        {
+            sb.append("Samples");
+        }
+
+        @Override
+        void appendSubjectDetails(StringBuffer subject)
+        {
+            subject.append(dataSetInformation.getExperimentIdentifier());
+        }
+
+        @Override
+        void appendMetadataFileContent(StringBuffer sb)
+        {
+            sb.append(SampleMetadataExtractor.EXPERIMENT_IDENTIFIER_KEY);
+            sb.append("=");
+            sb.append(dataSetInformation.getExperimentIdentifier());
+            sb.append("\n");
+
+            sb.append(SampleMetadataExtractor.EXPERIMENT_OWNER_EMAIL_KEY);
+            sb.append("=");
+            sb.append(dataSetInformation.tryGetUploadingUserEmail());
+            sb.append("\n");
+
+            sb.append(SampleMetadataExtractor.SAMPLE_CODE_PREFIX_KEY);
+            sb.append("=");
+            sb.append(SAMPLE_CODE_PREFIX);
+            sb.append("\n");
+        }
+
+        @Override
+        void appendMetadataFileName(StringBuffer sb)
+        {
+            sb.append(FolderOracle.SAMPLE_METADATA_FILENAME);
+
+        }
+    }
+
+    private class SampleEmailDetails extends EntityEmailDetails
+    {
+        @Override
+        boolean shouldSendEmail()
+        {
+            return true;
+        }
+
+        @Override
+        void appendEntityName(StringBuffer sb)
+        {
+            sb.append("Sample");
+        }
+
+        @Override
+        void appendFollowOnEntityName(StringBuffer sb)
+        {
+            sb.append("Data Sets");
+        }
+
+        @Override
+        void appendSubjectDetails(StringBuffer subject)
+        {
+            subject.append(dataSetInformation.getSampleIdentifier());
+        }
+
+        @Override
+        void appendMetadataFileContent(StringBuffer sb)
+        {
+        }
+
+        @Override
+        void appendMetadataFileName(StringBuffer sb)
+        {
+            sb.append(FolderOracle.DATA_SET_METADATA_FILENAME);
+
+        }
+    }
+
+    private class DatasetEmailDetails extends EntityEmailDetails
+    {
+        @Override
+        void appendEntityName(StringBuffer sb)
+        {
+            sb.append("Data Set");
+        }
+
+        @Override
+        void appendSubjectDetails(StringBuffer subject)
+        {
+            subject.append(dataSetInformation.getDataSetCode());
+        }
+    }
+
+    private class UnknownEmailDetails extends EntityEmailDetails
+    {
+        @Override
+        void appendEntityName(StringBuffer sb)
+        {
+            sb.append("Unknown");
+        }
+    }
+}
diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/ExperimentMetadataExtractor.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/ExperimentMetadataExtractor.java
index a73ee64970f..003b5bf2b70 100644
--- a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/ExperimentMetadataExtractor.java
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/ExperimentMetadataExtractor.java
@@ -53,7 +53,7 @@ class ExperimentMetadataExtractor
     // Internal state used during extraction
     private String projectCode;
 
-    private String experimentCode;
+    private String experimentCodePrefix;
 
     private String emailAddress;
 
@@ -97,7 +97,7 @@ class ExperimentMetadataExtractor
     private void extractMetadata()
     {
         projectCode = experimentMetadata.get(PROJECT_CODE_KEY);
-        experimentCode = experimentMetadata.get(EXPERIMENT_CODE_KEY);
+        experimentCodePrefix = experimentMetadata.get(EXPERIMENT_CODE_KEY);
         emailAddress = experimentMetadata.get(EXPERIMENT_OWNER_EMAIL_KEY);
     }
 
@@ -107,7 +107,7 @@ class ExperimentMetadataExtractor
     private ExperimentIdentifier createExperiment() throws EnvironmentFailureException
     {
         ExperimentIdentifier identifier =
-                new ExperimentIdentifier(null, SPACE_CODE, projectCode, experimentCode + "-"
+                new ExperimentIdentifier(null, SPACE_CODE, projectCode, experimentCodePrefix + "-"
                         + experimentCodeSuffix);
 
         // Check that the identifier is unique
@@ -136,7 +136,7 @@ class ExperimentMetadataExtractor
                     "A project code must be specified to register an experiment.");
         }
 
-        if (null == experimentCode)
+        if (null == experimentCodePrefix)
         {
             throw new UserFailureException(
                     "An experiment code must be specified to register an experiment.");
diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/FolderOracle.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/FolderOracle.java
index 9eccab4a2ef..9d66c6abfd6 100644
--- a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/FolderOracle.java
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/FolderOracle.java
@@ -65,7 +65,7 @@ class FolderOracle
             return type;
         }
 
-        File tryMetadataFile()
+        File tryGetMetadataFile()
         {
             return metadataFileOrNull;
         }
@@ -73,11 +73,11 @@ class FolderOracle
 
     // The known conventions for naming metadata files. If a new metadata file is created, cases
     // should be added to getFilenameFilter() and getFolderMetadataForFile() as well.
-    private static String EXPERIMENT_METADATA_FILENAME = "experiment.properties";
+    static String EXPERIMENT_METADATA_FILENAME = "experiment.properties";
 
-    private static String SAMPLE_METADATA_FILENAME = "sample.properties";
+    static String SAMPLE_METADATA_FILENAME = "sample.properties";
 
-    private static String DATA_SET_METADATA_FILENAME = "dataset.properties";
+    static String DATA_SET_METADATA_FILENAME = "dataset.properties";
 
     FolderOracle()
     {
diff --git a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/SampleMetadataExtractor.java b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/SampleMetadataExtractor.java
index 13bf4fa314f..d4fbb1d4343 100644
--- a/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/SampleMetadataExtractor.java
+++ b/rtd_cina/source/java/ch/systemsx/cisd/cina/dss/info/SampleMetadataExtractor.java
@@ -25,47 +25,55 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+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.SampleOwnerIdentifier;
 
 /**
  * Package-visible helper class to extract information from the XML metadata file and register a new
  * sample using this data.
+ * <p>
+ * This class assumes that the sample type CINA_SAMPLE_TYPE has been registered.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
 class SampleMetadataExtractor
 {
     // Keys expected in metadata properties file
-    public static final String SAMPLE_CODE_KEY = "sample";
+
+    public static final String PROJECT_CODE_KEY = ExperimentMetadataExtractor.PROJECT_CODE_KEY;
+
+    public static final String EXPERIMENT_IDENTIFIER_KEY = "experiment.identifier";
+
+    public static final String EXPERIMENT_OWNER_EMAIL_KEY =
+            ExperimentMetadataExtractor.EXPERIMENT_OWNER_EMAIL_KEY;
+
+    public static final String SAMPLE_CODE_PREFIX_KEY = "sample.code-prefix";
 
     // Instance state
     private final DataSetInformation dataSetInformation;
 
     private final Map<String, String> sampleMetadata;
 
-    private final IEncapsulatedOpenBISService openbisService;
+    private final String sampleCodeSuffix;
 
-    // Internal state used during extraction
-    private String projectCode;
+    private final IEncapsulatedOpenBISService openbisService;
 
-    private String experimentCode;
+    private ExperimentIdentifier experimentIdentifier;
 
-    private String sampleCode;
+    private String sampleCodePrefix;
 
     private String emailAddress;
 
-    static final String SPACE_CODE = "CINA";
-
-    static final String EXPERIMENT_TYPE_CODE = "CINA_EXP_TYPE";
-
-    static final String SAMPLE_TYPE_CODE = "CINA_SAMPLE_TYPE";
+    private static final String SAMPLE_TYPE_CODE = "CINA_SAMPLE_TYPE";
 
     SampleMetadataExtractor(DataSetInformation dataSetInformation,
-            Map<String, String> sampleMetadata, IEncapsulatedOpenBISService openbisService)
+            Map<String, String> sampleMetadata, String sampleCodeSuffix,
+            IEncapsulatedOpenBISService openbisService)
     {
         this.dataSetInformation = dataSetInformation;
         this.sampleMetadata = sampleMetadata;
+        this.sampleCodeSuffix = sampleCodeSuffix;
         this.openbisService = openbisService;
     }
 
@@ -79,20 +87,26 @@ class SampleMetadataExtractor
     {
         extractMetadata();
 
+        // Set the email address as early as possible because it will be used later to notify the
+        // user.
+        dataSetInformation.setUploadingUserEmail(emailAddress);
+
         // Check that that the required data was specified in the properties file.
         verifyRequiredMetadataDataHasBeenProvided();
 
-        this.createSample();
-        dataSetInformation.setSampleCode(sampleCode);
+        SampleIdentifier sampleId = this.createSample();
+        dataSetInformation.setExperimentIdentifier(experimentIdentifier);
+        dataSetInformation.setSampleCode(sampleId.getSampleCode());
         dataSetInformation.setUploadingUserEmail(emailAddress);
     }
 
     private void extractMetadata()
     {
-        projectCode = sampleMetadata.get(ExperimentMetadataExtractor.PROJECT_CODE_KEY);
-        experimentCode = sampleMetadata.get(ExperimentMetadataExtractor.EXPERIMENT_CODE_KEY);
-        sampleCode = sampleMetadata.get(SAMPLE_CODE_KEY);
-        emailAddress = sampleMetadata.get(ExperimentMetadataExtractor.EXPERIMENT_OWNER_EMAIL_KEY);
+        experimentIdentifier =
+                new ExperimentIdentifierFactory(sampleMetadata.get(EXPERIMENT_IDENTIFIER_KEY))
+                        .createIdentifier();
+        sampleCodePrefix = sampleMetadata.get(SAMPLE_CODE_PREFIX_KEY);
+        emailAddress = sampleMetadata.get(EXPERIMENT_OWNER_EMAIL_KEY);
     }
 
     /**
@@ -101,17 +115,15 @@ class SampleMetadataExtractor
      */
     private SampleIdentifier createSample()
     {
-        ExperimentIdentifier experimentId =
-                new ExperimentIdentifier(null, SPACE_CODE, projectCode, experimentCode);
-
         SampleIdentifier sampleId =
-                new SampleIdentifier(new GroupIdentifier((String) null, SPACE_CODE), sampleCode);
+                SampleIdentifier.createOwnedBy(new SampleOwnerIdentifier(experimentIdentifier),
+                        sampleCodePrefix + "-" + sampleCodeSuffix);
 
         NewSample sample = new NewSample();
         SampleType sampleType = new SampleType();
         sampleType.setCode(SAMPLE_TYPE_CODE);
         sample.setSampleType(sampleType);
-        sample.setExperimentIdentifier(experimentId.toString());
+        sample.setExperimentIdentifier(experimentIdentifier.toString());
         sample.setIdentifier(sampleId.toString());
 
         Sample dbSample = openbisService.tryGetSampleWithExperiment(sampleId);
@@ -128,19 +140,13 @@ class SampleMetadataExtractor
      */
     private void verifyRequiredMetadataDataHasBeenProvided() throws UserFailureException
     {
-        if (null == projectCode)
-        {
-            throw new UserFailureException(
-                    "A project code must be specified to register an experiment.");
-        }
-
-        if (null == experimentCode)
+        if (null == experimentIdentifier)
         {
             throw new UserFailureException(
                     "An experiment code must be specified to register an experiment.");
         }
 
-        if (null == sampleCode)
+        if (null == sampleCodePrefix)
         {
             throw new UserFailureException(
                     "An sample code must be specified to register an experiment.");
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractorTest.java b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractorTest.java
new file mode 100644
index 00000000000..a223bf275e5
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/CinaDataSetInfoExtractorTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010 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.cina.dss.info;
+
+import java.io.File;
+import java.util.Properties;
+
+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.exceptions.UserFailureException;
+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.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class CinaDataSetInfoExtractorTest extends AssertJUnit
+{
+    Mockery context;
+
+    IEncapsulatedOpenBISService openbisService;
+
+    CinaDataSetInfoExtractor extractor;
+
+    @BeforeMethod
+    public void beforeMethod()
+    {
+        context = new Mockery();
+        openbisService = context.mock(IEncapsulatedOpenBISService.class);
+        extractor = new CinaDataSetInfoExtractor(new Properties());
+    }
+
+    @AfterMethod
+    public void afterMethod()
+    {
+        // 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 testRegisterExperiment()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(openbisService).tryToGetExperiment(with(any(ExperimentIdentifier.class)));
+                    will(returnValue(null));
+                    one(openbisService).registerExperiment(with(any(NewExperiment.class)));
+                }
+            });
+
+        File experimentFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder");
+        DataSetInformation dataSetInformation =
+                extractor.getDataSetInformation(experimentFolder, openbisService);
+
+        assertTrue("no-one@nowhere.ch".equals(dataSetInformation.tryGetUploadingUserEmail()));
+    }
+
+    // @Test
+    // public void testRegisterSample()
+    // {
+    // context.checking(new Expectations()
+    // {
+    // {
+    // one(openbisService).tryToGetExperiment(with(any(ExperimentIdentifier.class)));
+    // will(returnValue(null));
+    // one(openbisService).registerExperiment(with(any(NewExperiment.class)));
+    // }
+    // });
+    //
+    // File sampleFolder =
+    // new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder");
+    // DataSetInformation dataSetInformation =
+    // extractor.getDataSetInformation(sampleFolder, openbisService);
+    //
+    // assertTrue("no-one@nowhere.ch".equals(dataSetInformation.tryGetUploadingUserEmail()));
+    // }
+
+    @Test
+    public void testRegisterAmbiguousFolder()
+    {
+        File ambiguousDataFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder");
+
+        try
+        {
+            extractor.getDataSetInformation(ambiguousDataFolder, openbisService);
+            fail("An ambiguous data folder should result in a UserFailureException.");
+        } catch (UserFailureException ex)
+        {
+
+        }
+    }
+
+    @Test
+    public void testRegisterEmptyFolder()
+    {
+        File emptyDataFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/empty-data-folder");
+        extractor.getDataSetInformation(emptyDataFolder, openbisService);
+    }
+}
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/FolderOracleTest.java b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/FolderOracleTest.java
new file mode 100644
index 00000000000..0288e64fc34
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/FolderOracleTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010 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.cina.dss.info;
+
+import java.io.File;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.cina.dss.info.FolderOracle.FolderMetadata;
+import ch.systemsx.cisd.cina.dss.info.FolderOracle.FolderType;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class FolderOracleTest extends AssertJUnit
+{
+
+    @Test
+    public void testExperimentFolder()
+    {
+        FolderOracle folderOracle = new FolderOracle();
+        File experimentFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder");
+        FolderMetadata metadata = folderOracle.getMetadataForFolder(experimentFolder);
+        assertTrue(metadata.getType() == FolderType.EXPERIMENT);
+        assertTrue("experiment.properties".equals(metadata.tryGetMetadataFile().getName()));
+    }
+
+    @Test
+    public void testSampleFolder()
+    {
+        FolderOracle folderOracle = new FolderOracle();
+        File sampleFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder");
+        FolderMetadata metadata = folderOracle.getMetadataForFolder(sampleFolder);
+        assertTrue(metadata.getType() == FolderType.SAMPLE);
+        assertTrue("sample.properties".equals(metadata.tryGetMetadataFile().getName()));
+    }
+
+    @Test
+    public void testDataSetFolder()
+    {
+        FolderOracle folderOracle = new FolderOracle();
+        File datasetFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/dataset-data-folder");
+        FolderMetadata metadata = folderOracle.getMetadataForFolder(datasetFolder);
+        assertTrue(metadata.getType() == FolderType.DATA_SET);
+        assertTrue("dataset.properties".equals(metadata.tryGetMetadataFile().getName()));
+    }
+
+    @Test
+    public void testAmbiguousFolder()
+    {
+        FolderOracle folderOracle = new FolderOracle();
+        File ambiguousFolder =
+                new File("sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder");
+        try
+        {
+            folderOracle.getMetadataForFolder(ambiguousFolder);
+            fail("The method getMetadataForFolder should throw an error on folder ambiguous-data-folder.");
+        } catch (UserFailureException ex)
+        {
+            // This should happen
+        }
+    }
+}
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/dataset.properties b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/dataset.properties
new file mode 100644
index 00000000000..124fde3eff7
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/dataset.properties
@@ -0,0 +1,3 @@
+project.code = CINA1
+experiment.code = EXP
+experiment.owner-email = no-one@nowhere.ch
\ No newline at end of file
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/sample.properties b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/sample.properties
new file mode 100644
index 00000000000..124fde3eff7
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/ambiguous-data-folder/sample.properties
@@ -0,0 +1,3 @@
+project.code = CINA1
+experiment.code = EXP
+experiment.owner-email = no-one@nowhere.ch
\ No newline at end of file
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/dataset-data-folder/dataset.properties b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/dataset-data-folder/dataset.properties
new file mode 100644
index 00000000000..124fde3eff7
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/dataset-data-folder/dataset.properties
@@ -0,0 +1,3 @@
+project.code = CINA1
+experiment.code = EXP
+experiment.owner-email = no-one@nowhere.ch
\ No newline at end of file
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/empty-data-folder/.gitignore b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/empty-data-folder/.gitignore
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder/experiment.properties b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder/experiment.properties
new file mode 100644
index 00000000000..124fde3eff7
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/experiment-data-folder/experiment.properties
@@ -0,0 +1,3 @@
+project.code = CINA1
+experiment.code = EXP
+experiment.owner-email = no-one@nowhere.ch
\ No newline at end of file
diff --git a/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder/sample.properties b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder/sample.properties
new file mode 100644
index 00000000000..124fde3eff7
--- /dev/null
+++ b/rtd_cina/sourceTest/java/ch/systemsx/cisd/cina/dss/info/sample-data-folder/sample.properties
@@ -0,0 +1,3 @@
+project.code = CINA1
+experiment.code = EXP
+experiment.owner-email = no-one@nowhere.ch
\ No newline at end of file
-- 
GitLab