From 054b1a9ac1791d9fd9954019e5afd734f5b7802a Mon Sep 17 00:00:00 2001 From: stellamit Date: Wed, 25 May 2011 18:39:12 +0000 Subject: [PATCH] NIHVIVO-1275 - updates to allow for the request of additional information related to a person in a linked data request for a person individual. --- .../freemarker/IndividualController.java | 36 +++++++-- .../utils/jena/InitialJenaModelUtils.java | 79 +++++++++++++++++-- 2 files changed, 104 insertions(+), 11 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index 2b2df0341..79965e264 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -4,8 +4,10 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; import java.io.IOException; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,6 +58,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; +import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; import edu.cornell.mannlib.vitro.webapp.web.ContentType; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ListedIndividualTemplateModel; @@ -72,6 +75,9 @@ public class IndividualController extends FreemarkerHttpServlet { private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(IndividualController.class); + private static final String RICH_EXPORT_ROOT = "/WEB-INF/rich-export/"; + private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person"; + private static final String INCLUDE_ALL = "all"; private static final Map namespaces = new HashMap() {{ put("vitro", VitroVocabulary.vitroURI); @@ -336,8 +342,10 @@ public class IndividualController extends FreemarkerHttpServlet { ontModel = (OntModel)session.getAttribute("jenaOntModel"); if( ontModel == null) ontModel = (OntModel)getServletContext().getAttribute("jenaOntModel"); - - Model newModel = getRDF(individual, ontModel, ModelFactory.createDefaultModel(),0); + + + String[] includes = vreq.getParameterValues("include"); + Model newModel = getRDF(individual,ontModel,ModelFactory.createDefaultModel(),0,includes); return new RdfResponseValues(rdfFormat, newModel); } @@ -597,7 +605,7 @@ public class IndividualController extends FreemarkerHttpServlet { return "enabled".equals(property); } - private Model getRDF(Individual entity, OntModel contextModel, Model newModel, int recurseDepth) { + private Model getRDF(Individual entity, OntModel contextModel, Model newModel, int recurseDepth, String[] includes) { Resource subj = newModel.getResource(entity.getURI()); @@ -625,7 +633,7 @@ public class IndividualController extends FreemarkerHttpServlet { Resource obj = newModel.getResource(os.getObjectURI()); newModel.add(newModel.createStatement(subj, prop, obj)); if ( includeInLinkedData(obj, contextModel)) { - newModel.add(getRDF(os.getObject(), contextModel, newModel, recurseDepth + 1)); + newModel.add(getRDF(os.getObject(), contextModel, newModel, recurseDepth + 1, includes)); } else { contextModel.enterCriticalSection(Lock.READ); try { @@ -640,7 +648,7 @@ public class IndividualController extends FreemarkerHttpServlet { newModel = getLabelAndTypes(entity, contextModel, newModel ); // get all the statements not covered by the object property / datatype property code above - // note implication that extendedLinkedData individuals will only be evaulated for the + // note implication that extendedLinkedData individuals will only be evaluated for the // recognized object properties. contextModel.enterCriticalSection(Lock.READ); try { @@ -654,7 +662,23 @@ public class IndividualController extends FreemarkerHttpServlet { } finally { contextModel.leaveCriticalSection(); } - + + if (recurseDepth == 0 && includes != null && entity.isVClass(PERSON_CLASS_URI)) { + + for (String include : includes) { + + String rootDir = null; + if (INCLUDE_ALL.equals(include)) { + rootDir = RICH_EXPORT_ROOT; + } else { + rootDir = RICH_EXPORT_ROOT + include + "/"; + } + + Model extendedModel = InitialJenaModelUtils.createModelFromQueries(getServletContext(), rootDir, contextModel, entity.getURI()); + newModel.add(extendedModel); + } + } + return newModel; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/InitialJenaModelUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/InitialJenaModelUtils.java index d8e207dd4..6dcfd5589 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/InitialJenaModelUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/jena/InitialJenaModelUtils.java @@ -2,9 +2,11 @@ package edu.cornell.mannlib.vitro.webapp.utils.jena; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Set; import javax.servlet.ServletContext; @@ -15,7 +17,11 @@ import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.AnonId; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; @@ -99,6 +105,69 @@ public class InitialJenaModelUtils { m.getProperty(VitroVocabulary.IN_CLASSGROUP), thingsClassGroup); return m; } + + public static Model createModelFromQueries(ServletContext sc, String rootDir, OntModel sourceModel, String subject) { + + Model model = ModelFactory.createDefaultModel(); + + Set pathSet = sc.getResourcePaths(rootDir); + + if (pathSet == null) { + log.warn(rootDir + " not found."); + return model; + } + + for ( String path : pathSet ) { + File file = new File(sc.getRealPath(path)); + if (file.isDirectory()) { + model.add(createModelFromQueries(sc, path, sourceModel, subject)); + } else if (file.isFile()) { + if (!path.endsWith(".sparql")) { + log.warn("Ignoring file " + path + " because the file extension is not sparql."); + continue; + } + model.add(createModelFromQuery(file, sourceModel, subject)); + } else { + log.warn("path is neither a directory nor a file " + path); + } + } // end - for + + return model; + } - + public static Model createModelFromQuery(File sparqlFile, OntModel sourceModel, String subject) { + + Model model = ModelFactory.createDefaultModel(); + + BufferedReader reader = null; + + try { + try { + reader = new BufferedReader(new FileReader(sparqlFile)); + StringBuffer fileContents = new StringBuffer(); + String ln; + + while ( (ln = reader.readLine()) != null) { + fileContents.append(ln).append('\n'); + } + + String query = fileContents.toString(); + String subjectString = "<" + subject + ">"; + query = query.replaceAll("PERSON_URI", subjectString); + + Query q = QueryFactory.create(query, Syntax.syntaxARQ); + QueryExecution qe = QueryExecutionFactory.create(q, sourceModel); + qe.execConstruct(model); + } catch (Exception e) { + log.error("Unable to process file " + sparqlFile.getAbsolutePath(), e); + } finally { + reader.close(); + } + } catch (IOException ioe) { + // this is for the reader.close above + log.warn("Exception while trying to close file: " + sparqlFile.getAbsolutePath(), ioe); + } + + return model; + } }