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

RDF crop, descriptor controllers updated for production

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