Commit 27540bcf authored by Matija Obreza's avatar Matija Obreza

Merge branch '167-download-repository-metadata' into 'master'

Resolve "Download repository metadata"

Closes #167

See merge request genesys-pgr/genesys-server!104
parents 1d509486 8f48536d
......@@ -792,7 +792,7 @@
</attributes>
</configuration>
</plugin>
<!-- <plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.9</version>
......@@ -815,7 +815,7 @@
<configuration>
<sortArtifactByName>true</sortArtifactByName>
</configuration>
</plugin> -->
</plugin>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
......
......@@ -55,6 +55,8 @@ import org.genesys2.server.service.impl.NonUniqueAccessionException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
public interface GenesysService {
/**
......
/*
* Copyright 2017 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.impl;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;
import com.opencsv.CSVWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Writes data in CSV format
*
* @author Andrey Lugovskoy.
*/
public abstract class ExporterToCSV<T> {
public static final Log LOG = LogFactory.getLog(ExporterToCSV.class);
public void downloadMetadata(Stream<T> entities, HttpServletResponse response, char separator, char quoteChar, char escapeChar, String lineEnd, String encoding) throws IOException {
try (CSVWriter writer = new CSVWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), encoding)), separator, quoteChar, escapeChar, lineEnd)) {
writer.writeNext(writeHeaders());
entities.forEach(element -> {
writer.writeNext(prepareLine(element), true);
});
writer.flush();
}
}
protected abstract String[] writeHeaders();
protected abstract String[] prepareLine(T element);
}
/*
* Copyright 2017 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.impl;
import org.genesys.filerepository.model.RepositoryFile;
import org.springframework.stereotype.Component;
/**
* @author Andrey Lugovskoy.
*/
@Component
public class FilesMetadataInfo extends ExporterToCSV<RepositoryFile> {
// @formatter:off
private final String[] CSV_HEADERS = new String[] {
"uuid",
"version",
"contentType",
"path",
"extension",
"originalFilename",
"title",
"subject",
"description",
"creator",
"created",
"rightsHolder",
"accessRights",
"license",
"bibliographicCitation"
};
// @formatter:on
@Override
protected String[] writeHeaders() {
return CSV_HEADERS;
}
@Override
protected String[] prepareLine(RepositoryFile element) {
// @formatter:off
return new String[] {
element.getUuid().toString(),
element.getVersion().toString(),
element.getContentType(),
element.getPath(),
element.getExtension(),
element.getOriginalFilename(),
element.getTitle(),
element.getSubject(),
element.getDescription(),
element.getCreator(),
element.getCreated(),
element.getRightsHolder(),
element.getAccessRights(),
element.getLicense(),
element.getBibliographicCitation()
};
// @formatter:on
}
}
......@@ -290,7 +290,8 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
public Page<AccessionDetails> listAccessionsDetails(Collection<Long> accessionIds, Pageable pageable) {
if (!accessionIds.isEmpty()) {
Page<Accession> data = accessionRepository.findById(accessionIds, pageable);
return new PageImpl<AccessionDetails>(getAccessionDetails(data.getContent().stream().map(a -> a.getId()).collect(Collectors.toList())), pageable, data.getTotalElements());
return new PageImpl<AccessionDetails>(getAccessionDetails(data.getContent().stream().map(a -> a.getId()).collect(Collectors.toList())), pageable,
data.getTotalElements());
} else {
return null;
}
......@@ -299,7 +300,8 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
@Override
public Accession getAccession(AccessionIdentifier3 aid3) throws NonUniqueAccessionException {
try {
Accession accession = accessionRepository.findOne(instituteRepository.findByCode(aid3.getHoldingInstitute()), aid3.getDoi(), aid3.getAccessionNumber(), aid3.getGenus());
Accession accession = accessionRepository
.findOne(instituteRepository.findByCode(aid3.getHoldingInstitute()), aid3.getDoi(), aid3.getAccessionNumber(), aid3.getGenus());
return lazyLoadAccession(accession);
} catch (IncorrectResultSizeDataAccessException e) {
LOG.error("Duplicate accession name instCode={} acceNumb={} genus={}", aid3.getHoldingInstitute(), aid3.getAccessionNumber(), aid3.getGenus());
......@@ -881,10 +883,10 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
* Update {@link SvalbardDeposit} data and link with Genesys accessions. The
* primary key for {@link SvalbardDeposit} is the <code>sgsv_id</code> as
* provided by NordGen.
*
*
* Any existing SGSV records are first deleted. Inserted and linked with
* accessions in this method.
*
*
* @param svalbardDeposits
* @return
*/
......@@ -1901,4 +1903,5 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
public List<Object[]> getLastUpdatedStatistics(FaoInstitute faoInstitute) {
return accessionRepository.lastUpdatedStatistics(faoInstitute);
}
}
......@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
......@@ -52,6 +53,7 @@ import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.OrganizationService;
import org.genesys2.server.service.StatisticsService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.server.service.impl.FilesMetadataInfo;
import org.genesys2.server.service.impl.FilterHandler;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
......@@ -66,6 +68,7 @@ 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.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -87,7 +90,7 @@ import org.springframework.web.util.UriUtils;
@RequestMapping("/wiews")
public class WiewsController extends BaseController {
private static final String MANAGE_FILES_JSP_PATH = "/wiews/files";
private static final String MANAGE_FILES_JSP_PATH = "/wiews/files";
@Autowired
private InstituteService instituteService;
......@@ -116,11 +119,15 @@ public class WiewsController extends BaseController {
@Autowired
private ElasticService elasticService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ImageGalleryService imageGalleryService;
@Autowired(required = false)
private FilesMetadataInfo filesMetadataInfo;
@Autowired
private ImageGalleryService imageGalleryService;
@RequestMapping("/")
public String view(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
......@@ -506,8 +513,6 @@ public class WiewsController extends BaseController {
public String uploadFile(@RequestParam MultipartFile file, @PathVariable String wiewsCode, @RequestParam String repositoryPath,
RedirectAttributes redirectAttributes) throws IOException {
//check user permissions
instituteService.getInstituteForEdit(wiewsCode);
final String mimeType = file.getContentType();
try {
......@@ -600,7 +605,6 @@ public class WiewsController extends BaseController {
instituteService.getInstituteForEdit(wiewsCode);
ImageGallery imageGallery = imageGalleryService.loadImageGallery(galleryPath);
String gallerySubPath = galleryPath.replace("/wiews/" + wiewsCode, "");
if (imageGallery == null) {
throw new ResourceNotFoundException("No image gallery here!");
......@@ -610,7 +614,6 @@ public class WiewsController extends BaseController {
model.addAttribute("thumbnailFormat", "200x200");
model.addAttribute("imageGallery", imageGallery);
model.addAttribute("wiewsCode", wiewsCode);
model.addAttribute("gallerySubPath", gallerySubPath);
return MANAGE_FILES_JSP_PATH + "/gallery/details";
}
......@@ -644,25 +647,40 @@ public class WiewsController extends BaseController {
}
redirectAttributes.addFlashAttribute("successMessage", "repository.gallery.successfully-updated");
return "redirect:/wiews/" + wiewsCode +"/files/gallery";
return "redirect:/wiews/" + wiewsCode + "/files/gallery";
}
@PostMapping(value = "{wiewsCode}/files/gallery/delete")
public String deleteFile(@RequestParam String galleryPath, RedirectAttributes redirectAttributes, @PathVariable("wiewsCode") String wiewsCode) throws InvalidRepositoryPathException {
public String deleteFile(@RequestParam String galleryPath, RedirectAttributes redirectAttributes, @PathVariable("wiewsCode") String wiewsCode) throws InvalidRepositoryPathException {
//check user permissions
instituteService.getInstituteForEdit(wiewsCode);
ImageGallery imageGallery = imageGalleryService.loadImageGallery(galleryPath);
ImageGallery imageGallery = imageGalleryService.loadImageGallery(galleryPath);
imageGalleryService.removeGallery(imageGallery);
redirectAttributes.addFlashAttribute("successMessage", "repository.gallery.removed");
return "redirect:/wiews/" + wiewsCode +"/files/gallery";
return "redirect:/wiews/" + wiewsCode + "/files/gallery";
}
@RequestMapping(value = "{wiewsCode}/files/download/metadata")
@Transactional(readOnly = true)
public void downloadMetadata(@PathVariable("wiewsCode") String wiewsCode, HttpServletResponse response) throws IOException {
// check user permissions
instituteService.getInstituteForEdit(wiewsCode);
final String repositoryPath = "/wiews/" + wiewsCode;
response.setContentType("text/csv;charset=UTF-16LE");
response.setHeader("Content-Disposition", "attachment; filename=" + wiewsCode + "_files_metadata.csv ");
Stream<RepositoryFile> files = repositoryService.streamFiles(repositoryPath);
filesMetadataInfo.downloadMetadata(files, response, '\t', '"', '\\', "\n", "UTF-16LE");
}
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
}
......@@ -853,7 +853,7 @@ repository.file.title=Title
repository.file.subject=Subject
repository.file.description=Description
repository.file.creator=Creator
repository.file.created=Created date
repository.file.created=Resource created
repository.file.rightsHolder=Rights holder
repository.file.accessRights=Access rights
repository.file.license=License name or URL
......@@ -864,8 +864,10 @@ repository.file.extent=Extent
repository.file.bibliographicCitation=Bibliographic citation
repository.file.dateSubmitted=Date of submission
repository.file.lastModifiedDate=Last modified date
repository.file.createdDate=Date of creation
file.upload-file=Upload file
file.download-metadata=Download metadata
file.upload-file.help=Select file for upload from local computer
file.manage-files=Manage files
......
......@@ -858,4 +858,5 @@ welcome.search-genesys=البحث في جينيسيس
welcome.networks=الشبكات
geo.country=الدولة:
file.download-metadata=تنزيل البيانات الوصفية
article.is.template=هو القالب:
......@@ -858,4 +858,5 @@ welcome.search-genesys=Genesys durchsuchen
welcome.networks=Netzwerke
geo.country=Land:
file.download-metadata=Metadaten herunterladen
article.is.template=Ist Vorlage:
......@@ -858,4 +858,5 @@ welcome.search-genesys=Buscar en Genesys
welcome.networks=Redes
geo.country=País:
file.download-metadata=Descargar metadatos
article.is.template=Es plantilla:
......@@ -858,4 +858,5 @@ welcome.search-genesys=جستجو در Genesys
welcome.networks=شبکه‌ها
geo.country=کشور:
file.download-metadata=دانلود ابرداده
article.is.template=الگو است:
......@@ -858,4 +858,5 @@ welcome.search-genesys=Recherche sur Genesys
welcome.networks=Réseaux
geo.country=Pays :
file.download-metadata=Télécharger les métadonnées
article.is.template=Est-ce que le modèle:
......@@ -858,4 +858,5 @@ welcome.search-genesys=Pesquisar no Genesys
welcome.networks=Redes
geo.country=País:
file.download-metadata=Baixar metadados
article.is.template=É modelo:
......@@ -858,4 +858,5 @@ welcome.search-genesys=Поиск по Genesys
welcome.networks=Сети
geo.country=Страна:
file.download-metadata=Загрузить метаданные
article.is.template=Шаблон:
......@@ -858,4 +858,5 @@ welcome.search-genesys=搜索Genesys
welcome.networks=网站
geo.country=国家/地区:
file.download-metadata=下載元數據
article.is.template=是模板
......@@ -47,7 +47,7 @@
<div class="col-md-6 margin-top-20">
<label for="created"><spring:message code="repository.file.created"/></label>
<input type="text" id="created" name="created" class="form-control" value="${file.createdDate}"
<input type="text" id="created" name="created" class="form-control" value="${file.created}"
placeholder="<spring:message code="repository.file.created" />">
</div>
......@@ -97,14 +97,22 @@
<div class="col-md-6 margin-top-20">
<label for="dateSubmitted"><spring:message code="repository.file.dateSubmitted"/></label>
<input type="text" id="dateSubmitted" name="createdDate" class="form-control" value="${file.dateSubmitted}"
<input type="text" id="dateSubmitted" name="dateSubmitted" class="form-control" value="${file.dateSubmitted}"
placeholder="<spring:message code="repository.file.dateSubmitted" />">
</div>
<div class="col-md-6 margin-top-20">
<label for="modified"><spring:message code="repository.file.lastModifiedDate"/></label>
<input type="text" id="modified" name="lastModifiedDate" class="form-control" value="${file.modified}"
placeholder="<spring:message code="repository.file.lastModifiedDate" />">
<label for="createdDate"><spring:message code="repository.file.createdDate"/></label>
<p type="text" id="createdDate" name="createdDate" class="form-control-static">
<local:prettyTime date="${file.createdDate}" locale="${pageContext.response.locale}"/>
</p>
</div>
<div class="col-md-6 margin-top-20">
<label for="lastModifiedDate"><spring:message code="repository.file.lastModifiedDate"/></label>
<p type="text" id="lastModifiedDate" name="lastModifiedDate" class="form-control-static">
<local:prettyTime date="${file.lastModifiedDate}" locale="${pageContext.response.locale}"/>
</p>
</div>
</div>
......
......@@ -82,6 +82,13 @@
</tbody>
</table>
<form style="padding-bottom: 5px;" action="<c:url value="/wiews/${wiewsCode}/files/download/metadata"><c:param name="${_csrf.parameterName}" value="${_csrf.token}" /></c:url>"
method="post" enctype="multipart/form-data" class="">
<input type="hidden" name="wiewsCode" value="${wiewsCode}"/>
<input type="hidden" name="repositoryPath" value="${currentPath}"/>
<button type="submit" class="btn btn-primary"><spring:message code="file.download-metadata"/></button>
</form>
<form action="<c:url value="/wiews/${wiewsCode}/upload-file"><c:param name="${_csrf.parameterName}" value="${_csrf.token}" /></c:url>"
method="post" enctype="multipart/form-data" class="">
......
......@@ -282,6 +282,11 @@ public abstract class GenesysServicesTest extends BaseSpringTest {
return new GenesysServiceImpl();
}
@Bean(name = "filesMetadataInfo")
public FilesMetadataInfo filesMetadataInfo(){
return new FilesMetadataInfo();
}
@Bean
public CropService cropService() {
return new CropServiceImpl();
......
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