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 2a591dc37b96e03672c451408ade999fa1762fcb..b5c65b3999946372cb0659a4f2bfa2e902a7d866 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 @@ -70,7 +70,6 @@ import java.util.zip.ZipOutputStream; import javax.annotation.PostConstruct; import javax.annotation.Resource; -import javax.validation.constraints.NotNull; import org.apache.commons.io.filefilter.NameFileFilter; import org.apache.log4j.Logger; @@ -326,66 +325,106 @@ public class ExportExecutor implements IExportExecutor final TextFormatting textFormatting, final boolean compatibleWithImport, final Set<ExportFormat> exportFormats) throws IOException { - final XLSExport.PrepareWorkbookResult xlsExportResult = exportFormats.contains(ExportFormat.XLSX) - ? XLSExport.prepareWorkbook(api, sessionToken, exportablePermIds, exportReferredMasterData, exportFields, textFormatting, - compatibleWithImport) - : null; - final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + +// final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); final String fullFileName = String.format("%s.%s%s", EXPORT_FILE_PREFIX, new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS").format(new Date()), ZIP_EXTENSION); final Collection<String> warnings = new ArrayList<>(); - ExplicitlyClosableOutputStream ecos = null; - try - ( - final Workbook wb = xlsExportResult != null ? xlsExportResult.getWorkbook() : null; - final FileOutputStream os = sessionWorkspaceProvider.getFileOutputStream(sessionToken, fullFileName); - final ZipOutputStream zos = new ZipOutputStream(os); - final BufferedOutputStream bos = new BufferedOutputStream(zos, BUFFER_SIZE); - ) - { - ecos = new ExplicitlyClosableOutputStream(bos); - // This export should be done at the end because Workbook closes the whole stream - if (xlsExportResult != null) - { - exportXls(zos, ecos, xlsExportResult, wb, warnings); - } + final boolean hasXlsxFormat = exportFormats.contains(ExportFormat.XLSX); + final boolean hasHtmlFormat = exportFormats.contains(ExportFormat.HTML); + final boolean hasPdfFormat = exportFormats.contains(ExportFormat.PDF); + final boolean hasDataFormat = exportFormats.contains(ExportFormat.DATA); + + if (hasXlsxFormat) + { + exportXlsx(api, sessionToken, exportablePermIds, exportReferredMasterData, exportFields, textFormatting, compatibleWithImport, warnings); + } + +// try +// ( +// final Workbook wb = xlsExportResult != null ? xlsExportResult.getWorkbook() : null; +// final FileOutputStream os = sessionWorkspaceProvider.getFileOutputStream(sessionToken, fullFileName); +// final BufferedOutputStream bos = new BufferedOutputStream(os, BUFFER_SIZE); +// ) +// { +// // This export should be done at the end because Workbook closes the whole stream +// if (xlsExportResult != null) +// { +// exportXls(zos, bos, xlsExportResult, wb, warnings); +// } +// +// final boolean hasHtmlFormat = exportFormats.contains(ExportFormat.HTML); +// final boolean hasPdfFormat = exportFormats.contains(ExportFormat.PDF); +// final boolean hasDataFormat = exportFormats.contains(ExportFormat.DATA); +// +// if (hasHtmlFormat || hasPdfFormat || hasDataFormat) +// { +// final EntitiesVo entitiesVo = new EntitiesVo(sessionToken, exportablePermIds); +// +// if (hasPdfFormat || hasHtmlFormat) +// { +// final Set<String> existingZipEntries = new HashSet<>(); +// putNextDocZipEntry(existingZipEntries, zos, null, null, null, null, null, null, null, null, null); +// exportSpacesDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); +// exportProjectsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); +// exportExperimentsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); +// exportSamplesDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); +// exportDataSetsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); +// } +// +// if (hasDataFormat) +// { +// final Set<String> existingZipEntries = new HashSet<>(); +// exportData(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields); +// } +// } +// } - final boolean hasHtmlFormat = exportFormats.contains(ExportFormat.HTML); - final boolean hasPdfFormat = exportFormats.contains(ExportFormat.PDF); - final boolean hasDataFormat = exportFormats.contains(ExportFormat.DATA); + return new ExportResult(fullFileName, warnings); + } - if (hasHtmlFormat || hasPdfFormat || hasDataFormat) - { - final EntitiesVo entitiesVo = new EntitiesVo(sessionToken, exportablePermIds); + private static void exportXlsx(final IApplicationServerApi api, final String sessionToken, final List<ExportablePermId> exportablePermIds, + final boolean exportReferredMasterData, final Map<String, Map<String, List<Map<String, String>>>> exportFields, + final TextFormatting textFormatting, final boolean compatibleWithImport, final Collection<String> warnings) throws IOException + { + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + final File sessionWorkspaceDirectory = sessionWorkspaceProvider.getSessionWorkspace(sessionToken).getCanonicalFile(); + final XLSExport.PrepareWorkbookResult xlsExportResult = XLSExport.prepareWorkbook(api, sessionToken, exportablePermIds, + exportReferredMasterData, exportFields, textFormatting, compatibleWithImport); - if (hasPdfFormat || hasHtmlFormat) - { - final Set<String> existingZipEntries = new HashSet<>(); - putNextDocZipEntry(existingZipEntries, zos, null, null, null, null, null, null, null, null, null); - exportSpacesDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); - exportProjectsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); - exportExperimentsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); - exportSamplesDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); - exportDataSetsDoc(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields, exportFormats); - } + final File xlsxDirectory = new File(sessionWorkspaceDirectory, XLSX_DIRECTORY); + mkdir(xlsxDirectory); + + final File scriptsDirectory = new File(xlsxDirectory, SCRIPTS_DIRECTORY); - if (hasDataFormat) + final Map<String, String> xlsExportScripts = xlsExportResult.getScripts(); + if (!xlsExportScripts.isEmpty()) + { + mkdir(scriptsDirectory); + + for (final Map.Entry<String, String> script : xlsExportScripts.entrySet()) + { + final File scriptFile = new File(scriptsDirectory, script.getKey() + PYTHON_EXTENSION); + try (final BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(scriptFile), BUFFER_SIZE)) { - final Set<String> existingZipEntries = new HashSet<>(); - exportData(zos, ecos, sessionToken, entitiesVo, existingZipEntries, exportFields); + bos.write(script.getValue().getBytes()); + bos.flush(); } } - } finally + } + + try ( + final Workbook wb = xlsExportResult.getWorkbook(); + final BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(new File(xlsxDirectory, METADATA_FILE_NAME)), BUFFER_SIZE); + ) { - if (ecos != null) - { - ecos.doClose(); - } + wb.write(bos); } - return new ExportResult(fullFileName, warnings); + warnings.addAll(xlsExportResult.getWarnings()); } private void exportData(final ZipOutputStream zos, final OutputStream os, final String sessionToken, @@ -1496,48 +1535,13 @@ public class ExportExecutor implements IExportExecutor return new File(configurer.getResolvedProps().getProperty(REPO_PATH_KEY, DEFAULT_REPO_PATH)); } - /** - * This is a wrapper class to prevent other libraries from closing an output stream. - */ - private static class ExplicitlyClosableOutputStream extends OutputStream + private static void mkdir(final File dir) { - - private final OutputStream out; - - private ExplicitlyClosableOutputStream(final OutputStream out) - { - this.out = out; - } - - @Override - public void write(final int b) throws IOException + final boolean created = dir.mkdir(); + if (!created) { - out.write(b); + throw new RuntimeException(String.format("Cannot create directory '%s'.", dir.getPath())); } - - @Override - public void write(final @NotNull byte[] b) throws IOException - { - out.write(b); - } - - @Override - public void write(final @NotNull byte[] b, final int off, final int len) throws IOException - { - out.write(b, off, len); - } - - @Override - public void flush() throws IOException - { - out.flush(); - } - - public void doClose() throws IOException - { - out.close(); - } - } private static class EntitiesVo