Commit 2e915b07 authored by Richard Bruskiewich's avatar Richard Bruskiewich Committed by Matija Obreza

Elaborating export of RDF for Crop records in GENESYS (crop table).

parent d28c5959
...@@ -18,8 +18,12 @@ package org.genesys2.server.model.impl; ...@@ -18,8 +18,12 @@ package org.genesys2.server.model.impl;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
//import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
...@@ -32,7 +36,6 @@ import javax.persistence.Transient; ...@@ -32,7 +36,6 @@ import javax.persistence.Transient;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store; import org.hibernate.search.annotations.Store;
...@@ -127,10 +130,10 @@ public class Crop extends GlobalVersionedAuditedModel { ...@@ -127,10 +130,10 @@ public class Crop extends GlobalVersionedAuditedModel {
} }
@Transient @Transient
private JsonNode i18nJO ; private JsonNode i18nJO;
@Transient @Transient
private JsonNode i18nJU ; private JsonNode i18nJU;
/* /*
* This is meant to be a complex language tag merge operation... is there an easier way? * This is meant to be a complex language tag merge operation... is there an easier way?
...@@ -146,35 +149,28 @@ public class Crop extends GlobalVersionedAuditedModel { ...@@ -146,35 +149,28 @@ public class Crop extends GlobalVersionedAuditedModel {
System.err.println("I18n = " + i18n); System.err.println("I18n = " + i18n);
e.printStackTrace(); e.printStackTrace();
} }
if(this.i18nJU != null) { if (this.i18nJU != null) {
Iterator<String> jui = this.i18nJU.fieldNames() ; Iterator<String> jui = this.i18nJU.fieldNames();
while(jui.hasNext()) { while (jui.hasNext()) {
String uField = jui.next() ; String uField = jui.next();
if(this.i18nJO.has(uField)) { if (this.i18nJO.has(uField)) {
JsonNode juf = this.i18nJU.get(uField) ; JsonNode juf = this.i18nJU.get(uField);
JsonNode jof = this.i18nJO.get(uField) ; JsonNode jof = this.i18nJO.get(uField);
Iterator<String> ulocales = juf.fieldNames() ; Iterator<String> ulocales = juf.fieldNames();
while(ulocales.hasNext()) { while (ulocales.hasNext()) {
String locale = ulocales.next() ; String locale = ulocales.next();
// TODO - append/overwrite jof.ufield.locale with juf.ufield.locale // TODO - append/overwrite jof.ufield.locale with
} // juf.ufield.locale
}
} }
} }
this.i18n = this.i18nJO.asText() ; this.i18n = this.i18nJO.asText();
} }
*/ */
} }
public String getName(Locale locale) { private synchronized void getI18nJson() {
return StringUtils.defaultIfBlank(translate("name", locale), this.name); if (this.i18nJ == null && ! StringUtils.isBlank(this.i18n)) {
}
public String getDescription(Locale locale) {
return StringUtils.defaultIfBlank(translate("description", locale), this.name);
}
private synchronized String translate(String field, Locale locale) {
if (this.i18nJ == null && !StringUtils.isBlank(this.i18n)) {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
try { try {
this.i18nJ = mapper.readTree(this.i18n); this.i18nJ = mapper.readTree(this.i18n);
...@@ -183,7 +179,58 @@ public class Crop extends GlobalVersionedAuditedModel { ...@@ -183,7 +179,58 @@ public class Crop extends GlobalVersionedAuditedModel {
e.printStackTrace(); e.printStackTrace();
} }
} }
}
private synchronized String translate(String field, Locale locale) {
getI18nJson() ;
return this.i18nJ != null && this.i18nJ.has(field) && this.i18nJ.get(field).has(locale.getLanguage()) ? this.i18nJ.get(field).get(locale.getLanguage()) return this.i18nJ != null && this.i18nJ.has(field) && this.i18nJ.get(field).has(locale.getLanguage()) ? this.i18nJ.get(field).get(locale.getLanguage())
.textValue() : null; .textValue() : null;
} }
@Transient
private Map<String,Map<String,String>> i18nMap = new HashMap<String,Map<String,String>>();
private synchronized Map<String,String> buildVernacularMap(String field) {
getI18nJson() ;
if(! this.i18nMap.containsKey(field) && this.i18nJ.has(field)) {
this.i18nMap.put(field, new HashMap<String,String>() ) ;
JsonNode fieldMap = this.i18nJ.get(field) ;
Iterator<String> languages = fieldMap.fieldNames() ;
while(languages.hasNext()) {
String language = languages.next() ;
String vernacular = fieldMap.get(language).textValue() ;
this.i18nMap.get(field).put(language, vernacular) ;
}
}
return i18nMap.get(field) ;
}
public String getName(Locale locale) {
return StringUtils.defaultIfBlank(translate("name", locale), this.name);
}
public String getDescription(Locale locale) {
return StringUtils.defaultIfBlank(translate("description", locale), this.name);
}
/**
* Method to return the map of available vernacular names of crops
* @return Map<String,String> with language code as the key and the vernacular string as the value.
*/
public Map<String,String> getLocalNameMap() {
return buildVernacularMap("name") ;
}
/**
* Method to return the map of available vernacular definitions of crops
* @return Map<String,String> with language code as the key and the vernacular string as the value.
*/
public Map<String,String> getLocalDefinitionMap() {
return buildVernacularMap("description") ;
}
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package org.genesys2.server.servlet.controller.rdf; package org.genesys2.server.servlet.controller.rdf;
import java.util.List; import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
...@@ -25,11 +26,14 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -25,11 +26,14 @@ 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.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
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.DC;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.service.CropService; import org.genesys2.server.service.CropService;
import org.genesys2.spring.ResourceNotFoundException; import org.genesys2.spring.ResourceNotFoundException;
import org.bioversityinternational.model.germplasm.CCO; import org.bioversityinternational.model.germplasm.CCO;
...@@ -75,7 +79,7 @@ public class CropControllerRdf extends RdfBaseController { ...@@ -75,7 +79,7 @@ public class CropControllerRdf extends RdfBaseController {
private void wrapCrop(Model model, Crop crop) { private void wrapCrop(Model model, Crop crop) {
Resource subject = createSubject(model, crop, CCO.getURI(), crop.getShortName()+" Taxon") ; Resource subject = createSubject(model, crop, CCO.getURI()+crop.getId(), crop.getShortName()+" Taxon") ;
subject.addProperty(DarwinCore.scientificName, crop.getShortName()) ; subject.addProperty(DarwinCore.scientificName, crop.getShortName()) ;
String seeAlso = crop.getRdfUri() ; String seeAlso = crop.getRdfUri() ;
...@@ -87,29 +91,37 @@ public class CropControllerRdf extends RdfBaseController { ...@@ -87,29 +91,37 @@ public class CropControllerRdf extends RdfBaseController {
/* /*
* vernacular names & descriptions in i18n * vernacular names & descriptions in i18n
* */
Map<String,String> vernacularNameMap = trait.getLocalNameMap() ; Map<String,String> vernacularNameMap = crop.getLocalNameMap() ;
if(vernacularNameMap!=null)
for( String language : vernacularNameMap.keySet() ) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularNameMap.get(language), language) ;
subject.addLiteral(DarwinCore.vernacularName,vernacularNameLiteral) ;
}
else
this._logger.warn("Empty vernacular crop name map for crop "+crop.getShortName());
Map<String,String> vernacularDefinitionMap = crop.getLocalDefinitionMap() ;
for( String language : vernacularNameMap.keySet() ) { if(vernacularDefinitionMap!=null)
Literal vernacularNameLiteral = for( String language : vernacularDefinitionMap.keySet() ) {
model.createLiteral(vernacularNameMap.get(language), language) ; Literal vernacularDefinitionLiteral =
traitSubject.addLiteral(DarwinCore.vernacularName,vernacularNameLiteral) ; model.createLiteral(vernacularDefinitionMap.get(language), language) ;
subject.addLiteral(DC.description,vernacularDefinitionLiteral) ;
}
else
this._logger.warn("Empty vernacular crop description map for crop "+crop.getShortName());
List<CropRule> rules = cropService.getCropRules(crop) ;
for(CropRule cr : rules) {
String species = cr.getSpecies() ;
String genus = cr.getGenus() ;
Boolean isIncluded = cr.isIncluded() ;
} }
Map<String,String> vernacularDefinitionMap = trait.getLocalDefinitionMap() ;
for( String language : vernacularDefinitionMap.keySet() ) {
Literal vernacularDefinitionLiteral =
model.createLiteral(vernacularDefinitionMap.get(language), language) ;
traitSubject.addLiteral(DC.description,vernacularDefinitionLiteral) ;
}
*/
/*
model.addAttribute("cropTaxonomies", cropService.getCropTaxonomies(crop, new PageRequest(0, 20, new Sort("taxonomy.genus", "taxonomy.species"))));
*/
} }
@RequestMapping @RequestMapping
......
...@@ -19,6 +19,8 @@ package org.genesys2.server.servlet.controller.rdf; ...@@ -19,6 +19,8 @@ package org.genesys2.server.servlet.controller.rdf;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletResponse;
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;
...@@ -30,7 +32,6 @@ import org.springframework.web.bind.annotation.PathVariable; ...@@ -30,7 +32,6 @@ 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.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
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;
...@@ -50,30 +51,66 @@ import org.bioversityinternational.model.rdf.skos.SKOS; ...@@ -50,30 +51,66 @@ import org.bioversityinternational.model.rdf.skos.SKOS;
@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 static final String DESCRIPTOR_NS = getBaseUri()+"/descriptors/";;
public final static String CATEGORY_NS = DESCRIPTOR_NS+"categories/" ; public static final String CATEGORY_NS = DESCRIPTOR_NS+"categories/" ;
public final static String TRAIT_NS = DESCRIPTOR_NS+"trait/" ; public static final String TRAIT_NS = DESCRIPTOR_NS+"trait/" ;
public final static String METHOD_NS = DESCRIPTOR_NS+"method/" ; public static final String METHOD_NS = DESCRIPTOR_NS+"method/" ;
public final static String SCALE_NS = DESCRIPTOR_NS+"scale/" ; public static final String SCALE_NS = DESCRIPTOR_NS+"scale/" ;
@Autowired @Autowired
private TraitService traitService; private TraitService traitService;
@Override /**
protected Model startModel() { * Method to retrieve list of all descriptor meta-data
Model model = super.startModel(); * recorded in the database, formatted as Turtle RDF.
model.setNsPrefix("cat", CATEGORY_NS ); *
model.setNsPrefix("trait", TRAIT_NS ); * @return List of RDF Turtle formatted trait properties
model.setNsPrefix("method",METHOD_NS ); */
model.setNsPrefix("scale", SCALE_NS ); @RequestMapping
return model ; public @ResponseBody
Object dumpAll() {
Model model = startModel() ;
wrapCategories(model) ;
for(Parameter trait : traitService.listTraits())
wrapTrait(model, trait) ;
for(Method method : traitService.listMethods()) {
Parameter trait = method.getParameter() ;
wrapMethod(model, trait, method) ;
}
return endModel(model) ;
} }
/* /*
* Creates and annotates a Method subject * Creates and annotates a Method subject
*/ */
private Resource categorySubject(Model model, ParameterCategory category) { private Resource categorySubject(Model model, ParameterCategory category) {
return createSubject(model, category, CATEGORY_NS, category.getName() ) ; return createSubject(model, category, CATEGORY_NS+category.getId(), category.getName() ) ;
}
/*
* Method generates RDF for one trait category record as RDF.
*/
private void wrapCategories(Model model) {
List<ParameterCategory> categories = traitService.listCategories() ;
for(ParameterCategory category:categories) {
// Insert category record into RDF model
Resource subject = categorySubject(model, category) ;
CCO.Vocabulary.set(model, subject, CCO.Vocabulary.CATEGORY, "Plant") ;
subject.addProperty(SKOS.broader, CCO.TraitCategory) ;
Map<String,String> vernacularNameMap = category.getLocalNameMap() ;
for(String language:vernacularNameMap.keySet()) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularNameMap.get(language), language) ;
subject.addLiteral(SKOS.prefLabel, vernacularNameLiteral) ;
}
}
} }
/** /**
...@@ -100,22 +137,8 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -100,22 +137,8 @@ public class DescriptorControllerRdf extends RdfBaseController {
Model model = startModel() ; Model model = startModel() ;
List<ParameterCategory> categories = traitService.listCategories() ; wrapCategories(model) ;
for(ParameterCategory category:categories) {
// Insert category record into RDF model
Resource subject = createSubject(model, category, CCO.getURI(), category.getName()) ;
CCO.Vocabulary.set(model, subject, CCO.Vocabulary.CATEGORY, "Plant") ;
subject.addProperty(SKOS.broader, CCO.TraitCategory) ;
Map<String,String> vernacularNameMap = category.getLocalNameMap() ;
for(String language:vernacularNameMap.keySet()) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularNameMap.get(language), language) ;
subject.addLiteral(SKOS.prefLabel, vernacularNameLiteral) ;
}
}
return endModel(model) ; return endModel(model) ;
} }
...@@ -140,7 +163,7 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -140,7 +163,7 @@ public class DescriptorControllerRdf extends RdfBaseController {
* Creates and annotates a Method subject * Creates and annotates a Method subject
*/ */
private Resource traitSubject(Model model, Parameter trait) { private Resource traitSubject(Model model, Parameter trait) {
return createProperty(model, trait, TRAIT_NS, trait.getTitle() ) ; return createProperty(model, trait, DESCRIPTOR_NS+trait.getId(), trait.getTitle() ) ;
} }
/* /*
...@@ -209,7 +232,7 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -209,7 +232,7 @@ public class DescriptorControllerRdf extends RdfBaseController {
*/ */
@RequestMapping("/{traitId}") @RequestMapping("/{traitId}")
public @ResponseBody public @ResponseBody
Object dumpTrait(@PathVariable long traitId) { Object dumpTrait(@PathVariable long traitId, HttpServletResponse response) {
Parameter trait = traitService.getTrait(traitId); Parameter trait = traitService.getTrait(traitId);
...@@ -221,6 +244,8 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -221,6 +244,8 @@ public class DescriptorControllerRdf extends RdfBaseController {
wrapTrait(model, trait) ; wrapTrait(model, trait) ;
response.setDateHeader("Last-Modified", trait.getLastModifiedDate().getTime());
return endModel(model); return endModel(model);
} }
...@@ -313,8 +338,19 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -313,8 +338,19 @@ public class DescriptorControllerRdf extends RdfBaseController {
private Resource[] traitAndMethodSubjects(Model model, Parameter trait, Method method) { private Resource[] traitAndMethodSubjects(Model model, Parameter trait, Method method) {
Resource[] subjects = new Resource[3] ; Resource[] subjects = new Resource[3] ;
subjects[0] = traitSubject(model, trait) ; subjects[0] = traitSubject(model, trait) ;
subjects[1] = createProperty(model, method, METHOD_NS, trait.getTitle()+" Method" ) ; subjects[1] = createProperty(
subjects[2] = createProperty(model, method, SCALE_NS, trait.getTitle()+" Scale" ) ; model,
method,
DESCRIPTOR_NS+trait.getId()+"/"+method.getId(),
trait.getTitle()+" Method"
) ;
subjects[2] = createProperty(
model,
method,
/* not sure if this is a complete enough specification for a Scale URI...*/
SCALE_NS+trait.getId()+"/"+method.getId(),
trait.getTitle()+" Scale"
) ;
return subjects ; return subjects ;
} }
...@@ -441,7 +477,14 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -441,7 +477,14 @@ public class DescriptorControllerRdf extends RdfBaseController {
Resource scaleSubj, Resource scaleVocabulary, String units Resource scaleSubj, Resource scaleVocabulary, String units
) { ) {
Resource scaleValuesSubj = createProperty(model, method, SCALE_NS, trait.getTitle()+" Scale Values", true) ; Resource scaleValuesSubj =
createProperty(
model,
method,
SCALE_NS+trait.getId()+"/"+method.getId(),
trait.getTitle()+" Scale Values",
true // is a SKOS Collection...
) ;
scaleSubj.addProperty( CCO.scaleType, "Nominal" ) ; scaleSubj.addProperty( CCO.scaleType, "Nominal" ) ;
scaleSubj.addProperty( CCO.scaleUnit, scaleValuesSubj ) ; scaleSubj.addProperty( CCO.scaleUnit, scaleValuesSubj ) ;
scaleValuesSubj.addProperty(SKOS.inScheme, scaleVocabulary ) ; scaleValuesSubj.addProperty(SKOS.inScheme, scaleVocabulary ) ;
...@@ -452,7 +495,13 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -452,7 +495,13 @@ public class DescriptorControllerRdf extends RdfBaseController {
Map<String, String> codeMap = TraitCode.parseCodeMap(options); Map<String, String> codeMap = TraitCode.parseCodeMap(options);
int n = 1 ; int n = 1 ;
for(String code : codeMap.keySet()) { for(String code : codeMap.keySet()) {
Resource valueSubj = createProperty(model, method, SCALE_NS, trait.getTitle()+" Scale Value"+n) ; Resource valueSubj =
createProperty(
model,
method,
SCALE_NS+trait.getId()+"/"+method.getId()+"/"+n,
trait.getTitle()+" Scale Value"+n
) ;
scaleValuesSubj.addProperty( SKOS.member, valueSubj ) ; scaleValuesSubj.addProperty( SKOS.member, valueSubj ) ;
valueSubj.addProperty( SKOS.broader, scaleSubj ) ; valueSubj.addProperty( SKOS.broader, scaleSubj ) ;
valueSubj.addProperty(SKOS.inScheme, scaleVocabulary ) ; valueSubj.addProperty(SKOS.inScheme, scaleVocabulary ) ;
...@@ -483,7 +532,6 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -483,7 +532,6 @@ public class DescriptorControllerRdf extends RdfBaseController {
Parameter trait = method.getParameter() ; Parameter trait = method.getParameter() ;
wrapMethod(model, trait, method) ; wrapMethod(model, trait, method) ;
} }
return endModel(model) ; return endModel(model) ;
} }
...@@ -497,7 +545,7 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -497,7 +545,7 @@ public class DescriptorControllerRdf extends RdfBaseController {
*/ */
@RequestMapping("/{traitId}/{methodId}") @RequestMapping("/{traitId}/{methodId}")
public @ResponseBody public @ResponseBody
Object dumpMethod( @PathVariable long traitId, @PathVariable long methodId) { Object dumpMethod( @PathVariable long traitId, @PathVariable long methodId, HttpServletResponse response) {
Parameter trait = traitService.getTrait(traitId); Parameter trait = traitService.getTrait(traitId);
...@@ -520,6 +568,8 @@ public class DescriptorControllerRdf extends RdfBaseController { ...@@ -520,6 +568,8 @@ public class DescriptorControllerRdf extends RdfBaseController {
wrapTrait(model, trait) ; wrapTrait(model, trait) ;
wrapMethod(model, trait, method) ; wrapMethod(model, trait, method) ;
response.setDateHeader("Last-Modified", method.getLastModifiedDate().getTime());
return endModel(model); return endModel(model);
} }
......
...@@ -22,6 +22,7 @@ import java.io.UnsupportedEncodingException; ...@@ -22,6 +22,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Date; import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;