From 65875ce7ff27171fa5b9e67845e5620551e8f394 Mon Sep 17 00:00:00 2001
From: vkovtun <vkovtun@ethz.ch>
Date: Wed, 4 Oct 2023 14:30:01 +0200
Subject: [PATCH] BIS-772: Writing implementation for export.

---
 .../v3/executor/exporter/ExportExecutor.java  | 121 ++++++++++++++++--
 .../generic/server/xls/export/XLSExport.java  |   5 +
 .../1/as/services/xls-export/xls-export.py    |   2 +-
 3 files changed, 118 insertions(+), 10 deletions(-)

diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
index 42d9344c6bf..15f2b7e7bac 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/exporter/ExportExecutor.java
@@ -17,31 +17,40 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.exporter;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
 
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.ExportOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.data.Attribute;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.data.ExportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.data.IExportableFields;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.data.SelectedFields;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.options.ExportFormat;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.exporter.options.ExportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportScript;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.UncompressedImportData;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ZipImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.id.PropertyTypePermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.xls.export.ExportableKind;
+import ch.ethz.sis.openbis.generic.server.xls.export.ExportablePermId;
+import ch.ethz.sis.openbis.generic.server.xls.export.FieldType;
+import ch.ethz.sis.openbis.generic.server.xls.export.XLSExport;
 import ch.ethz.sis.openbis.generic.server.xls.importer.XLSImport;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 
+@SuppressWarnings("SizeReplaceableByIsEmpty")
 @Component
 public class ExportExecutor implements IExportExecutor
 {
@@ -49,9 +58,103 @@ public class ExportExecutor implements IExportExecutor
     @Override
     public void doExport(final IOperationContext context, final ExportOperation operation)
     {
-        final ExportData exportData = operation.getExportData();
+        try {
+            final ExportData exportData = operation.getExportData();
+            final ExportOptions exportOptions = operation.getExportOptions();
+            final Set<ExportFormat> formats = exportOptions.getFormats();
 
-        // TODO: implement
+            if (formats.contains(ExportFormat.XLS))
+            {
+                // TODO: extract to a method
+
+                final IApplicationServerInternalApi applicationServerApi = CommonServiceProvider.getApplicationServerApi();
+
+//                final ch.ethz.sis.openbis.generic.server.xls.export.ImportOptions importerImportOptions =
+//                        new ch.ethz.sis.openbis.generic.server.xls.importer.ImportOptions();
+//
+//                final boolean projectSamplesEnabled = Boolean.parseBoolean(applicationServerApi.getServerInformation(context.getSession().getSessionToken())
+//                        .get("project-samples-enabled"));
+//                importerImportOptions.setAllowProjectSamples(projectSamplesEnabled);
+
+                final List<ExportablePermId> exportablePermIds = exportData.getPermIds().stream().map(exportablePermIdDto ->
+                        new ExportablePermId(
+                                ExportableKind.valueOf(exportablePermIdDto.getExportableKind().name()), exportablePermIdDto.getPermId())).collect(
+                        Collectors.toList());
+
+                final IExportableFields fields = exportData.getFields();
+                final Map<String, Map<String, List<Map<String, String>>>> exportFields;
+                if (fields instanceof SelectedFields)
+                {
+                    final SelectedFields selectedFields = (SelectedFields) fields;
+                    exportFields = new HashMap<>();
+
+                    // TODO: are all attributes exported?
+                    final Collection<Attribute> attributes = EnumSet.copyOf(selectedFields.getAttributes());
+                    if (attributes.size() > 0)
+                    {
+                        final Map<String, List<Map<String, String>>> selectedAttributes =
+                                attributes.stream().collect(Collectors.toMap(Attribute::name, this::convertAttributeToMap));
+
+                        exportFields.put("TYPE", selectedAttributes);
+                    }
+
+                    final List<PropertyTypePermId> properties = selectedFields.getProperties();
+                    // TODO: how to map PropertyTypePermId to entity kind?
+                    properties.stream().collect(Collectors.toMap(propertyTypePermId -> propertyTypePermId.))
+                } else
+                {
+                    exportFields = null;
+                }
+
+                // TODO: file prefix probably should be configurable
+                final XLSExport.ExportResult exportResult = XLSExport.export("export", applicationServerApi, context.getSession().getSessionToken(),
+                        exportablePermIds, exportOptions.isWithReferredTypes(), exportFields,
+                        XLSExport.TextFormatting.valueOf(exportOptions.getXlsTextFormat().name()), exportOptions.isWithImportCompatibility());
+            }
+        } catch (final IOException e)
+        {
+            throw UserFailureException.fromTemplate(e, "IO exception exporting.");
+        }
+    }
+
+    private List<Map<String, String>> convertAttributeToMap(final Attribute attribute)
+    {
+        final List<Map<String, String>> result = new ArrayList<>();
+        result.add(Map.of("type", FieldType.ATTRIBUTE.name(), "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.CODE.getName()));
+        result.add(Map.of("type", FieldType.ATTRIBUTE.name(), "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.DESCRIPTION.getName()));
+        switch (attribute)
+        {
+            case SPACE:
+            {
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(), "id",
+                        ch.ethz.sis.openbis.generic.server.xls.export.Attribute.REGISTRATOR.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(), "id",
+                        ch.ethz.sis.openbis.generic.server.xls.export.Attribute.REGISTRATION_DATE.getName()));
+                break;
+            }
+            case SAMPLE_TYPE:
+            {
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(), "id",
+                        ch.ethz.sis.openbis.generic.server.xls.export.Attribute.AUTO_GENERATE_CODES.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.VALIDATION_SCRIPT.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.GENERATED_CODE_PREFIX.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.UNIQUE_SUBCODES.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.MODIFICATION_DATE.getName()));
+                break;
+            }
+            case EXPERIMENT_TYPE:
+            {
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.VALIDATION_SCRIPT.getName()));
+                result.add(Map.of("type", FieldType.ATTRIBUTE.name(),
+                        "id", ch.ethz.sis.openbis.generic.server.xls.export.Attribute.MODIFICATION_DATE.getName()));
+                break;
+            }
+        }
     }
 
     private static void importXls(final IOperationContext context, final ImportOperation operation, final Map<String, String> scripts,
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/XLSExport.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/XLSExport.java
index 5800293f841..cbe490c6a52 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/XLSExport.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/XLSExport.java
@@ -70,6 +70,11 @@ public class XLSExport
 
     private static final String TYPE_KEY = "TYPE";
 
+    private XLSExport()
+    {
+        throw new UnsupportedOperationException("Instantiation of a utility class.");
+    }
+
     public static ExportResult export(final String filePrefix, final IApplicationServerApi api,
             final String sessionToken, final List<ExportablePermId> exportablePermIds,
             final boolean exportReferredMasterData,
diff --git a/ui-admin/src/core-plugins/admin/1/as/services/xls-export/xls-export.py b/ui-admin/src/core-plugins/admin/1/as/services/xls-export/xls-export.py
index a49b4c060df..499602fba1e 100644
--- a/ui-admin/src/core-plugins/admin/1/as/services/xls-export/xls-export.py
+++ b/ui-admin/src/core-plugins/admin/1/as/services/xls-export/xls-export.py
@@ -34,7 +34,7 @@ def export(context, parameters):
                         "<SAMPLE_TYPE | EXPERIMENT_TYPE | DATASET_TYPE | VOCABULARY_TYPE | SPACE | PROJECT>": [
                           {"type": "ATTRIBUTE", "id": "<attribute name>"},
                           ...
-                        ] - attribute for each type and entity without types to be exported,
+                        ] - attributes for each type and entity without types to be exported,
                             if the list is empty no attributes will be exported for the given one
                         ...
                     },
-- 
GitLab