diff --git a/src/main/java/org/genesys2/server/api/v1/AccessionController.java b/src/main/java/org/genesys2/server/api/v1/AccessionController.java index cedd500e706565c031ce0a000e9fb48fdd3d3772..584a4100103d61e6a16ebe06620d2aa05d8c1e06 100644 --- a/src/main/java/org/genesys2/server/api/v1/AccessionController.java +++ b/src/main/java/org/genesys2/server/api/v1/AccessionController.java @@ -486,6 +486,51 @@ public class AccessionController { } } + @PreAuthorize("isAuthenticated()") + @RequestMapping(value = "/download-selected", method = RequestMethod.POST, params = { "mcpd" }) + public void downloadMcpdByUuids(@RequestParam(value="uuids", required = true) Set uuids, HttpServletResponse response) throws IOException { + // Create JSON filter + AccessionFilter filter = new AccessionFilter(); + filter.uuid().addAll(uuids); + + final long countFiltered = accessionService.countAccessions(filter); + if (countFiltered > DOWNLOAD_LIMIT) { + throw new InvalidApiUsageException("Refusing to export more than " + DOWNLOAD_LIMIT + " entries"); + } + + // Write MCPD to the stream. + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-selected-%1s.xlsx\"", System.currentTimeMillis())); + + final OutputStream outputStream = response.getOutputStream(); + try { + downloadService.writeXlsxMCPD(filter, outputStream, null, null); + response.flushBuffer(); + } catch (EOFException e) { + LOG.warn("Download was aborted: {}", e.getMessage()); + } + } + + @RequestMapping(value = "/download-selected", method = RequestMethod.POST, params = { "dwca" }) + public void downloadDwcaByUuids(@RequestParam(value="uuids", required = true) Set uuids, HttpServletResponse response) throws Exception { + // Create JSON filter + AccessionFilter filter = new AccessionFilter(); + filter.uuid().addAll(uuids); + + final long countFiltered = accessionService.countAccessions(filter); + if (countFiltered > DOWNLOAD_LIMIT) { + throw new InvalidApiUsageException("Refusing to export more than " + DOWNLOAD_LIMIT + " entries"); + } + + // Write Darwin Core Archive to the stream. + response.setContentType("application/zip"); + response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-selected-%1$s.zip\"", System.currentTimeMillis())); + + final OutputStream outputStream = response.getOutputStream(); + genesysService.writeAccessions(filter, outputStream, null, null); + response.flushBuffer(); + } + @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/download", method = RequestMethod.POST, params = { "mcpd" }) public void downloadMcpd(@RequestParam(value = "f", required = false, defaultValue = "") String filterCode, @RequestParam(value="filter", required = false) AccessionFilter filter, HttpServletResponse response) throws IOException { @@ -505,7 +550,7 @@ public class AccessionController { final OutputStream outputStream = response.getOutputStream(); try { - downloadService.writeXlsxMCPD(filterInfo.filter, outputStream); + downloadService.writeXlsxMCPD(filterInfo.filter, outputStream, filterInfo.filterCode, "/a/" + filterInfo.filterCode); response.flushBuffer(); } catch (EOFException e) { LOG.warn("Download was aborted: {}", e.getMessage()); @@ -532,7 +577,7 @@ public class AccessionController { final OutputStream outputStream = response.getOutputStream(); try { - downloadService.writeXlsxPDCI(filterInfo.filter, outputStream); + downloadService.writeXlsxPDCI(filterInfo.filter, outputStream, filterInfo.filterCode, "/a/" + filterInfo.filterCode); response.flushBuffer(); } catch (EOFException e) { LOG.warn("Download was aborted: {}", e.getMessage()); @@ -555,7 +600,7 @@ public class AccessionController { response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-%1$s.zip\"", filterInfo.filterCode)); final OutputStream outputStream = response.getOutputStream(); - genesysService.writeAccessions(filterInfo.filter, outputStream); + genesysService.writeAccessions(filterInfo.filter, outputStream, filterInfo.filterCode, "/a/" + filterInfo.filterCode); response.flushBuffer(); } diff --git a/src/main/java/org/genesys2/server/api/v1/InstituteController.java b/src/main/java/org/genesys2/server/api/v1/InstituteController.java index 4e84f58cc0bd70b425f776aa63a473ffe28b9a8e..b531269b1ef85a68befadf3444984f9213c14498 100644 --- a/src/main/java/org/genesys2/server/api/v1/InstituteController.java +++ b/src/main/java/org/genesys2/server/api/v1/InstituteController.java @@ -200,7 +200,7 @@ public class InstituteController { response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-%1$s.zip\"", faoInstitute.getCode())); final OutputStream outputStream = response.getOutputStream(); - genesysService.writeAccessions(filter, outputStream); + genesysService.writeAccessions(filter, outputStream, null, "/wiews/" + faoInstitute.getCode()); response.flushBuffer(); } @@ -224,7 +224,7 @@ public class InstituteController { final OutputStream outputStream = response.getOutputStream(); try { - downloadService.writeXlsxPDCI(filter, outputStream); + downloadService.writeXlsxPDCI(filter, outputStream, null, "/wiews/" + faoInstitute.getCode()); response.flushBuffer(); } catch (EOFException e) { LOG.warn("Download was aborted", e); @@ -251,7 +251,7 @@ public class InstituteController { final OutputStream outputStream = response.getOutputStream(); try { - downloadService.writeXlsxMCPD(filter, outputStream); + downloadService.writeXlsxMCPD(filter, outputStream, null, "/wiews/" + faoInstitute.getCode()); response.flushBuffer(); } catch (EOFException e) { LOG.warn("Download was aborted", e); diff --git a/src/main/java/org/genesys2/server/service/DownloadService.java b/src/main/java/org/genesys2/server/service/DownloadService.java index 0d35fa0e3f51e8c373643075072e04d7f114c91d..8525af6c1276cc490e3edde73c614b25576fb503 100644 --- a/src/main/java/org/genesys2/server/service/DownloadService.java +++ b/src/main/java/org/genesys2/server/service/DownloadService.java @@ -39,15 +39,15 @@ import org.genesys2.server.service.filter.AccessionFilter; */ public interface DownloadService { - void writeXlsxMCPD(AccessionFilter accessionFilter, OutputStream outputStream) throws IOException; + void writeXlsxMCPD(AccessionFilter accessionFilter, OutputStream outputStream, String shortFilter, String dataSource) throws IOException; - void writeXlsxMCPD(Predicate predicate, OutputStream outputStream, String filters, String dataSource) throws IOException; + void writeXlsxMCPD(Predicate predicate, OutputStream outputStream, String shortFilter, String dataSource) throws IOException; - void writeXlsxMCPD(JPQLQuery queryAccessionId, OutputStream outputStream, String filters, String dataSource) throws IOException; + void writeXlsxMCPD(JPQLQuery queryAccessionId, OutputStream outputStream, String shortFilter, String dataSource) throws IOException; - void writeXlsxMCPD(IDownloadAction action, OutputStream outputStream, String filters, String dataSource) throws IOException; + void writeXlsxMCPD(IDownloadAction action, OutputStream outputStream, String shortFilter, String dataSource) throws IOException; - void writeXlsxPDCI(AccessionFilter accessionFilter, OutputStream outputStream) throws IOException; + void writeXlsxPDCI(AccessionFilter accessionFilter, OutputStream outputStream, String shortFilter, String dataSource) throws IOException; void writeXlsxDescriptor(List descriptors, OutputStream outputStream) throws IOException; diff --git a/src/main/java/org/genesys2/server/service/GenesysService.java b/src/main/java/org/genesys2/server/service/GenesysService.java index 7c6fee2987ce82b2d863ab3bb06c3cb344b3ae2c..65e653f1c79feecf5360c531f01ca14d70693272 100644 --- a/src/main/java/org/genesys2/server/service/GenesysService.java +++ b/src/main/java/org/genesys2/server/service/GenesysService.java @@ -152,7 +152,7 @@ public interface GenesysService { long countDatasets(FaoInstitute faoInstitute); - void writeAccessions(AccessionFilter filter, OutputStream outputStream) throws Exception; + void writeAccessions(AccessionFilter filter, OutputStream outputStream, String shortFilter, String dataSource) throws Exception; List listAccessionsGeo(Set copy); diff --git a/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java index 534034253196b3bf2173c0d8fa98391e58ba3446..67e43229606911623d240fb26140f9e1578d6049 100644 --- a/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java @@ -21,7 +21,6 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URLEncoder; import java.sql.ResultSet; import java.sql.SQLException; import java.text.MessageFormat; @@ -168,9 +167,6 @@ public class DownloadServiceImpl implements DownloadService { @Autowired private TraitService traitService; - @Value("${base.url}") - private String baseUrl; - @Value("${frontend.url}") private String frontendUrl; @@ -197,9 +193,7 @@ public class DownloadServiceImpl implements DownloadService { } @Override - public void writeXlsxMCPD(AccessionFilter filter, OutputStream outputStream) throws IOException { - final String dataSource = baseUrl + "/explore?filter=" + filter.toString(); - + public void writeXlsxMCPD(AccessionFilter filter, OutputStream outputStream, String shortFilter, String dataSource) throws IOException { if (filter.isFulltextQuery()) { writeXlsxMCPD((action) -> { try { @@ -208,14 +202,14 @@ public class DownloadServiceImpl implements DownloadService { } catch (Exception e) { LOG.warn("Error generating: {}", e.getMessage()); } - }, outputStream, filter.toString(), dataSource); + }, outputStream, shortFilter, dataSource); } else { - writeXlsxMCPD(filter.buildPredicate(), outputStream, filter.toString(), dataSource); + writeXlsxMCPD(filter.buildPredicate(), outputStream, shortFilter, dataSource); } } @Override - public void writeXlsxMCPD(Predicate predicate, OutputStream outputStream, String filters, String dataSource) throws IOException { + public void writeXlsxMCPD(Predicate predicate, OutputStream outputStream, String shortFilter, String dataSource) throws IOException { PathBuilder builder = new PathBuilderFactory().create(Accession.class); Querydsl querydsl = new Querydsl(entityManager, builder); JPQLQuery query = querydsl.createQuery(QAccession.accession) @@ -227,11 +221,11 @@ public class DownloadServiceImpl implements DownloadService { // apply filter query.where(predicate); - writeXlsxMCPD(query, outputStream, filters, dataSource); + writeXlsxMCPD(query, outputStream, shortFilter, dataSource); } @Override - public void writeXlsxMCPD(JPQLQuery queryAccessionId, OutputStream outputStream, String filters, String dataSource) throws IOException { + public void writeXlsxMCPD(JPQLQuery queryAccessionId, OutputStream outputStream, String shortFilter, String dataSource) throws IOException { writeXlsxMCPD((action) -> { try { accessionProcessor.process(queryAccessionId, action, null); @@ -239,11 +233,11 @@ public class DownloadServiceImpl implements DownloadService { } catch (Exception e) { LOG.warn("Error generating: {}", e.getMessage()); } - }, outputStream, filters, dataSource); + }, outputStream, shortFilter, dataSource); } @Override - public void writeXlsxMCPD(IDownloadAction action, OutputStream outputStream, String filters, String dataSource) throws IOException { + public void writeXlsxMCPD(IDownloadAction action, OutputStream outputStream, String shortFilter, String dataSource) throws IOException { XSSFWorkbook template = new XSSFWorkbook(getClass().getResourceAsStream("/template/download/MCPD.xlsx")); POIXMLProperties props = template.getProperties(); @@ -251,7 +245,9 @@ public class DownloadServiceImpl implements DownloadService { coreProp.setCreated(new Nullable(new Date())); POIXMLProperties.CustomProperties custProp = props.getCustomProperties(); - custProp.addProperty("Filter", filters); + if (StringUtils.isNotBlank(shortFilter)) { + custProp.addProperty("Filter", shortFilter); + } custProp.addProperty("Genesys URL", frontendUrl); // keep 50 rows in memory, exceeding rows will be flushed to disk @@ -262,23 +258,30 @@ public class DownloadServiceImpl implements DownloadService { Sheet legal = wb.getXSSFSheet("Legal information"); Row r; Cell c; - r = legal.createRow(0); + int row = 0; + r = legal.createRow(row++); r.createCell(0).setCellValue("Server URL"); r.createCell(1).setCellValue(frontendUrl); - r = legal.createRow(1); - r.createCell(0).setCellValue("Filters"); - r.createCell(1).setCellValue(filters); - r = legal.createRow(2); - r.createCell(0).setCellValue("Data source"); - c = r.createCell(1); - c.setCellValue(dataSource); - r = legal.createRow(3); + if (StringUtils.isNotBlank(shortFilter)) { + r = legal.createRow(row++); + r.createCell(0).setCellValue("Filters"); + r.createCell(1).setCellValue(shortFilter); + } + + if (StringUtils.isNotBlank(dataSource)) { + r = legal.createRow(row++); + r.createCell(0).setCellValue("Data source"); + c = r.createCell(1); + c.setCellValue(frontendUrl + dataSource); + } + + r = legal.createRow(row++); r.createCell(0).setCellValue("Date"); c = r.createCell(1); c.setCellStyle(dateStyle); c.setCellValue(new Date()); - r = legal.createRow(4); + r = legal.createRow(row); r.createCell(0).setCellValue("Attribution"); r.createCell(1).setCellValue(frontendUrl + "/content/terms"); @@ -787,7 +790,7 @@ public class DownloadServiceImpl implements DownloadService { } @Override - public void writeXlsxPDCI(final AccessionFilter filter, final OutputStream outputStream) throws IOException { + public void writeXlsxPDCI(final AccessionFilter filter, final OutputStream outputStream, String shortFilter, String dataSource) throws IOException { XSSFWorkbook template = new XSSFWorkbook(getClass().getResourceAsStream("/template/download/PDCI.xlsx")); @@ -801,22 +804,29 @@ public class DownloadServiceImpl implements DownloadService { Sheet legal = wb.getXSSFSheet("Legal information"); Row r; Cell c; - r = legal.createRow(0); + int row = 0; + r = legal.createRow(row++); r.createCell(0).setCellValue("Server URL"); updateCellUrl(r, 1, frontendUrl); - r = legal.createRow(1); - r.createCell(0).setCellValue("Filters"); - r.createCell(1).setCellValue(filter.toString()); - r = legal.createRow(2); - r.createCell(0).setCellValue("Data source"); - updateCellUrl(r, 1, baseUrl + "/explore?filter=" + URLEncoder.encode(filter.toString(), "UTF-8")); - - r = legal.createRow(3); + + if (StringUtils.isNotBlank(shortFilter)) { + r = legal.createRow(row++); + r.createCell(0).setCellValue("Filters"); + r.createCell(1).setCellValue(shortFilter); + } + + if (StringUtils.isNotBlank(dataSource)) { + r = legal.createRow(row++); + r.createCell(0).setCellValue("Data source"); + updateCellUrl(r, 1, frontendUrl + dataSource); + } + + r = legal.createRow(row++); r.createCell(0).setCellValue("Date"); c = r.createCell(1); c.setCellStyle(dateStyle); c.setCellValue(new Date()); - r = legal.createRow(4); + r = legal.createRow(row); r.createCell(0).setCellValue("Attribution"); updateCellUrl(r, 1, frontendUrl + "/content/terms"); diff --git a/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java index 85ad5fa005344b73ed4aa5fa32390b8b9446a3be..cf38185387e47203d8f337a8dbcd7e23d3fd811c 100644 --- a/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java @@ -41,6 +41,7 @@ import java.util.zip.ZipOutputStream; import javax.persistence.EntityManager; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.security.SecurityContextUtil; import org.genesys.blocks.security.model.AclSid; import org.genesys.blocks.security.service.CustomAclService; @@ -105,6 +106,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; @@ -131,6 +133,9 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { public static final Logger LOG = LoggerFactory.getLogger(GenesysServiceImpl.class); + @Value("${frontend.url}") + private String frontendUrl; + @Autowired private EntityManager entityManager; @@ -1072,19 +1077,23 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Override // TODO FIXME Need proper term URLs - public void writeAccessions(final AccessionFilter filter, final OutputStream outputStream) throws Exception { + public void writeAccessions(final AccessionFilter filter, final OutputStream outputStream, String shortFilter, String dataSource) throws Exception { // UTF8 is used for encoding entry names final ZipOutputStream zos = new ZipOutputStream(outputStream); - zos.setComment("Genesys Accessions filter=" + filter); + final StringBuilder commentBuilder = new StringBuilder("Genesys Accessions"); + if (StringUtils.isNotBlank(shortFilter)) { + commentBuilder.append(" ").append("filter=").append(shortFilter); + } + zos.setComment(commentBuilder.toString()); zos.flush(); // Filter information final ZipEntry readmeEntry = new ZipEntry("README.txt"); - readmeEntry.setComment("Extra iformation"); + readmeEntry.setComment("Extra information"); readmeEntry.setTime(System.currentTimeMillis()); zos.putNextEntry(readmeEntry); - writeREADME(filter, zos); + writeREADME(zos, shortFilter, dataSource); zos.closeEntry(); zos.flush(); @@ -1206,19 +1215,24 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { outputStream.flush(); } - private void writeREADME(AccessionFilter filter, ZipOutputStream zos) throws IOException { + private void writeREADME(ZipOutputStream zos, String shortFilter, String dataSource) throws IOException { final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(zos)); bw.write("Date:\t"); bw.write(new Date().toString()); bw.write("\n"); - bw.write("Filter:\t"); - bw.write(filter.toString()); - bw.write("\n"); + if (StringUtils.isNotBlank(shortFilter)) { + bw.write("Filter:\t"); + bw.write(shortFilter); + bw.write("\n"); + } - bw.write("URL:\thttps://www.genesys-pgr.org/explore?filter="); - bw.write(filter.toString()); - bw.write("\n"); + if (StringUtils.isNotBlank(dataSource)) { + bw.write("URL:\t"); + bw.write(frontendUrl); + bw.write(dataSource); + bw.write("\n"); + } bw.write("Attribution:\t"); bw.write("https://www.genesys-pgr.org/content/terms");