NIHVIVO-3516 fixed merge tool so it doesn't strand triples in a graph named with SDB's union URI

This commit is contained in:
brianjlowe 2011-12-16 17:20:10 +00:00
parent f3d6e33a01
commit 2bdb44685f
3 changed files with 814 additions and 791 deletions

View file

@ -80,6 +80,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestWorkflowProcessor; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestWorkflowProcessor;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaOutputUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaOutputUtils;
import edu.cornell.mannlib.vitro.webapp.utils.jena.WorkflowOntology; import edu.cornell.mannlib.vitro.webapp.utils.jena.WorkflowOntology;
@ -621,23 +622,25 @@ public class JenaIngestController extends BaseEditController {
if(uri1!=null){ if(uri1!=null){
JenaIngestUtils utils = new JenaIngestUtils(); JenaIngestUtils utils = new JenaIngestUtils();
/* /*
* get baseOnt, Ont and infOnt models * get baseOnt and infOnt models
*/ */
OntModel baseOntModel = (OntModel) getServletContext().getAttribute("baseOntModel"); OntModel baseOntModel = ModelContext.getBaseOntModel(
OntModel ontModel = (OntModel) getServletContext());
getServletContext().getAttribute("jenaOntModel"); OntModel tboxOntModel = ModelContext.getUnionOntModelSelector(
OntModel infOntModel = (OntModel) getServletContext()).getTBoxModel();
getServletContext().getAttribute(JenaBaseDao.INFERENCE_ONT_MODEL_ATTRIBUTE_NAME);
/* /*
* calling method that does the merge operation. * calling method that does the merge operation.
*/ */
String result = utils.doMerge(uri1,uri2,baseOntModel,ontModel,infOntModel,usePrimaryLabelOnly); MergeResult result = utils.doMerge(
vreq.getSession().setAttribute("leftoverModel", utils.getLeftOverModel()); uri1, uri2, baseOntModel, tboxOntModel, usePrimaryLabelOnly);
vreq.setAttribute("result",result);
vreq.setAttribute("title","Merge Resources"); vreq.getSession().setAttribute(
vreq.setAttribute("bodyJsp",MERGE_RESULT); "leftoverModel", result.getLeftoverModel());
} vreq.setAttribute("result", result);
else{ vreq.setAttribute("title", "Merge Resources");
vreq.setAttribute("bodyJsp", MERGE_RESULT);
} else{
vreq.setAttribute("title","Merge Resources"); vreq.setAttribute("title","Merge Resources");
vreq.setAttribute("bodyJsp",MERGE_RESOURCES); vreq.setAttribute("bodyJsp",MERGE_RESOURCES);
} }
@ -1192,7 +1195,7 @@ public class JenaIngestController extends BaseEditController {
ontModel.leaveCriticalSection(); ontModel.leaveCriticalSection();
} }
if(!namespacePresent){ if(!namespacePresent){
result = "0 resource renamed"; result = "no resources renamed";
return result; return result;
} }
for( String oldURIStr : urisToChange){ for( String oldURIStr : urisToChange){

View file

@ -2,7 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.utils.jena; package edu.cornell.mannlib.vitro.webapp.utils.jena;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -16,15 +15,12 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
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 org.openrdf.model.vocabulary.RDFS;
import com.hp.hpl.jena.ontology.FunctionalProperty;
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.ontology.OntProperty;
import com.hp.hpl.jena.rdf.model.Literal; 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;
@ -41,11 +37,11 @@ import com.hp.hpl.jena.util.ResourceUtils;
import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao;
public class JenaIngestUtils { public class JenaIngestUtils {
@ -591,132 +587,151 @@ public class JenaIngestUtils {
} }
} }
public String doMerge(String uri1,String uri2,OntModel baseOntModel,OntModel ontModel,OntModel infOntModel,String usePrimaryLabelOnly){ public class MergeResult {
private String resultText;
private Model leftoverModel;
public MergeResult() {}
public MergeResult(String resultText, Model leftoverModel) {
this.resultText = resultText;
this.leftoverModel = leftoverModel;
}
public void setResultText(String resultText) {
this.resultText = resultText;
}
public String getResultText() {
return this.resultText;
}
public void setLeftoverModel(Model leftoverModel) {
this.leftoverModel = leftoverModel;
}
public Model getLeftoverModel() {
return this.leftoverModel;
}
}
public MergeResult doMerge(String uri1, String uri2, OntModel baseOntModel,
OntModel tboxOntModel, String usePrimaryLabelOnly){
boolean functionalPresent = false; boolean functionalPresent = false;
Resource res1 = baseOntModel.getResource(uri1); // primary resource Resource res1 = baseOntModel.getResource(uri1); // primary resource
Model res1Model = ModelFactory.createDefaultModel();
Resource res2 = baseOntModel.getResource(uri2); // secondary resource Resource res2 = baseOntModel.getResource(uri2); // secondary resource
String result = null; Model res2Model = ModelFactory.createDefaultModel();
baseOntModel.enterCriticalSection(Lock.WRITE);
/* // get statements of both the resources
* get statements of both the resources baseOntModel.enterCriticalSection(Lock.READ);
*/ try {
StmtIterator stmtItr1 = baseOntModel.listStatements(res1,(Property)null,(RDFNode)null); res1Model.add(
StmtIterator stmtItr2 = baseOntModel.listStatements(res2,(Property)null,(RDFNode)null); baseOntModel.listStatements(res1, (Property)null, (RDFNode)null));
StmtIterator stmtItr3 = baseOntModel.listStatements((Resource)null,(Property)null,(RDFNode)res2); res2Model.add(
baseOntModel.listStatements(res2, (Property)null, (RDFNode)null));
res2Model.add(
baseOntModel.listStatements(
(Resource)null, (Property)null, (RDFNode)res2));
} finally {
baseOntModel.leaveCriticalSection();
}
/* // if primary resource has no statements, return
* if primary resource has no statements, return if (res1Model.isEmpty()){
*/ return new MergeResult("resource 1 not present", null);
if(!stmtItr1.hasNext()){ } else if(res2Model.isEmpty()){
result = "resource 1 not present"; return new MergeResult("resource 2 not present", null);
res1.removeAll((Property)null);
baseOntModel.leaveCriticalSection();
return result;
}
/*
* if secondary resource has no statements, return
*/
else if(!stmtItr2.hasNext()){
result = "resource 2 not present";
res2.removeAll((Property)null);
baseOntModel.leaveCriticalSection();
return result;
} }
int counter = 0; int counter = 0;
Model leftoverModel = ModelFactory.createDefaultModel(); Model leftoverModel = ModelFactory.createDefaultModel();
ontModel.enterCriticalSection(Lock.WRITE);
infOntModel.enterCriticalSection(Lock.WRITE);
try{
/*
* Iterate through statements of secondary resource
*/
// Iterate through statements of secondary resource
StmtIterator stmtItr2 = res2Model.listStatements(
res2, (Property) null, (RDFNode) null);
while(stmtItr2.hasNext()){ while(stmtItr2.hasNext()){
Statement stmt = stmtItr2.nextStatement();
Statement stmt = stmtItr2.next(); if(isFunctional(stmt.getPredicate(), tboxOntModel)) {
Property prop = stmt.getPredicate(); // if the property is null or functional then dump the statement into
OntProperty oprop = baseOntModel.getOntProperty(prop.getURI()); // the leftover model, else add it to base, ont and inf models as a
// part of the primary resource.
/* leftoverModel.add(res2, stmt.getPredicate(), stmt.getObject());
* if the property is null or functional then dump the statement into leftover model
* else add it to base, ont and inf models as a part of primary resource.
*/
if(oprop!=null && oprop.isFunctionalProperty()){
leftoverModel.add(res2,stmt.getPredicate(),stmt.getObject());
functionalPresent = true; functionalPresent = true;
} } else if (stmt.getPredicate().equals(RDFS.label) &&
/* usePrimaryLabelOnly!=null && !usePrimaryLabelOnly.isEmpty()) {
* if the checkbox is checked, use primary resource rdfs:labels only and dump secondary resource rdfs:labels // if the checkbox is checked, use primary resource rdfs:labels only
* into leftoverModel // and dump secondary resource rdfs:labels into leftoverModel
*/ leftoverModel.add(res2, stmt.getPredicate(), stmt.getObject());
else if(prop.getURI().equals("http://www.w3.org/2000/01/rdf-schema#label") &&
usePrimaryLabelOnly!=null && !usePrimaryLabelOnly.isEmpty()){
leftoverModel.add(res2,stmt.getPredicate(),stmt.getObject());
functionalPresent = true; functionalPresent = true;
} } else {
else{ baseOntModel.enterCriticalSection(Lock.WRITE);
baseOntModel.add(res1,stmt.getPredicate(),stmt.getObject()); try {
ontModel.add(res1,stmt.getPredicate(),stmt.getObject()); baseOntModel.add(res1, stmt.getPredicate(), stmt.getObject());
infOntModel.add(res1,stmt.getPredicate(),stmt.getObject());
counter++; counter++;
} finally {
baseOntModel.leaveCriticalSection();
} }
} }
/* }
* replace secondary resource with primary resource in all the statements where
* secondary resource is present as an object. // replace secondary resource with primary resource in all the statements
*/ // where secondary resource is present as an object.
while(stmtItr3.hasNext()){ StmtIterator stmtItr3 = res2Model.listStatements(
(Resource) null, (Property) null, res2);
while (stmtItr3.hasNext()){
Statement stmt = stmtItr3.nextStatement(); Statement stmt = stmtItr3.nextStatement();
Resource sRes = stmt.getSubject(); Resource sRes = stmt.getSubject();
Property sProp = stmt.getPredicate(); Property sProp = stmt.getPredicate();
baseOntModel.add(sRes,sProp,res1); baseOntModel.enterCriticalSection(Lock.WRITE);
ontModel.add(sRes,sProp,res1); try {
infOntModel.add(sRes,sProp,res1); baseOntModel.add(sRes, sProp, res1);
} counter++;
Resource ontRes = ontModel.getResource(res2.getURI()); } finally {
Resource infRes = infOntModel.getResource(res2.getURI());
/*
* Remove all the statements of secondary resource from all the models.
*/
baseOntModel.removeAll((Resource)null,(Property)null,(RDFNode)res2);
ontModel.removeAll((Resource)null,(Property)null,(RDFNode)res2);
infOntModel.removeAll((Resource)null,(Property)null,(RDFNode)res2);
res2.removeAll((Property)null);
ontRes.removeAll((Property)null);
infRes.removeAll((Property)null);
}
finally{
baseOntModel.leaveCriticalSection(); baseOntModel.leaveCriticalSection();
infOntModel.leaveCriticalSection();
ontModel.leaveCriticalSection();
} }
setLeftOverModel(leftoverModel); }
if(counter>0 && functionalPresent)
result = "merged " + counter + " statements. Some statements could not be merged."; // Remove all the statements of secondary resource
else if(counter>0 && !functionalPresent) baseOntModel.enterCriticalSection(Lock.WRITE);
result = "merged " + counter + " statements."; try {
else if(counter==0) baseOntModel.remove(res2Model);
result = "No statements merged"; } finally {
baseOntModel.leaveCriticalSection();
}
MergeResult result = new MergeResult();
if (!leftoverModel.isEmpty()) {
result.setLeftoverModel(leftoverModel);
}
if (counter > 0 && functionalPresent) {
result.setResultText("merged " + counter +
" statements. Some statements could not be merged.");
} else if(counter>0 && !functionalPresent) {
result.setResultText("merged " + counter + " statements.");
} else if (counter==0) {
result.setResultText("No statements merged");
}
return result; return result;
} }
private Model leftoverModel = ModelFactory.createDefaultModel();
public void setLeftOverModel(Model leftoverModel){ private boolean isFunctional(Property property, OntModel tboxOntModel) {
this.leftoverModel = leftoverModel; tboxOntModel.enterCriticalSection(Lock.READ);
try {
return (tboxOntModel.contains(
property, RDF.type, OWL.FunctionalProperty));
} finally {
tboxOntModel.leaveCriticalSection();
} }
public Model getLeftOverModel(){
return this.leftoverModel;
} }
public void doPermanentURI(String oldModel,String newModel,String oldNamespace, public void doPermanentURI(String oldModel, String newModel, String oldNamespace,
String newNamespace,String dNamespace,ModelMaker maker,VitroRequest vreq){ String newNamespace, String dNamespace, ModelMaker maker,
VitroRequest vreq) {
WebappDaoFactory wdf = vreq.getFullWebappDaoFactory(); WebappDaoFactory wdf = vreq.getFullWebappDaoFactory();
Model m = maker.getModel(oldModel); Model m = maker.getModel(oldModel);
@ -733,8 +748,7 @@ public class JenaIngestUtils {
tempModel.add(stmt); tempModel.add(stmt);
} }
rsItr = tempModel.listResourcesWithProperty((Property)null); rsItr = tempModel.listResourcesWithProperty((Property)null);
} } else{
else{
rsItr = m.listResourcesWithProperty((Property)null); rsItr = m.listResourcesWithProperty((Property)null);
} }
@ -799,9 +813,9 @@ public class JenaIngestUtils {
continue; continue;
} }
} }
}
}
}
}
public String getUnusedURI(String newNamespace,WebappDaoFactory wdf){ public String getUnusedURI(String newNamespace,WebappDaoFactory wdf){
String uri = null; String uri = null;
String errMsg = null; String errMsg = null;

View file

@ -1,5 +1,6 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%> <%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<%@page import="edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %>
@ -11,8 +12,13 @@
<h2><a class="ingestMenu" href="ingest">Ingest Menu</a> > Merge Individuals</h2> <h2><a class="ingestMenu" href="ingest">Ingest Menu</a> > Merge Individuals</h2>
<%String result = (String) request.getAttribute("result");%> <%
MergeResult resultObj = (MergeResult) request.getAttribute("result");
String result = resultObj.getResultText();
%>
<p><b><%=result%></b></p> <p><b><%=result%></b></p>
<%if(!result.equals("resource 1 not present") && !result.equals("resource 2 not present")){ <%if(!result.equals("resource 1 not present") && !result.equals("resource 2 not present")){
if(!result.equals("No statements merged") && !result.endsWith("statements.")){%> if(!result.equals("No statements merged") && !result.endsWith("statements.")){%>
<p>Download non-mergeable statements.</p> <p>Download non-mergeable statements.</p>