Commit c054dac5 authored by Matija Obreza's avatar Matija Obreza

MCPD XLSX

parent c117b8ce
......@@ -522,6 +522,11 @@
<artifactId>transifex-client</artifactId>
<version>0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10.1</version>
</dependency>
</dependencies>
<build>
......
......@@ -20,6 +20,7 @@ import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.RowCallbackHandler;
public interface GenesysLowlevelRepository {
......@@ -53,4 +54,6 @@ public interface GenesysLowlevelRepository {
int countAccessions(AppliedFilters filter);
void listAccessionIds(AppliedFilters filter, Sort sort, RowCallbackHandler rowCallbackHandler);
}
......@@ -32,6 +32,7 @@ import org.genesys2.server.service.impl.DirectMysqlQuery;
import org.genesys2.server.service.impl.DirectMysqlQuery.MethodResolver;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
......@@ -256,6 +257,34 @@ public class GenesysLowlevelRepositoryImpl implements GenesysLowlevelRepository
}, rowCallbackHandler);
}
@Override
public void listAccessionIds(final AppliedFilters filter, final Sort sort, final RowCallbackHandler rowCallbackHandler) {
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accession", "a");
directQuery.jsonFilter(filter, new MethodResolver() {
@Override
public Method getMethod(final long methodId) {
return GenesysLowlevelRepositoryImpl.this.methodRepository.findOne(methodId);
}
});
directQuery.sort(sort);
this.jdbcTemplate.query(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(final Connection con) throws SQLException {
final PreparedStatement stmt = con.prepareStatement(directQuery
.getQuery("a.id"));
final ArgumentPreparedStatementSetter apss = new ArgumentPreparedStatementSetter(directQuery.getParameters());
apss.setValues(stmt);
// Set mysql JConnector to stream results
// stmt.setFetchSize(Integer.MIN_VALUE);
return stmt;
}
}, rowCallbackHandler);
}
@Override
public void listAccessionsGeo(final AppliedFilters filter, final RowCallbackHandler rowCallbackHandler) {
final DirectMysqlQuery directQuery = new DirectMysqlQuery("accessiongeo", "geo");
......
/**
* Copyright 2014 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.service;
import java.io.IOException;
import java.io.OutputStream;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
/**
* Defines available downloads
*
* @author matijaobreza
*
*/
public interface DownloadService {
void writeXlsxMCPD(AppliedFilters filters, OutputStream outputStream) throws IOException;
}
......@@ -37,6 +37,7 @@ import org.genesys2.server.service.impl.FilterHandler.MinValueFilter;
import org.genesys2.server.service.impl.FilterHandler.StartsWithFilter;
import org.genesys2.server.service.impl.FilterHandler.ValueRangeFilter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
public class DirectMysqlQuery {
......@@ -85,7 +86,9 @@ public class DirectMysqlQuery {
if (StringUtils.isNotBlank(alias)) {
sb.append(alias).append(StringUtils.SPACE);
}
if (StringUtils.isNotBlank(onExpr)) {
sb.append("on ").append(onExpr).append(StringUtils.SPACE);
}
return this;
}
......@@ -397,18 +400,13 @@ public class DirectMysqlQuery {
return params.toArray();
}
public DirectMysqlQuery pageable(Pageable pageable) {
public DirectMysqlQuery sort(Sort sort) {
if (sortBuffer.length() != 0) {
throw new RuntimeException("sortBuffer is not blank, invalid use of #pageable(Pageable)");
}
if (pageable == null) {
return this;
}
if (pageable.getSort() != null) {
sortBuffer.append("\n order by ");
for (final Order o : pageable.getSort()) {
for (final Order o : sort) {
if (LOG.isDebugEnabled()) {
LOG.debug("Order: " + o);
}
......@@ -422,6 +420,21 @@ public class DirectMysqlQuery {
sortBuffer.append("a.").append(o.getProperty());
sortBuffer.append(" ").append(o.getDirection());
}
return this;
}
public DirectMysqlQuery pageable(Pageable pageable) {
if (sortBuffer.length() != 0) {
throw new RuntimeException("sortBuffer is not blank, invalid use of #pageable(Pageable)");
}
if (pageable == null) {
return this;
}
if (pageable.getSort() != null) {
sort(pageable.getSort());
}
sortBuffer.append(" limit ");
if (LOG.isDebugEnabled()) {
......
......@@ -38,6 +38,7 @@ import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.genesys.ParameterCategory;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.DownloadService;
import org.genesys2.server.service.ElasticService;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysFilterService;
......@@ -57,6 +58,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -71,6 +73,8 @@ import com.jhlabs.image.MapColorsFilter;
@Controller
public class ExplorerController extends BaseController {
private static final int DOWNLOAD_LIMIT = 100000;
@Autowired
private GenesysFilterService filterService;
......@@ -98,6 +102,9 @@ public class ExplorerController extends BaseController {
@Autowired
private FilterHandler filterHandler;
@Autowired
private DownloadService downloadService;
private final ObjectMapper mapper = new ObjectMapper();
/**
......@@ -161,12 +168,10 @@ public class ExplorerController extends BaseController {
}
model.addAttribute("crop", crop);
// JSP works with JsonObject
final Map<?, ?> filters = mapper.readValue(appliedFilters.toString(), Map.class);
model.addAttribute("filters", filters);
selectedFilters = appliedFilters.getFilterNames();
final List<GenesysFilter> currentFilters = filterHandler.selectFilters(selectedFilters);
final List<GenesysFilter> availableFilters = filterHandler.listAvailableFilters();
......@@ -187,7 +192,6 @@ public class ExplorerController extends BaseController {
return "/accession/explore";
}
/**
* Browse all using Elasticsearch
*
......@@ -221,12 +225,10 @@ public class ExplorerController extends BaseController {
}
model.addAttribute("crop", crop);
// JSP works with JsonObject // TODO Handle -filter.key!!
final Map<?, ?> filters = mapper.readValue(appliedFilters.toString(), Map.class);
model.addAttribute("filters", filters);
selectedFilters = appliedFilters.getFilterNames();
final List<GenesysFilter> currentFilters = filterHandler.selectFilters(selectedFilters);
final List<GenesysFilter> availableFilters = filterHandler.listAvailableFilters();
......@@ -247,7 +249,6 @@ public class ExplorerController extends BaseController {
return "/accession/explore-es";
}
@RequestMapping(value = "/additional-filter", method = RequestMethod.GET)
public String getAdditionalFilters(ModelMap model, @RequestParam(value = "filter", required = true, defaultValue = "") String[] selectedFilters)
throws IOException {
......@@ -332,6 +333,29 @@ public class ExplorerController extends BaseController {
response.flushBuffer();
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/explore/download/mcpd", method = RequestMethod.POST)
public void downloadXlsxMCPD(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
HttpServletResponse response) throws IOException {
final AppliedFilters appliedFilters = updateFilterWithCrop(null, jsonFilter);
final int countFiltered = genesysService.countAccessions(appliedFilters);
_logger.info("Attempting to download XLSX MCPD for " + countFiltered + " accessions");
if (countFiltered > DOWNLOAD_LIMIT) {
throw new RuntimeException("Refusing to export more than " + DOWNLOAD_LIMIT + " entries");
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-filtered.xlsx\""));
// Write Darwin Core Archive to the stream.
final OutputStream outputStream = response.getOutputStream();
downloadService.writeXlsxMCPD(appliedFilters, outputStream);
response.flushBuffer();
}
private AppliedFilters updateFilterWithCrop(String cropName, String jsonFilter) throws IOException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
......@@ -386,7 +410,6 @@ public class ExplorerController extends BaseController {
@RequestParam(value = "filter", required = true) String jsonFilter, @RequestParam(value = "color", required = false) String color,
HttpServletResponse response) {
try {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
......@@ -444,7 +467,8 @@ public class ExplorerController extends BaseController {
}
@RequestMapping(value = "/explore/overview")
public String overview(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter) throws IOException, SearchException {
public String overview(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter) throws IOException,
SearchException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
String[] selectedFilters = appliedFilters.getFilterNames();
......
......@@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionGeo;
import org.genesys2.server.service.DownloadService;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.impl.FilterHandler;
......@@ -45,21 +46,20 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@Scope("request")
@RequestMapping("/sel")
public class SelectionController extends BaseController {
private final ObjectMapper mapper = new ObjectMapper();
@Autowired
private SelectionBean selectionBean;
@Autowired
private GenesysService genesysService;
@Autowired
private DownloadService downloadService;
@RequestMapping("/")
public String view(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
......@@ -151,6 +151,29 @@ public class SelectionController extends BaseController {
response.flushBuffer();
}
@RequestMapping(value = "/download/mcpd", method = RequestMethod.POST)
public void downloadXlsxMCPD(ModelMap model, HttpServletResponse response) throws IOException {
// Create JSON filter
final AppliedFilters appliedFilters = new AppliedFilters();
AppliedFilter arr = new FilterHandler.AppliedFilter().setFilterName(FilterConstants.ID);
for (final long id : selectionBean.copy()) {
arr.addFilterValue(new FilterHandler.LiteralValueFilter(id));
}
appliedFilters.add(arr);
final int countFiltered = genesysService.countAccessions(appliedFilters);
_logger.info("Attempting to download XLSX MCPD for " + countFiltered + " accessions");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-accessions-selected.xlsx\""));
// Write Darwin Core Archive to the stream.
final OutputStream outputStream = response.getOutputStream();
downloadService.writeXlsxMCPD(appliedFilters, outputStream);
response.flushBuffer();
}
// TODO REMOVE
@RequestMapping(value = "/json/count", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
......
......@@ -358,6 +358,7 @@ filter.available=Available for distribution
filter.donorCode=Donor institute
filter.duplSite=Site of safety duplication
filter.download-dwca=Download ZIP
filter.download-mcpd=Download MCPD
filter.add=Add filter
filter.additional=Additional filters
filter.apply=Apply
......
......@@ -37,6 +37,13 @@
<button class="btn btn-default" type="submit"><spring:message code="filter.download-dwca" /></button>
</form>
</c:if>
<security:authorize access="isAuthenticated()">
<form style="display: inline-block" method="post" action="<c:url value="/explore/download/mcpd" />">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="hidden" name="filter" value="<c:out value="${jsonFilter}" />" />
<button class="btn btn-default" type="submit"><spring:message code="filter.download-mcpd" /></button>
</form>
</security:authorize>
<a class="btn btn-default" href="<c:url value="/explore/overview"><c:param name="filter">${jsonFilter}</c:param></c:url>"><span class="glyphicon glyphicon-eye-open"></span><span style="margin-left: 0.5em;"><spring:message code="data-overview.short" /></span></a>
<a class="btn btn-default" href="<c:url value="/explore/map"><c:param name="filter">${jsonFilter}</c:param></c:url>"><span class="glyphicon glyphicon-globe"></span><span style="margin-left: 0.5em;"><spring:message code="maps.view-map" /></span></a>
</div>
......
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