Commit 9c432517 authored by Matija Obreza's avatar Matija Obreza

Merge branch '401-download-mcpd-for-subsets-and-datasets' into 'master'

Resolve "Download MCPD for subsets and datasets"

Closes #401

See merge request genesys-pgr/genesys-server!330
parents 0c6d6f8e 1b44fac0
......@@ -16,6 +16,7 @@
package org.genesys.catalog.service;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
......@@ -454,4 +455,12 @@ public interface DatasetService {
*/
Dataset getDataset(UUID uuid, Integer version);
/**
* Generate Excel file with MCPD passport data for provided dataset.
*
* @param dataset the dataset
* @param outputStream the stream
*/
void writeXlsxMCPD(Dataset dataset, OutputStream outputStream) throws IOException;
}
......@@ -20,6 +20,7 @@ import static org.genesys.catalog.model.dataset.QDatasetCreator.datasetCreator;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
......@@ -37,6 +38,7 @@ import java.util.stream.Collectors;
import javax.validation.Valid;
import com.querydsl.jpa.JPAExpressions;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.genesys.blocks.security.service.CustomAclService;
......@@ -47,6 +49,7 @@ import org.genesys.catalog.model.dataset.DatasetCreator;
import org.genesys.catalog.model.dataset.DatasetLocation;
import org.genesys.catalog.model.dataset.DatasetVersions;
import org.genesys.catalog.model.dataset.QDataset;
import org.genesys.catalog.model.dataset.QDatasetAccessionRef;
import org.genesys.catalog.model.filters.DatasetFilter;
import org.genesys.catalog.model.traits.Descriptor;
import org.genesys.catalog.persistence.dataset.DatasetAccessionRefRepository;
......@@ -70,6 +73,7 @@ import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.service.DownloadService;
import org.genesys2.util.JPAUtils;
......@@ -348,6 +352,13 @@ public class DatasetServiceImpl implements DatasetService {
return dataset;
}
@Override
public void writeXlsxMCPD(Dataset dataset, OutputStream outputStream) throws IOException {
Predicate predicate = QAccession.accession.id.in(JPAExpressions.selectFrom(QDatasetAccessionRef.datasetAccessionRef)
.select(QDatasetAccessionRef.datasetAccessionRef.accession.id).where(QDatasetAccessionRef.datasetAccessionRef.dataset.eq(dataset)));
downloadService.writeXlsxMCPD(predicate, outputStream);
}
/**
* {@inheritDoc}
*/
......
......@@ -16,7 +16,9 @@
package org.genesys2.server.api.v1;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
import java.util.Set;
......@@ -60,6 +62,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/**
* The Class DatasetController.
*
......@@ -542,4 +546,26 @@ public class DatasetController extends ApiBaseController {
public DatasetLocation loadLocationByUuid(@PathVariable("locationUuid") final UUID locationUuid) throws NotFoundElement {
return datasetService.loadLocation(locationUuid);
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "{uuid}/download", method = RequestMethod.POST, params = { "mcpd" })
public void downloadMcpd(@PathVariable("uuid") final UUID datasetUuid, HttpServletResponse response) throws IOException, NotFoundElement {
final Dataset dataset = datasetService.getDataset(datasetUuid, null);
if (dataset == null) {
throw new NotFoundElement();
}
// Write MCPD to the stream.
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"MCPD - %1s.xlsx\"", dataset.getUuid()));
// response.flushBuffer();
final OutputStream outputStream = response.getOutputStream();
try {
datasetService.writeXlsxMCPD(dataset, outputStream);
response.flushBuffer();
} catch (EOFException e) {
LOG.warn("Download was aborted: {}", e.getMessage());
}
}
}
......@@ -16,7 +16,9 @@
package org.genesys2.server.api.v1;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
......@@ -45,11 +47,14 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import javax.servlet.http.HttpServletResponse;
/**
* The Class SubsetController.
*
......@@ -59,7 +64,7 @@ import io.swagger.annotations.Api;
@PreAuthorize("isAuthenticated()")
@RequestMapping(SubsetController.API_BASE)
@Api(tags = { "subset" })
public class SubsetController {
public class SubsetController extends ApiBaseController {
/** The Constant API_BASE. */
public static final String API_BASE = ApiBaseController.APIv1_BASE + "/subset";
......@@ -273,4 +278,26 @@ public class SubsetController {
return subsetService.rejectSubset(subset);
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "{uuid}/download", method = RequestMethod.POST, params = { "mcpd" })
public void downloadMcpd(@PathVariable("uuid") final UUID subsetUuid, HttpServletResponse response) throws IOException, NotFoundElement {
final Subset subset = subsetService.getSubset(subsetUuid);
if (subset == null) {
throw new NotFoundElement();
}
// Write MCPD to the stream.
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"MCPD - %1s.xlsx\"", subset.getUuid()));
// response.flushBuffer();
final OutputStream outputStream = response.getOutputStream();
try {
subsetService.writeXlsxMCPD(subset, outputStream);
response.flushBuffer();
} catch (EOFException e) {
LOG.warn("Download was aborted: {}", e.getMessage());
}
}
}
......@@ -21,6 +21,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import com.querydsl.core.types.Predicate;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.traits.Descriptor;
import org.genesys2.server.model.genesys.Metadata;
......@@ -37,6 +38,8 @@ public interface DownloadService {
void writeXlsxMCPD(AccessionFilter accessionFilter, OutputStream outputStream) throws IOException;
void writeXlsxMCPD(Predicate predicate, OutputStream outputStream) throws IOException;
void writeXlsxPDCI(AccessionFilter accessionFilter, OutputStream outputStream) throws IOException;
void writeXlsxDescriptor(List<Descriptor> descriptors, OutputStream outputStream) throws IOException;
......
......@@ -16,6 +16,8 @@
package org.genesys2.server.service;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Set;
......@@ -291,4 +293,12 @@ public interface SubsetService {
* @return the subset
*/
Subset setAccessionRefs(Subset input, @Valid Set<AccessionRef> accessionRefs);
/**
* Generate Excel file with MCPD passport data for provided subset.
*
* @param subset the subset
* @param outputStream the stream
*/
void writeXlsxMCPD(Subset subset, OutputStream outputStream) throws IOException;
}
......@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.common.usermodel.HyperlinkType;
......@@ -179,7 +180,17 @@ public class DownloadServiceImpl implements DownloadService {
}
@Override
public void writeXlsxMCPD(final AccessionFilter filter, final OutputStream outputStream) throws IOException {
public void writeXlsxMCPD(AccessionFilter filter, OutputStream outputStream) throws IOException {
final String dataSource = baseUrl + "/explore?filter=" + filter.toString();
writeXlsxMCPD(filter.buildQuery(), outputStream, filter.toString(), dataSource);
}
@Override
public void writeXlsxMCPD(Predicate predicate, OutputStream outputStream) throws IOException {
writeXlsxMCPD(predicate, outputStream, "", "");
}
private void writeXlsxMCPD(Predicate predicate, OutputStream outputStream, String filters, String dataSource) throws IOException {
XSSFWorkbook template = new XSSFWorkbook(getClass().getResourceAsStream("/template/download/MCPD.xlsx"));
POIXMLProperties props = template.getProperties();
......@@ -187,7 +198,7 @@ public class DownloadServiceImpl implements DownloadService {
coreProp.setCreated(new Nullable<Date>(new Date()));
POIXMLProperties.CustomProperties custProp = props.getCustomProperties();
custProp.addProperty("Filter", filter.toString());
custProp.addProperty("Filter", filters);
custProp.addProperty("Genesys URL", baseUrl);
// keep 50 rows in memory, exceeding rows will be flushed to disk
......@@ -203,11 +214,11 @@ public class DownloadServiceImpl implements DownloadService {
r.createCell(1).setCellValue(baseUrl);
r = legal.createRow(1);
r.createCell(0).setCellValue("Filters");
r.createCell(1).setCellValue(filter.toString());
r.createCell(1).setCellValue(filters);
r = legal.createRow(2);
r.createCell(0).setCellValue("Data source");
c = r.createCell(1);
c.setCellValue(baseUrl + "/explore?filter=" + filter.toString());
c.setCellValue(dataSource);
r = legal.createRow(3);
r.createCell(0).setCellValue("Date");
......@@ -225,7 +236,7 @@ public class DownloadServiceImpl implements DownloadService {
// Write accession information
final Writer writer = new Writer();
try {
accessionProcessor.process(filter, (accession) -> {
accessionProcessor.process(predicate, (accession) -> {
writer.processMCPD(sheet, wbStyles, accession);
return accession;
});
......
......@@ -18,6 +18,8 @@ package org.genesys2.server.service.impl;
import static org.genesys2.server.model.impl.QSubsetCreator.subsetCreator;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
......@@ -30,6 +32,7 @@ import java.util.stream.Collectors;
import javax.validation.Valid;
import com.querydsl.jpa.JPAExpressions;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.genesys.blocks.security.service.CustomAclService;
......@@ -40,8 +43,10 @@ import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.UserRole;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionRef;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.QSubset;
import org.genesys2.server.model.impl.QSubsetAccessionRef;
import org.genesys2.server.model.impl.Subset;
import org.genesys2.server.model.impl.SubsetAccessionRef;
import org.genesys2.server.model.impl.SubsetCreator;
......@@ -50,6 +55,7 @@ import org.genesys2.server.persistence.FaoInstituteRepository;
import org.genesys2.server.persistence.SubsetAccessionRefRepository;
import org.genesys2.server.persistence.SubsetCreatorRepository;
import org.genesys2.server.persistence.SubsetRepository;
import org.genesys2.server.service.DownloadService;
import org.genesys2.server.service.SubsetService;
import org.genesys2.server.service.filter.SubsetFilter;
import org.genesys2.util.JPAUtils;
......@@ -123,6 +129,10 @@ public class SubsetServiceImpl implements SubsetService {
@Autowired
private CustomAclService aclService;
/** The download service. */
@Autowired
private DownloadService downloadService;
/**
* {@inheritDoc}
*/
......@@ -713,4 +723,11 @@ public class SubsetServiceImpl implements SubsetService {
subsetRepository.save(datasets);
return updates.get();
}
@Override
public void writeXlsxMCPD(Subset subset, OutputStream outputStream) throws IOException {
Predicate predicate = QAccession.accession.id.in(JPAExpressions.selectFrom(QSubsetAccessionRef.subsetAccessionRef)
.select(QSubsetAccessionRef.subsetAccessionRef.accession.id).where(QSubsetAccessionRef.subsetAccessionRef.subset.eq(subset)));
downloadService.writeXlsxMCPD(predicate, outputStream);
}
}
......@@ -65,10 +65,24 @@ public class AccessionProcessor {
/// Size of database batch scan for IDs
private int batchSize = 1000;
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public void process(AccessionFilter filter, IAccessionAction action) throws Exception {
process(filter.buildQuery(), action, null);
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public void process(AccessionFilter filter, IAccessionAction action, Long maxSize) throws Exception {
process(filter.buildQuery(), action, maxSize);
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public void process(Predicate predicate, IAccessionAction action) throws Exception {
process(predicate, action, null);
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public void process(Predicate predicate, IAccessionAction action, Long maxSize) throws Exception {
Predicate predicate = filter.buildQuery();
long count = accessionRepository.count(predicate);
PathBuilder<Accession> builder = new PathBuilderFactory().create(Accession.class);
......@@ -113,12 +127,7 @@ public class AccessionProcessor {
} while (results.size() > 0 && (maxSize == null || startPosition < maxSize));
stopWatch.stop();
LOG.info("Processing Accessions for filter {} took {}ms", filter, stopWatch.getTime());
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public void process(AccessionFilter filter, IAccessionAction action) throws Exception {
process(filter, action, null);
LOG.info("Processing Accessions took {}ms", stopWatch.getTime());
}
private void loadAndProcess(List<Long> accessionIds, IAccessionAction action) throws Exception {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment