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:
parent
d546a5ace3
commit
d6094eeb50
2 changed files with 85 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.individual;
|
package edu.cornell.mannlib.vitro.webapp.controller.individual;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
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.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
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.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
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.RDFNode;
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
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.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RdfResponseValues;
|
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.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.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
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 RICH_EXPORT_ROOT = "/WEB-INF/rich-export/";
|
||||||
private static final String INCLUDE_ALL = "all";
|
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 VitroRequest vreq;
|
||||||
private final ServletContext ctx;
|
private final ServletContext ctx;
|
||||||
private final String individualUri;
|
private final String individualUri;
|
||||||
|
@ -118,6 +134,7 @@ public class IndividualRdfAssembler {
|
||||||
o.add(getStatementsAboutEntity());
|
o.add(getStatementsAboutEntity());
|
||||||
o.add(getLabelsAndTypesOfRelatedObjects());
|
o.add(getLabelsAndTypesOfRelatedObjects());
|
||||||
filterByPolicy(o);
|
filterByPolicy(o);
|
||||||
|
addDocumentMetadata(o);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,4 +285,65 @@ public class IndividualRdfAssembler {
|
||||||
return richExportModel;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class IndividualRequestAnalyzer {
|
||||||
.getLog(IndividualRequestAnalyzer.class);
|
.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 HTML_REQUEST = Pattern.compile("^/display/([^/]+)$");
|
||||||
private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]+)$");
|
private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]+)$");
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public class IndividualRequestAnalyzer {
|
||||||
IndividualController.ACCEPTED_CONTENT_TYPES);
|
IndividualController.ACCEPTED_CONTENT_TYPES);
|
||||||
|
|
||||||
if (RDFXML_MIMETYPE.equals(ctStr) || N3_MIMETYPE.equals(ctStr)
|
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);
|
return new ContentType(ctStr);
|
||||||
}
|
}
|
||||||
} catch (Throwable th) {
|
} catch (Throwable th) {
|
||||||
|
@ -167,6 +167,7 @@ public class IndividualRequestAnalyzer {
|
||||||
* /individual/localname/localname.rdf
|
* /individual/localname/localname.rdf
|
||||||
* /individual/localname/localname.n3
|
* /individual/localname/localname.n3
|
||||||
* /individual/localname/localname.ttl
|
* /individual/localname/localname.ttl
|
||||||
|
* /individual/localname/localname.jsonld
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return null on failure.
|
* @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.rdf
|
||||||
* http://vivo.cornell.edu/individual/n23/n23.n3
|
* http://vivo.cornell.edu/individual/n23/n23.n3
|
||||||
* http://vivo.cornell.edu/individual/n23/n23.ttl
|
* http://vivo.cornell.edu/individual/n23/n23.ttl
|
||||||
|
* http://vivo.cornell.edu/individual/n23/n23.jsonld
|
||||||
*/
|
*/
|
||||||
Matcher rdfMatch = RDF_REQUEST.matcher(url);
|
Matcher rdfMatch = RDF_REQUEST.matcher(url);
|
||||||
if (rdfMatch.matches() && rdfMatch.groupCount() == 2) {
|
if (rdfMatch.matches() && rdfMatch.groupCount() == 2) {
|
||||||
|
@ -270,6 +272,9 @@ public class IndividualRequestAnalyzer {
|
||||||
if ("ttl".equals(rdfType)) {
|
if ("ttl".equals(rdfType)) {
|
||||||
return ContentType.TURTLE;
|
return ContentType.TURTLE;
|
||||||
}
|
}
|
||||||
|
if ("jsonld".equals(rdfType)) {
|
||||||
|
return ContentType.JSON;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue