Commit 6d2b0c19 authored by Matija Obreza's avatar Matija Obreza
Browse files

Crops, rules and Crop Taxonomies

parent ec08038d
......@@ -14,7 +14,6 @@
* limitations under the License.
**/
package org.crophub.rest.common.listener.sample;
import java.util.HashSet;
......@@ -30,27 +29,24 @@ import org.springframework.stereotype.Service;
@Service("createAdminListener")
public class CreateAdminListener extends RunAsAdminListener {
@Autowired
private UserService userService;
@Override
public void init() throws Exception {
_logger.info("Start adding sample admin");
if(!userService.exists("admin@example.com")){
User user = new User();
user.setEmail("admin@example.com");
user.setPassword("admin");
user.setName("Sample Admin");
Set<UserRole> userRoles = new HashSet<UserRole>();
userRoles.add(UserRole.ADMINISTRATOR);
user.setRoles(userRoles);
// user.setUserGroups(userGroupService.getUserGroupList());
userService.addUser(user);
}
_logger.info("Sample admin has been added successfully");
}
@Autowired
private UserService userService;
@Override
public void init() throws Exception {
_logger.info("Checking for admin account");
if (!userService.exists("admin@example.com")) {
User user = new User();
user.setEmail("admin@example.com");
user.setPassword("admin");
user.setName("Sample Admin");
Set<UserRole> userRoles = new HashSet<UserRole>();
userRoles.add(UserRole.ADMINISTRATOR);
user.setRoles(userRoles);
// user.setUserGroups(userGroupService.getUserGroupList());
userService.addUser(user);
_logger.info("Sample admin has been added successfully");
}
}
}
package org.crophub.rest.common.model.impl;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.crophub.rest.common.model.BusinessModel;
......@@ -12,8 +16,8 @@ import org.crophub.rest.common.model.BusinessModel;
public class Crop extends BusinessModel {
private static final long serialVersionUID = -2686341831839109257L;
@Column(nullable = false, length = 200)
private String name;
@Column(nullable = false, length = 2)
private String language;
/**
* Crop short name used as short name in URLs
......@@ -21,9 +25,18 @@ public class Crop extends BusinessModel {
@Column(nullable = false, length = 50, unique = true)
private String shortName;
@Column(nullable = false, length = 200)
private String name;
@Lob
private String description;
/**
* Rules
*/
@OneToMany(mappedBy = "crop", fetch = FetchType.EAGER, cascade = {}, orphanRemoval = true)
private List<CropRule> cropRules;
public String getName() {
return name;
}
......@@ -48,4 +61,20 @@ public class Crop extends BusinessModel {
this.description = description;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public List<CropRule> getCropRules() {
return cropRules;
}
public void setCropRules(List<CropRule> cropRules) {
this.cropRules = cropRules;
}
}
package org.crophub.rest.common.model.impl;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.crophub.rest.common.model.BusinessModel;
/**
* Crop rules establish which taxonomies are part of a {@link Crop}.
*
* @author mobreza
*/
@Entity
@Table(name = "croprule")
public class CropRule extends BusinessModel {
private static final long serialVersionUID = -2336100072991067193L;
@Column
private boolean included;
@Column(nullable = false, length = 100)
private String genus;
@Column
private String species;
@ManyToOne(cascade = {}, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "cropId")
private Crop crop;
public boolean isIncluded() {
return included;
}
public void setIncluded(boolean included) {
this.included = included;
}
public String getGenus() {
return genus;
}
public void setGenus(String genus) {
this.genus = genus;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public Crop getCrop() {
return crop;
}
public void setCrop(Crop crop) {
this.crop = crop;
}
}
package org.crophub.rest.common.model.impl;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.crophub.rest.common.model.BusinessModel;
import org.crophub.rest.common.model.genesys.Taxonomy;
@Entity
@Table(name = "croptaxonomy")
public class CropTaxonomy extends BusinessModel {
private static final long serialVersionUID = 8973799991421179782L;
@ManyToOne(cascade = {}, optional = false)
@JoinColumn(name = "cropId")
private Crop crop;
@ManyToOne(cascade = {}, optional = false)
@JoinColumn(name = "taxonomyId")
private Taxonomy taxonomy;
public Crop getCrop() {
return crop;
}
public void setCrop(Crop crop) {
this.crop = crop;
}
public Taxonomy getTaxonomy() {
return taxonomy;
}
public void setTaxonomy(Taxonomy taxonomy) {
this.taxonomy = taxonomy;
}
}
......@@ -77,4 +77,7 @@ public interface AccessionRepository extends JpaRepository<Accession, Long> {
Page<Accession> findByInstituteAndTaxonomy(FaoInstitute institute, Taxonomy taxonomy, Pageable pageable);
Page<Accession> findByTaxonomy(Taxonomy taxonomy, Pageable pageable);
@Query("select a from Accession a where a.taxonomy in ( ?1 )")
Page<Accession> findByTaxonomy(Collection<Taxonomy> taxonomies, Pageable pageable);
}
......@@ -16,10 +16,15 @@
package org.crophub.rest.common.persistence.domain;
import java.util.List;
import org.crophub.rest.common.model.impl.Crop;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CropRepository extends JpaRepository<Crop, Long> {
Crop findByShortName(String shortName);
List<Crop> findByLanguage(String language, Sort sort);
}
/**
* Copyright 2013 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.crophub.rest.common.persistence.domain;
import java.util.List;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.CropRule;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CropRuleRepository extends JpaRepository<CropRule, Long> {
List<CropRule> findByCrop(Crop crop);
}
/**
* Copyright 2013 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.crophub.rest.common.persistence.domain;
import java.util.List;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.CropTaxonomy;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface CropTaxonomyRepository extends JpaRepository<CropTaxonomy, Long> {
List<CropTaxonomy> findByCrop(Crop crop);
@Query("select distinct t from CropTaxonomy ct inner join ct.taxonomy t where ct.crop = ?1")
List<Taxonomy> findTaxonomiesByCrop(Crop crop);
@Query("select ct from CropTaxonomy ct where ct.taxonomy= ?1 and ct.crop.language = ?2")
Crop findByTaxonomyAndLanguage(Taxonomy taxonomy, String language);
@Modifying
@Query("delete from CropTaxonomy ct where ct.crop = ?1")
void clearCrop(Crop crop);
}
......@@ -16,9 +16,13 @@
package org.crophub.rest.common.persistence.domain;
import java.util.List;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TaxonomyRepository extends JpaRepository<Taxonomy, Long> {
Taxonomy getByGenusAndSpecies(String genus, String species);
List<Taxonomy> findByGenus(String genus);
}
package org.crophub.rest.common.service;
import java.util.List;
import java.util.Locale;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.CropTaxonomy;
public interface CropService {
List<Crop> list();
Crop getCrop(String shortName);
List<Crop> list(Locale locale);
Crop getCrop(Locale locale, Taxonomy taxonomy);
void rebuildTaxonomies();
List<CropTaxonomy> getCropTaxonomies(Crop crop);
}
......@@ -14,6 +14,7 @@ import org.crophub.rest.common.model.genesys.Metadata;
import org.crophub.rest.common.model.genesys.Method;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
......@@ -71,4 +72,6 @@ public interface GenesysService {
Page<Accession> listAccessions(Pageable pageable);
Page<Accession> listAccessionsByCrop(Crop crop, Pageable pageable);
}
package org.crophub.rest.common.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.CropRule;
import org.crophub.rest.common.model.impl.CropTaxonomy;
import org.crophub.rest.common.persistence.domain.CropRepository;
import org.crophub.rest.common.persistence.domain.CropRuleRepository;
import org.crophub.rest.common.persistence.domain.CropTaxonomyRepository;
import org.crophub.rest.common.persistence.domain.TaxonomyRepository;
import org.crophub.rest.common.service.CropService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
......@@ -20,14 +30,146 @@ public class CropServiceImpl implements CropService {
@Autowired
CropRepository cropRepository;
@Autowired
CropRuleRepository cropRuleRepository;
@Autowired
CropTaxonomyRepository cropTaxonomyRepository;
@Autowired
TaxonomyRepository taxonomyRepository;
@Override
public Crop getCrop(String shortName) {
return cropRepository.findByShortName(shortName);
}
@Override
public List<Crop> list(Locale locale) {
return cropRepository.findByLanguage(locale.getLanguage(), new Sort("name"));
}
@Override
public Crop getCrop(Locale locale, Taxonomy taxonomy) {
return cropTaxonomyRepository.findByTaxonomyAndLanguage(taxonomy, locale.getLanguage());
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void rebuildTaxonomies() {
LOG.warn("REBUILDING ALL CROP TAXONOMIES!");
// for each crop
for (Crop crop : cropRepository.findAll()) {
LOG.info("Rebuilding crop taxonomy for: " + crop.getName());
// for all rules
List<CropRule> cropRules = crop.getCropRules();
LOG.warn("Using rules: " + cropRules);
rebuildCropTaxonomies(crop, cropRules);
}
}
private void rebuildCropTaxonomies(Crop crop, List<CropRule> cropRules) {
List<CropRule> rulesSorted = new ArrayList<CropRule>(cropRules);
List<CropRule> includedTaxa = new ArrayList<CropRule>();
List<CropRule> excludedTaxa = new ArrayList<CropRule>();
for (CropRule cr : rulesSorted) {
if (cr.isIncluded()) {
LOG.debug("Included: " + cr);
includedTaxa.add(cr);
} else {
LOG.debug("Excluded: " + cr);
excludedTaxa.add(cr);
}
}
LOG.info("Included: " + includedTaxa.size());
LOG.info("Excluded: " + excludedTaxa.size());
List<Taxonomy> taxa = new ArrayList<Taxonomy>();
for (CropRule cr : includedTaxa) {
if (cr.getSpecies() == null) {
taxa.addAll(taxonomyRepository.findByGenus(cr.getGenus()));
} else {
taxa.add(taxonomyRepository.getByGenusAndSpecies(cr.getGenus(), cr.getSpecies()));
}
}
for (CropRule cr : excludedTaxa) {
if (cr.getSpecies() == null) {
for (Taxonomy notincluded : taxonomyRepository.findByGenus(cr.getGenus())) {
for (int i = taxa.size() - 1; i >= 0; i--) {
if (taxa.get(i).getId().equals(notincluded.getId())) {
taxa.remove(i);
}
}
}
} else {
Taxonomy notincluded = taxonomyRepository.getByGenusAndSpecies(cr.getGenus(), cr.getSpecies());
for (int i = taxa.size() - 1; i >= 0; i--) {
if (taxa.get(i).getId().equals(notincluded.getId())) {
taxa.remove(i);
}
}
}
}
LOG.warn("Clearing crop taxonomy for " + crop.getName());
// To check
List<CropTaxonomy> existing = cropTaxonomyRepository.findByCrop(crop);
List<CropTaxonomy> toRemove = new ArrayList<CropTaxonomy>();
// Remove existing if not in list
for (CropTaxonomy ct : existing) {
long taxonomyId = ct.getTaxonomy().getId();
boolean found = false;
for (Taxonomy taxonomy : taxa) {
if (taxonomyId == taxonomy.getId()) {
found = true;
break;
}
}
if (!found) {
toRemove.add(ct);
}
}
cropTaxonomyRepository.delete(toRemove);
List<CropTaxonomy> toAdd = new ArrayList<CropTaxonomy>();
// To add
for (Taxonomy taxonomy : taxa) {
boolean found = false;
for (CropTaxonomy ct : existing) {
if (ct.getTaxonomy().getId().equals(taxonomy.getId())) {
found = true;
break;
}
}
if (!found) {
CropTaxonomy ct = new CropTaxonomy();
ct.setCrop(crop);
ct.setTaxonomy(taxonomy);
toAdd.add(ct);
}
}
cropTaxonomyRepository.save(toAdd);
}
@Override
public List<Crop> list() {
return cropRepository.findAll(new Sort("name"));
public List<CropTaxonomy> getCropTaxonomies(Crop crop) {
return cropTaxonomyRepository.findByCrop(crop);
}
}
......@@ -16,12 +16,14 @@ import org.crophub.rest.common.model.genesys.Metadata;
import org.crophub.rest.common.model.genesys.Method;
import org.crophub.rest.common.model.genesys.Taxonomy;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.model.impl.Crop;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.crophub.rest.common.persistence.domain.AccessionBreedingRepository;
import org.crophub.rest.common.persistence.domain.AccessionCollectRepository;
import org.crophub.rest.common.persistence.domain.AccessionNameRepository;
import org.crophub.rest.common.persistence.domain.AccessionRepository;
import org.crophub.rest.common.persistence.domain.AccessionTraitRepository;
import org.crophub.rest.common.persistence.domain.CropTaxonomyRepository;
import org.crophub.rest.common.persistence.domain.MetadataMethodRepository;
import org.crophub.rest.common.persistence.domain.MetadataRepository;
import org.crophub.rest.common.persistence.domain.MethodRepository;
......@@ -57,6 +59,9 @@ public class GenesysServiceImpl implements GenesysService {
private MetadataMethodRepository metadataMethodRepository;
@Autowired
private TraitValueRepository traitValueRepository;
@Autowired
private CropTaxonomyRepository cropTaxonomyRepository;
@Autowired
private MethodRepository methodRepository;
......@@ -193,4 +198,9 @@ public class GenesysServiceImpl implements GenesysService {
public Page<Accession> listAccessions(Pageable pageable) {
return accessionRepository.findAll(pageable);
}
@Override