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