VIVO-774 More functionality: implement deleteFauxProperty()
This commit is contained in:
parent
564130329e
commit
190bf87979
9 changed files with 519 additions and 110 deletions
|
@ -6,15 +6,27 @@ import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
|
||||
/**
|
||||
* Represents a specialization on an ObjectProperty, only meaningful for
|
||||
* display.
|
||||
*
|
||||
* Must have a baseURI and a rangeURI. Other fields are optional.
|
||||
* BaseURI is required, may not be null, and may not be modified.
|
||||
*
|
||||
* It would be nice to place the same restrictions on rangeURI, but it may be
|
||||
* null when the FauxProperty is being created, and it may be modified. The DAO
|
||||
* will need to check rangeURI for validity before accepting an insert or
|
||||
* modification.
|
||||
*
|
||||
* TODO Can we do this more cleanly? Can handle this as two classes FauxProperty
|
||||
* and NewFauxProperty, and have each class enforce its own internal
|
||||
* constraints? For example, the range must not be null, must represent a valid
|
||||
* class, and must be equal to or a subclass of the range of the base property.
|
||||
*/
|
||||
public class FauxProperty extends BaseResourceBean implements ResourceBean {
|
||||
private final String rangeURI;
|
||||
private final String domainURI;
|
||||
public class FauxProperty extends BaseResourceBean implements ResourceBean, RoleRestrictedProperty {
|
||||
private String rangeURI;
|
||||
private String domainURI;
|
||||
|
||||
private String rangeLabel;
|
||||
private String domainLabel;
|
||||
|
@ -28,15 +40,22 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean {
|
|||
* @param baseURI
|
||||
* URI of the property. May not be null.
|
||||
* @param rangeUri
|
||||
* URI of the object class. May not be null.
|
||||
* URI of the object class. May be null.
|
||||
*/
|
||||
public FauxProperty(String domainURI, String baseURI, String rangeURI) {
|
||||
super(Objects.requireNonNull(baseURI, "baseURI may not be null"));
|
||||
this.rangeURI = Objects.requireNonNull(rangeURI,
|
||||
"rangeURI may not be null");
|
||||
this.rangeURI = rangeURI;
|
||||
this.domainURI = domainURI;
|
||||
}
|
||||
|
||||
public FauxProperty() {
|
||||
// This is required by OperationUtils.cloneBean()
|
||||
}
|
||||
|
||||
public void setRangeURI(String rangeURI) {
|
||||
this.rangeURI = rangeURI;
|
||||
}
|
||||
|
||||
public String getRangeURI() {
|
||||
return rangeURI;
|
||||
}
|
||||
|
@ -49,6 +68,10 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean {
|
|||
return (rangeLabel == null) ? localName(rangeURI) : rangeLabel;
|
||||
}
|
||||
|
||||
public void setDomainURI(String domainURI) {
|
||||
this.domainURI = domainURI;
|
||||
}
|
||||
|
||||
public String getDomainURI() {
|
||||
return domainURI;
|
||||
}
|
||||
|
|
|
@ -2,16 +2,36 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
||||
import edu.cornell.mannlib.vedit.beans.FormObject;
|
||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
import edu.cornell.mannlib.vedit.util.FormUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class FauxPropertyRetryController extends BaseEditController {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(FauxPropertyRetryController.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void doPost(HttpServletRequest req, HttpServletResponse response) {
|
||||
if (!isAuthorizedToDisplayPage(req, response,
|
||||
|
@ -19,13 +39,98 @@ public class FauxPropertyRetryController extends BaseEditController {
|
|||
return;
|
||||
}
|
||||
|
||||
VitroRequest request = new VitroRequest(req);
|
||||
|
||||
// create an EditProcessObject for this and put it in the session
|
||||
EditProcessObject epo = super.createEpo(request);
|
||||
|
||||
ServletContext ctx = getServletContext();
|
||||
|
||||
FauxPropertyDao fpDao = ModelAccess.on(ctx).getWebappDaoFactory()
|
||||
.getFauxPropertyDao();
|
||||
epo.setDataAccessObject(fpDao);
|
||||
|
||||
FauxProperty fpForEditing = null;
|
||||
if (epo.getUseRecycledBean()) {
|
||||
fpForEditing = (FauxProperty) epo.getNewBean();
|
||||
} else {
|
||||
String create = request.getParameter("create");
|
||||
String baseUri = request.getParameter("baseUri");
|
||||
String rangeUri = request.getParameter("rangeUri");
|
||||
String domainUri = request.getParameter("domainUri");
|
||||
if (create != null) {
|
||||
fpForEditing = new FauxProperty(null, baseUri, null);
|
||||
epo.setAction("insert");
|
||||
} else {
|
||||
fpForEditing = fpDao.getFauxPropertyByUris(domainUri, baseUri,
|
||||
rangeUri);
|
||||
if (fpForEditing == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"FauxProperty does not exist for <" + domainUri
|
||||
+ "> ==> <" + baseUri + "> ==> <"
|
||||
+ rangeUri + ">");
|
||||
}
|
||||
epo.setAction("update");
|
||||
}
|
||||
epo.setOriginalBean(fpForEditing);
|
||||
}
|
||||
|
||||
// set any validators
|
||||
// TODO NONE YET
|
||||
|
||||
// set up any listeners
|
||||
epo.setChangeListenerList(Collections
|
||||
.singletonList(new PropertyRestrictionListener(ctx)));
|
||||
|
||||
// where should the postinsert pageforwarder go?
|
||||
// TODO
|
||||
// make a postdelete pageforwarder that will send us to the control
|
||||
// panel for the base property.
|
||||
// TODO
|
||||
|
||||
FormObject foo = new FormObject();
|
||||
foo.setErrorMap(epo.getErrMsgMap());
|
||||
|
||||
// We will need to set a lot of option lists and stuff.
|
||||
// TODO
|
||||
|
||||
// Put attributes on the request so the JSP can populate the fields.
|
||||
// request.setAttribute("transitive",propertyForEditing.getTransitive());
|
||||
// request.setAttribute("objectIndividualSortPropertyURI",
|
||||
// propertyForEditing.getObjectIndividualSortPropertyURI());
|
||||
// TODO
|
||||
|
||||
// checkboxes are pretty annoying : we don't know if someone *unchecked*
|
||||
// a box, so we have to default to false on updates.
|
||||
// propertyForEditing.setSymmetric(false);
|
||||
// TODO
|
||||
|
||||
epo.setFormObject(foo);
|
||||
|
||||
FormUtils.populateFormFromBean(fpForEditing, epo.getAction(), foo,
|
||||
epo.getBadValueMap());
|
||||
|
||||
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
request.setAttribute("bodyJsp","/templates/edit/formBasic.jsp");
|
||||
request.setAttribute("colspan","5");
|
||||
request.setAttribute("formJsp","/templates/edit/specific/fauxProperty_retry.jsp");
|
||||
request.setAttribute("scripts","/templates/edit/formBasic.js");
|
||||
request.setAttribute("title","Faux Property Editing Form");
|
||||
request.setAttribute("_action",epo.getAction());
|
||||
setRequestAttributes(request,epo);
|
||||
|
||||
try {
|
||||
rd.forward(request, response);
|
||||
} catch (Exception e) {
|
||||
log.error("Could not forward to view.");
|
||||
log.error(e.getMessage());
|
||||
log.error(e.getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,4 +42,17 @@ public interface FauxPropertyDao {
|
|||
FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri);
|
||||
|
||||
/**
|
||||
* Delete this FauxProperty from the display model.
|
||||
*
|
||||
* Delete any ConfigContext that is based on the constraints in this
|
||||
* FauxProperty, and any ObjectPropertyDisplayConfigs that depend on that
|
||||
* ConfigContext.
|
||||
*
|
||||
* If no such ConfigContext is found, no error is raised.
|
||||
*
|
||||
* No check is made to see whether the ObjectPropertyDisplayConfig matches
|
||||
* the settings on this FauxProperty.
|
||||
*/
|
||||
void deleteFauxProperty(FauxProperty fp);
|
||||
}
|
||||
|
|
|
@ -48,4 +48,14 @@ public class FauxPropertyDaoFiltering extends BaseFiltering implements FauxPrope
|
|||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao#deleteFauxProperty(edu.cornell.mannlib.vitro.webapp.beans.FauxProperty)
|
||||
*/
|
||||
@Override
|
||||
public void deleteFauxProperty(FauxProperty fp) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("FauxPropertyDao.deleteFauxProperty() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,16 +4,21 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
|||
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.bindValues;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.uriValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.Property;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.ResIterator;
|
||||
|
@ -23,6 +28,7 @@ import com.hp.hpl.jena.vocabulary.RDF;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.AbstractOntModelDecorator;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||
|
@ -51,49 +57,12 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
|
||||
private static final Property DISPLAY_NAME = createProperty(APPLICATION_CONTEXT_NS
|
||||
+ "displayName");
|
||||
private static final Property RDFS_LABEL = createProperty(VitroVocabulary.LABEL);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Queries and parsers
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
// TODO Add a filter that will reject solutions that include qualifiedByDomain
|
||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
private static final QueryParser<String> PARSER_LOCATE_CONFIG_CONTEXT = new QueryParser<String>() {
|
||||
@Override
|
||||
protected String defaultValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parseResults(String queryStr, ResultSet results) {
|
||||
if (results.hasNext()) {
|
||||
return ifResourcePresent(results.next(), "context", null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The instance
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -164,7 +133,7 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
QUALIFIED_BY_DOMAIN);
|
||||
|
||||
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
||||
populateInstance(fp, displayModel, context);
|
||||
populateInstance(fp, context);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
|
@ -172,61 +141,72 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
@Override
|
||||
public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
String queryString;
|
||||
if (domainUri == null) {
|
||||
queryString = substituteUri(
|
||||
substituteUri(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN,
|
||||
baseUri, "baseUri"), rangeUri, "rangeUri");
|
||||
} else {
|
||||
queryString = substituteUri(
|
||||
substituteUri(
|
||||
substituteUri(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN,
|
||||
baseUri, "baseUri"), rangeUri,
|
||||
"rangeUri"), domainUri, "domainUri");
|
||||
}
|
||||
|
||||
String contextUri = new SparqlQueryRunner(displayModel)
|
||||
.executeSelect(PARSER_LOCATE_CONFIG_CONTEXT, queryString);
|
||||
|
||||
if (contextUri == null) {
|
||||
log.debug("Can't find a ContextConfig for '" + domainUri
|
||||
+ "', '" + baseUri + "', '" + rangeUri + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<ConfigContext> contexts = ConfigContext.findByQualifiers(models,
|
||||
domainUri, baseUri, rangeUri);
|
||||
for (ConfigContext context : contexts) {
|
||||
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
||||
populateInstance(fp, displayModel, createResource(contextUri));
|
||||
populateInstance(fp, createResource(context.getContextUri()));
|
||||
return fp;
|
||||
}
|
||||
log.debug("Can't find a FauxProperty for '" + domainUri + "', '"
|
||||
+ baseUri + "', '" + rangeUri + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFauxProperty(FauxProperty fp) {
|
||||
Set<ConfigContext> contexts = ConfigContext.findByQualifiers(models,
|
||||
fp.getDomainURI(), fp.getURI(), fp.getRangeURI());
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().write()) {
|
||||
for (ConfigContext context : contexts) {
|
||||
Resource configResource = createResource(context.getConfigUri());
|
||||
displayModel.removeAll(configResource, null, null);
|
||||
displayModel.removeAll(null, null, configResource);
|
||||
Resource contextResource = createResource(context.getContextUri());
|
||||
displayModel.removeAll(contextResource, null, null);
|
||||
displayModel.removeAll(null, null, contextResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add labels, annotations, and whatever else we can find on the
|
||||
* ConfigContext.
|
||||
* ObjectPropertyDisplayConfig.
|
||||
*/
|
||||
private void populateInstance(FauxProperty fp, LockedOntModel model,
|
||||
Resource context) {
|
||||
String configUri = getUriValue(model, context, HAS_CONFIGURATION);
|
||||
if (configUri == null) {
|
||||
return;
|
||||
}
|
||||
Resource config = createResource(configUri);
|
||||
private void populateInstance(FauxProperty fp, Resource context) {
|
||||
// Range label and domain label.
|
||||
try (LockedOntModel tboxModel = models.getTBoxModel().read()) {
|
||||
String rangeLabel = getStringValue(tboxModel,
|
||||
createProperty(fp.getRangeURI()), RDFS_LABEL);
|
||||
if (rangeLabel != null) {
|
||||
fp.setRangeLabel(rangeLabel);
|
||||
}
|
||||
|
||||
String displayName = getStringValue(model, config, DISPLAY_NAME);
|
||||
if (displayName != null) {
|
||||
fp.setPickListName(displayName);
|
||||
String domainLabel = getStringValue(tboxModel,
|
||||
createProperty(fp.getDomainURI()), RDFS_LABEL);
|
||||
if (domainLabel != null) {
|
||||
fp.setDomainLabel(domainLabel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Display name.
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
String configUri = getUriValue(displayModel, context,
|
||||
HAS_CONFIGURATION);
|
||||
if (configUri == null) {
|
||||
return;
|
||||
}
|
||||
Resource config = createResource(configUri);
|
||||
|
||||
String displayName = getStringValue(displayModel, config,
|
||||
DISPLAY_NAME);
|
||||
if (displayName != null) {
|
||||
fp.setPickListName(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO pull all sorts of things from the configuration.
|
||||
// TODO pull labels for the domain and range classes.
|
||||
}
|
||||
|
||||
private String substituteUri(String queryString, String variableName,
|
||||
String uri) {
|
||||
return queryString.replace("?" + variableName, "<" + uri + ">");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,6 +263,135 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
return node.asLiteral().getString();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ConfigContext
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
// TODO Add a filter that will reject solutions that include
|
||||
// qualifiedByDomain
|
||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
private static class ParserLocateConfigContext extends
|
||||
QueryParser<Set<ConfigContext>> {
|
||||
private final String domainUri;
|
||||
private final String baseUri;
|
||||
private final String rangeUri;
|
||||
|
||||
public ParserLocateConfigContext(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
this.domainUri = domainUri;
|
||||
this.baseUri = baseUri;
|
||||
this.rangeUri = rangeUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ConfigContext> defaultValue() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ConfigContext> parseResults(String queryStr,
|
||||
ResultSet results) {
|
||||
Set<ConfigContext> set = new HashSet<>();
|
||||
while (results.hasNext()) {
|
||||
QuerySolution row = results.next();
|
||||
String contextUri = ifResourcePresent(row, "context", null);
|
||||
String configUri = ifResourcePresent(row, "config", null);
|
||||
if (contextUri != null && configUri != null) {
|
||||
set.add(new ConfigContext(contextUri, configUri, domainUri,
|
||||
baseUri, rangeUri));
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConfigContext {
|
||||
public static Set<ConfigContext> findByQualifiers(
|
||||
LockingOntModelSelector models, String domainUri,
|
||||
String baseUri, String rangeUri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
|
||||
String queryString;
|
||||
if (domainUri == null) {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri));
|
||||
} else {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri),
|
||||
uriValue("domainUri", domainUri));
|
||||
}
|
||||
|
||||
ParserLocateConfigContext parser = new ParserLocateConfigContext(
|
||||
domainUri, baseUri, rangeUri);
|
||||
return new SparqlQueryRunner(displayModel).executeSelect(
|
||||
parser, queryString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final String contextUri;
|
||||
private final String configUri;
|
||||
private final String domainUri;
|
||||
private final String baseUri;
|
||||
private final String rangeUri;
|
||||
|
||||
public ConfigContext(String contextUri, String configUri,
|
||||
String domainUri, String baseUri, String rangeUri) {
|
||||
this.contextUri = contextUri;
|
||||
this.configUri = configUri;
|
||||
this.domainUri = domainUri;
|
||||
this.baseUri = baseUri;
|
||||
this.rangeUri = rangeUri;
|
||||
}
|
||||
|
||||
public String getContextUri() {
|
||||
return contextUri;
|
||||
}
|
||||
|
||||
public String getConfigUri() {
|
||||
return configUri;
|
||||
}
|
||||
|
||||
public String getDomainUri() {
|
||||
return domainUri;
|
||||
}
|
||||
|
||||
public String getBaseUri() {
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public String getRangeUri() {
|
||||
return rangeUri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper classes. Are they worth it, just to use try-with-resources?
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -297,6 +406,10 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
public LockableOntModel getDisplayModel() {
|
||||
return new LockableOntModel(oms.getDisplayModel());
|
||||
}
|
||||
|
||||
public LockableOntModel getTBoxModel() {
|
||||
return new LockableOntModel(oms.getTBoxModel());
|
||||
}
|
||||
}
|
||||
|
||||
private static class LockableOntModel {
|
||||
|
@ -310,6 +423,11 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
ontModel.enterCriticalSection(Lock.READ);
|
||||
return new LockedOntModel(ontModel);
|
||||
}
|
||||
|
||||
public LockedOntModel write() {
|
||||
ontModel.enterCriticalSection(Lock.WRITE);
|
||||
return new LockedOntModel(ontModel);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LockedOntModel extends AbstractOntModelDecorator
|
||||
|
@ -328,4 +446,5 @@ public class FauxPropertyDaoJena implements FauxPropertyDao {
|
|||
super.leaveCriticalSection();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -137,4 +137,35 @@ public class SparqlQueryRunner {
|
|||
|
||||
}
|
||||
|
||||
public static String bindValues(String rawString, VariableValue... values) {
|
||||
String queryString = rawString;
|
||||
for (VariableValue value: values) {
|
||||
queryString = value.bind(queryString);
|
||||
}
|
||||
return queryString;
|
||||
}
|
||||
|
||||
public static UriValue uriValue(String name, String uri) {
|
||||
return new UriValue(name, uri);
|
||||
}
|
||||
|
||||
public interface VariableValue {
|
||||
String bind(String rawString);
|
||||
}
|
||||
|
||||
private static class UriValue implements VariableValue {
|
||||
private final String name;
|
||||
private final String uri;
|
||||
|
||||
public UriValue(String name, String uri) {
|
||||
this.name = name;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bind(String rawString) {
|
||||
return rawString.replaceAll("\\?" + name + "\\b", "<" + uri + ">");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
/**
|
||||
* For now, just test the methods that manipulate the query string.
|
||||
*/
|
||||
public class SparqlQueryRunnerTest extends AbstractTestClass {
|
||||
@Test
|
||||
public void bindValuesNameNotFound() {
|
||||
String raw = "No such name here";
|
||||
String expected = raw;
|
||||
assertEquals(expected, bindValues(raw, uriValue("bogus", "BOGUS")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindOneUri() {
|
||||
String raw = "Replace both ?this and ?this also.";
|
||||
String expected = "Replace both <URI> and <URI> also.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindTwoUris() {
|
||||
String raw = "Replace both ?this and ?that also.";
|
||||
String expected = "Replace both <URI> and <ANOTHER> also.";
|
||||
assertEquals(
|
||||
expected,
|
||||
bindValues(raw, uriValue("this", "URI"),
|
||||
uriValue("that", "ANOTHER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorWordBoundary() {
|
||||
String raw = "Replace ?this but not ?thistle.";
|
||||
String expected = "Replace <URI> but not ?thistle.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorStringLimit() {
|
||||
String raw = "?this";
|
||||
String expected = "<URI>";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
private static final String REAL_WORLD_RAW = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor ?baseUri ; \n" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
private static final String REAL_WORLD_EXPECTED = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor <http://vivoweb.org/ontology/core#relates> ; \n" //
|
||||
+ " :qualifiedByDomain <http://vivoweb.org/ontology/core#Contract> ; \n" //
|
||||
+ " :qualifiedBy <http://vivoweb.org/ontology/core#ResearcherRole> ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
@Test
|
||||
public void realWorldExample() {
|
||||
assertEquals(
|
||||
REAL_WORLD_EXPECTED,
|
||||
bindValues(
|
||||
REAL_WORLD_RAW,
|
||||
uriValue("baseUri",
|
||||
"http://vivoweb.org/ontology/core#relates"),
|
||||
uriValue("domainUri",
|
||||
"http://vivoweb.org/ontology/core#Contract"),
|
||||
uriValue("rangeUri",
|
||||
"http://vivoweb.org/ontology/core#ResearcherRole")));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
|
||||
<%@ taglib prefix="form" uri="http://vitro.mannlib.cornell.edu/edit/tags" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
|
||||
<h1>Like, TOTALLY BOGUS.</h1>
|
|
@ -98,18 +98,25 @@
|
|||
<c:if test="${!empty fauxproperties}">
|
||||
<c:forEach var="fauxproperty" items="${fauxproperties}">
|
||||
<ul style="list-style-type:none;">
|
||||
<c:url var="fauxpropertyURL" value="fauxpropertyEdit">
|
||||
<c:param name="property" value="${property.URI}"/>
|
||||
<c:param name="domain" value="${fauxproperty.domainURI}" />
|
||||
<c:param name="range" value="${fauxproperty.rangeURI}" />
|
||||
</c:url>
|
||||
<li>
|
||||
<a href="${fauxpropertyURL}">${fauxproperty.pickListName}</a>
|
||||
<c:choose>
|
||||
<c:when test="${empty fauxproperty.domainLabel}">
|
||||
<c:url var="fauxpropertyURL" value="editForm">
|
||||
<c:param name="controller" value="FauxProperty"/>
|
||||
<c:param name="baseUri" value="${property.URI}"/>
|
||||
<c:param name="rangeUri" value="${fauxproperty.rangeURI}" />
|
||||
</c:url>
|
||||
<a href="${fauxpropertyURL}">${fauxproperty.pickListName}</a>
|
||||
no domain,
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<c:url var="fauxpropertyURL" value="editForm">
|
||||
<c:param name="controller" value="FauxProperty"/>
|
||||
<c:param name="baseUri" value="${property.URI}"/>
|
||||
<c:param name="domainUri" value="${fauxproperty.domainURI}" />
|
||||
<c:param name="rangeUri" value="${fauxproperty.rangeURI}" />
|
||||
</c:url>
|
||||
<a href="${fauxpropertyURL}">${fauxproperty.pickListName}</a>
|
||||
domain: ${fauxproperty.domainLabel},
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
@ -120,14 +127,17 @@
|
|||
</c:if>
|
||||
</td>
|
||||
<td>
|
||||
<form action="editForm" method="get">
|
||||
<input type="hidden" name="basepropertyURI" value="${property.URI}"/>
|
||||
<input type="hidden" name="controller" value="FauxProperty"/>
|
||||
<input type="submit" class="form-button" value="Create New Faux Property"/>
|
||||
</form>
|
||||
<form action="editForm" method="get">
|
||||
<input type="hidden" name="create" value="create"/>
|
||||
<input type="hidden" name="baseUri" value="${property.URI}"/>
|
||||
<input type="hidden" name="controller" value="FauxProperty"/>
|
||||
<input type="submit" class="form-button" value="Create New Faux Property"/>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr><td colspan="3"><hr/></td></tr>
|
||||
<!-- _____________________________________________ superproperties __________________________________________ -->
|
||||
<tr valign="bottom" align="center">
|
||||
|
|
Loading…
Add table
Reference in a new issue