Commit 0a7b4ecf authored by Matija Obreza's avatar Matija Obreza

RDF crop, descriptor controllers updated for production

parent 04980747
......@@ -497,9 +497,8 @@
<dependency>
<groupId>org.bioversityinternational</groupId>
<artifactId>org.bioversityinternational.ontology</artifactId>
<version>0.0.6</version>
<version>0.6.2</version>
</dependency>
</dependencies>
<build>
......
......@@ -19,6 +19,12 @@ package org.genesys2.server.servlet.controller.rdf;
import java.util.List;
import java.util.Map;
import org.bioversityinternational.model.germplasm.CCO;
import org.bioversityinternational.model.rdf.dwc.DarwinCore;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.service.CropService;
import org.genesys2.spring.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -33,19 +39,12 @@ import com.hp.hpl.jena.vocabulary.DC;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.service.CropService;
import org.genesys2.spring.ResourceNotFoundException;
import org.bioversityinternational.model.germplasm.CCO;
import org.bioversityinternational.model.rdf.dwc.DarwinCore;
@Controller
@RequestMapping(value = "/crops", method = RequestMethod.GET, headers = "accept=text/turtle", produces = RdfBaseController.RDF_MEDIATYPE_TURTLE)
public class CropControllerRdf extends RdfBaseController {
public static final String CROPS_NS = getBaseUri()+"/crops/";;
public static final String SPECIES_NS = CROPS_NS+"species/" ;
private final String CROPS_NS = "/crops/";
private final String SPECIES_NS = CROPS_NS + "species/";
@Autowired
private CropService cropService;
......@@ -71,44 +70,41 @@ public class CropControllerRdf extends RdfBaseController {
.
*/
private void wrapCrop(Model model, Crop crop) {
Resource cropSubj = createSubject(model, crop, CROPS_NS+crop.getId(), crop.getShortName()+" Taxon") ;
cropSubj.addProperty(DarwinCore.scientificName, crop.getShortName()) ;
String seeAlso = crop.getRdfUri() ;
if(seeAlso!=null)
cropSubj.addProperty(
RDFS.seeAlso,
model.createResource(seeAlso)
) ;
Resource cropSubj = createSubject(model, crop, CROPS_NS + crop.getShortName(), crop.getShortName() + " Taxon");
// FIXME That's probably not right
cropSubj.addProperty(DarwinCore.scientificName, crop.getShortName());
String seeAlso = crop.getRdfUri();
if (seeAlso != null)
cropSubj.addProperty(RDFS.seeAlso, model.createResource(seeAlso));
/*
* vernacular names & descriptions in i18n
*/
Map<String,String> vernacularNameMap = crop.getLocalNameMap() ;
if(vernacularNameMap!=null)
for( String language : vernacularNameMap.keySet() ) {
Literal vernacularNameLiteral =
model.createLiteral(vernacularNameMap.get(language), language) ;
cropSubj.addLiteral(DarwinCore.vernacularName,vernacularNameLiteral) ;
*/
Map<String, String> vernacularNameMap = crop.getLocalNameMap();
if (vernacularNameMap != null)
for (String language : vernacularNameMap.keySet()) {
Literal vernacularNameLiteral = model.createLiteral(vernacularNameMap.get(language), language);
cropSubj.addLiteral(DarwinCore.vernacularName, vernacularNameLiteral);
}
else
this._logger.warn("Empty vernacular crop name map for crop "+crop.getShortName());
Map<String,String> vernacularDefinitionMap = crop.getLocalDefinitionMap() ;
if(vernacularDefinitionMap!=null)
for( String language : vernacularDefinitionMap.keySet() ) {
Literal vernacularDefinitionLiteral =
model.createLiteral(vernacularDefinitionMap.get(language), language) ;
cropSubj.addLiteral(DC.description,vernacularDefinitionLiteral) ;
this._logger.warn("Empty vernacular crop name map for crop " + crop.getShortName());
Map<String, String> vernacularDefinitionMap = crop.getLocalDefinitionMap();
if (vernacularDefinitionMap != null)
for (String language : vernacularDefinitionMap.keySet()) {
Literal vernacularDefinitionLiteral = model.createLiteral(vernacularDefinitionMap.get(language), language);
cropSubj.addLiteral(DC.description, vernacularDefinitionLiteral);
}
else
this._logger.warn("Empty vernacular crop description map for crop "+crop.getShortName());
this._logger.warn("Empty vernacular crop description map for crop " + crop.getShortName());
/* Exemplar for CropRule species...
/*
* Exemplar for CropRule species...
*
genesys:MusaAcuminata a cco:Species;
dwc:scientificName "Musa acuminata" ;
......@@ -122,55 +118,53 @@ public class CropControllerRdf extends RdfBaseController {
Note: current GENESYS data model does NOT track the description of a species...
*/
List<CropRule> rules = cropService.getCropRules(crop) ;
for(CropRule cr : rules) {
String species = cr.getSpecies() ;
String genus = cr.getGenus() ;
Boolean isIncluded = cr.isIncluded() ;
Resource speciesSubj =
createSubject(
model,
crop,
SPECIES_NS+canonicalID(species,true),
species
) ;
speciesSubj.addProperty(RDF.type, CCO.Species ) ;
speciesSubj.addProperty(DarwinCore.scientificName, species ) ;
speciesSubj.addProperty(DarwinCore.genus, genus ) ;
speciesSubj.addProperty(CCO.speciesIncluded, isIncluded.toString() ) ;
List<CropRule> rules = cropService.getCropRules(crop);
for (CropRule cr : rules) {
String species = cr.getSpecies();
String genus = cr.getGenus();
Boolean isIncluded = cr.isIncluded();
// FIXME in CropRule the Genus is required, species is not.
if (species != null) {
Resource speciesSubj = createSubject(model, crop, SPECIES_NS + canonicalID(species, true), species);
speciesSubj.addProperty(RDF.type, CCO.Species);
speciesSubj.addProperty(DarwinCore.scientificName, species);
speciesSubj.addProperty(DarwinCore.genus, genus);
speciesSubj.addProperty(CCO.speciesIncluded, isIncluded.toString());
}
}
}
@RequestMapping
public @ResponseBody
String dumpCrops() {
Model model = startModel() ;
List<Crop> crops = cropService.listCrops() ;
for(Crop crop : crops) wrapCrop( model, crop) ;
Model model = startModel();
List<Crop> crops = cropService.listCrops();
for (Crop crop : crops)
wrapCrop(model, crop);
return endModel(model) ;
return endModel(model);
}
@RequestMapping("/{shortName}")
public @ResponseBody
String dumpCrop(@PathVariable(value = "shortName") String shortName) {
_logger.debug("Dump RDF data for crop: " + shortName);
Model model = startModel() ;
Model model = startModel();
Crop crop = cropService.getCrop(shortName);
if (crop == null) {
throw new ResourceNotFoundException();
}
wrapCrop(model,crop) ;
return endModel(model) ;
wrapCrop(model, crop);
return endModel(model);
}
}
......@@ -21,6 +21,15 @@ import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import org.bioversityinternational.model.germplasm.CCO;
import org.bioversityinternational.model.rdf.dc.DublinCore;
import org.bioversityinternational.model.rdf.dwc.DarwinCore;
import org.bioversityinternational.model.rdf.skos.SKOS;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.VersionedAuditedModel;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.UserService;
import org.genesys2.server.servlet.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
......@@ -31,25 +40,14 @@ import com.hp.hpl.jena.vocabulary.DC;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import org.genesys2.server.exception.UserException;
import org.genesys2.server.model.VersionedAuditedModel;
import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.UserService;
import org.genesys2.server.servlet.controller.BaseController;
import org.bioversityinternational.model.germplasm.CCO;
import org.bioversityinternational.model.rdf.dc.DublinCore;
import org.bioversityinternational.model.rdf.dwc.DarwinCore;
import org.bioversityinternational.model.rdf.skos.SKOS;
/**
* Controller which simply handles RDF requests
*/
public abstract class RdfBaseController extends BaseController {
@Autowired
private UserService userService;
/**
* A String equivalent of {@link RdfBaseController#RDF_MEDIATYPE_XML}.
*/
......@@ -60,203 +58,209 @@ public abstract class RdfBaseController extends BaseController {
*/
public final static String RDF_MEDIATYPE_TURTLE = "text/turtle";
protected static final String GCDT = "Global Crop Diversity Trust" ;
protected static final String RDF_MODEL_VERSION = "Revision: 0.1" ;
// TODO: the @Value initialization with the Spring set Property base.url
// here doesn't seem to work (even if I set the variable to a non-static private
protected static final String GCDT = "Global Crop Diversity Trust";
protected static final String RDF_MODEL_VERSION = "Revision: 0.1";
@Value("${base.url}")
private static String baseUrl = "http://genesys-pgr.org" ;
protected static String getBaseUri() {
if(baseUrl==null)
throw new NullPointerException("Base URI not set in RdfBaseController?") ;
return baseUrl ;
}
private String baseUrl;
protected String getBaseUri() {
if (baseUrl == null)
throw new NullPointerException("Base URI not set in RdfBaseController?");
return baseUrl;
}
protected static String modelVersion() {
return RDF_MODEL_VERSION ;
return RDF_MODEL_VERSION;
}
/*
* Method to set up the RDF model with basic global annotation.
*/
protected Model startModel() {
Model model = ModelFactory.createDefaultModel();
model.setNsPrefix("rdf", RDF.getURI() );
model.setNsPrefix("rdfs", RDFS.getURI() );
model.setNsPrefix("dc", DC.getURI() );
model.setNsPrefix("dcterms", DublinCore.getURI() );
model.setNsPrefix("dwc", DarwinCore.getURI() );
model.setNsPrefix("skos", SKOS.getURI() );
model.setNsPrefix("cco", CCO.getURI() );
model.setNsPrefix("genesys", getBaseUri()+"/" );
return model ;
model.setNsPrefix("rdf", RDF.getURI());
model.setNsPrefix("rdfs", RDFS.getURI());
model.setNsPrefix("dc", DC.getURI());
model.setNsPrefix("dcterms", DublinCore.getURI());
model.setNsPrefix("dwc", DarwinCore.getURI());
model.setNsPrefix("skos", SKOS.getURI());
model.setNsPrefix("cco", CCO.getURI());
model.setNsPrefix("genesys", getBaseUri() + "/");
return model;
}
/**
* Generates a canonical RDF identifier from its input string
* (blanks removed, with title case or camel case words, depending
* on capitalizeFirst being true or false, respectively)
* Generates a canonical RDF identifier from its input string (blanks
* removed, with title case or camel case words, depending on
* capitalizeFirst being true or false, respectively)
*
* @param identifier
* @param capitlizeFirst - if true, then the first letter of the identifier is capitalized
* @param capitlizeFirst
* - if true, then the first letter of the identifier is
* capitalized
* @return
*/
public static String canonicalID(String identifier, Boolean capitalizeFirst) {
String[] words = identifier.split("\\s") ;
identifier = "" ;
for(String word: words) {
if(!capitalizeFirst) {
String[] words = identifier.split("\\s");
identifier = "";
for (String word : words) {
if (!capitalizeFirst) {
// only run once in the loop if false (reset to true...)
identifier += word.toLowerCase() ;
capitalizeFirst = true ;
identifier += word.toLowerCase();
capitalizeFirst = true;
} else {
identifier += word.substring(0,1).toUpperCase() ;
identifier += word.substring(1).toLowerCase() ;
identifier += word.substring(0, 1).toUpperCase();
identifier += word.substring(1).toLowerCase();
}
}
return identifier ;
return identifier;
}
/*
* Method to create a subject Resource initialized with common core annotation.
* Method to create a subject Resource initialized with common core
* annotation.
*/
// Same as following method but defaults to SKOS.Concept ...
private Resource createResource(
Model model,
VersionedAuditedModel entity,
String uri,
String tag,
Boolean isProperty
) {
return createResource( model, entity, uri, tag, isProperty, false ) ;
private Resource createResource(Model model, VersionedAuditedModel entity, String uri, String tag, Boolean isProperty) {
return createResource(model, entity, uri, tag, isProperty, false);
}
// This version checks a flag for SKOS:Collection status
private Resource createResource(
Model model,
VersionedAuditedModel entity,
String uri,
String tag,
Boolean isProperty,
Boolean isCollection // SKOS type - true if isa SKOS:Collection
) {
Resource subject = model.createResource(uri) ;
subject.addProperty(DC.publisher,GCDT) ;
if(isCollection)
subject.addProperty(RDF.type, SKOS.Collection) ;
private Resource createResource(Model model, VersionedAuditedModel entity, String uri, String tag, Boolean isProperty, Boolean isCollection // SKOS
// type
// -
// true
// if
// isa
// SKOS:Collection
) {
Resource subject = model.createResource(getBaseUri() + uri);
subject.addProperty(DC.publisher, GCDT);
if (isCollection)
subject.addProperty(RDF.type, SKOS.Collection);
else
subject.addProperty(RDF.type, SKOS.Concept) ;
subject.addProperty(RDF.type, SKOS.Concept);
if(isProperty)
tag= canonicalID(tag,false) ;
if (isProperty)
tag = canonicalID(tag, false);
else
tag = canonicalID(tag,true) ;
subject.addProperty(SKOS.hiddenLabel,tag) ;
tag = canonicalID(tag, true);
subject.addProperty(SKOS.hiddenLabel, tag);
// dc:creator <user>
long userId = entity.getCreatedBy() ;
try {
User user = userService.getUserById(userId) ;
// just put the user's name for now?
subject.addProperty(DC.creator, user.getName()) ;
} catch (UserException e) {
this._logger.debug("Invalid user access?", e);
Long userId = entity.getCreatedBy();
if (userId != null) {
try {
User user = userService.getUserById(userId);
// just put the user's name for now?
subject.addProperty(DC.creator, user.getName());
} catch (UserException e) {
this._logger.debug("Invalid user access?", e);
}
}
// dc:date <createdData>
Date createdDate = entity.getCreatedDate() ;
subject.addProperty(DC.date, createdDate.toString()) ;
Date createdDate = entity.getCreatedDate();
if (createdDate != null)
subject.addProperty(DC.date, createdDate.toString());
// dc:hasVersion <createdData>
String version = String.valueOf(entity.getVersion()) ;
subject.addProperty(DublinCore.hasVersion, version ) ;
return subject ;
String version = String.valueOf(entity.getVersion());
subject.addProperty(DublinCore.hasVersion, version);
return subject;
}
/**
* Method to create a Subject Resource initialized with common core annotation.
* Method to create a Subject Resource initialized with common core
* annotation.
*/
protected Resource createSubject(Model model, VersionedAuditedModel entity, String uri, String tag) {
return createResource(model, entity, uri, tag, false) ;
return createResource(model, entity, uri, tag, false);
}
/**
* Method to create a Property Resource initialized with common core annotation.
* Method to create a Property Resource initialized with common core
* annotation.
*/
protected Resource createProperty(Model model, VersionedAuditedModel entity, String uri, String tag) {
return createResource(model, entity, uri, tag, true) ;
return createResource(model, entity, uri, tag, true);
}
/**
* Method to create a Property Resource initialized with common core annotation.
* This version checks if the Resource is meant to be a SKOS Collection
* Method to create a Property Resource initialized with common core
* annotation. This version checks if the Resource is meant to be a SKOS
* Collection
*/
protected Resource createProperty(Model model, VersionedAuditedModel entity, String uri, String tag, Boolean isCollection) {
return createResource(model, entity, uri, tag, true, isCollection) ;
return createResource(model, entity, uri, tag, true, isCollection);
}
/*
* Method to create an Object Resource initialized with common core annotation.
* Method to create an Object Resource initialized with common core
* annotation.
*/
protected Resource createObject(Model model, VersionedAuditedModel entity, String uri, String tag) {
return createResource(model, entity, uri, tag, false) ;
return createResource(model, entity, uri, tag, false);
}
protected void seeAlso(Model model, Resource subject, String seeAlso) {
if(seeAlso!=null)
subject.addProperty(RDFS.seeAlso,model.createResource(seeAlso)) ;
if (seeAlso != null)
subject.addProperty(RDFS.seeAlso, model.createResource(seeAlso));
}
/**
* Method to write out the model as a Turtle RDF string
*
* @param model - Apache Jena RDF Model class object of current model being rendered
* @param format Predefined values are "RDF/XML", "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") and "N3".
* @param model
* - Apache Jena RDF Model class object of current model being
* rendered
* @param format
* Predefined values are "RDF/XML", "RDF/XML-ABBREV", "N-TRIPLE",
* "TURTLE", (and "TTL") and "N3".
* @return
*/
/*
* TODO: maybe convert this to an HTTP Converter (which can handle diverse RDF formats?)
* TODO: maybe convert this to an HTTP Converter (which can handle diverse
* RDF formats?)
*/
protected String endModel(Model model, String format) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
if(format==null)//model.write(ps, "RDF/XML-ABBREV") ;
model.write(ps, "TURTLE") ;
if (format == null)// model.write(ps, "RDF/XML-ABBREV") ;
model.write(ps, "TURTLE");
else
model.write(ps,format) ;
String output = "" ;
model.write(ps, format);
String output = "";
try {
output = os.toString("UTF8");
} catch (UnsupportedEncodingException e) {
_logger.debug("os.toString(\"UTF8\") failed while to write out parameter categories as Turtle RDF");
}
_logger.trace("RdfBaseController.endModel() returning RDF text: "+output);
return output ;
_logger.trace("RdfBaseController.endModel() returning RDF text: " + output);
return output;
}
/*
* Method to write out the model as a Turtle RDF string
* (TODO: maybe convert this to an HTTP Converter which can
* handle other RDF formats?)
* Method to write out the model as a Turtle RDF string (TODO: maybe convert
* this to an HTTP Converter whic