Commit aa5e4dfb authored by Matija Obreza's avatar Matija Obreza

Merge branch 'forages' into staging

* forages:
  Reassign accession#crop based on #cropName

# Conflicts:
#	src/main/java/org/genesys2/server/persistence/domain/AccessionRepository.java
#	src/main/java/org/genesys2/server/service/GenesysService.java
#	src/main/java/org/genesys2/server/service/impl/CropServiceImpl.java
#	src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java
#	src/main/webapp/WEB-INF/jsp/crop/index.jsp
parents 19367777 197ac55b
......@@ -575,7 +575,7 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>0.0.26</version>
<version>1.0</version>
<executions>
<execution>
<id>install node and npm</id>
......@@ -610,13 +610,15 @@
<goals>
<goal>grunt</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>build</arguments>
<arguments>build --no-color</arguments>
<srcdir>${basedir}/src/main/sourceapp</srcdir>
<outputdir>${basedir}/src/main/webapp/html</outputdir>
<triggerfiles>
<triggerfile>Gruntfile.js</triggerfile>
<triggerfile>package.json</triggerfile>
<triggerfile>src/main/sourceapp/**</triggerfile>
</triggerfiles>
</configuration>
</execution>
......
......@@ -65,7 +65,7 @@ public class Crop extends GlobalVersionedAuditedModel implements AclAwareModel {
@Column(nullable = false, length = 50, unique = true)
private String shortName;
@Column(name = "otherName", nullable = false)
@Column(name = "otherName", nullable = false, unique = true)
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "cropname", joinColumns = @JoinColumn(name = "cropId", referencedColumnName = "id"), uniqueConstraints = { @UniqueConstraint(columnNames = "otherName") })
@OrderBy("otherName")
......
......@@ -25,6 +25,7 @@ import java.util.stream.Stream;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.FaoInstitute;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
......@@ -126,4 +127,11 @@ public interface AccessionRepository extends JpaRepository<Accession, Long> {
@Query(nativeQuery=true, value="update accession a inner join sgsvdeposit sd on sd.acceId=a.id set a.inSGSV=true where sd.id in (?1)")
@Modifying
public void setInSvalbard(List<Long> sgsvId);
@Query("select a from Accession a where a.cropName != null")
Stream<Accession> streamWithCropname();
@Query("update Accession a set a.crop = ?2 where a = ?1")
@Modifying
public void updateCrop(Accession accession, Crop crop);
}
......@@ -98,4 +98,13 @@ public interface CropService {
*/
List<Crop> getCrops(List<String> cropNames);
/**
* Update crop aliases
*
* @param crop
* @param otherNames
* @return updated crop
*/
Crop updateAliases(Crop crop, List<String> otherNames);
}
......@@ -18,11 +18,13 @@ package org.genesys2.server.service;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import org.genesys2.server.model.elastic.AccessionDetails;
import org.genesys2.server.model.genesys.Accession;
......@@ -261,5 +263,9 @@ public interface GenesysService {
void regenerateAccessionSequentialNumber();
List<SvalbardDeposit> saveSvalbards(List<SvalbardDeposit> svalbards);
Stream<Accession> streamWithCropname();
List<Accession> saveAccessionCrops(ArrayList<Accession> copy);
}
......@@ -42,6 +42,7 @@ import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.AccessionRemark;
import org.genesys2.server.model.genesys.Taxonomy2;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.json.Api1Constants;
import org.genesys2.server.persistence.domain.AccessionCustomRepository;
......@@ -571,12 +572,27 @@ public class BatchRESTServiceImpl implements BatchRESTService {
throw new RESTApiDataTypeException("cropName must be a String");
}
final String cropName = value.textValue().trim();
if (!StringUtils.equals(cropName, accession.getCropName())) {
final String cropName = StringUtils.trimToNull(value.textValue());
if (!StringUtils.equals(cropName, accession.getCropName()) || accession.getCrop() == null) {
// existing cropName doesn't match or current crop assigned is null
accession.setCropName(cropName);
accession.setCrop(cropService.getCrop(cropName));
return true;
}
if (StringUtils.isNotBlank(cropName)) {
// has cropName, check if needs updating
Crop newCrop = cropService.getCrop(cropName);
if (accession.getCrop() == null || (newCrop != null && accession.getCrop().getId() != newCrop.getId())) {
accession.setCrop(newCrop);
return true;
}
} else if (accession.getCrop() != null) {
// blank but has crop assigned
accession.setCrop(null);
return true;
}
}
return false;
}
......
......@@ -16,6 +16,15 @@
package org.genesys2.server.service.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang.StringUtils;
......@@ -42,8 +51,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@Service
@Transactional(readOnly = true)
public class CropServiceImpl implements CropService {
......@@ -72,6 +79,7 @@ public class CropServiceImpl implements CropService {
private Taxonomy2Repository taxonomy2Repository;
@Override
@Cacheable(value = CACHE_CROPS, key = "#shortName")
public Crop getCrop(String shortName) {
Crop crop = cropRepository.findByShortName(shortName);
......@@ -103,6 +111,18 @@ public class CropServiceImpl implements CropService {
public void updateBlurp(Crop crop, String textBody, String summary, Locale locale) {
contentService.updateArticle(crop, "blurp", null, textBody, summary, locale);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#crop, 'ADMINISTRATION')")
@Transactional(readOnly = false)
@CacheEvict(value = CACHE_CROPS, allEntries = true)
public Crop updateAliases(Crop crop, List<String> otherNames) {
crop.setOtherNames(otherNames.stream().distinct().map(otherName -> StringUtils.trim(otherName)).filter(otherName -> StringUtils.isNotBlank(otherName))
.sorted().collect(Collectors.toList()));
return cropRepository.save(crop);
}
@Override
@Cacheable(value = CACHE_CROPS, key = "'findAll'")
......
......@@ -33,11 +33,16 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.persistence.EntityManager;
import com.opencsv.CSVWriter;
import com.opencsv.ResultSetHelper;
import com.opencsv.ResultSetHelperService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang.StringUtils;
......@@ -122,10 +127,6 @@ import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.opencsv.CSVWriter;
import com.opencsv.ResultSetHelper;
import com.opencsv.ResultSetHelperService;
@Service
@Transactional(readOnly = true)
public class GenesysServiceImpl implements GenesysService, DatasetService {
......@@ -786,10 +787,11 @@ 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.
* 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.
* Any existing SGSV records are first deleted. Inserted and linked with accessions in this
* method.
*
* @param svalbardDeposits
* @return
......@@ -820,28 +822,27 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
if (updatedCount > 0 && LOG.isDebugEnabled()) {
LOG.debug("Linked " + updatedCount + " accessions by alias in set " + sgsvIds);
}
allUpdates+=updatedCount;
allUpdates += updatedCount;
// link indirectly where INSTCODE matches alternative sgsvCode, GENUS and ACCENUMB match
updatedCount = svalbardRepository.linkInDirectly(sgsvIds);
if (updatedCount > 0 && LOG.isDebugEnabled()) {
LOG.debug("Linked " + updatedCount + " accessions using alternate code in set " + sgsvIds);
}
allUpdates+=updatedCount;
allUpdates += updatedCount;
// link directly where INSTCODE, GENUS and ACCENUMB match
updatedCount = svalbardRepository.linkDirectly(sgsvIds);
if (updatedCount > 0 && LOG.isDebugEnabled()) {
LOG.debug("Linked " + updatedCount + " accessions in set " + sgsvIds);
}
allUpdates+=updatedCount;
allUpdates += updatedCount;
accessionRepository.setInSvalbard(sgsvIds);
// Do it again.
entityManager.flush();
entityManager.clear();
// reload after updates
svalbardDeposits = svalbardRepository.findAll(sgsvIds);
......@@ -1211,8 +1212,8 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
private void writeAccessionsCore(final AppliedFilters filters, ZipOutputStream zos) throws IOException {
@SuppressWarnings("resource")
final CSVWriter csv = new CSVWriter(new BufferedWriter(new OutputStreamWriter(zos)), ',', '"', '\\', "\n");
csv.writeNext(new String[] { "genesysId", "uuid", "instCode", "acceNumb", "genus", "species", "fullTaxa", "orgCty", "acqSrc", "acqDate", "mlsStat", "available", "historic", "storage",
"sampStat", "duplSite", "createdBy", "createdDate", "lastModifiedBy", "lastModifiedDate" });
csv.writeNext(new String[] { "genesysId", "uuid", "instCode", "acceNumb", "genus", "species", "fullTaxa", "orgCty", "acqSrc", "acqDate", "mlsStat", "available", "historic",
"storage", "sampStat", "duplSite", "createdBy", "createdDate", "lastModifiedBy", "lastModifiedDate" });
final ResultSetHelper csvResultsetHelper = new CSVResultSetHelper();
......@@ -1788,4 +1789,18 @@ public class GenesysServiceImpl implements GenesysService, DatasetService {
genesysLowlevelRepository.updateAccessionSequentialNumber(batch);
}
@Override
public Stream<Accession> streamWithCropname() {
return accessionRepository.streamWithCropname();
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
// @PreAuthorize("hasRole('ADMINISTRATOR')")
public List<Accession> saveAccessionCrops(ArrayList<Accession> accessions) {
for (Accession accession : accessions)
accessionRepository.updateCrop(accession, cropService.getCrop(accession.getCropName()));
return accessions;
}
}
......@@ -16,6 +16,10 @@
package org.genesys2.server.servlet.controller;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.elasticsearch.common.lang3.StringUtils;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropTaxonomy;
import org.genesys2.server.service.ContentService;
......@@ -31,6 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -92,19 +97,34 @@ public class CropController extends BaseController {
}
@RequestMapping("/{shortName}/edit")
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#crop, 'ADMINISTRATION')")
public String edit(ModelMap model, @PathVariable(value = "shortName") String shortName) {
view(model, shortName);
return "/crop/edit";
}
@RequestMapping("/{shortName}/new")
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#crop, 'ADMINISTRATION')")
public String newCrop(ModelMap model, @PathVariable(value = "shortName") String shortName) throws Exception {
_logger.debug("Making crop " + shortName);
if (cropService.getCrop(shortName) != null) {
throw new Exception("Crop exists.");
}
Crop crop = new Crop();
crop.setShortName(shortName);
model.addAttribute("crop", crop);
return "/crop/edit";
}
@RequestMapping("/{shortName}/update")
public String update(ModelMap model, @PathVariable(value = "shortName") String shortName, @RequestParam("blurp") String aboutBody,
@RequestParam(value = "summary", required = false) String summary) {
public String update(ModelMap model, @PathVariable(value = "shortName") String shortName, @RequestParam("cropName") String cropName,
@RequestParam("blurp") String aboutBody, @RequestParam(value = "summary", required = false) String summary) {
_logger.debug("Updating crop " + shortName);
final Crop crop = cropService.getCrop(shortName);
Crop crop = cropService.getCrop(shortName);
if (crop == null) {
throw new ResourceNotFoundException();
crop = cropService.addCrop(shortName, cropName, null, null);
}
cropService.updateBlurp(crop, aboutBody, summary, getLocale());
......@@ -112,6 +132,21 @@ public class CropController extends BaseController {
return "redirect:/c/" + shortName;
}
@RequestMapping(value = "/{shortName}/update", params = { "otherNames" })
public String updateOtherNames(ModelMap model, @PathVariable(value = "shortName") String shortName, @RequestParam("otherNames") String otherNames) {
_logger.debug("Updating crop aliases for " + shortName);
final Crop crop = cropService.getCrop(shortName);
if (crop == null) {
throw new ResourceNotFoundException();
}
cropService.updateAliases(crop, Arrays.stream(otherNames.split("\\n|,|;")).distinct().map(otherName -> StringUtils.trim(otherName))
.filter(otherName -> StringUtils.isNotBlank(otherName)).sorted().collect(Collectors.toList()));
return edit(model, shortName);
}
@RequestMapping("/{shortName}/ajax/taxonomies")
public String ajaxTaxonomies(ModelMap model, @PathVariable(value = "shortName") String shortName,
@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
......@@ -128,13 +163,6 @@ public class CropController extends BaseController {
return "/crop/ajax.taxonomies";
}
@RequestMapping(value = "/rebuild", method = RequestMethod.POST)
public String rebuild() {
_logger.info("Rebuilding taxonomies");
cropService.rebuildTaxonomies();
return "redirect:/";
}
@RequestMapping("/{shortName}/data")
public String viewData(ModelMap model, @PathVariable(value = "shortName") String shortName,
@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
......
......@@ -20,18 +20,32 @@ import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.xml.parsers.ParserConfigurationException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.persistence.domain.GenesysLowlevelRepository;
import org.genesys2.server.service.*;
import org.genesys2.server.service.CountryNamesUpdater;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.ElasticService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoRegionService;
import org.genesys2.server.service.GeoService;
import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.server.service.impl.ContentSanitizer;
import org.genesys2.server.service.worker.ElasticUpdater;
import org.genesys2.server.service.worker.ITPGRFAStatusUpdater;
......@@ -42,13 +56,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.xml.sax.SAXException;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@RequestMapping("/admin")
@PreAuthorize("hasRole('ADMINISTRATOR')")
......@@ -96,6 +110,12 @@ public class AdminController {
@Autowired
private TaxonomyService taxonomyService;
@Autowired
private CropService cropService;
@PersistenceContext
private EntityManager entityManager;
ObjectMapper mapper = new ObjectMapper();
@RequestMapping("/")
......@@ -354,10 +374,42 @@ public class AdminController {
return "redirect:/admin/";
}
@RequestMapping(value = "/rebuild-taxonomies", method = RequestMethod.POST)
public String rebuild() {
LOG.info("Rebuilding taxonomies");
cropService.rebuildTaxonomies();
return "redirect:/admin/";
}
@RequestMapping(value = "/cleanup-taxonomies", method = RequestMethod.POST)
public String cleanupTaxonomies() {
taxonomyService.cleanupTaxonomies();
return "redirect:/admin/";
}
@Transactional(readOnly=true, propagation=Propagation.REQUIRES_NEW)
@RequestMapping(value = "/cropname-crop", method = RequestMethod.POST)
public String assignCropWithCropname() {
LOG.info("Assigning crops to accessions with CROPNAME.");
AtomicLong counter = new AtomicLong(0);
List<Accession> batch = Collections.synchronizedList(new ArrayList<>());
genesysService.streamWithCropname().parallel().forEach(accession -> {
batch.add(accession);
ArrayList<Accession> copy = null;
synchronized (batch) {
if (batch.size() > 100) {
copy = new ArrayList<>(batch);
batch.clear();
}
}
if (copy != null) {
genesysService.saveAccessionCrops(copy);
}
if (counter.incrementAndGet() % 1000 == 0 && LOG.isInfoEnabled()) {
LOG.info("Updated " + counter.get() + " records");
}
});
LOG.info("Done assigning crops to accessions with CROPNAME.");
return "redirect:/admin/";
}
}
......@@ -66,8 +66,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object listCrops() {
public @ResponseBody Object listCrops() {
LOG.info("Listing crops");
final List<Crop> crops = cropService.list(LocaleContextHolder.getLocale());
return crops;
......@@ -80,8 +79,7 @@ public class CropsController extends RestController {
* @throws ValidationException
*/
@RequestMapping(value = "", method = { RequestMethod.PUT, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object createCrop(@RequestBody Crop cropJson) throws ValidationException {
public @ResponseBody Object createCrop(@RequestBody Crop cropJson) throws ValidationException {
LOG.info("Creating crop");
final Validator validator = new Validator();
final List<ConstraintViolation> violations = validator.validate(cropJson);
......@@ -108,8 +106,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCrop(@PathVariable("shortName") String shortName) throws AuthorizationException {
public @ResponseBody Object getCrop(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop " + shortName);
return cropService.getCrop(shortName);
}
......@@ -121,8 +118,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}", method = RequestMethod.DELETE, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Crop deleteCrop(@PathVariable("shortName") String shortName) throws AuthorizationException {
public @ResponseBody Crop deleteCrop(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop " + shortName);
return cropService.delete(cropService.getCrop(shortName));
}
......@@ -134,8 +130,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}/descriptors", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropDescriptors(@PathVariable("shortName") String shortName) throws AuthorizationException {
public @ResponseBody Object getCropDescriptors(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop descriptors " + shortName);
final Crop crop = cropService.getCrop(shortName);
final Page<Parameter> descriptors = traitService.listTraits(crop, new PageRequest(0, 50));
......@@ -149,8 +144,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}/rules", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropRules(@PathVariable("shortName") String shortName) throws AuthorizationException {
public @ResponseBody Object getCropRules(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop rules " + shortName);
final Crop crop = cropService.getCrop(shortName);
final List<CropRule> cropRules = cropService.getCropRules(crop);
......@@ -166,8 +160,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}/rules", method = { RequestMethod.PUT, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
List<CropRule> updateCropRules(@PathVariable("shortName") String shortName, @RequestBody List<CropRule> rules) throws AuthorizationException {
public @ResponseBody List<CropRule> updateCropRules(@PathVariable("shortName") String shortName, @RequestBody List<CropRule> rules) throws AuthorizationException {
LOG.info("Updating crop rules for " + shortName);
final Crop crop = cropService.getCrop(shortName);
if (crop == null)
......@@ -185,8 +178,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}/taxa", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropTaxa(@PathVariable("shortName") String shortName) throws AuthorizationException {
public @ResponseBody Object getCropTaxa(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop taxa " + shortName);
final Crop crop = cropService.getCrop(shortName);
final Page<CropTaxonomy> cropTaxa = cropService.getCropTaxonomies(crop, new PageRequest(0, 50));
......@@ -200,8 +192,7 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "/rebuild", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
String rebuild() {
public @ResponseBody String rebuild() {
cropService.rebuildTaxonomies();
return JSON_OK;
}
......@@ -213,13 +204,12 @@ public class CropsController extends RestController {
* @throws AuthorizationException
*/
@RequestMapping(value = "{shortName}/rebuild", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
String rebuildCrop(@PathVariable("shortName") String shortName) {
public @ResponseBody String rebuildCrop(@PathVariable("shortName") String shortName) {
LOG.info("Updating crop rules for " + shortName);
final Crop crop = cropService.getCrop(shortName);
if (crop == null)
throw new ResourceNotFoundException("No crop " + shortName);
cropService.rebuildTaxonomies(crop);
return JSON_OK;
}
......
......@@ -150,6 +150,8 @@ crop.taxonomy-rules=Taxonomic rules
crop.view-descriptors=View crop descriptors...
crop.page.edit.title=Edit {0}
crop.summary=Summary (HTML metadata)
crop.name-en=Crop name (in English)
crop.cropname-aliases=Other accepted names
activity.recent-activity=Recent activity
......
......@@ -1568,7 +1568,6 @@ $light-font-family: 'Roboto-Light';
.map-section {
margin-bottom: 20px;
.map-wrapper {
width: 77%;
margin: 0 auto;
img {
width: