Commit eda753ce authored by Richard Bruskiewich's avatar Richard Bruskiewich Committed by Matija Obreza
Browse files

Turtle RDF publication of Trait and Methods is evolving... latest iteration.

parent 9d910c9c
...@@ -497,7 +497,7 @@ ...@@ -497,7 +497,7 @@
<dependency> <dependency>
<groupId>org.bioversityinternational</groupId> <groupId>org.bioversityinternational</groupId>
<artifactId>org.bioversityinternational.ontology</artifactId> <artifactId>org.bioversityinternational.ontology</artifactId>
<version>0.0.5</version> <version>0.0.6</version>
</dependency> </dependency>
</dependencies> </dependencies>
......
...@@ -36,6 +36,8 @@ public interface TraitService { ...@@ -36,6 +36,8 @@ public interface TraitService {
Parameter getTrait(long traitId); Parameter getTrait(long traitId);
List<Parameter> listTraits();
List<Method> getTraitMethods(Parameter trait); List<Method> getTraitMethods(Parameter trait);
Method getMethod(long traitId); Method getMethod(long traitId);
......
...@@ -134,15 +134,15 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset ...@@ -134,15 +134,15 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
@Autowired @Autowired
private CropTaxonomyRepository cropTaxonomyRepository; private CropTaxonomyRepository cropTaxonomyRepository;
@Autowired
private MethodRepository methodRepository;
@Autowired @Autowired
private ParameterCategoryRepository parameterCategoryRepository; private ParameterCategoryRepository parameterCategoryRepository;
@Autowired @Autowired
private ParameterRepository parameterRepository; private ParameterRepository parameterRepository;
@Autowired
private MethodRepository methodRepository;
@Autowired @Autowired
private OrganizationRepository organizationRepository; private OrganizationRepository organizationRepository;
...@@ -401,6 +401,15 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset ...@@ -401,6 +401,15 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return accessionRepository.findByInstitute(members, pageable); return accessionRepository.findByInstitute(members, pageable);
} }
@Override
public List<ParameterCategory> listCategories() {
return parameterCategoryRepository.findAll(new Sort(new Order(Direction.ASC, "id")));
}
@Override
public List<Parameter> listTraits() {
return parameterRepository.findAll(new Sort(new Order(Direction.ASC, "id")));
}
@Override @Override
public Page<Parameter> listTraits(Pageable pageable) { public Page<Parameter> listTraits(Pageable pageable) {
return parameterRepository.findAll(pageable); return parameterRepository.findAll(pageable);
...@@ -1283,11 +1292,6 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset ...@@ -1283,11 +1292,6 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return null; return null;
} }
@Override
public List<ParameterCategory> listCategories() {
return parameterCategoryRepository.findAll(new Sort(new Order(Direction.ASC, "id")));
}
@Override @Override
public Map<ParameterCategory, List<Parameter>> mapTraits(Crop crop, List<ParameterCategory> parameterCategories) { public Map<ParameterCategory, List<Parameter>> mapTraits(Crop crop, List<ParameterCategory> parameterCategories) {
if (parameterCategories == null || parameterCategories.size() == 0) if (parameterCategories == null || parameterCategories.size() == 0)
...@@ -1318,4 +1322,5 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset ...@@ -1318,4 +1322,5 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return paramMethods; return paramMethods;
} }
} }
...@@ -19,6 +19,9 @@ package org.genesys2.server.servlet.controller.rdf; ...@@ -19,6 +19,9 @@ package org.genesys2.server.servlet.controller.rdf;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.bioversityinternational.model.germplasm.CCO;
import org.bioversityinternational.model.rdf.skos.SKOS;
import org.genesys2.server.model.genesys.Metadata;
import org.genesys2.server.model.genesys.Method; import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.Parameter; import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.genesys.ParameterCategory; import org.genesys2.server.model.genesys.ParameterCategory;
...@@ -27,25 +30,17 @@ import org.genesys2.server.model.impl.Crop; ...@@ -27,25 +30,17 @@ import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.service.TraitService; import org.genesys2.server.service.TraitService;
import org.genesys2.spring.ResourceNotFoundException; import org.genesys2.spring.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import org.bioversityinternational.model.rdf.skos.SKOS;
import org.bioversityinternational.model.germplasm.CCO;
/** /**
* Controller which simply handles RDF Turtle meta-data requests * Controller which simply handles RDF Turtle meta-data requests
*/ */
...@@ -53,9 +48,31 @@ import org.bioversityinternational.model.germplasm.CCO; ...@@ -53,9 +48,31 @@ import org.bioversityinternational.model.germplasm.CCO;
@RequestMapping(value = "/descriptors", method = RequestMethod.GET, headers = "accept=text/turtle", produces = RdfBaseController.RDF_MEDIATYPE_TURTLE) @RequestMapping(value = "/descriptors", method = RequestMethod.GET, headers = "accept=text/turtle", produces = RdfBaseController.RDF_MEDIATYPE_TURTLE)
public class DescriptorControllerRdf extends RdfBaseController { public class DescriptorControllerRdf extends RdfBaseController {
public final static String DESCRIPTOR_NS = GENESYS_BASEURI+"/descriptors/";
public final static String CATEGORY_NS = DESCRIPTOR_NS+"categories/" ;
public final static String TRAIT_NS = DESCRIPTOR_NS+"trait/" ;
public final static String METHOD_NS = DESCRIPTOR_NS+"method/" ;
public final static String SCALE_NS = DESCRIPTOR_NS+"scale/" ;
@Autowired @Autowired
private TraitService traitService; private TraitService traitService;
@Override
protected Model startModel() {
Model model = super.startModel();
model.setNsPrefix("cat", CATEGORY_NS );
model.setNsPrefix("trait", TRAIT_NS );
model.setNsPrefix("method",METHOD_NS );
model.setNsPrefix("scale", SCALE_NS );
return model ;
}
/*
* Creates and annotates a Method subject
*/
private Resource categorySubject(Model model, ParameterCategory category) {
return createSubject(model, category, CATEGORY_NS, category.getName() ) ;
}
/** /**
* Method to publish ParameterCategory meta-data as RDF * Method to publish ParameterCategory meta-data as RDF
...@@ -77,45 +94,31 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -77,45 +94,31 @@ public class DescriptorControllerRdf extends RdfBaseController {
*/ */
@RequestMapping(value = "/categories") @RequestMapping(value = "/categories")
public @ResponseBody public @ResponseBody
String viewCategories() { String dumpCategories() {
Model model = startModel() ; Model model = startModel() ;
List<ParameterCategory> categories = traitService.listCategories() ; List<ParameterCategory> categories = traitService.listCategories() ;
for(ParameterCategory category:categories) { for(ParameterCategory category:categories) {
// Insert category record into RDF model // Insert category record into RDF model
Resource subject = createSubject(model, CCO.getURI()+category.getName()) ; Resource subject = createSubject(model, category, CCO.getURI(), category.getName()) ;
subject.addProperty(SKOS.inScheme,CCO.PlantTraitCategoryVocabulary) ; CCO.Vocabulary.set(model, subject, CCO.Vocabulary.CATEGORY, "Plant") ;
subject.addProperty(SKOS.broader, CCO.TraitCategory) ; subject.addProperty(SKOS.broader, CCO.TraitCategory) ;
Map<String,String> vernacularNameMap = category.getLocalNameMap() ; Map<String,String> vernacularNameMap = category.getLocalNameMap() ;
for(String language:vernacularNameMap.keySet()) { for(String language:vernacularNameMap.keySet()) {
Literal vernacularNameLiteral = Literal vernacularNameLiteral =
model.createLiteral(vernacularNameMap.get(language), language) ; model.createLiteral(vernacularNameMap.get(language), language) ;
subject.addProperty(SKOS.prefLabel, vernacularNameLiteral) ; subject.addLiteral(SKOS.prefLabel, vernacularNameLiteral) ;
} }
} }
return endModel(model) ; return endModel(model) ;
} }
@RequestMapping() /**
public @ResponseBody * Trait Turtle RDF format Exemplar:
Object index(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
model.addAttribute("pagedData", traitService.listTraits(new PageRequest(page - 1, 50, new Sort("title"))));
return "/descr/index";
}
/**
* Method to publish crop trait property ("Parameter") meta-data as multi-lingual RDF
*
* @param model
* @return RDF formatted list of categories
*
* Exemplar:
* *
* cco:MusaTrait a skos:Concept; * cco:MusaTrait a skos:Concept;
* cco:category cco:GeneralTrait ; * cco:category cco:GeneralTrait ;
...@@ -130,33 +133,34 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -130,33 +133,34 @@ public class DescriptorControllerRdf extends RdfBaseController {
* skos:inScheme cco:MusaTraitVocabulary; * skos:inScheme cco:MusaTraitVocabulary;
* dc:creator "Bioversity International"; * dc:creator "Bioversity International";
*/ */
@RequestMapping("/{traitId}")
public @ResponseBody /*
Object view(@PathVariable long traitId) { * Creates and annotates a Method subject
*/
Parameter trait = traitService.getTrait(traitId); private Resource traitSubject(Model model, Parameter trait) {
return createProperty(model, trait, TRAIT_NS, trait.getTitle() ) ;
if (trait == null) { }
throw new ResourceNotFoundException();
} /*
* Method generates RDF for one trait record as RDF.
Model model = startModel() ; */
private void wrapTrait(Model model, Parameter trait) {
Resource subject = createSubject(model, GENESYS_BASEURI+"/descriptors/"+traitId ) ; Resource traitSubject = traitSubject(model, trait) ;
subject.addProperty(RDF.type, SKOS.Concept) ;
String seeAlso = trait.getRdfUri() ; String seeAlso = trait.getRdfUri() ;
if(seeAlso!=null) if(seeAlso!=null)
subject.addProperty( traitSubject.addProperty(
RDFS.seeAlso, RDFS.seeAlso,
model.createResource(seeAlso) model.createResource(seeAlso)
) ; ) ;
Crop crop = trait.getCrop() ; Crop crop = trait.getCrop() ;
CCO.Vocabulary.set(model, subject, CCO.Vocabulary.TRAIT, crop.getShortName()) ; CCO.Vocabulary.set(model, traitSubject, CCO.Vocabulary.TRAIT, crop.getShortName()) ;
ParameterCategory category = trait.getCategory() ; ParameterCategory category = trait.getCategory() ;
subject.addProperty(CCO.category, model.createResource(category.getRdfUri())) ; Resource categorySubject = categorySubject(model, category) ;
traitSubject.addProperty(CCO.category, categorySubject) ;
//model.addAttribute("traitMethods", traitService.getTraitMethods(trait)); //model.addAttribute("traitMethods", traitService.getTraitMethods(trait));
Map<String,String> vernacularTitleMap = trait.getLocalTitleMap() ; Map<String,String> vernacularTitleMap = trait.getLocalTitleMap() ;
...@@ -164,7 +168,7 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -164,7 +168,7 @@ public class DescriptorControllerRdf extends RdfBaseController {
for( String language : vernacularTitleMap.keySet() ) { for( String language : vernacularTitleMap.keySet() ) {
Literal vernacularNameLiteral = Literal vernacularNameLiteral =
model.createLiteral(vernacularTitleMap.get(language), language) ; model.createLiteral(vernacularTitleMap.get(language), language) ;
subject.addProperty(SKOS.prefLabel,vernacularNameLiteral) ; traitSubject.addLiteral(SKOS.prefLabel,vernacularNameLiteral) ;
} }
/* /*
...@@ -175,38 +179,228 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -175,38 +179,228 @@ public class DescriptorControllerRdf extends RdfBaseController {
for( String language : vernacularDefinitionMap.keySet() ) { for( String language : vernacularDefinitionMap.keySet() ) {
Literal vernacularNameLiteral = Literal vernacularNameLiteral =
model.createLiteral(vernacularTitleMap.get(language), language) ; model.createLiteral(vernacularTitleMap.get(language), language) ;
subject.addProperty(SKOS.prefLabel,vernacularNameLiteral) ; subject.addLiteral(SKOS.prefLabel,vernacularNameLiteral) ;
} }
*/ */
}
/**
* Method to retrieve list of all trait properties in the database, formatted as Turtle RDF
* @return List of RDF Turtle formatted trait properties
*/
@RequestMapping()
public @ResponseBody
Object dumpTraits() {
Model model = startModel() ;
for(Parameter trait : traitService.listTraits()) wrapTrait(model, trait) ;
return endModel(model) ;
}
/**
* Method to publish crop trait property ("Parameter") meta-data as multi-lingual RDF
*
* @param PathVariable long traitId
* @return RDF formatted list of categories
*/
@RequestMapping("/{traitId}")
public @ResponseBody
Object dumpTrait(@PathVariable long traitId) {
Parameter trait = traitService.getTrait(traitId);
if (trait == null) {
throw new ResourceNotFoundException();
}
Model model = startModel() ;
wrapTrait(model, trait) ;
return endModel(model); return endModel(model);
} }
/**
* Trait Method RDF Exemplar (from the Bioversity model...
* some properties may not be generated from the GENESYS database)
*
* cco:fruitLengthMethod a skos:Concept;
* skos:broader cco:MusaTraitMethod;
* skos:related cco:fruitLength ;
* cco:trait cco:fruitLength ;
* dcterms:created "2014/01/14 12:00:00";
* dcterms:modified "2014/01/14 12:00:00";
* skos:prefLabel "Fruit length method"@en;
* skos:definition "Measured length of the fruit, without pedicel."@en;
* skos:prefLabel "Método para Longitud de los frutos [cm]"@es;
* skos:definition "Medir el longitud del fruto, sin el pedicelo."@es;
* skos:prefLabel "Фрукты метод длина"@ru;
* skos:definition "Измеряется длина плода, без плодоножки."@ru;
* skos:prefLabel "果长法"@zh;
* skos:definition "测得的果实长度,无花梗"@zh;
* skos:inScheme cco:MusaTraitMethodVocabulary
* .
*
* cco:fruitLengthMethod2 a skos:Concept;
* skos:broader cco:MusaTraitMethod;
* skos:related cco:fruitLength ;
* cco:trait cco:fruitLength ;
* dcterms:created "2014/01/14 12:00:00";
* dcterms:modified "2014/01/14 12:00:00";
* skos:prefLabel "Alternative fruit length method"@en;
* skos:definition "Measured length of the fruit, with the pedicel."@en;
* skos:prefLabel "Método alternativo para longitud de los frutos [cm]"@es;
* skos:definition "Medir el longitud del fruto, con el pedicelo."@es;
* skos:prefLabel "Альтернативный метод длина фрукты"@ru;
* skos:definition "Измеряется длина плода, с плодоножки."@ru;
* skos:prefLabel "另类水果长度的方法"@zh;
* skos:definition "测得的果实长度,与花梗"@zh;
* skos:inScheme cco:MusaTraitMethodVocabulary
* .
*
* cco:fruitLengthScale a skos:Concept;
* skos:broader cco:MusaTraitScale ;
* skos:related cco:fruitLengthMethod, cco:fruitLengthMethod2 ;
* cco:method cco:fruitLengthMethod, cco:fruitLengthMethod2 ;
* skos:prefLabel "Fruit length scale"@en;
* skos:prefLabel "Escala Longitud de los frutos [cm] "@es;
* dcterms:created "2014/01/14 12:00:00";
* dcterms:modified "2014/01/14 12:00:00";
* skos:inScheme cco:MusaTraitScaleVocabulary ;
* skos:definition "1 =<15 cm, 2 16- 20 cm, 3 21- 25 cm, 4 26- 30 cm, 5 >=31 cm"@en;
* skos:definition "1 =< 15 cm, 2 16-20 cm, 3 21-25 cm, 4 26-30 cm, 5 > =31 cm"@es;
* cco:scaleType "Nominal";
* cco:scaleUnit cco:fruitLengthScaleValues
* .
*
* cco:fruitLengthScaleValues a skos:Collection;
* skos:prefLabel "Fruit length scale values"@en ;
* skos:prefLabel "Valores para Longitud de los frutos [cm]"@es ;
* dcterms:created "2014/01/14 12:00:00";
* dcterms:modified "2014/01/14 12:00:00";
* skos:definition "Controlled list of values for Fruit length"@en;
* skos:definition "Lista controlada de valores para Longitud de los frutos [cm]"@es;
* skos:member cco:fruitLengthScaleValue1, cco:fruitLengthScaleValue2, cco:fruitLengthScaleValue3, cco:fruitLengthScaleValue4, cco:fruitLengthScaleValue5
* .
*
* cco:fruitLengthScaleValue1
* a cco:IntegerValueRange ;
* cco:integerMinValue "0"^^xsd:integer ;
* cco:integerMaxValue "15"^^xsd:integer ;
* cco:scaleUnit "cm" ;
* skos:broader cco:fruitLengthScale;
* dcterms:created "2014/01/14 12:00:00";
* dcterms:modified "2014/01/14 12:00:00";
* skos:prefLabel "=<15 cm"@en ;
* skos:prefLabel "=<15 cm"@es ;
* skos:altLabel "1" ;
* skos:definition "=<15 cm"@en ;
* skos:definition "=<15 cm"@es ;
* skos:inScheme cco:MusaTraitScaleVocabulary
* .
*
*/
/*
* Creates and annotates a Method subject
*/
private Resource[] traitAndMethodSubjects(Model model, Parameter trait, Method method) {
Resource[] subjects = new Resource[2] ;
subjects[0] = traitSubject(model, trait) ;
subjects[1] = createProperty(model, method, METHOD_NS, trait.getTitle()+" Method" ) ;
return subjects ;
}
/*
* Method generates RDF for one trait method.
*/
private void wrapMethod(Model model, Parameter trait, Method method) {
int TRAIT = 0 , METHOD = 1 ;
Resource[] subjects = traitAndMethodSubjects(model,trait,method) ;
Resource traitSubj = subjects[0] ;
Resource methodSubj = subjects[1] ;
String seeAlso = method.getRdfUri() ;
if(seeAlso!=null)
methodSubj.addProperty(
RDFS.seeAlso,
model.createResource(seeAlso)
) ;
Crop crop = trait.getCrop() ;
CCO.Vocabulary.set(model, methodSubj, CCO.Vocabulary.METHOD, crop.getShortName()) ;
methodSubj.addProperty( SKOS.related, traitSubj ) ;
methodSubj.addProperty( CCO.trait, traitSubj ) ;
/*
//model.addAttribute("traitMethods", traitService.getTraitMethods(trait));
Map<String,String> vernacularTitleMap = trait.getLocalTitleMap() ;
for( String language : vernacularTitleMap.keySet() ) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularTitleMap.get(language), language) ;
methodSubject.addLiteral(SKOS.prefLabel,vernacularNameLiteral) ;
}
TODO - The Parameter table doesn't yet appear to track trait descriptions...
Map<String,String> vernacularTitleMap = trait.getLocalTitleMap() ;
for( String language : vernacularDefinitionMap.keySet() ) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularTitleMap.get(language), language) ;
subject.addLiteral(SKOS.prefLabel,vernacularNameLiteral) ;
}
List<Metadata> metadata = traitService.listMetadataByMethod(method);
if (method.isCoded()) {
Map<String, String> codeMap = TraitCode.parseCodeMap(method.getOptions());
//model.addAttribute("codeMap", codeMap);
//model.addAttribute("codeStatistics", traitService.getMethodStatistics(method));
}
*/
}
/**
* Method to publish a single crop trait method and associated scale meta-data, as multi-lingual RDF
*
* @param traitId
* @param methodId
* @return RDF formatted list of categories
*/
@RequestMapping("/{traitId}/{methodId}") @RequestMapping("/{traitId}/{methodId}")
public @ResponseBody public @ResponseBody
Object view(ModelMap model, @PathVariable long traitId, @PathVariable long methodId) { Object dumpMethod( @PathVariable long traitId, @PathVariable long methodId) {
Parameter trait = traitService.getTrait(traitId); Parameter trait = traitService.getTrait(traitId);
if (trait == null) { if (trait == null) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }
Method method = traitService.getMethod(methodId); Method method = traitService.getMethod(methodId);
if (method == null) { if (method == null) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }
if (!method.getParameter().getId().equals(trait.getId())) { if (!method.getParameter().getId().equals(trait.getId())) {
_logger.warn("Method does not belong to Param"); _logger.warn("Method does not belong to Param");
}