VIVO-925 When creating class or properties, permit URIs that are already in use...
...as long as they aren't already declared as things, classes or properties
This commit is contained in:
parent
837d2afdad
commit
5c1944f508
8 changed files with 129 additions and 90 deletions
|
@ -21,12 +21,13 @@ public interface WebappDaoFactory {
|
||||||
public String checkURI(String uriStr);
|
public String checkURI(String uriStr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks a URI String for two things: well-formedness and, optionally,
|
* Checks a URI String to see whether it is suitable for use on a new editable entity.
|
||||||
* uniqueness in the model. Ill-formed strings or those matching URIs
|
* It must be well-formed, and it must not be declared in the model as a Thing, Class,
|
||||||
* already in use will cause an error message to be returned.
|
* ObjectProperty or DataProperty. Ill-formed strings or those so declared will
|
||||||
|
* cause an error message to be returned.
|
||||||
* @return error message String if invalid; otherwise null
|
* @return error message String if invalid; otherwise null
|
||||||
*/
|
*/
|
||||||
public String checkURI(String uriStr, boolean checkUniqueness);
|
public String checkURIForEditableEntity(String uriStr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a given URI string exists in the system:
|
* Check if a given URI string exists in the system:
|
||||||
|
|
|
@ -88,11 +88,12 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
||||||
return innerWebappDaoFactory.checkURI(uriStr);
|
return innerWebappDaoFactory.checkURI(uriStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String checkURI(String uriStr, boolean checkUniqueness) {
|
@Override
|
||||||
return innerWebappDaoFactory.checkURI(uriStr, checkUniqueness);
|
public String checkURIForEditableEntity(String uriStr) {
|
||||||
}
|
return innerWebappDaoFactory.checkURIForEditableEntity(uriStr);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasExistingURI(String uriStr) {
|
public boolean hasExistingURI(String uriStr) {
|
||||||
return innerWebappDaoFactory.hasExistingURI(uriStr);
|
return innerWebappDaoFactory.hasExistingURI(uriStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -487,7 +487,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
|
||||||
ontModel.enterCriticalSection(Lock.WRITE);
|
ontModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
||||||
String errMsgStr = getWebappDaoFactory().checkURI(dtp.getURI());
|
String errMsgStr = getWebappDaoFactory().checkURIForEditableEntity(dtp.getURI());
|
||||||
if (errMsgStr != null) {
|
if (errMsgStr != null) {
|
||||||
throw new InsertException(errMsgStr);
|
throw new InsertException(errMsgStr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,7 +534,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
|
||||||
ontModel.enterCriticalSection(Lock.WRITE);
|
ontModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
||||||
String errMsgStr = getWebappDaoFactory().checkURI(prop.getURI());
|
String errMsgStr = getWebappDaoFactory().checkURIForEditableEntity(prop.getURI());
|
||||||
if (errMsgStr != null) {
|
if (errMsgStr != null) {
|
||||||
throw new InsertException(errMsgStr);
|
throw new InsertException(errMsgStr);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
|
||||||
com.hp.hpl.jena.ontology.ObjectProperty inv = null;
|
com.hp.hpl.jena.ontology.ObjectProperty inv = null;
|
||||||
if (hasInverse(prop)) {
|
if (hasInverse(prop)) {
|
||||||
log.debug("non-null inverse URI: " +prop.getURIInverse());
|
log.debug("non-null inverse URI: " +prop.getURIInverse());
|
||||||
errMsgStr = getWebappDaoFactory().checkURI(prop.getURIInverse());
|
errMsgStr = getWebappDaoFactory().checkURIForEditableEntity(prop.getURIInverse());
|
||||||
if (errMsgStr != null) {
|
if (errMsgStr != null) {
|
||||||
throw new InsertException("Unusable URI for inverse property: "+errMsgStr);
|
throw new InsertException("Unusable URI for inverse property: "+errMsgStr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -934,7 +934,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
|
||||||
ontModel.enterCriticalSection(Lock.WRITE);
|
ontModel.enterCriticalSection(Lock.WRITE);
|
||||||
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
|
||||||
try {
|
try {
|
||||||
String errMsgStr = getWebappDaoFactory().checkURI(cls.getURI());
|
String errMsgStr = getWebappDaoFactory().checkURIForEditableEntity(cls.getURI());
|
||||||
if (errMsgStr != null) {
|
if (errMsgStr != null) {
|
||||||
throw new InsertException(errMsgStr);
|
throw new InsertException(errMsgStr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ 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.RDFNode;
|
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
||||||
|
|
||||||
|
@ -174,41 +176,67 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
||||||
return this.properties;
|
return this.properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String checkURI(String uriStr) {
|
public String checkURI(String uriStr) {
|
||||||
return checkURI(uriStr, true);
|
String errorMessage = checkURIForValidity(uriStr);
|
||||||
}
|
if (errorMessage != null) {
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.hasExistingURI(uriStr)) {
|
||||||
|
return "URI is already in use. Please enter another URI. ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String checkURI(String uriStr, boolean checkUniqueness) {
|
public String checkURIForEditableEntity(String uriStr) {
|
||||||
uriStr = (uriStr == null) ? " " : uriStr;
|
String errorMessage = checkURIForValidity(uriStr);
|
||||||
String errorMsg = "";
|
if (errorMessage != null) {
|
||||||
String duplicateMsg = "URI is already in use. " +
|
return errorMessage;
|
||||||
"Please enter another URI. ";
|
}
|
||||||
IRIFactory factory = IRIFactory.jenaImplementation();
|
|
||||||
IRI iri = factory.create( uriStr );
|
|
||||||
if (iri.hasViolation(false) ) {
|
|
||||||
errorMsg += (iri.violations(false).next())
|
|
||||||
.getShortMessage() + " ";
|
|
||||||
} else if (checkUniqueness) {
|
|
||||||
boolean existingURI = this.hasExistingURI(uriStr);
|
|
||||||
if(existingURI) {
|
|
||||||
errorMsg+="Not a valid URI. Please enter another URI. ";
|
|
||||||
errorMsg+=duplicateMsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (errorMsg.length()>0) ? errorMsg : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(hasEditableEntity(uriStr)) {
|
||||||
|
return "URI is already in use. Please enter another URI. ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//Check if URI already in use or not either as resource OR as property
|
private String checkURIForValidity(String uriStr) {
|
||||||
|
uriStr = (uriStr == null) ? " " : uriStr;
|
||||||
|
|
||||||
|
IRI iri = IRIFactory.jenaImplementation().create(uriStr);
|
||||||
|
if (iri.hasViolation(false)) {
|
||||||
|
return (iri.violations(false).next()).getShortMessage() + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Resource res = ResourceFactory.createResource(uriStr);
|
||||||
|
if (res.getLocalName().matches("\\d+")) {
|
||||||
|
return "Localname must contain at least one non-numeric "
|
||||||
|
+ "character. Please enter another URI. ";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Not a valid URI. Please enter another URI. ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if URI already in use or not either as resource OR as property
|
||||||
@Override
|
@Override
|
||||||
public boolean hasExistingURI(String uriStr) {
|
public boolean hasExistingURI(String uriStr) {
|
||||||
OntModel ontModel = ontModelSelector.getFullModel();
|
OntModel ontModel = ontModelSelector.getFullModel();
|
||||||
return URIUtils.hasExistingURI(uriStr, ontModel);
|
return URIUtils.hasExistingURI(uriStr, ontModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasEditableEntity(String uriStr) {
|
||||||
|
OntModel ontModel = ontModelSelector.getFullModel();
|
||||||
|
return URIUtils.hasEditableEntity(uriStr, ontModel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebappDaoFactory getUserAwareDaoFactory(String userURI) {
|
public WebappDaoFactory getUserAwareDaoFactory(String userURI) {
|
||||||
return new WebappDaoFactoryJena(this, userURI);
|
return new WebappDaoFactoryJena(this, userURI);
|
||||||
|
|
|
@ -2,59 +2,67 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils.jena;
|
package edu.cornell.mannlib.vitro.webapp.utils.jena;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
import com.hp.hpl.jena.rdf.model.Property;
|
||||||
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.ResourceFactory;
|
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
|
import com.hp.hpl.jena.vocabulary.RDF;
|
||||||
|
|
||||||
public class URIUtils {
|
public class URIUtils {
|
||||||
|
public static boolean hasExistingURI(String uriStr, OntModel ontModel) {
|
||||||
private static final Log log = LogFactory.getLog(URIUtils.class.getName());
|
ontModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
public static boolean hasExistingURI(String uriStr, OntModel ontModel) {
|
if (anyStatements(ontModel, createResource(uriStr), null, null)) {
|
||||||
boolean existingURI = false;
|
return true;
|
||||||
ontModel.enterCriticalSection(Lock.READ);
|
|
||||||
try {
|
|
||||||
boolean validPropertyURI = true;
|
|
||||||
String localName = uriStr.substring(uriStr.lastIndexOf("/") + 1);
|
|
||||||
//if local name is only numbers, this is not a valid uri for a property
|
|
||||||
if(localName.matches("\\d+")) {
|
|
||||||
validPropertyURI = false;
|
|
||||||
}
|
|
||||||
Resource newURIAsRes = ResourceFactory.createResource(uriStr);
|
|
||||||
|
|
||||||
StmtIterator closeIt = ontModel.listStatements(
|
|
||||||
newURIAsRes, null, (RDFNode)null);
|
|
||||||
if (closeIt.hasNext()) {
|
|
||||||
existingURI = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
//if not in the subject position, check in object position
|
|
||||||
if (!existingURI) {
|
|
||||||
closeIt = ontModel.listStatements(null, null, newURIAsRes);
|
|
||||||
if (closeIt.hasNext()) {
|
|
||||||
existingURI= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Check for property
|
|
||||||
if (validPropertyURI && !existingURI) {
|
|
||||||
Property newURIAsProp = ResourceFactory.createProperty(uriStr);
|
|
||||||
closeIt = ontModel.listStatements(
|
|
||||||
null, newURIAsProp, (RDFNode)null);
|
|
||||||
if (closeIt.hasNext()) {
|
|
||||||
existingURI = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
ontModel.leaveCriticalSection();
|
|
||||||
}
|
}
|
||||||
|
if (anyStatements(ontModel, null, createProperty(uriStr), null)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (anyStatements(ontModel, null, null, createResource(uriStr))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
ontModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasEditableEntity(String uriStr, OntModel ontModel) {
|
||||||
|
ontModel.enterCriticalSection(Lock.READ);
|
||||||
|
try {
|
||||||
|
Resource res = createResource(uriStr);
|
||||||
|
if (anyStatements(ontModel, res, RDF.type, OWL.Thing)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (anyStatements(ontModel, res, RDF.type, OWL.Class)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (anyStatements(ontModel, res, RDF.type, OWL.DatatypeProperty)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (anyStatements(ontModel, res, RDF.type, OWL.ObjectProperty)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
ontModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean anyStatements(OntModel m, Resource s, Property p,
|
||||||
|
RDFNode o) {
|
||||||
|
StmtIterator stmts = m.listStatements(s, p, o);
|
||||||
|
try {
|
||||||
|
return stmts.hasNext();
|
||||||
|
} finally {
|
||||||
|
stmts.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return existingURI;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
||||||
this.objectPropertyDao = objectPropertyDao;
|
this.objectPropertyDao = objectPropertyDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setObjectPropertyStatementDao(ObjectPropertyStatementDao objectPropertyStatementDao) {
|
public void setObjectPropertyStatementDao(
|
||||||
|
ObjectPropertyStatementDao objectPropertyStatementDao) {
|
||||||
this.objectPropertyStatementDao = objectPropertyStatementDao;
|
this.objectPropertyStatementDao = objectPropertyStatementDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +162,9 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String checkURI(String uriStr, boolean checkUniqueness) {
|
public String checkURIForEditableEntity(String uriStr) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"WebappDaoFactory.checkURI() not implemented.");
|
"WebappDaoFactory.checkURIForNewEditableEntity() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Reference in a new issue