VIVO-295 Added a metadata section to LOD results.

Includes date and rights, among other things. While we're at it, support LOD requests with /n123/n123.jsonld
This commit is contained in:
j2blake 2013-10-04 15:37:17 -04:00
parent d546a5ace3
commit d6094eeb50
2 changed files with 85 additions and 2 deletions

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.individual;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@ -11,10 +12,13 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
@ -33,6 +37,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RdfResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
@ -71,6 +76,17 @@ public class IndividualRdfAssembler {
private static final String RICH_EXPORT_ROOT = "/WEB-INF/rich-export/";
private static final String INCLUDE_ALL = "all";
private static final String NS_DC = "http://purl.org/dc/elements/1.1/";
private static final String URI_RIGHTS = NS_DC + "rights";
private static final String URI_DATE = NS_DC + "date";
private static final String URI_PUBLISHER = NS_DC + "publisher";
private static final String NS_FOAF = "http://xmlns.com/foaf/0.1/";
private static final String URI_DOCUMENT = NS_FOAF + "Document";
private static final String URI_LABEL = VitroVocabulary.RDFS + "label";
private static final String URI_TYPE = VitroVocabulary.RDF_TYPE;
private final VitroRequest vreq;
private final ServletContext ctx;
private final String individualUri;
@ -118,6 +134,7 @@ public class IndividualRdfAssembler {
o.add(getStatementsAboutEntity());
o.add(getLabelsAndTypesOfRelatedObjects());
filterByPolicy(o);
addDocumentMetadata(o);
return o;
}
@ -268,4 +285,65 @@ public class IndividualRdfAssembler {
return richExportModel;
}
/**
* Add info about the RDF itself.
*
* It will look something like this:
*
* <pre>
* <http://vivo.cornell.edu/individual/n6628/n6628.rdf>
* rdfs:label "RDF description of Baker, Able - http://vivo.cornell.edu/individual/n6628" ;
* rdf:type foaf:Document ;
* dc:publisher <http://vivo.cornell.edu> ;
* dc:date "2007-07-13"^^xsd:date ;
* dc:rights <http://vivo.cornell.edu/termsOfUse> .
* </pre>
*/
private void addDocumentMetadata(OntModel o) {
String baseUrl = figureBaseUrl();
String documentUri = createDocumentUri();
String label = createDocumentLabel(o);
Literal dateLiteral = createDateLiteral(o);
Resource md = o.getResource(documentUri);
o.add(md, o.getProperty(URI_LABEL), label);
o.add(md, o.getProperty(URI_TYPE), o.getResource(URI_DOCUMENT));
o.add(md, o.getProperty(URI_PUBLISHER), o.getResource(baseUrl));
o.add(md, o.getProperty(URI_DATE), dateLiteral);
o.add(md, o.getProperty(URI_RIGHTS),
o.getResource(baseUrl + "/termsOfUse"));
}
private String figureBaseUrl() {
int cutHere = individualUri.indexOf("/individual");
return (cutHere > 0) ? individualUri.substring(0, cutHere)
: individualUri;
}
private String createDocumentUri() {
return vreq.getRequestURL().toString();
}
private String createDocumentLabel(OntModel o) {
String label = null;
NodeIterator nodes = o.listObjectsOfProperty(
o.getResource(individualUri), o.getProperty(URI_LABEL));
while (nodes.hasNext()) {
RDFNode n = nodes.nextNode();
if (n.isLiteral()) {
label = n.asLiteral().getString();
}
}
if (label == null) {
return "RDF description of " + individualUri;
} else {
return "RDF description of " + label + " - " + individualUri;
}
}
private Literal createDateLiteral(OntModel o) {
return o.createTypedLiteral(new Date(), XSDDatatype.XSDdate);
}
}

View file

@ -28,7 +28,7 @@ public class IndividualRequestAnalyzer {
.getLog(IndividualRequestAnalyzer.class);
private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]+)/\\1\\.(rdf|n3|ttl)$");
private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]+)/\\1\\.(rdf|n3|ttl|jsonld)$");
private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]+)$");
private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]+)$");
@ -145,7 +145,7 @@ public class IndividualRequestAnalyzer {
IndividualController.ACCEPTED_CONTENT_TYPES);
if (RDFXML_MIMETYPE.equals(ctStr) || N3_MIMETYPE.equals(ctStr)
|| TTL_MIMETYPE.equals(ctStr)) {
|| TTL_MIMETYPE.equals(ctStr) || JSON_MIMETYPE.equals(ctStr)) {
return new ContentType(ctStr);
}
} catch (Throwable th) {
@ -167,6 +167,7 @@ public class IndividualRequestAnalyzer {
* /individual/localname/localname.rdf
* /individual/localname/localname.n3
* /individual/localname/localname.ttl
* /individual/localname/localname.jsonld
* </pre>
*
* @return null on failure.
@ -257,6 +258,7 @@ public class IndividualRequestAnalyzer {
* http://vivo.cornell.edu/individual/n23/n23.rdf
* http://vivo.cornell.edu/individual/n23/n23.n3
* http://vivo.cornell.edu/individual/n23/n23.ttl
* http://vivo.cornell.edu/individual/n23/n23.jsonld
*/
Matcher rdfMatch = RDF_REQUEST.matcher(url);
if (rdfMatch.matches() && rdfMatch.groupCount() == 2) {
@ -270,6 +272,9 @@ public class IndividualRequestAnalyzer {
if ("ttl".equals(rdfType)) {
return ContentType.TURTLE;
}
if ("jsonld".equals(rdfType)) {
return ContentType.JSON;
}
}
return null;