From c55b3f25e49650164ed1fa99271f6bb0cef56844 Mon Sep 17 00:00:00 2001 From: Yannick Marcon Date: Wed, 7 Dec 2022 23:17:20 +0100 Subject: [PATCH] Deferred attachment stream extraction --- .../StudyTableSourceServiceRegistry.java | 69 +++++++++++-------- .../mica/core/source/ExcelTableSource.java | 13 ++-- .../mica/spi/source/StudyTableFileSource.java | 2 +- .../mica/spi/source/StudyTableFileStream.java | 24 +++++++ 4 files changed, 74 insertions(+), 34 deletions(-) create mode 100644 mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileStream.java diff --git a/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java b/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java index 2fb3907308..bc03b656d5 100644 --- a/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java +++ b/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java @@ -78,7 +78,7 @@ private StudyTableSource makeStudyTableSourceInternal(StudyTableContext context, if (ExcelTableSource.isFor(source)) { ExcelTableSource tableSource = ExcelTableSource.fromURN(source); tableSource.setStudyTableContext(context); - tableSource.initialise(getFileInputStream(context, tableSource.getPath())); + tableSource.initialise(new AttachmentStream(context, tableSource.getPath())); return tableSource; } Optional serviceOptional = pluginsService.getStudyTableSourceServices().stream() @@ -88,43 +88,56 @@ private StudyTableSource makeStudyTableSourceInternal(StudyTableContext context, tableSource.setStudyTableContext(context); if (tableSource instanceof StudyTableFileSource) { StudyTableFileSource fileSource = (StudyTableFileSource)tableSource; - fileSource.initialise(getFileInputStream(context, fileSource.getPath())); + fileSource.initialise(new AttachmentStream(context, fileSource.getPath())); } return tableSource; } throw new NoSuchElementException("Missing study-table-source plugin to handle source: " + source); } - private InputStream getFileInputStream(StudyTableContext context, String path) { - String fullPath = path; - Optional attachmentState; - if (!fullPath.startsWith("/")) { - // not a full path, then it may be relative to the dataset's folder - fullPath = String.format("/%s-dataset/%s/%s", (context.getDataset() instanceof StudyDataset ? "collected" : "harmonized"), context.getDataset().getId(), path); - attachmentState = getAttachmentState(fullPath); - // not found, then try a path relative to the study's folder - if (!attachmentState.isPresent()) { - fullPath = String.format("/%s-study/%s/%s", (context.getStudy() instanceof Study ? "individual" : "harmonization"), context.getStudy().getId(), path); + + private class AttachmentStream implements StudyTableFileStream { + + private final StudyTableContext context; + private final String path; + + private AttachmentStream(StudyTableContext context, String path) { + this.context = context; + this.path = path; + } + + @Override + public InputStream getInputStream() { + String fullPath = path; + Optional attachmentState; + if (!fullPath.startsWith("/")) { + // not a full path, then it may be relative to the dataset's folder + fullPath = String.format("/%s-dataset/%s/%s", (context.getDataset() instanceof StudyDataset ? "collected" : "harmonized"), context.getDataset().getId(), path); + attachmentState = getAttachmentState(fullPath); + // not found, then try a path relative to the study's folder + if (!attachmentState.isPresent()) { + fullPath = String.format("/%s-study/%s/%s", (context.getStudy() instanceof Study ? "individual" : "harmonization"), context.getStudy().getId(), path); + attachmentState = getAttachmentState(fullPath); + } + } else { attachmentState = getAttachmentState(fullPath); } - } else { - attachmentState = getAttachmentState(fullPath); - } - if (attachmentState.isPresent()) { - return fileStoreService.getFile(attachmentState.get().getAttachment().getFileReference()); - } else { - throw new NoSuchValueTableException("No value table at " + fullPath); + if (attachmentState.isPresent()) { + return fileStoreService.getFile(attachmentState.get().getAttachment().getFileReference()); + } else { + throw new NoSuchValueTableException("No value table at " + fullPath); + } } - } - private Optional getAttachmentState(String fullPath) { - log.info("Reading study table from file: {}", fullPath); - Pair pathName = FileSystemService.extractPathName(fullPath); - try { - AttachmentState state = fileSystemService.getAttachmentState(pathName.getKey(), pathName.getValue(), false); - return Optional.of(state); - } catch (Exception e) { - return Optional.empty(); + private Optional getAttachmentState(String fullPath) { + log.info("Reading study table from file: {}", fullPath); + Pair pathName = FileSystemService.extractPathName(fullPath); + try { + AttachmentState state = fileSystemService.getAttachmentState(pathName.getKey(), pathName.getValue(), false); + return Optional.of(state); + } catch (Exception e) { + return Optional.empty(); + } } } diff --git a/mica-core/src/main/java/org/obiba/mica/core/source/ExcelTableSource.java b/mica-core/src/main/java/org/obiba/mica/core/source/ExcelTableSource.java index 76e94e74fd..1fcc496b43 100644 --- a/mica-core/src/main/java/org/obiba/mica/core/source/ExcelTableSource.java +++ b/mica-core/src/main/java/org/obiba/mica/core/source/ExcelTableSource.java @@ -16,12 +16,10 @@ import org.obiba.magma.datasource.excel.ExcelDatasource; import org.obiba.magma.support.Initialisables; import org.obiba.mica.spi.source.AbstractStudyTableSource; -import org.obiba.mica.spi.source.IVariable; import org.obiba.mica.spi.source.StudyTableFileSource; -import org.obiba.mica.web.model.Mica; +import org.obiba.mica.spi.source.StudyTableFileStream; import javax.validation.constraints.NotNull; -import java.io.InputStream; import java.util.List; public class ExcelTableSource extends AbstractStudyTableSource implements StudyTableFileSource { @@ -35,6 +33,8 @@ public class ExcelTableSource extends AbstractStudyTableSource implements StudyT private ExcelDatasource excelDatasource; + private StudyTableFileStream fileStream; + public static boolean isFor(String source) { if (Strings.isNullOrEmpty(source) || !source.startsWith("urn:file:")) return false; @@ -84,12 +84,15 @@ public String getURN() { } @Override - public void initialise(InputStream in) { - excelDatasource = new ExcelDatasource(path, in); + public void initialise(StudyTableFileStream in) { + this.fileStream = in; + // deferred init + this.initialized = false; } private void ensureInitialized() { if (!initialized) { + excelDatasource = new ExcelDatasource(path, fileStream.getInputStream()); Initialisables.initialise(excelDatasource); initialized = true; } diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileSource.java b/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileSource.java index 527ebdca71..a1a6d5010b 100644 --- a/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileSource.java +++ b/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileSource.java @@ -29,6 +29,6 @@ public interface StudyTableFileSource extends StudyTableSource { * * @param in */ - void initialise(InputStream in); + void initialise(StudyTableFileStream in); } diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileStream.java b/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileStream.java new file mode 100644 index 0000000000..0914f2d3f4 --- /dev/null +++ b/mica-spi/src/main/java/org/obiba/mica/spi/source/StudyTableFileStream.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.spi.source; + +import java.io.InputStream; + +public interface StudyTableFileStream { + + /** + * Get the Mica file input stream on demand. + * + * @return + */ + InputStream getInputStream(); + +}