From d8d704064e70f57597deb0005417593cac9cb736 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Mon, 5 Aug 2013 16:48:23 -0400 Subject: [PATCH 01/44] work in progress on data migration and related changes to support ISF --- .../controller/jena/RDFUploadController.java | 15 ++++-- .../dao/jena/ObjectPropertyDaoJena.java | 6 ++- .../MultipartHttpServletRequest.java | 2 + .../webapp/ontology/update/ABoxUpdater.java | 49 ++++++++++++------- .../ontology/update/AtomicOntologyChange.java | 5 ++ .../ontology/update/KnowledgeBaseUpdater.java | 16 ++++-- .../ontology/update/OntologyChangeParser.java | 6 +++ .../webapp/ontology/update/TBoxUpdater.java | 5 ++ 8 files changed, 75 insertions(+), 29 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java index 24fe90dce..a196d8d28 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java @@ -77,11 +77,16 @@ public class RDFUploadController extends JenaIngestController { VitroRequest request = new VitroRequest(req); LoginStatusBean loginBean = LoginStatusBean.getBean(request); - String modelName = req.getParameter("modelName"); - if(modelName!=null){ - loadRDF(req,request,response); - return; - } + try { + String modelName = req.getParameter("modelName"); + if(modelName!=null){ + loadRDF(req,request,response); + return; + } + } catch (Exception e) { + log.error(e,e); + throw new RuntimeException(e); + } boolean remove = "remove".equals(request.getParameter("mode")); String verb = remove?"Removed":"Added"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index b1973d45d..5a5f537cb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -905,8 +905,8 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp "SELECT ?property ?range ?filename WHERE { \n" + " { ?property display:listViewConfigFile ?filename \n" + " } UNION { \n" + - " ?lv config:listViewConfigFile ?filename . \n " + - " ?configuration config:hasListView ?lv . " + + " ?configuration config:listViewConfigFile ?filename . \n " + +// " ?configuration config:hasListView ?lv . " + " ?context config:hasConfiguration ?configuration . \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + @@ -955,6 +955,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } else { String filename = soln.getLiteral("filename").getLexicalForm(); + log.info("putting " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map"); customListViewConfigFileMap.put(new Pair(prop, rangeUri), filename); } } @@ -963,6 +964,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, op.getRangeVClassURI())); if (customListViewConfigFileName == null) { + log.info("no list view found for " + op.getURI() + " qualified by " + op.getRangeVClassURI()); customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, OWL.Thing.getURI())); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java index 76f90a174..95f96f10a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/uploadrequest/MultipartHttpServletRequest.java @@ -57,6 +57,7 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest { throws IOException{ super(request); storeFilesToTempDir = false; + setup(request); } @@ -73,6 +74,7 @@ public class MultipartHttpServletRequest extends FileUploadServletRequest { storeFilesToTempDir = true; this.maxFileSize = maxFileSize; this.tempDir = figureTemporaryDirectory(request); + setup(request); } private void setup(HttpServletRequest request){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java index 29ab6a58a..0482750e8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java @@ -4,10 +4,12 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update; import java.io.IOException; import java.util.ArrayList; -import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; @@ -24,7 +26,6 @@ import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; -import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType; @@ -34,6 +35,7 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.Ato */ public class ABoxUpdater { + private final Log log = LogFactory.getLog(ABoxUpdater.class); private OntModel oldTboxModel; private OntModel newTboxModel; private OntModel aboxModel; @@ -388,20 +390,33 @@ public class ABoxUpdater { Iterator propItr = changes.iterator(); while(propItr.hasNext()){ AtomicOntologyChange propChangeObj = propItr.next(); - switch (propChangeObj.getAtomicChangeType()){ - case ADD: - addProperty(propChangeObj); - break; - case DELETE: - deleteProperty(propChangeObj); - break; - case RENAME: - renameProperty(propChangeObj); - break; - default: - logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType()); - break; - } + log.info("processing " + propChangeObj); + try { + if (propChangeObj.getAtomicChangeType() == null) { + log.error("Missing change type; skipping " + propChangeObj); + continue; + } + switch (propChangeObj.getAtomicChangeType()){ + case ADD: + log.info("add"); + addProperty(propChangeObj); + break; + case DELETE: + log.info("delete"); + deleteProperty(propChangeObj); + break; + case RENAME: + log.info("rename"); + renameProperty(propChangeObj); + break; + default: + log.info("unknown"); + logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType()); + break; + } + } catch (Exception e) { + log.error(e,e); + } } } @@ -518,7 +533,7 @@ public class ABoxUpdater { private void renameProperty(AtomicOntologyChange propObj) throws IOException { - //logger.log("Processing a property rename from: " + propObj.getSourceURI() + " to " + propObj.getDestinationURI()); + logger.log("Processing a property rename from: " + propObj.getSourceURI() + " to " + propObj.getDestinationURI()); OntProperty oldProperty = oldTboxModel.getOntProperty(propObj.getSourceURI()); OntProperty newProperty = newTboxModel.getOntProperty(propObj.getDestinationURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/AtomicOntologyChange.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/AtomicOntologyChange.java index e19b095ff..4fbab936d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/AtomicOntologyChange.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/AtomicOntologyChange.java @@ -30,6 +30,11 @@ public class AtomicOntologyChange { this.notes = notes; } + @Override + public String toString() { + return "Source: " + sourceURI + "; Destination: " + destinationURI + + "; Type: " + atomicChangeType + "; Notes:" + notes; + } /** * Contains the URI of a class or property in the previous version of diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 62aab4416..09ab5b19d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -98,14 +98,18 @@ public class KnowledgeBaseUpdater { AtomicOntologyChangeLists changes = new AtomicOntologyChangeLists(rawChanges,settings.getNewTBoxModel(),settings.getOldTBoxModel()); //process the TBox before the ABox - log.info("\tupdating tbox annotations"); - updateTBoxAnnotations(); - + try { + log.info("\tupdating tbox annotations"); + updateTBoxAnnotations(); + } catch (Exception e) { + log.error(e,e); + } + try { migrateMigrationMetadata(servletContext); logger.log("Migrated migration metadata"); } catch (Exception e) { - log.debug("unable to migrate migration metadata " + e.getMessage()); + log.error("unable to migrate migration metadata " + e.getMessage()); } log.info("\tupdating the abox"); @@ -390,11 +394,13 @@ public class KnowledgeBaseUpdater { while(listItr.hasNext()) { AtomicOntologyChange changeObj = listItr.next(); if (changeObj.getSourceURI() != null){ - + log.info("triaging " + changeObj); if (oldTboxModel.getOntProperty(changeObj.getSourceURI()) != null){ atomicPropertyChanges.add(changeObj); + log.info("added to property changes"); } else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) { atomicClassChanges.add(changeObj); + log.info("added to class changes"); } else if ("Prop".equals(changeObj.getNotes())) { atomicPropertyChanges.add(changeObj); } else if ("Class".equals(changeObj.getNotes())) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java index 6ef0467ea..a966de494 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java @@ -9,6 +9,8 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.skife.csv.CSVReader; import org.skife.csv.SimpleReader; @@ -23,6 +25,8 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.Ato public class OntologyChangeParser { + private final Log log = LogFactory.getLog(OntologyChangeParser.class); + private ChangeLogger logger; public OntologyChangeParser(ChangeLogger logger) { @@ -85,6 +89,8 @@ public class OntologyChangeParser { } + log.info(changeObj); + changeObjects.add(changeObj); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java index b5d66613a..bf5c27817 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java @@ -104,6 +104,11 @@ public class TBoxUpdater { // if the default has changed in the new version of the ontology AND if // the site hasn't overidden the previous default in their knowledge base. + if(oldTboxAnnotationsModel == null) { + logger.log("oldTboxAnnotationModel is null; aborting update of annotation values"); + return; + } + StmtIterator iter = oldTboxAnnotationsModel.listStatements(); while (iter.hasNext()) { From dd80f542ea30613e0dce4b5d88ad1ce84cd6173c Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 6 Aug 2013 10:34:33 -0400 Subject: [PATCH 02/44] work on application ontology support for property/class configuration --- .../dao/jena/ObjectPropertyDaoJena.java | 2 +- .../EditRequestDispatchController.java | 24 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 5a5f537cb..3a882a93b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -286,7 +286,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp public ObjectProperty getObjectPropertyByURIAndRangeURI(String propertyURI, String rangeURI) { ObjectProperty op = getObjectPropertyByURI(propertyURI); - if (op == null) { + if (op == null || rangeURI == null) { return op; } op.setRangeVClassURI(rangeURI); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index fba13b869..b31bbf10c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -215,9 +215,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { // *** check for a predicate URI in the request }else if( predicateUri != null && !predicateUri.isEmpty() ){ - Property prop = getProperty( predicateUri, vreq); + Property prop = getProperty( predicateUri, rangeUri, vreq); if (prop != null && rangeUri != null) { - editConfGeneratorName = getCustomEntryFormForPropertyAndRange(prop, rangeUri); + editConfGeneratorName = getCustomEntryForm(prop); } else if( prop != null && prop.getCustomEntryForm() != null ){ //there is a custom form, great! let's use it. editConfGeneratorName = prop.getCustomEntryForm(); @@ -247,25 +247,19 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { return editConfGeneratorName; } - private String getCustomEntryFormForPropertyAndRange(Property prop, String rangeUri){ - String entryFormName = null; - // = ApplicationConfigurationOntologyUtils.getEntryForm(prop.getURI(), rangeUri); - if (entryFormName == null) { - if (prop.getCustomEntryForm() != null) { - return prop.getCustomEntryForm(); - } else { - return DEFAULT_OBJ_FORM; - } + private String getCustomEntryForm(Property prop){ + if (prop.getCustomEntryForm() == null) { + return DEFAULT_OBJ_FORM; } else { - prop.setCustomEntryForm(entryFormName); - return entryFormName; + return prop.getCustomEntryForm(); } } - private Property getProperty(String predicateUri, VitroRequest vreq) { + private Property getProperty(String predicateUri, String rangeUri, VitroRequest vreq) { Property p = null; try{ - p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(predicateUri); + p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURIAndRangeURI( + predicateUri, rangeUri); if(p == null) { p = vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri); } From 887cc94e8d07d691b3645d7c39b15e18ad1f46e3 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 6 Aug 2013 16:22:58 -0400 Subject: [PATCH 03/44] updating pullProperty() to pull property/class combos --- .../web/templatemodels/individual/GroupedPropertyList.java | 7 ++++++- .../individual/ObjectPropertyTemplateModel.java | 5 ++--- .../templatemodels/individual/PropertyTemplateModel.java | 5 +++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index e7498e668..920eb8f40 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -457,11 +457,16 @@ public class GroupedPropertyList extends BaseTemplateModel { } public PropertyTemplateModel pullProperty(String propertyUri) { + return pullProperty(propertyUri, null); + } + + public PropertyTemplateModel pullProperty(String propertyUri, String rangeUri) { for (PropertyGroupTemplateModel pgtm : groups) { List properties = pgtm.getProperties(); for (PropertyTemplateModel ptm : properties) { - if (propertyUri.equals(ptm.getUri())) { + if (propertyUri.equals(ptm.getUri()) && + (rangeUri == null || rangeUri.equals(ptm.getRangeUri()))) { // Remove the property from the group. // NB Works with a for-each loop instead of an iterator, // since iteration doesn't continue after the remove. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 49e36d284..2e4fd2fd3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -80,7 +80,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel private PropertyListConfig config; private String objectKey; private String sortDirection; - private String rangeURI; ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq, boolean editing) @@ -90,7 +89,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel setName(op.getDomainPublic()); sortDirection = op.getDomainEntitySortDirection(); - rangeURI = op.getRangeVClassURI(); + rangeUri = op.getRangeVClassURI(); // Get the config for this object property try { @@ -157,7 +156,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel protected List> getStatementData() { ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao(); - return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeURI, getSelectQuery(), getConstructQueries(), sortDirection); + return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeUri, getSelectQuery(), getConstructQueries(), sortDirection); } protected abstract boolean isEmpty(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java index 6569e28d0..41cfabfb7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java @@ -29,6 +29,7 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { protected final VitroRequest vreq; protected final String subjectUri; protected final String propertyUri; + protected String rangeUri; private final String localName; protected Map verboseDisplay; @@ -110,6 +111,10 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { return propertyUri; } + public String getRangeUri() { + return rangeUri; + } + public String getAddUrl() { //log.info("addUrl=" + addUrl); return (addUrl != null) ? addUrl : ""; From cbdbe629d1aa0e9b1d37949063a9b7fe885b2e16 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 7 Aug 2013 13:48:37 -0400 Subject: [PATCH 04/44] work on converting editing to be ISF compatible --- .../controller/EditRequestDispatchController.java | 3 +++ .../edit/EditConfigurationTemplateModel.java | 1 + .../CollatedObjectPropertyTemplateModel.java | 2 +- .../ObjectPropertyStatementTemplateModel.java | 10 +++++++--- .../UncollatedObjectPropertyTemplateModel.java | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index b31bbf10c..1ba55f5ed 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -171,6 +171,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { makeEditConfigurationVTwo( editConfGeneratorName, vreq, session); } + if(editConfig == null) { + log.error("editConfig is null! How did this happen?"); + } String editKey = EditConfigurationUtils.getEditKey(vreq); editConfig.setEditKey(editKey); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index f4306cb17..7203cbbb9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -458,6 +458,7 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { subjectUri, predicateUri, objectKey, + null, statementDisplay, null, vreq); ReadOnlyBeansWrapper wrapper = new ReadOnlyBeansWrapper(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java index fd634595e..780fb050d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java @@ -218,7 +218,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM } listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri, - propertyUri, objectKey, map, getTemplateName(), vreq)); + propertyUri, rangeUri, objectKey, map, getTemplateName(), vreq)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java index f68441b96..9c94b25b4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java @@ -31,7 +31,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl private final String editUrl; private final String deleteUrl; - public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String objectKey, + public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String rangeUri, String objectKey, Map data, String templateName, VitroRequest vreq) { super(subjectUri, propertyUri, vreq); @@ -45,7 +45,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl // Do delete url first, since it is used in building edit url this.deleteUrl = makeDeleteUrl(); - this.editUrl = makeEditUrl(ops); + this.editUrl = makeEditUrl(ops, rangeUri); } private String makeDeleteUrl() { @@ -90,7 +90,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl return UrlBuilder.getUrl(EDIT_PATH, params); } - private String makeEditUrl(ObjectPropertyStatement ops) { + private String makeEditUrl(ObjectPropertyStatement ops, String rangeUri) { // Is the edit link suppressed for this property? if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) { return ""; @@ -115,6 +115,10 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl params.put("deleteProhibited", "prohibited"); } + if (rangeUri != null) { + params.put("rangeUri", rangeUri); + } + params.putAll(UrlBuilder.getModelParams(vreq)); return UrlBuilder.getUrl(EDIT_PATH, params); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java index 15f53b4c4..c6be5211f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java @@ -41,7 +41,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat String objectKey = getObjectKey(); for (Map map : statementData) { statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, - propertyUri, objectKey, map, getTemplateName(), vreq)); + propertyUri, rangeUri, objectKey, map, getTemplateName(), vreq)); } postprocessStatementList(statements); From dffc40dd3b18e1ee80cce10d36f896178bfd6c7d Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 9 Aug 2013 16:23:01 -0400 Subject: [PATCH 05/44] continued work on ISF conversion and data migration --- .../dao/jena/ObjectPropertyDaoJena.java | 4 +- .../webapp/dao/jena/PropertyDaoJena.java | 8 +- .../vitro/webapp/dao/jena/VClassDaoJena.java | 8 +- .../ontology/update/KnowledgeBaseUpdater.java | 6 +- .../servlet/setup/AssembleModelsSetup.java | 85 ------------------- .../servlet/setup/UpdateKnowledgeBase.java | 27 ++++-- .../individual/GroupedPropertyList.java | 9 +- 7 files changed, 42 insertions(+), 105 deletions(-) delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 3a882a93b..82f177ddf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -955,7 +955,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } else { String filename = soln.getLiteral("filename").getLexicalForm(); - log.info("putting " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map"); + log.debug("putting " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map"); customListViewConfigFileMap.put(new Pair(prop, rangeUri), filename); } } @@ -964,7 +964,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, op.getRangeVClassURI())); if (customListViewConfigFileName == null) { - log.info("no list view found for " + op.getURI() + " qualified by " + op.getRangeVClassURI()); + log.debug("no list view found for " + op.getURI() + " qualified by " + op.getRangeVClassURI()); customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, OWL.Thing.getURI())); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index a457b607c..af7de97e3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -721,7 +721,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { propInsts.add(getPropInstForPropertyAndRange(op, rangeRes, applicableProperties)); List additionalFauxSubpropertyRangeURIs = getAdditionalFauxSubpropertyRangeURIsForPropertyURI(propertyURI); for (String rangeURI : additionalFauxSubpropertyRangeURIs) { - if (getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) { + if (rangeRes == null || getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) { propInsts.add(getPropInstForPropertyAndRange( op, ResourceFactory.createResource(rangeURI), applicableProperties)); } @@ -740,7 +740,9 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { Map applicableProperties) { PropertyInstance pi = new PropertyInstance(); String domainURIStr = getURIStr(op.getDomain()); - if (rangeRes != null) { + if (rangeRes == null) { + pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above + } else { String rangeClassURI; if (rangeRes.isAnon()) { rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId() @@ -757,8 +759,6 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { range.setName(range.getLocalName()); } pi.setRangeClassName(range.getName()); - } else { - pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above } pi.setDomainClassURI(domainURIStr); VClass domain = getWebappDaoFactory().getVClassDao() diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index 8c4a20e77..af559b5d0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -462,9 +462,11 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { while (classIt.hasNext()) { try { Individual classInd = classIt.next(); - OntClass cls = classInd.as(OntClass.class); - if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) { - classes.add(new VClassJena(cls,getWebappDaoFactory())); + if(classInd.canAs(OntClass.class)) { + OntClass cls = classInd.as(OntClass.class); + if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) { + classes.add(new VClassJena(cls,getWebappDaoFactory())); + } } } catch (ClassCastException cce) { log.error(cce, cce); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 09ab5b19d..1ae0ddd3e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -73,7 +73,7 @@ public class KnowledgeBaseUpdater { performUpdate(servletContext); } catch (Exception e) { logger.logError(e.getMessage()); - e.printStackTrace(); + log.error(e,e); } if (!logger.errorsWritten()) { @@ -300,7 +300,7 @@ public class KnowledgeBaseUpdater { * needs to be updated to conform to a new ontology version */ public boolean updateRequired(ServletContext servletContext) throws IOException { - boolean required = false; + boolean required = true; String sparqlQueryStr = loadSparqlQuery(settings.getAskUpdatedQueryFile()); if (sparqlQueryStr == null) { @@ -342,7 +342,7 @@ public class KnowledgeBaseUpdater { File file = new File(filePath); if (!file.exists()) { - return null; + throw new RuntimeException("SPARQL file not found at " + filePath); } BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuffer fileContents = new StringBuffer(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java deleted file mode 100644 index d95c4fc68..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java +++ /dev/null @@ -1,85 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup; - -import java.io.InputStream; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.assembler.Assembler; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; -import com.hp.hpl.jena.vocabulary.RDF; - -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; - -/** - * This is the beginning of a more sane and flexible model management system, - * especially necessary for DataStaR. - * Don't use it yet; it's going to change. - * (That part is still insane, I know.) - * @author bjl23 - */ -public class AssembleModelsSetup implements ServletContextListener { - - private static final Log log = LogFactory.getLog(AssembleModelsSetup.class); - - private List assembledModels = new LinkedList(); - - private String ASSEMBLERS_DIR_PATH = "/WEB-INF/assemblers/"; - private Resource ASSEMBLER_OBJECT = ResourceFactory.createProperty("http://jena.hpl.hp.com/2005/11/Assembler#Object"); - private String SYNTAX = "N3"; - - public void contextInitialized(ServletContextEvent sce) { - OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getBaseOntModel(); - // read assemblers out of assemblers directory - Set pathSet = sce.getServletContext().getResourcePaths(ASSEMBLERS_DIR_PATH); - for (String path : (Set)pathSet) { - InputStream assemblerInputStream = sce.getServletContext().getResourceAsStream(path); - Model assemblerModel = ModelFactory.createDefaultModel(); - try { - assemblerModel.read(assemblerInputStream, null, SYNTAX); - ExtendedIterator assemblerIt = assemblerModel.listResourcesWithProperty(RDF.type,ASSEMBLER_OBJECT); - while (assemblerIt.hasNext()) { - Resource assemblerObj = (Resource) assemblerIt.next(); - Model assembledModel = Assembler.general.openModel(assemblerObj); - /* special stuff here */ - Model memModel = ModelFactory.createDefaultModel(); - memModel.add(assembledModel); - memModel.register(new ModelSynchronizer(assembledModel)); - /* end special stuff */ - if (assembledModel != null) { - jenaOntModel.addSubModel(memModel); - } - } - if (assemblerIt != null) { - assemblerIt.close(); - } - } catch (Exception e) { - log.error("Unable to use assembler at "+path); - } - } - System.out.println("ContextListener AssembleModelsSetup done"); - } - - public void contextDestroyed(ServletContextEvent sce) { - for (Model model : assembledModels) { - if (model != null) { - model.close(); - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 6dda504f2..3c851007f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -54,6 +54,9 @@ public class UpdateKnowledgeBase implements ServletContextListener { private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class); private static final String DATA_DIR = "/WEB-INF/ontologies/update/"; + private static final String DIFF_FILE = DATA_DIR + "diff.tab.txt"; + private static final String ASK_QUERY_FILE = DATA_DIR + "askUpdated.sparql"; + private static final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3"; private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/"; private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; @@ -75,6 +78,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { try { UpdateSettings settings = new UpdateSettings(); putReportingPathsIntoSettings(ctx, settings); + putNonReportingPathsIntoSettings(ctx, settings); WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); settings.setDefaultNamespace(wadf.getDefaultNamespace()); @@ -113,7 +117,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH)); settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView); } catch (Exception e) { - log.info("unable to read display model migration files, display model not migrated. " + e.getMessage()); + log.info("Unable to read display model migration files. " + e.getMessage()); tryMigrateDisplay = false; } @@ -121,8 +125,11 @@ public class UpdateKnowledgeBase implements ServletContextListener { KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings); try { - if (ontologyUpdater.updateRequired(ctx)) { + if (!ontologyUpdater.updateRequired(ctx)) { + log.info("No data migration required."); + } else { ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); + log.info("Data migration required"); ontologyUpdater.update(ctx); if (tryMigrateDisplay) { try { @@ -144,6 +151,17 @@ public class UpdateKnowledgeBase implements ServletContextListener { } } + + /** + * Set the paths for the files that specify how to perform the update + */ + private void putNonReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) { + settings.setAskUpdatedQueryFile(ctx.getRealPath(ASK_QUERY_FILE)); + settings.setDiffFile(ctx.getRealPath(DIFF_FILE)); + settings.setSuccessAssertionsFile(ctx.getRealPath(SUCCESS_ASSERTIONS_FILE)); + settings.setSuccessRDFFormat("N3"); + } + /** * Create the directories where we will report on the update. * Put the paths for the directories and files into the settings object. @@ -156,11 +174,6 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setDataDir(dataDir.toString()); StartupStatus.getBean(ctx).info(this, "Updating knowledge base: reports are in '" + dataDir + "'"); - settings.setAskUpdatedQueryFile(dataDir.resolve("askUpdated.sparql").toString()); - settings.setDiffFile(dataDir.resolve("diff.tab.txt").toString()); - settings.setSuccessAssertionsFile(dataDir.resolve("success.n3").toString()); - settings.setSuccessRDFFormat("N3"); - settings.setSparqlConstructAdditionsDir(createDirectory(dataDir, "sparqlConstructs", "additions").toString()); settings.setSparqlConstructDeletionsDir(createDirectory(dataDir, "sparqlConstructs", "deletions").toString()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 920eb8f40..a850a9c71 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -20,6 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; @@ -175,7 +176,13 @@ public class GroupedPropertyList extends BaseTemplateModel { // There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to // DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties // is defined using PropertyInstance rather than ObjectProperty. - PropertyInstanceDao piDao = wdf.getPropertyInstanceDao(); + + // Getting WebappDaoFactory from the session because we can't have the filtering + // that gets applied to the request. This breaks blank node structures in the + // restrictions that determine applicable properties. + WebappDaoFactory wadf = ModelAccess.on(vreq.getSession().getServletContext()).getWebappDaoFactory(); + PropertyInstanceDao piDao = wadf.getPropertyInstanceDao(); + Collection allPropInstColl = piDao .getAllPossiblePropInstForIndividual(subject.getURI()); if (allPropInstColl != null) { From 72314df521bbb70f0f218ef9f57b4b33d4f88a0b Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 21 Aug 2013 12:58:42 -0400 Subject: [PATCH 06/44] workaround for property editing nontermination --- .../vitro/webapp/controller/edit/PropertyRetryController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java index 760c1905b..0c8781180 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java @@ -37,6 +37,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; @@ -69,7 +70,8 @@ public class PropertyRetryController extends BaseEditController { action = epo.getAction(); } - ObjectPropertyDao propDao = request.getUnfilteredWebappDaoFactory().getObjectPropertyDao(); + ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao(); + //getUnfilteredWebappDaoFactory().getObjectPropertyDao(); epo.setDataAccessObject(propDao); OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao(); VClassDao vclassDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); From e96b3968d73a5a433b9fe2f5bd295947ead974b0 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 23 Aug 2013 11:06:28 -0400 Subject: [PATCH 07/44] minor improvements --- .../webapp/controller/edit/Classes2ClassesRetryController.java | 3 ++- .../vitro/webapp/servlet/setup/SimpleReasonerSetup.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java index 262db6590..f724e82b1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java @@ -19,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; public class Classes2ClassesRetryController extends BaseEditController { @@ -43,7 +44,7 @@ public class Classes2ClassesRetryController extends BaseEditController { action = epo.getAction(); } - VClassDao vcDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); + VClassDao vcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getVClassDao(); epo.setDataAccessObject(vcDao); Classes2Classes objectForEditing = new Classes2Classes(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index b84913c54..d8ae881ae 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -142,7 +142,8 @@ public class SimpleReasonerSetup implements ServletContextListener { private void waitForTBoxReasoning(PelletListener pelletListener) throws InterruptedException { int sleeps = 0; - while (sleeps < 1000 && pelletListener.isReasoning()) { + // sleep at least once to make sure the TBox reasoning gets started + while ((0 == sleeps) || ((sleeps < 1000) && pelletListener.isReasoning())) { if ((sleeps % 10) == 0) { // print message at 10 second intervals log.info("Waiting for initial TBox reasoning to complete"); } From d618f8f51ae3650fffd11c12c9ed27a5c9ca7222 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Mon, 26 Aug 2013 11:19:40 -0400 Subject: [PATCH 08/44] VIVO-42 support for union ranges and other related improvements --- .../mannlib/vitro/webapp/beans/VClass.java | 5 + .../controller/edit/VclassEditController.java | 7 +- .../vitro/webapp/dao/jena/JenaBaseDao.java | 2 + .../jena/ObjectPropertyStatementDaoJena.java | 12 +- .../webapp/dao/jena/PropertyDaoJena.java | 127 ++++++++++-------- .../vitro/webapp/dao/jena/VClassJena.java | 28 ++++ .../dao/jena/pellet/PelletListener.java | 2 + .../VTwo/EditConfigurationUtils.java | 8 +- .../IndividualsViaObjectPropetyOptions.java | 28 ++-- .../DefaultObjectPropertyFormGenerator.java | 71 +++++++--- .../rdfservice/impl/jena/RDFServiceJena.java | 3 +- .../edit/EditConfigurationTemplateModel.java | 24 ++-- 12 files changed, 211 insertions(+), 106 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java index 849cd7f5e..128161cb5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java @@ -3,6 +3,8 @@ package edu.cornell.mannlib.vitro.webapp.beans; import java.text.Collator; +import java.util.ArrayList; +import java.util.List; import org.openrdf.model.impl.URIImpl; @@ -91,6 +93,9 @@ public class VClass extends BaseResourceBean implements Comparable public Float getSearchBoost() { return searchBoost; } public void setSearchBoost( Float boost ){ searchBoost = boost;} + public boolean isUnion() { return false; } + public List getUnionComponents() { return new ArrayList(); } + /** * Default constructor */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java index 19199f330..10e5debd1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassEditController.java @@ -24,6 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -44,7 +45,7 @@ public class VclassEditController extends BaseEditController { EditProcessObject epo = super.createEpo(request, FORCE_NEW); request.setAttribute("epoKey", epo.getKey()); - VClassDao vcwDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); + VClassDao vcwDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao(); VClass vcl = (VClass)vcwDao.getVClassByURI(request.getParameter("uri")); if (vcl == null) { @@ -140,8 +141,8 @@ public class VclassEditController extends BaseEditController { HashMap formSelect = new HashMap(); // tells the JSP what select lists are populated, and thus should be displayed request.setAttribute("formSelect",formSelect); - // if supported, we want to show only the asserted superclasses and subclasses. Don't want to see anonymous classes, restrictions, etc. - VClassDao vcDao = request.getUnfilteredAssertionsWebappDaoFactory().getVClassDao(); + // if supported, we want to show only the asserted superclasses and subclasses. + VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao(); List superURIs = vcDao.getSuperClassURIs(vcl.getURI(),false); List superVClasses = new ArrayList(); Iterator superURIit = superURIs.iterator(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 6e8fe09d1..8de45f9f1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -925,8 +925,10 @@ public class JenaBaseDao extends JenaBaseDaoCon { return null; if (vitroURIStr.indexOf(PSEUDO_BNODE_NS)==0) { String idStr = vitroURIStr.split("#")[1]; + log.debug("Trying to get bnode " + idStr); RDFNode rdfNode = ontModel.getRDFNode(Node.createAnon(AnonId.create(idStr))); if ( (rdfNode != null) && (rdfNode.canAs(OntClass.class)) ) { + log.debug("found it"); cls = rdfNode.as(OntClass.class); } } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index 073c1189f..289e10822 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -282,8 +282,6 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec if("desc".equalsIgnoreCase( sortDirection ) ){ queryString = queryString.replaceAll(" ASC\\(", " DESC("); } - - log.debug("Query string for object property " + propertyUri + ": " + queryString); Query query = null; try { @@ -297,10 +295,12 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec QuerySolutionMap initialBindings = new QuerySolutionMap(); initialBindings.add("subject", ResourceFactory.createResource(subjectUri)); initialBindings.add("property", ResourceFactory.createResource(propertyUri)); - if (rangeUri != null) { + if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) { initialBindings.add("objectType", ResourceFactory.createResource(rangeUri)); } + log.debug("Query string for object property " + propertyUri + ": " + queryString); + // Run the SPARQL query to get the properties List> list = new ArrayList>(); DatasetWrapper w = dwf.getDatasetWrapper(); @@ -350,13 +350,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec Model constructedModel = ModelFactory.createDefaultModel(); for (String queryString : constructQueries) { + + queryString = queryString.replace("?subject", "<" + subjectUri + ">"); + queryString = queryString.replace("?property", "<" + propertyUri + ">"); log.debug("CONSTRUCT query string for object property " + propertyUri + ": " + queryString); - queryString = queryString.replace("?subject", "<" + subjectUri + ">"); - queryString = queryString.replace("?property", "<" + propertyUri + ">"); - // we no longer need this query object, but we might want to do this // query parse step to improve debugging, depending on the error returned // through the RDF API diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index af7de97e3..ab79e8589 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -16,6 +16,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.IntersectionClass; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntProperty; @@ -348,7 +349,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { Statement statement = stmtIter.next(); if ( statement.getSubject().canAs(OntClass.class) ) { - classURISet.addAll(getRelatedClasses(statement.getSubject().as(OntClass.class))); + classURISet.addAll(getRestrictedClasses(statement.getSubject().as(OntClass.class))); } else { log.warn("getClassesWithRestrictionOnProperty: Unexpected use of onProperty: it is not applied to a class"); } @@ -381,9 +382,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } /** - * Finds all named superclasses, subclasses and equivalent classes of - * the given class. - * + * Find named classes to which a restriction "applies" * @param resourceURI identifier of a class * @return set of class URIs * @@ -391,13 +390,12 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { * the ontology model. */ - public HashSet getRelatedClasses(OntClass ontClass) { + public HashSet getRestrictedClasses(OntClass ontClass) { HashSet classSet = new HashSet(); List classList = ontClass.listEquivalentClasses().toList(); classList.addAll(ontClass.listSubClasses().toList()); - classList.addAll(ontClass.listSuperClasses().toList()); Iterator it = classList.iterator(); @@ -406,6 +404,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { if (!oc.isAnon()) { classSet.add(oc.getURI()); + } else { + classSet.addAll(getRestrictedClasses(oc)); } } @@ -621,6 +621,28 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { return classes; } + private List getRelatedRestrictions(OntClass ontClass) { + List relatedRestrictions = new ArrayList(); + if (ontClass.isRestriction()) { + relatedRestrictions.add(ontClass.as(Restriction.class)); + } else if (ontClass.isIntersectionClass()) { + IntersectionClass inter = ontClass.as(IntersectionClass.class); + Iterator operIt = inter.listOperands(); + while (operIt.hasNext()) { + relatedRestrictions.addAll(getRelatedRestrictions(operIt.next())); + } + } else { + List superClasses = listSuperClasses(ontClass); + superClasses.addAll(listEquivalentClasses(ontClass)); + for (OntClass sup : superClasses) { + if (!sup.equals(ontClass)) { + relatedRestrictions.addAll(getRelatedRestrictions(sup)); + } + } + } + return relatedRestrictions; + } + public List getAllPropInstByVClasses(List vclasses) { List propInsts = new ArrayList(); @@ -651,55 +673,52 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { String VClassURI = vclass.getURI(); OntClass ontClass = getOntClass(ontModel,VClassURI); - if (ontClass != null) { - List relatedClasses = new ArrayList(); - relatedClasses.addAll(listEquivalentClasses(ontClass)); - relatedClasses.addAll(listSuperClasses(ontClass)); - for (OntClass relatedClass : relatedClasses) { - // find properties in restrictions - if (relatedClass.isRestriction() && relatedClass.canAs(Restriction.class)) { - // TODO: check if restriction is something like - // maxCardinality 0 or allValuesFrom owl:Nothing, - // in which case the property is NOT applicable! - Restriction rest = relatedClass.as(Restriction.class); - OntProperty onProperty = rest.getOnProperty(); - if (onProperty != null) { - Resource[] ranges = new Resource[2]; - if (rest.isAllValuesFromRestriction()) { - ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom(); - } else if (rest.isSomeValuesFromRestriction()) { - ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom(); - } - updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges); - } - } - } - - List propertyList = - getPropertiesWithAppropriateDomainFor(VClassURI); - for (Resource prop : propertyList) { - if (prop.getNameSpace() != null - && !NONUSER_NAMESPACES.contains( - prop.getNameSpace()) ) { - StmtIterator rangeSit = prop.listProperties( - RDFS.range); - Resource rangeRes = null; - while (rangeSit.hasNext()) { - Statement s = rangeSit.nextStatement(); - if (s.getObject().isURIResource()) { - rangeRes = (Resource) s.getObject(); - } - } - Resource[] ranges = new Resource[2]; - ranges[0] = rangeRes; - updatePropertyRangeMap( - applicableProperties, prop.getURI(), ranges); - - } - } - + if (ontClass == null) { + continue; } - } + List relatedRestrictions = getRelatedRestrictions(ontClass); + for (Restriction rest : relatedRestrictions) { + // find properties in restrictions + // TODO: check if restriction is something like + // maxCardinality 0 or allValuesFrom owl:Nothing, + // in which case the property is NOT applicable! + OntProperty onProperty = rest.getOnProperty(); + if (onProperty != null) { + Resource[] ranges = new Resource[2]; + if (rest.isAllValuesFromRestriction()) { + ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom(); + } else if (rest.isSomeValuesFromRestriction()) { + ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom(); + } + updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges); + } + } + + List propertyList = + getPropertiesWithAppropriateDomainFor(VClassURI); + for (Resource prop : propertyList) { + if (prop.getNameSpace() != null + && !NONUSER_NAMESPACES.contains( + prop.getNameSpace()) ) { + StmtIterator rangeSit = prop.listProperties( + RDFS.range); + Resource rangeRes = null; + while (rangeSit.hasNext()) { + Statement s = rangeSit.nextStatement(); + if (s.getObject().isURIResource()) { + rangeRes = (Resource) s.getObject(); + } + } + Resource[] ranges = new Resource[2]; + ranges[0] = rangeRes; + updatePropertyRangeMap( + applicableProperties, prop.getURI(), ranges); + + } + } + + } + } catch (Exception e) { log.error("Unable to get applicable properties " + "by examining property restrictions and domains", e); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java index c4db19dd2..436ae8bd9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java @@ -2,10 +2,15 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.UnionClass; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; @@ -376,4 +381,27 @@ public class VClassJena extends VClass { } } } + + @Override + public boolean isUnion() { + return this.cls.isUnionClass(); + } + + //TODO consider anonymous components + @Override + public List getUnionComponents() { + List unionComponents = new ArrayList(); + if (isUnion()) { + UnionClass union = this.cls.as(UnionClass.class); + Iterator opIt = union.listOperands(); + while(opIt.hasNext()) { + OntClass component = opIt.next(); + if (!component.isAnon()) { + unionComponents.add(new VClassJena(component, this.webappDaoFactory)); + } + } + } + return unionComponents; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java index 58be08c6d..47634ddba 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java @@ -624,8 +624,10 @@ public class PelletListener implements ModelChangedListener { if ( (additionModel.size() > 0) || (removalModel.size()>0) ) { if (!isSynchronizing) { if (foreground) { + log.debug("Running Pellet in foreground."); (new PelletSynchronizer()).run(); } else { + log.debug("Running Pellet in background."); new Thread(new PelletSynchronizer(), "PelletListener.PelletSynchronizer").start(); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java index 5068e2b1b..97bd06225 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java @@ -58,7 +58,13 @@ public class EditConfigurationUtils { } public static VClass getRangeVClass(VitroRequest vreq) { - return vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(getRangeUri(vreq)); + // This needs a WebappDaoFactory with no filtering/RDFService + // funny business because it needs to be able to retrieve anonymous union + // classes by their "pseudo-bnode URIs". + // Someday we'll need to figure out a different way of doing this. + WebappDaoFactory ctxDaoFact = ModelAccess.on( + vreq.getSession().getServletContext()).getWebappDaoFactory(); + return ctxDaoFact.getVClassDao().getVClassByURI(getRangeUri(vreq)); } //get individual diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java index 39095ba3f..fdc1f008a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java @@ -27,13 +27,13 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { private static final String LEFT_BLANK = ""; private String subjectUri; private String predicateUri; - private String rangeUri; + private List rangeTypes; private String objectUri; private String defaultOptionLabel; public IndividualsViaObjectPropetyOptions(String subjectUri, - String predicateUri, String rangeUri, String objectUri) throws Exception { + String predicateUri, List rangeTypes, String objectUri) throws Exception { super(); if (subjectUri == null || subjectUri.equals("")) { @@ -45,7 +45,7 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { this.subjectUri = subjectUri; this.predicateUri = predicateUri; - this.rangeUri = rangeUri; + this.rangeTypes = rangeTypes; this.objectUri = objectUri; } @@ -78,8 +78,8 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { //get all vclasses applicable to the individual subject HashSet vclassesURIs = getApplicableVClassURIs(subject, wDaoFact); - if (rangeUri != null) { - vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeUri, wDaoFact); + if (!rangeTypes.isEmpty()) { + vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeTypes, wDaoFact); } if (vclassesURIs.size() == 0) { @@ -117,9 +117,13 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { private HashSet getApplicableVClassURIs(Individual subject, WebappDaoFactory wDaoFact) { HashSet vclassesURIs = new HashSet(); - if (rangeUri != null) { - log.debug("individualsViaObjectProperty using rangeUri " + rangeUri); - vclassesURIs.add(rangeUri); + if (!rangeTypes.isEmpty()) { + StringBuffer rangeBuff = new StringBuffer(); + for (VClass rangeType : rangeTypes) { + vclassesURIs.add(rangeType.getURI()); + rangeBuff.append(rangeType.getURI()).append(", "); + } + log.debug("individualsViaObjectProperty using rangeUri " + rangeBuff.toString()); return vclassesURIs; } @@ -144,13 +148,15 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { } private HashSet filterToSubclassesOfRange(HashSet vclassesURIs, - String rangeUri, + List rangeTypes, WebappDaoFactory wDaoFact) { HashSet filteredVClassesURIs = new HashSet(); VClassDao vcDao = wDaoFact.getVClassDao(); for (String vclass : vclassesURIs) { - if (vclass.equals(rangeUri) || vcDao.isSubClassOf(vclass, rangeUri)) { - filteredVClassesURIs.add(vclass); + for (VClass rangeType : rangeTypes) { + if (vclass.equals(rangeType.getURI()) || vcDao.isSubClassOf(vclass, rangeType.getURI())) { + filteredVClassesURIs.add(vclass); + } } } return filteredVClassesURIs; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java index 8ffa4e04c..69ae7f40a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java @@ -99,41 +99,60 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene return getDefaultObjectEditConfiguration(vreq, session); } - protected List getRangeTypes(VitroRequest vreq) { - WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory(); - List types = new ArrayList(); + protected List getRangeTypes(VitroRequest vreq) { + // This first part needs a WebappDaoFactory with no filtering/RDFService + // funny business because it needs to be able to retrieve anonymous union + // classes by their "pseudo-bnode URIs". + // Someday we'll need to figure out a different way of doing this. + WebappDaoFactory ctxDaoFact = ModelAccess.on( + vreq.getSession().getServletContext()).getWebappDaoFactory(); + List types = new ArrayList(); Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq); String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); String rangeUri = EditConfigurationUtils.getRangeUri(vreq); if (rangeUri != null) { - types.add(rangeUri); + VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(rangeUri); + if (!rangeVClass.isUnion()) { + types.add(rangeVClass); + } else { + for (VClass unionComponent : rangeVClass.getUnionComponents()) { + types.add(unionComponent); + } + } return types; } + WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory(); //Get all vclasses applicable to subject List vClasses = subject.getVClasses(); - HashSet typesHash = new HashSet(); + HashMap typesHash = new HashMap(); for(VClass vclass: vClasses) { List rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri); if(rangeVclasses != null) { for(VClass range: rangeVclasses) { //a hash will keep a unique list of types and so prevent duplicates - typesHash.add(range.getURI()); + typesHash.put(range.getURI(), range); } } } - types.addAll(typesHash); + types.addAll(typesHash.values()); return types; } private boolean tooManyRangeOptions(VitroRequest vreq, HttpSession session ) throws SolrServerException { - List types = getRangeTypes(vreq); + List rangeTypes = getRangeTypes(vreq); SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext()); + List types = new ArrayList(); //empty list means the range is not set to anything, force Thing - if(types.size() == 0 ){ - types = new ArrayList(); - types.add(VitroVocabulary.OWL_THING); - } + if(types.size() == 0 ){ + types.add(VitroVocabulary.OWL_THING); + } else { + for (VClass vclass : rangeTypes) { + if (vclass.getURI() != null) { + types.add(vclass.getURI()); + } + } + } long count = 0; for( String type:types){ @@ -184,7 +203,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene this.setSparqlQueries(editConfiguration); //set fields - setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq), EditConfigurationUtils.getRangeUri(vreq)); + setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq), getRangeTypes(vreq)); // No need to put in session here b/c put in session within edit request dispatch controller instead //placing in session depends on having edit key which is handled in edit request dispatch controller @@ -358,7 +377,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene setFields(editConfiguration, vreq, predicateUri, null); } - protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, String rangeUri) throws Exception { + protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, List rangeTypes) throws Exception { FieldVTwo field = new FieldVTwo(); field.setName("objectVar"); @@ -370,7 +389,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene field.setOptions( new IndividualsViaObjectPropetyOptions( subjectUri, predicateUri, - rangeUri, + rangeTypes, objectUri)); }else{ field.setOptions(null); @@ -441,14 +460,22 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene formSpecificData.put("editMode", getEditMode(vreq).toString().toLowerCase()); //We also need the type of the object itself - List types = getRangeTypes(vreq); + List types = getRangeTypes(vreq); //if types array contains only owl:Thing, the search will not return any results //In this case, set an empty array - if(types.size() == 1 && types.get(0).equals(VitroVocabulary.OWL_THING) ){ - types = new ArrayList(); + if(types.size() == 1 && types.get(0).getURI().equals(VitroVocabulary.OWL_THING) ){ + types = new ArrayList(); } - formSpecificData.put("objectTypes", StringUtils.join(types, ",")); + StringBuffer typesBuff = new StringBuffer(); + for (VClass type : types) { + if (type.getURI() != null) { + typesBuff.append(type.getURI()).append(","); + } + } + + formSpecificData.put("objectTypes", typesBuff.toString()); + log.debug("autocomplete object types : " + formSpecificData.get("objectTypes")); //Get label for individual if it exists if(EditConfigurationUtils.getObjectIndividual(vreq) != null) { @@ -464,15 +491,15 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene editConfiguration.setFormSpecificData(formSpecificData); } - private Object rangeIndividualsExist(HttpSession session, List types) throws SolrServerException { + private Object rangeIndividualsExist(HttpSession session, List types) throws SolrServerException { SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext()); boolean rangeIndividualsFound = false; - for( String type:types){ + for( VClass type:types){ //solr for type count. SolrQuery query = new SolrQuery(); - query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type); + query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type.getURI()); query.setRows(0); QueryResponse rsp = solrServer.query(query); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java index ddf192b84..e9461099a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java @@ -129,6 +129,7 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic Resource s2 = (Resource) n; // now run yet another describe query String smallerTree = makeDescribe(s2); + log.info(smallerTree); Query smallerTreeQuery = QueryFactory.create(smallerTree); QueryExecution qe3 = QueryExecutionFactory.create( smallerTreeQuery, tree); @@ -184,7 +185,7 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic } queryBuff.append("} \n"); - log.debug(queryBuff.toString()); + log.info(queryBuff.toString()); Query construct = QueryFactory.create(queryBuff.toString()); // make a plain dataset to force the query to be run in a way that diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index 7203cbbb9..b74c130f7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -525,15 +525,23 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { if( subjectVClasses == null ) { vclasses = wdf.getVClassDao().getAllVclasses(); } else if (rangeClass != null) { + List rangeVClasses = new ArrayList(); vclasses = new ArrayList(); - vclasses.add(rangeClass); - List subURIs = wdf.getVClassDao().getSubClassURIs(rangeClass.getURI()); - for (String subClassURI : subURIs) { - VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI); - if (subClass != null) { - vclasses.add(subClass); - } - } + if (!rangeClass.isUnion()) { + rangeVClasses.add(rangeClass); + } else { + rangeVClasses.addAll(rangeClass.getUnionComponents()); + } + for(VClass rangeVClass : rangeVClasses) { + vclasses.add(rangeVClass); + List subURIs = wdf.getVClassDao().getSubClassURIs(rangeVClass.getURI()); + for (String subClassURI : subURIs) { + VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI); + if (subClass != null) { + vclasses.add(subClass); + } + } + } } else { //this hash is used to make sure there are no duplicates in the vclasses //a more elegant method may look at overriding equals/hashcode to enable a single hashset of VClass objects From 528283ab163a3404f7c90e29e9555ebbd50d63e8 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Mon, 26 Aug 2013 15:12:20 -0400 Subject: [PATCH 09/44] supporting qualifiedByDomain in app ontology --- ...ApplicationConfigurationOntologyUtils.java | 29 ++++++++++++++++--- .../individual/GroupedPropertyList.java | 4 +-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 9aab09eab..5ba2bd600 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -20,8 +20,12 @@ import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.vocabulary.RDFS; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; @@ -30,16 +34,17 @@ public class ApplicationConfigurationOntologyUtils { private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class); - public static List getAdditionalFauxSubpropertiesForList(List propList, VitroRequest vreq) { + public static List getAdditionalFauxSubpropertiesForList(List propList, Individual subject, VitroRequest vreq) { ServletContext ctx = vreq.getSession().getServletContext(); Model displayModel = ModelAccess.on(ctx).getDisplayModel(); Model tboxModel = ModelAccess.on(ctx).getOntModel(ModelID.UNION_TBOX); - return getAdditionalFauxSubpropertiesForList(propList, displayModel, tboxModel); + return getAdditionalFauxSubpropertiesForList(propList, subject, displayModel, tboxModel); } public static List getAdditionalFauxSubpropertiesForList(List propList, + Individual subject, Model displayModel, Model tboxModel) { List additionalProps = new ArrayList(); @@ -47,11 +52,12 @@ public class ApplicationConfigurationOntologyUtils { String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT ?range ?label ?group ?customForm WHERE { \n" + + "SELECT DISTINCT ?range ?domain ?label ?group ?customForm WHERE { \n" + " ?p rdfs:subPropertyOf ?property . \n" + " ?context config:configContextFor ?p . \n" + " ?context config:qualifiedBy ?range . \n" + " ?context config:hasConfiguration ?configuration . \n" + + " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + @@ -70,6 +76,10 @@ public class ApplicationConfigurationOntologyUtils { newProp.setURI(op.getURI()); QuerySolution qsoln = rs.nextSolution(); log.debug(qsoln); + Resource domainRes = qsoln.getResource("domain"); + if(domainRes != null && !appropriateDomain(domainRes, subject, tboxModel)) { + continue; + } Resource rangeRes = qsoln.getResource("range"); if (rangeRes != null) { newProp.setRangeVClassURI(rangeRes.getURI()); @@ -104,6 +114,17 @@ public class ApplicationConfigurationOntologyUtils { return additionalProps; } - + private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) { + for (VClass vclass : subject.getVClasses()) { + if ((vclass.getURI() != null) && + ((vclass.getURI().equals(domainRes.getURI()) || + (tboxModel.contains( + ResourceFactory.createResource( + vclass.getURI()), RDFS.subClassOf, domainRes))))) { + return true; + } + } + return false; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index a850a9c71..39ec73225 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -75,9 +75,9 @@ public class GroupedPropertyList extends BaseTemplateModel { List populatedObjectPropertyList = subject .getPopulatedObjectPropertyList(); - List additions = ApplicationConfigurationOntologyUtils + Collection additions = ApplicationConfigurationOntologyUtils .getAdditionalFauxSubpropertiesForList( - populatedObjectPropertyList, vreq); + populatedObjectPropertyList, subject, vreq); if (log.isDebugEnabled()) { for (ObjectProperty t : additions) { log.debug(t.getDomainPublic() + " " + t.getGroupURI()); From 6869cda316b08d9a6dd17917ee81c26f7b389cdb Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Mon, 26 Aug 2013 16:13:35 -0400 Subject: [PATCH 10/44] support for domain qualification in list views --- .../dao/jena/ObjectPropertyDaoJena.java | 31 +++++++++++++------ ...ApplicationConfigurationOntologyUtils.java | 10 ++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 82f177ddf..ba0766626 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -910,6 +910,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp " ?context config:hasConfiguration ?configuration . \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + + " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + " } \n" + "}"; @@ -925,14 +926,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp //TODO private void addPropertyClassCombinationsToListViewMap(HashMap) - // Map key is pair of object property and range class URI - // If range is unspecified, OWL.Thing.getURI() is used in the key. - Map, String> customListViewConfigFileMap = null; + // Map key is inner pair of object property and range class URI, + // with first member of outer pair being a domain class URI. + // If domain or range is unspecified, OWL.Thing.getURI() is used in the key. + Map>, String> customListViewConfigFileMap = null; @Override public String getCustomListViewConfigFileName(ObjectProperty op) { if (customListViewConfigFileMap == null) { - customListViewConfigFileMap = new HashMap, String>(); + customListViewConfigFileMap = new HashMap>, String>(); OntModel displayModel = getOntModelSelector().getDisplayModel(); //Get all property to list view config file mappings in the system QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel); @@ -945,6 +947,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String rangeUri = (rangeNode != null) ? ((Resource) rangeNode).getURI() : OWL.Thing.getURI(); + RDFNode domainNode = soln.get("domain"); + String domainUri = (domainNode != null) + ? ((Resource) domainNode).getURI() + : OWL.Thing.getURI(); ObjectProperty prop = getObjectPropertyByURI(propertyUri); if (prop == null) { //This is a warning only if this property is the one for which we're searching @@ -955,17 +961,24 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } else { String filename = soln.getLiteral("filename").getLexicalForm(); - log.debug("putting " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map"); - customListViewConfigFileMap.put(new Pair(prop, rangeUri), filename); + log.debug("putting " + domainUri + " " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map"); + customListViewConfigFileMap.put( + new Pair>( + domainUri, new Pair( + prop, rangeUri)), filename); } } qexec.close(); } - String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, op.getRangeVClassURI())); + String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair>(op.getDomainVClassURI(), new Pair(op, op.getRangeVClassURI()))); if (customListViewConfigFileName == null) { - log.debug("no list view found for " + op.getURI() + " qualified by " + op.getRangeVClassURI()); - customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, OWL.Thing.getURI())); + log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI() + " and domain " + op.getDomainVClassURI()); + customListViewConfigFileName = customListViewConfigFileMap.get(new Pair>(OWL.Thing.getURI(), new Pair(op, op.getRangeVClassURI()))); + } + if (customListViewConfigFileName == null) { + log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI()); + customListViewConfigFileName = customListViewConfigFileMap.get(new Pair>(OWL.Thing.getURI(), new Pair(op, OWL.Thing.getURI()))); } return customListViewConfigFileName; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 5ba2bd600..895ad76d6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -77,8 +77,14 @@ public class ApplicationConfigurationOntologyUtils { QuerySolution qsoln = rs.nextSolution(); log.debug(qsoln); Resource domainRes = qsoln.getResource("domain"); - if(domainRes != null && !appropriateDomain(domainRes, subject, tboxModel)) { - continue; + if(domainRes != null) { + if(!appropriateDomain(domainRes, subject, tboxModel)) { + continue; + } else { + newProp.setDomainVClassURI(domainRes.getURI()); + } + } else { + newProp.setDomainVClassURI(op.getDomainVClassURI()); } Resource rangeRes = qsoln.getResource("range"); if (rangeRes != null) { From 43c47d0a558092ee28f15c544cd64a8d82c82d50 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 27 Aug 2013 15:46:15 -0400 Subject: [PATCH 11/44] fixes bug in list view support for domain-side qualification --- .../mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java | 2 +- .../vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java | 4 ++++ .../web/templatemodels/individual/GroupedPropertyList.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index ba0766626..8c4dc5b25 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -902,7 +902,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING = "PREFIX display: \n" + "PREFIX config: \n" + - "SELECT ?property ?range ?filename WHERE { \n" + + "SELECT ?property ?range ?domain ?filename WHERE { \n" + " { ?property display:listViewConfigFile ?filename \n" + " } UNION { \n" + " ?configuration config:listViewConfigFile ?filename . \n " + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index 289e10822..7b754f465 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -279,6 +279,10 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec Model constructedModel = constructModelForSelectQueries( subjectUri, propertyUri, constructQueryStrings); + if(log.isDebugEnabled()) { + log.debug("Constructed model has " + constructedModel.size() + " statements."); + } + if("desc".equalsIgnoreCase( sortDirection ) ){ queryString = queryString.replaceAll(" ASC\\(", " DESC("); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 39ec73225..a2af46880 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -80,7 +80,7 @@ public class GroupedPropertyList extends BaseTemplateModel { populatedObjectPropertyList, subject, vreq); if (log.isDebugEnabled()) { for (ObjectProperty t : additions) { - log.debug(t.getDomainPublic() + " " + t.getGroupURI()); + log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " + t.getDomainVClassURI()); } log.debug("Added " + additions.size() + " properties due to application configuration ontology"); From e3d6e37ab914d5e01e421c751c865364b9ddb8f6 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 29 Aug 2013 10:58:34 -0400 Subject: [PATCH 12/44] support for domain qualification in property config --- .../vitro/webapp/dao/ObjectPropertyDao.java | 2 +- .../filtering/ObjectPropertyDaoFiltering.java | 4 +- .../dao/jena/ObjectPropertyDaoJena.java | 17 +++- .../webapp/dao/jena/PropertyDaoJena.java | 96 +++++++++++++------ .../vitro/webapp/dao/jena/VClassDaoJena.java | 7 +- .../VTwo/EditConfigurationUtils.java | 4 + .../EditRequestDispatchController.java | 9 +- .../edit/EditConfigurationTemplateModel.java | 1 + .../CollatedObjectPropertyTemplateModel.java | 2 +- .../individual/GroupedPropertyList.java | 25 +++-- .../ObjectPropertyStatementTemplateModel.java | 12 ++- .../ObjectPropertyTemplateModel.java | 4 + .../individual/PropertyTemplateModel.java | 1 + .../webapp/dao/ObjectPropertyDaoStub.java | 2 +- 14 files changed, 129 insertions(+), 57 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java index 7d70cfc52..6c120ee79 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java @@ -15,7 +15,7 @@ public interface ObjectPropertyDao extends PropertyDao { public ObjectProperty getObjectPropertyByURI(String objectPropertyURI); - public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI); + public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI); public List getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java index 7e8704582..525301c3b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java @@ -49,8 +49,8 @@ class ObjectPropertyDaoFiltering extends BaseFiltering implements ObjectProperty return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); } - public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { - ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIAndRangeURI(objectPropertyURI, rangeURI); + public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) { + ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIs(objectPropertyURI, domainURI, rangeURI); return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 8c4dc5b25..8cef89672 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -284,19 +284,28 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } - public ObjectProperty getObjectPropertyByURIAndRangeURI(String propertyURI, String rangeURI) { + public ObjectProperty getObjectPropertyByURIs(String propertyURI, String domainURI, String rangeURI) { + if(log.isDebugEnabled()) { + log.debug("Getting " + propertyURI + " with domain " + domainURI + " and range " + rangeURI); + } ObjectProperty op = getObjectPropertyByURI(propertyURI); if (op == null || rangeURI == null) { return op; } + op.setDomainVClassURI(domainURI); op.setRangeVClassURI(rangeURI); String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + "SELECT ?range ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + - " ?context config:configContextFor <" + propertyURI + "> . \n" + - " ?context config:qualifiedBy <" + rangeURI + "> . \n" + - " ?context config:hasConfiguration ?configuration . \n" + + " ?context config:configContextFor <" + propertyURI + "> . \n"; + if (domainURI != null) { + propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n"; + }; + if (rangeURI != null) { + propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n"; + }; + propQuery += " ?context config:hasConfiguration ?configuration . \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index ab79e8589..1e04c66e0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -34,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sdb.util.Pair; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.sparql.resultset.ResultSetMem; import com.hp.hpl.jena.vocabulary.OWL; @@ -52,7 +53,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { protected static final Log log = LogFactory.getLog(PropertyDaoJena.class.getName()); - + protected static final String FAUX_PROPERTY_FLAG = "FAUX"; + private static final Map NAMESPACES = new HashMap() {{ put("afn", VitroVocabulary.AFN); put("owl", VitroVocabulary.OWL); @@ -329,7 +331,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { public List getClassesWithRestrictionOnProperty(String propertyURI) { if (propertyURI == null) { - log.info("getClassesWithRestrictionOnProperty: called with null propertyURI"); + log.warn("getClassesWithRestrictionOnProperty: called with null propertyURI"); return null; } @@ -524,15 +526,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } } - List piList = getAllPropInstByVClasses(vclasses); + return getAllPropInstByVClasses(vclasses); - for (PropertyInstance pi : piList) { - pi.setDomainClassURI(ind.getVClassURI()); - // TODO: improve. This is so the DWR property editing passes the - // individual's VClass to get the right restrictions - } - - return piList; } /* @@ -737,12 +732,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { : (op.getRange() == null && foundRanges[1] != null) ? foundRanges[1] : op.getRange(); - propInsts.add(getPropInstForPropertyAndRange(op, rangeRes, applicableProperties)); - List additionalFauxSubpropertyRangeURIs = getAdditionalFauxSubpropertyRangeURIsForPropertyURI(propertyURI); - for (String rangeURI : additionalFauxSubpropertyRangeURIs) { - if (rangeRes == null || getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) { - propInsts.add(getPropInstForPropertyAndRange( - op, ResourceFactory.createResource(rangeURI), applicableProperties)); + Resource domainRes = op.getDomain(); + propInsts.add(getPropInst( + op, domainRes, rangeRes, applicableProperties)); + List> additionalFauxSubpropertyDomainAndRangeURIs = + getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI( + propertyURI); + for (Pair domainAndRangeURIs : + additionalFauxSubpropertyDomainAndRangeURIs) { + boolean applicablePropInst = false; + if (rangeRes == null || + !getWebappDaoFactory().getVClassDao().isSubClassOf( + rangeRes.getURI(), domainAndRangeURIs.getRight())) { + if (domainAndRangeURIs.getLeft() == null) { + applicablePropInst = true; + } else { + for(VClass vclass : vclasses) { + if (vclass.getURI() != null && vclass.getURI().equals( + domainAndRangeURIs.getLeft())) { + applicablePropInst = true; + break; + } + } + } + if (applicablePropInst) { + propInsts.add(getPropInst( + op, + ResourceFactory.createResource(domainAndRangeURIs.getLeft()), + ResourceFactory.createResource(domainAndRangeURIs.getRight()), + applicableProperties)); + } } } } @@ -755,10 +774,16 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } - private PropertyInstance getPropInstForPropertyAndRange(OntProperty op, Resource rangeRes, - Map applicableProperties) { + private PropertyInstance getPropInst(OntProperty op, Resource domainRes, Resource rangeRes, + Map applicableProperties) { + if (log.isDebugEnabled() && domainRes != null && rangeRes != null) { + log.debug("getPropInst() op: " + op.getURI() + " domain: " + + domainRes.getURI() + " range: " + rangeRes.getURI()); + } PropertyInstance pi = new PropertyInstance(); - String domainURIStr = getURIStr(op.getDomain()); + String domainURIStr = (domainRes != null && !domainRes.isAnon()) ? + domainURIStr = domainRes.getURI() + : null; if (rangeRes == null) { pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above } else { @@ -780,14 +805,16 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { pi.setRangeClassName(range.getName()); } pi.setDomainClassURI(domainURIStr); - VClass domain = getWebappDaoFactory().getVClassDao() - .getVClassByURI(domainURIStr); - if (domain == null) { - domain = new VClass(); - domain.setURI(domainURIStr); - domain.setName(domain.getLocalName()); + if (domainURIStr != null) { + VClass domain = getWebappDaoFactory().getVClassDao() + .getVClassByURI(domainURIStr); + if (domain == null) { + domain = new VClass(); + domain.setURI(domainURIStr); + domain.setName(domain.getLocalName()); + } + pi.setDomainClassName(domain.getName()); } - pi.setDomainClassName(domain.getName()); pi.setSubjectSide(true); pi.setPropertyURI(op.getURI()); pi.setPropertyName(getLabelOrId(op)); // TODO @@ -796,14 +823,15 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { return pi; } - private List getAdditionalFauxSubpropertyRangeURIsForPropertyURI(String propertyURI) { - List rangeURIs = new ArrayList(); + private List> getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI(String propertyURI) { + List> domainAndRangeURIs = new ArrayList>(); String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT ?range WHERE { \n" + + "SELECT ?domain ?range WHERE { \n" + " ?context config:configContextFor <" + propertyURI + "> . \n" + " ?context config:qualifiedBy ?range . \n" + + " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + "}"; Query q = QueryFactory.create(propQuery); @@ -813,12 +841,18 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { while (rs.hasNext()) { QuerySolution qsoln = rs.nextSolution(); Resource rangeRes = qsoln.getResource("range"); - rangeURIs.add(rangeRes.getURI()); + String rangeURI = rangeRes.getURI(); + Resource domainRes = qsoln.getResource("domain"); + String domainURI = null; + if (domainRes != null && !domainRes.isAnon()) { + domainURI = domainRes.getURI(); + } + domainAndRangeURIs.add(new Pair(domainURI, rangeURI)); } } finally { qe.close(); } - return rangeURIs; + return domainAndRangeURIs; } private String getURIStr(Resource res) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index af559b5d0..1d168eb63 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -1093,11 +1093,8 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { OntModel ontModel = getOntModel(); try { ontModel.enterCriticalSection(Lock.READ); - OntClass oc1 = getOntClass(ontModel, vclassURI1); - OntClass oc2 = getOntClass(ontModel, vclassURI2); - if (oc1 == null || oc2 == null) { - return false; - } + Resource oc1 = ontModel.getResource(vclassURI1); + Resource oc2 = ontModel.getResource(vclassURI2); return ontModel.contains(oc1, RDFS.subClassOf, oc2); } finally { ontModel.leaveCriticalSection(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java index 97bd06225..534bce2a4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java @@ -53,6 +53,10 @@ public class EditConfigurationUtils { return vreq.getParameter("objectUri"); } + public static String getDomainUri(VitroRequest vreq) { + return vreq.getParameter("domainUri"); + } + public static String getRangeUri(VitroRequest vreq) { return vreq.getParameter("rangeUri"); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index 1ba55f5ed..692f9212d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -202,6 +202,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { String editConfGeneratorName = null; String predicateUri = getPredicateUri(vreq); + String domainUri = EditConfigurationUtils.getDomainUri(vreq); String rangeUri = EditConfigurationUtils.getRangeUri(vreq); // *** handle the case where the form is specified as a request parameter *** @@ -218,7 +219,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { // *** check for a predicate URI in the request }else if( predicateUri != null && !predicateUri.isEmpty() ){ - Property prop = getProperty( predicateUri, rangeUri, vreq); + Property prop = getProperty( predicateUri, domainUri, rangeUri, vreq); if (prop != null && rangeUri != null) { editConfGeneratorName = getCustomEntryForm(prop); } else if( prop != null && prop.getCustomEntryForm() != null ){ @@ -258,11 +259,11 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { } } - private Property getProperty(String predicateUri, String rangeUri, VitroRequest vreq) { + private Property getProperty(String predicateUri, String domainUri, String rangeUri, VitroRequest vreq) { Property p = null; try{ - p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURIAndRangeURI( - predicateUri, rangeUri); + p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURIs( + predicateUri, domainUri, rangeUri); if(p == null) { p = vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index b74c130f7..95b4a80b5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -459,6 +459,7 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { predicateUri, objectKey, null, + null, statementDisplay, null, vreq); ReadOnlyBeansWrapper wrapper = new ReadOnlyBeansWrapper(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java index 780fb050d..047854a73 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java @@ -218,7 +218,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM } listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri, - propertyUri, rangeUri, objectKey, map, getTemplateName(), vreq)); + propertyUri, domainUri, rangeUri, objectKey, map, getTemplateName(), vreq)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index a2af46880..7c023e022 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -89,7 +89,7 @@ public class GroupedPropertyList extends BaseTemplateModel { populatedObjectPropertyList.addAll(additions); propertyList.addAll(populatedObjectPropertyList); - + // If editing this page, merge in object properties applicable to the individual that are currently // unpopulated, so the properties are displayed to allow statements to be added to these properties. // RY In future, we should limit this to properties that the user has permission to add properties to. @@ -190,7 +190,7 @@ public class GroupedPropertyList extends BaseTemplateModel { if (pi != null) { if (!alreadyOnObjectPropertyList( populatedObjectPropertyList, pi)) { - addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getRangeClassURI(), + addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI(), propertyList); } } else { @@ -206,7 +206,7 @@ public class GroupedPropertyList extends BaseTemplateModel { // constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()). for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) { if (!alreadyOnPropertyList(propertyList, propertyUri)) { - addObjectPropertyToPropertyList(propertyUri, null, propertyList); + addObjectPropertyToPropertyList(propertyUri, null, null, propertyList); } } } @@ -218,16 +218,29 @@ public class GroupedPropertyList extends BaseTemplateModel { } for (ObjectProperty op : opList) { if (op.getURI() != null && op.getURI().equals(pi.getPropertyURI())) { - return true; + if(op.getDomainVClassURI() == null) { + if(pi.getDomainClassURI() == null) { + return true; + } + } else if (op.getDomainVClassURI().equals(pi.getDomainClassURI())) { + return true; + } + if(op.getRangeVClassURI() == null) { + if (pi.getDomainClassURI() == null) { + return true; + } + } else if (op.getRangeVClassURI().equals(pi.getRangeClassURI())) { + return true; + } } } return false; } - private void addObjectPropertyToPropertyList(String propertyUri, String rangeUri, + private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri, List propertyList) { ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); - ObjectProperty op = opDao.getObjectPropertyByURIAndRangeURI(propertyUri, rangeUri); + ObjectProperty op = opDao.getObjectPropertyByURIs(propertyUri, domainUri, rangeUri); if (op == null) { log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")"); } else if (op.getURI() == null) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java index 9c94b25b4..ae7e145d5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java @@ -33,6 +33,11 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String rangeUri, String objectKey, Map data, String templateName, VitroRequest vreq) { + this (subjectUri, propertyUri, null, rangeUri, objectKey, data, templateName, vreq); + } + + public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String domainUri, String rangeUri, String objectKey, + Map data, String templateName, VitroRequest vreq) { super(subjectUri, propertyUri, vreq); this.data = Collections.unmodifiableMap(new HashMap(data)); @@ -45,7 +50,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl // Do delete url first, since it is used in building edit url this.deleteUrl = makeDeleteUrl(); - this.editUrl = makeEditUrl(ops, rangeUri); + this.editUrl = makeEditUrl(ops, domainUri, rangeUri); } private String makeDeleteUrl() { @@ -90,7 +95,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl return UrlBuilder.getUrl(EDIT_PATH, params); } - private String makeEditUrl(ObjectPropertyStatement ops, String rangeUri) { + private String makeEditUrl(ObjectPropertyStatement ops, String domainUri, String rangeUri) { // Is the edit link suppressed for this property? if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) { return ""; @@ -115,6 +120,9 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl params.put("deleteProhibited", "prohibited"); } + if (domainUri != null) { + params.put("domainUri", rangeUri); + } if (rangeUri != null) { params.put("rangeUri", rangeUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 2e4fd2fd3..99da9d493 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -89,6 +89,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel setName(op.getDomainPublic()); sortDirection = op.getDomainEntitySortDirection(); + domainUri = op.getDomainVClassURI(); rangeUri = op.getRangeVClassURI(); // Get the config for this object property @@ -132,6 +133,9 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel "subjectUri", subjectUri, "predicateUri", propertyUri); + if (domainUri != null) { + params.put("domainUri", domainUri); + } if (rangeUri != null) { params.put("rangeUri", rangeUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java index 41cfabfb7..14a4db56b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java @@ -29,6 +29,7 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { protected final VitroRequest vreq; protected final String subjectUri; protected final String propertyUri; + protected String domainUri; protected String rangeUri; private final String localName; diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java index 0017b9291..54ba17477 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java @@ -67,7 +67,7 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { } @Override - public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { + public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) { return getObjectPropertyByURI(objectPropertyURI); } From b1d549f01ff5e042beb0272abce9136b32eedcca Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 29 Aug 2013 12:00:51 -0400 Subject: [PATCH 13/44] minor change to sparql query for domain-qualified property configs --- .../mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 8cef89672..0079e8737 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -301,7 +301,9 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp " ?context config:configContextFor <" + propertyURI + "> . \n"; if (domainURI != null) { propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n"; - }; + } else { + propQuery += " FILTER NOT EXISTS { ?context config:qualifiedByDomain ?domainURI } \n"; + } if (rangeURI != null) { propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n"; }; From ca32a51740d9ca1b082c87461c4b3578de64982e Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 30 Aug 2013 17:04:12 -0400 Subject: [PATCH 14/44] support for edit permissions for qualified properties (almost finished) --- .../permissions/DisplayByRolePermission.java | 22 +- .../permissions/EditByRolePermission.java | 13 +- .../auth/policy/BaseSelfEditingPolicy.java | 9 +- .../DisplayRestrictedDataToSelfPolicy.java | 16 +- .../webapp/auth/policy/PermissionsPolicy.java | 2 + .../webapp/auth/policy/PolicyHelper.java | 11 +- .../webapp/auth/policy/SelfEditingPolicy.java | 5 +- .../bean/PropertyRestrictionPolicyHelper.java | 202 ++++++++++-------- .../AbstractRelationshipPolicy.java | 5 +- .../ifaces/RequestActionConstants.java | 3 + .../AbstractDataPropertyStatementAction.java | 12 ++ ...AbstractObjectPropertyStatementAction.java | 18 +- .../AbstractPropertyStatementAction.java | 3 + .../propstmt/AddObjectPropertyStatement.java | 5 +- .../propstmt/DropObjectPropertyStatement.java | 3 +- .../propstmt/EditObjectPropertyStatement.java | 5 +- .../vitro/webapp/beans/ObjectProperty.java | 8 +- .../mannlib/vitro/webapp/beans/Property.java | 22 ++ .../controller/admin/ShowAuthController.java | 2 +- .../freemarker/ImageUploadController.java | 10 +- ...ApplicationConfigurationOntologyUtils.java | 167 +++++++++------ .../edit/EditConfigurationTemplateModel.java | 7 +- .../BaseIndividualTemplateModel.java | 2 +- .../CollatedObjectPropertyTemplateModel.java | 7 +- .../DataPropertyStatementTemplateModel.java | 15 +- .../individual/DataPropertyTemplateModel.java | 2 +- .../individual/EditLinkSuppressor.java | 13 +- .../NameStatementTemplateModel.java | 7 +- .../ObjectPropertyStatementTemplateModel.java | 40 ++-- .../ObjectPropertyTemplateModel.java | 2 +- .../PropertyStatementTemplateModel.java | 7 +- .../individual/PropertyTemplateModel.java | 2 + ...UncollatedObjectPropertyTemplateModel.java | 2 +- .../auth/policy/SelfEditingPolicyTest.java | 29 +-- .../auth/policy/SelfEditingPolicy_2_Test.java | 7 +- .../PropertyRestrictionPolicyHelperTest.java | 79 ++++--- .../PropertyRestrictionPolicyHelperStub.java | 15 +- 37 files changed, 469 insertions(+), 310 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java index 80aae91d2..19b9e141f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java @@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Is the user authorized to display properties that are marked as restricted to @@ -82,7 +83,7 @@ public class DisplayByRolePermission extends Permission { */ private boolean isAuthorized(DisplayDataProperty action) { String predicateUri = action.getDataProperty().getURI(); - return canDisplayPredicate(predicateUri); + return canDisplayPredicate(new Property(predicateUri)); } /** @@ -90,8 +91,7 @@ public class DisplayByRolePermission extends Permission { * predicate. */ private boolean isAuthorized(DisplayObjectProperty action) { - String predicateUri = action.getObjectProperty().getURI(); - return canDisplayPredicate(predicateUri); + return canDisplayPredicate(action.getObjectProperty()); } /** @@ -103,7 +103,7 @@ public class DisplayByRolePermission extends Permission { String subjectUri = stmt.getIndividualURI(); String predicateUri = stmt.getDatapropURI(); return canDisplayResource(subjectUri) - && canDisplayPredicate(predicateUri); + && canDisplayPredicate(new Property(predicateUri)); } /** @@ -113,12 +113,10 @@ public class DisplayByRolePermission extends Permission { private boolean isAuthorized(DisplayObjectPropertyStatement action) { ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); String subjectUri = stmt.getSubjectURI(); - String predicateUri = stmt.getPropertyURI(); - String rangeUri = (stmt.getProperty() == null) ? null - : stmt.getProperty().getRangeVClassURI(); + Property predicate = stmt.getProperty(); String objectUri = stmt.getObjectURI(); return canDisplayResource(subjectUri) - && canDisplayPredicate(predicateUri, rangeUri) + && canDisplayPredicate(predicate) && canDisplayResource(objectUri); } @@ -126,14 +124,10 @@ public class DisplayByRolePermission extends Permission { return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( resourceUri, this.roleLevel); } - - private boolean canDisplayPredicate(String predicateUri) { - return canDisplayPredicate(predicateUri, null); - } - private boolean canDisplayPredicate(String predicateUri, String rangeUri) { + private boolean canDisplayPredicate(Property predicate) { return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(predicateUri, rangeUri, this.roleLevel); + .canDisplayPredicate(predicate, this.roleLevel); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java index 6d5e64363..93c962015 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java @@ -12,6 +12,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Is the user authorized to edit properties that are marked as restricted to a @@ -78,9 +79,9 @@ public class EditByRolePermission extends Permission { */ private boolean isAuthorized(AbstractDataPropertyStatementAction action) { String subjectUri = action.getSubjectUri(); - String predicateUri = action.getPredicateUri(); + Property predicate = action.getPredicate(); return canModifyResource(subjectUri) - && canModifyPredicate(predicateUri); + && canModifyPredicate(predicate); } /** @@ -89,10 +90,10 @@ public class EditByRolePermission extends Permission { */ private boolean isAuthorized(AbstractObjectPropertyStatementAction action) { String subjectUri = action.getSubjectUri(); - String predicateUri = action.getPredicateUri(); + Property predicate = action.getPredicate(); String objectUri = action.getObjectUri(); return canModifyResource(subjectUri) - && canModifyPredicate(predicateUri) + && canModifyPredicate(predicate) && canModifyResource(objectUri); } @@ -101,9 +102,9 @@ public class EditByRolePermission extends Permission { resourceUri, roleLevel); } - private boolean canModifyPredicate(String predicateUri) { + private boolean canModifyPredicate(Property predicate) { return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - predicateUri, roleLevel); + predicate, roleLevel); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java index 7d1563d0a..326ee93ef 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java @@ -8,6 +8,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPoli import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * A base class with utility methods for policies involving self-editing. @@ -26,9 +27,9 @@ public abstract class BaseSelfEditingPolicy { uri, roleLevel); } - protected boolean canModifyPredicate(String uri) { + protected boolean canModifyPredicate(Property predicate) { return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - uri, roleLevel); + predicate, roleLevel); } protected PolicyDecision cantModifyResource(String uri) { @@ -36,9 +37,9 @@ public abstract class BaseSelfEditingPolicy { + uri); } - protected PolicyDecision cantModifyPredicate(String uri) { + protected PolicyDecision cantModifyPredicate(Property predicate) { return inconclusiveDecision("No access to admin predicates; cannot modify " - + uri); + + predicate.getURI()); } protected PolicyDecision userNotAuthorizedToStatement() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java index 0f3e5e2bc..7ffbd627d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java @@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Permit display of various data if it relates to the user's associated @@ -92,14 +93,14 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { Collection individuals) { DataPropertyStatement stmt = action.getDataPropertyStatement(); String subjectUri = stmt.getIndividualURI(); - String predicateUri = stmt.getDatapropURI(); - if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) + Property predicate = new Property(stmt.getDatapropURI()); + if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate) && isAboutAssociatedIndividual(individuals, stmt)) { return authorized("user may view DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); + + subjectUri + " ==> " + predicate.getURI()); } else { return defaultDecision("user may not view DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); + + subjectUri + " ==> " + predicate.getURI()); } } @@ -115,7 +116,8 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { String subjectUri = stmt.getSubjectURI(); String predicateUri = stmt.getPropertyURI(); String objectUri = stmt.getObjectURI(); - if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) + if (canDisplayResource(subjectUri) && canDisplayPredicate(new Property + (predicateUri)) && canDisplayResource(objectUri) && isAboutAssociatedIndividual(individuals, stmt)) { return authorized("user may view ObjectPropertyStatement " @@ -143,9 +145,9 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { uri, RoleLevel.SELF); } - private boolean canDisplayPredicate(String uri) { + private boolean canDisplayPredicate(Property predicate) { return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(uri, RoleLevel.SELF); + .canDisplayPredicate(predicate, RoleLevel.SELF); } private boolean isAboutAssociatedIndividual(Collection selves, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java index 2bf85a628..c424ca355 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java @@ -35,6 +35,8 @@ public class PermissionsPolicy implements PolicyIface { log.debug("Permission " + p + " approves request " + whatToAuth); return new BasicPolicyDecision(Authorization.AUTHORIZED, "PermissionsPolicy: approved by " + p); + } else { + log.trace("Permission " + p + " denies request " + whatToAuth); } } log.debug("No permission will approve " + whatToAuth); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java index ec9611df3..69e8839ce 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java @@ -75,7 +75,8 @@ public class PolicyHelper { } Resource subject = stmt.getSubject(); - Property predicate = stmt.getPredicate(); + edu.cornell.mannlib.vitro.webapp.beans.Property predicate = + new edu.cornell.mannlib.vitro.webapp.beans.Property(stmt.getPredicate().getURI()); RDFNode objectNode = stmt.getObject(); if ((subject == null) || (predicate == null) || (objectNode == null)) { return false; @@ -84,7 +85,7 @@ public class PolicyHelper { RequestedAction action; if (objectNode.isResource()) { action = new AddObjectPropertyStatement(modelToBeModified, - subject.getURI(), predicate.getURI(), objectNode + subject.getURI(), predicate, objectNode .asResource().getURI()); } else { action = new AddDataPropertyStatement(modelToBeModified, @@ -106,7 +107,9 @@ public class PolicyHelper { } Resource subject = stmt.getSubject(); - Property predicate = stmt.getPredicate(); + edu.cornell.mannlib.vitro.webapp.beans.Property predicate = + new edu.cornell.mannlib.vitro.webapp.beans.Property(); + predicate.setURI(stmt.getPredicate().getURI()); RDFNode objectNode = stmt.getObject(); if ((subject == null) || (predicate == null) || (objectNode == null)) { return false; @@ -115,7 +118,7 @@ public class PolicyHelper { RequestedAction action; if (objectNode.isResource()) { action = new DropObjectPropertyStatement(modelToBeModified, - subject.getURI(), predicate.getURI(), objectNode + subject.getURI(), predicate, objectNode .asResource().getURI()); } else { action = new DropDataPropertyStatement(modelToBeModified, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java index e3a6b8dec..6ad28bfd2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java @@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDa import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Policy to use for Vivo Self-Editing based on NetId for use at Cornell. All @@ -69,7 +70,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements private PolicyDecision isAuthorizedForObjectPropertyAction( List userUris, AbstractObjectPropertyStatementAction action) { String subject = action.getSubjectUri(); - String predicate = action.getPredicateUri(); + Property predicate = action.getPredicate(); String object = action.getObjectUri(); if (!canModifyResource(subject)) { @@ -96,7 +97,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements private PolicyDecision isAuthorizedForDataPropertyAction( List userUris, AbstractDataPropertyStatementAction action) { String subject = action.getSubjectUri(); - String predicate = action.getPredicateUri(); + Property predicate = action.getPredicate(); if (!canModifyResource(subject)) { return cantModifyResource(subject); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java index eb462b5df..c64006f31 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; @@ -17,6 +18,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -24,18 +26,23 @@ import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.impl.Util; +import com.hp.hpl.jena.sdb.util.Pair; import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; +import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils; /** * Assists the role-based policies in determining whether a property or resource @@ -108,17 +115,22 @@ public class PropertyRestrictionPolicyHelper { Model displayModel) { - Map displayThresholdMap = new HashMap(); - Map modifyThresholdMap = new HashMap(); + Map>, RoleLevel> displayThresholdMap = + new HashMap>, RoleLevel>(); + Map>, RoleLevel> modifyThresholdMap = + new HashMap>, RoleLevel>(); + + OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, + ModelFactory.createUnion(displayModel, model)); + + + populateThresholdMap(union, displayThresholdMap, + VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); + populateThresholdMap( + union, + modifyThresholdMap, + VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); - if (model != null) { - populateThresholdMap(model, displayThresholdMap, - VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); - populateThresholdMap( - model, - modifyThresholdMap, - VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); - } PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper( PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, @@ -127,15 +139,49 @@ public class PropertyRestrictionPolicyHelper { return bean; } + private RoleLevel getModifyThreshold(Property property) { + return getThreshold(property, modifyThresholdMap); + } + + private RoleLevel getThreshold(Property property, + Map>, RoleLevel> + thresholdMap) { + if (property.getURI() == null) { + return RoleLevel.NOBODY; + } + String domainURI = (false && property.getDomainVClassURI() == null) + ? OWL.Thing.getURI() : property.getDomainVClassURI(); + String rangeURI = (false && property.getRangeVClassURI() == null) + ? OWL.Thing.getURI() : property.getRangeVClassURI(); + RoleLevel roleLevel = getRoleLevelFromMap( + domainURI, property.getURI(), rangeURI, thresholdMap); + if (roleLevel == null) { + roleLevel = getRoleLevelFromMap( + OWL.Thing.getURI(), property.getURI(), OWL.Thing.getURI(), + thresholdMap); + } + return roleLevel; + } + + private RoleLevel getRoleLevelFromMap(String domainURI, + String predicateURI, + String rangeURI, + Map>, RoleLevel> map) { + return map.get( + new Pair>( + domainURI, new Pair( + predicateURI, rangeURI))); + } + /** * Find all the resources that possess this property, and map the resource * URI to the required RoleLevel. */ private static void populateThresholdMap(OntModel model, - Map map, String propertyUri) { + Map>, RoleLevel> map, String propertyUri) { model.enterCriticalSection(Lock.READ); try { - Property property = model.getProperty(propertyUri); + com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri); StmtIterator stmts = model.listStatements((Resource) null, property, (Resource) null); while (stmts.hasNext()) { @@ -147,7 +193,29 @@ public class PropertyRestrictionPolicyHelper { } Resource object = (Resource) objectNode; RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); - map.put(subject.getURI(), role); + map.put(new Pair>( + OWL.Thing.getURI(), new Pair( + subject.getURI(), OWL.Thing.getURI())), role); + ObjectProperty op = new ObjectProperty(); + op.setURI(subject.getURI()); + List fauxOps = ApplicationConfigurationOntologyUtils + .getAdditionalFauxSubproperties(op, null, model, model); + for (ObjectProperty faux : fauxOps) { + role = null; + if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT + .equals(propertyUri)) { + role = faux.getProhibitedFromUpdateBelowRoleLevel(); + } else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT + .equals(propertyUri)) { + role = faux.getHiddenFromDisplayBelowRoleLevel(); + } + if (role != null) { + log.info("Putting D:" + faux.getDomainVClassURI() + " P:" + subject.getURI() + " R:" + faux.getRangeVClassURI() + " ==> L:" + role); + map.put(new Pair>( + faux.getDomainVClassURI(), new Pair( + subject.getURI(), faux.getRangeVClassURI())), role); + } + } } stmts.close(); } finally { @@ -175,15 +243,14 @@ public class PropertyRestrictionPolicyHelper { * These URIs can be displayed only if the user's role is at least as high * as the threshold role. */ - private final Map displayThresholdMap; + private final Map>, RoleLevel> displayThresholdMap; /** * These URIs can be modified only if the user's role is at least as high as * the threshold role. */ - private final Map modifyThresholdMap; + private final Map>, RoleLevel> modifyThresholdMap; - private final Model displayModel; /** * Store unmodifiable versions of the inputs. @@ -194,14 +261,15 @@ public class PropertyRestrictionPolicyHelper { protected PropertyRestrictionPolicyHelper( Collection modifyProhibitedNamespaces, Collection modifyExceptionsAllowedUris, - Map displayThresholdMap, - Map modifyThresholdMap, + Map>, RoleLevel> displayThresholdMap, + Map>, RoleLevel> modifyThresholdMap, Model displayModel) { this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces); this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris); - this.displayThresholdMap = unmodifiable(displayThresholdMap); - this.modifyThresholdMap = unmodifiable(modifyThresholdMap); - this.displayModel = displayModel; + this.displayThresholdMap = displayThresholdMap; + this.modifyThresholdMap = modifyThresholdMap; +// this.displayThresholdMap = unmodifiable(displayThresholdMap); +// this.modifyThresholdMap = unmodifiable(modifyThresholdMap); if (log.isDebugEnabled()) { log.debug("prohibited: " + this.modifyProhibitedNamespaces); @@ -219,6 +287,7 @@ public class PropertyRestrictionPolicyHelper { } } + @SuppressWarnings("unused") private Map unmodifiable(Map raw) { if (raw == null) { return Collections.emptyMap(); @@ -271,32 +340,21 @@ public class PropertyRestrictionPolicyHelper { log.debug("can modify resource '" + resourceUri + "'"); return true; } - - public boolean canDisplayPredicate(String predicateUri, RoleLevel userRole) { - return canDisplayPredicate(predicateUri, null, userRole); - } /** * If display of a predicate is restricted, the user's role must be at least * as high as the restriction level. */ - public boolean canDisplayPredicate(String predicateUri, String rangeUri, RoleLevel userRole) { + public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { + //TODO change + String predicateUri = predicate.getURI(); + if (predicateUri == null) { log.debug("can't display predicate: predicateUri was null"); return false; } - RoleLevel displayThreshold = RoleLevel.NOBODY; - if (rangeUri == null) { - displayThreshold = displayThresholdMap.get(predicateUri); - } else { - log.debug("Getting display threshold for " + predicateUri + " " + rangeUri); - displayThreshold = getDisplayThreshold(predicateUri, rangeUri); - if (displayThreshold == null) { - displayThreshold = displayThresholdMap.get(predicateUri); - } - log.debug(displayThreshold); - } + RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap); if (isAuthorized(userRole, displayThreshold)) { log.debug("can display predicate: '" + predicateUri @@ -310,44 +368,6 @@ public class PropertyRestrictionPolicyHelper { return false; } - /** - * Gets the role level threshold for displaying a predicate with a particular - * object class - * @param predicateUri - * @param rangeUri - * @return RoleLevel threshold - */ - private RoleLevel getDisplayThreshold(String predicateUri, String rangeUri) { - String query = "PREFIX rdfs: \n" + - "PREFIX config: \n" + - "PREFIX vitro: \n" + - "SELECT ?level WHERE { \n" + -// " ?p rdfs:subPropertyOf ?property . \n" + - " ?context config:configContextFor ?p . \n" + - " ?context config:qualifiedBy ?range . \n" + - " ?context config:hasConfiguration ?configuration . \n" + - " ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?level \n" + - "}"; - Query q = QueryFactory.create(query); - QueryExecution qe = QueryExecutionFactory.create(q, displayModel); - try { - ResultSet rs = qe.execSelect(); - if (!rs.hasNext()) { - return null; - } - while(rs.hasNext()) { - QuerySolution qsoln = rs.nextSolution(); - Resource levelRes = qsoln.getResource("level"); - if (levelRes != null) { - return RoleLevel.getRoleByUri(levelRes.getURI()); - } - } - } finally { - qe.close(); - } - return null; - } - /** * A predicate cannot be modified if its namespace is in the prohibited list * (some exceptions are allowed). @@ -355,32 +375,36 @@ public class PropertyRestrictionPolicyHelper { * If modification of a predicate is restricted, the user's role must be at * least as high as the restriction level. */ - public boolean canModifyPredicate(String predicateUri, RoleLevel userRole) { - if (predicateUri == null) { - log.debug("can't modify predicate: predicateUri was null"); + public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { + if (predicate == null || predicate.getURI() == null) { + log.debug("can't modify predicate: predicate was null"); return false; } - if (modifyProhibitedNamespaces.contains(namespace(predicateUri))) { - if (modifyExceptionsAllowedUris.contains(predicateUri)) { - log.debug("'" + predicateUri + "' is a permitted exception"); + if (modifyProhibitedNamespaces.contains(namespace(predicate.getURI()))) { + if (modifyExceptionsAllowedUris.contains(predicate.getURI())) { + log.debug("'" + predicate.getURI() + "' is a permitted exception"); } else { - log.debug("can't modify resource '" + predicateUri + log.debug("can't modify resource '" + predicate.getURI() + "': prohibited namespace: '" - + namespace(predicateUri) + "'"); + + namespace(predicate.getURI()) + "'"); return false; } } - RoleLevel modifyThreshold = modifyThresholdMap.get(predicateUri); + RoleLevel modifyThreshold = getModifyThreshold(predicate); if (isAuthorized(userRole, modifyThreshold)) { - log.debug("can modify predicate: '" + predicateUri + "', userRole=" + log.debug("can modify predicate: '" + predicate.getURI() + "', domain=" + + predicate.getDomainVClassURI() + ", range=" + + predicate.getRangeVClassURI() + ", userRole=" + userRole + ", thresholdRole=" + modifyThreshold); return true; } - log.debug("can't modify predicate: '" + predicateUri + "', userRole=" - + userRole + ", thresholdRole=" + modifyThreshold); + log.debug("can't modify predicate: '" + predicate.getURI() + "', domain=" + + predicate.getDomainVClassURI() + ", range=" + + predicate.getRangeVClassURI() + ", userRole=" + + userRole + ", thresholdRole=" + modifyThreshold); return false; } @@ -422,7 +446,7 @@ public class PropertyRestrictionPolicyHelper { throw new NullPointerException( "display model has not been initialized."); } - + PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper .createBean(model, displayModel); PropertyRestrictionPolicyHelper.setBean(ctx, bean); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java index 02dd57f16..359c646b2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java @@ -13,6 +13,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * A collection of building-block methods so we can code a policy based on the @@ -34,9 +35,9 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface { uri, RoleLevel.SELF); } - protected boolean canModifyPredicate(String uri) { + protected boolean canModifyPredicate(Property predicate) { return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - uri, RoleLevel.SELF); + predicate, RoleLevel.SELF); } protected PolicyDecision cantModifyResource(String uri) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java index 738814cbb..73b1c6785 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java @@ -2,9 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + public class RequestActionConstants { public static String actionNamespace = "java:"; public static String SOME_URI = "?SOME_URI"; + public static Property SOME_PREDICATE = new Property(SOME_URI); public static String SOME_LITERAL = "?SOME_LITERAL"; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java index 024709878..bfcf98c2a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * A base class for requested actions that involve adding, editing, or dropping @@ -14,12 +15,16 @@ public abstract class AbstractDataPropertyStatementAction extends AbstractPropertyStatementAction { private final String subjectUri; private final String predicateUri; + private final Property predicate; public AbstractDataPropertyStatementAction(OntModel ontModel, String subjectUri, String predicateUri) { super(ontModel); this.subjectUri = subjectUri; this.predicateUri = predicateUri; + Property dataProperty = new Property(); + dataProperty.setURI(predicateUri); + this.predicate = dataProperty; } public AbstractDataPropertyStatementAction(OntModel ontModel, @@ -28,12 +33,19 @@ public abstract class AbstractDataPropertyStatementAction extends this.subjectUri = (dps.getIndividual() == null) ? dps .getIndividualURI() : dps.getIndividual().getURI(); this.predicateUri = dps.getDatapropURI(); + Property dataProperty = new Property(); + dataProperty.setURI(predicateUri); + this.predicate = dataProperty; } public String getSubjectUri() { return subjectUri; } + public Property getPredicate() { + return predicate; + } + @Override public String getPredicateUri() { return predicateUri; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java index da380c383..700b0bf24 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * A base class for requested actions that involve adding, editing, or deleting @@ -13,14 +14,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; public abstract class AbstractObjectPropertyStatementAction extends AbstractPropertyStatementAction { private final String subjectUri; - private final String predicateUri; + private final Property predicate; private final String objectUri; public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri, - String predicateUri, String objectUri) { + Property predicate, String objectUri) { super(ontModel); this.subjectUri = subjectUri; - this.predicateUri = predicateUri; + this.predicate = predicate; this.objectUri = objectUri; } @@ -28,8 +29,7 @@ public abstract class AbstractObjectPropertyStatementAction extends super(ontModel); this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI() : ops.getSubject().getURI(); - this.predicateUri = (ops.getProperty() == null) ? ops.getPropertyURI() - : ops.getProperty().getURI(); + this.predicate = (ops.getProperty()); this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops .getObject().getURI(); } @@ -42,9 +42,13 @@ public abstract class AbstractObjectPropertyStatementAction extends return objectUri; } + public Property getPredicate() { + return predicate; + } + @Override public String getPredicateUri() { - return predicateUri; + return predicate.getURI(); } @Override @@ -55,6 +59,6 @@ public abstract class AbstractObjectPropertyStatementAction extends @Override public String toString() { return this.getClass().getSimpleName() + ": <" + subjectUri + "> <" - + predicateUri + "> <" + objectUri + ">"; + + predicate.getURI() + "> <" + objectUri + ">"; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java index 82434a2bd..6f5d95dae 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * A base class for requested actions that involve adding, editing, or deleting @@ -27,5 +28,7 @@ public abstract class AbstractPropertyStatementAction extends RequestedAction { */ public abstract String[] getResourceUris(); + public abstract Property getPredicate(); + public abstract String getPredicateUri(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java index 423893328..286850787 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Should we allow the user to add this ObjectPropertyStatement to this model? @@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; public class AddObjectPropertyStatement extends AbstractObjectPropertyStatementAction { public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub, - String uriOfPred, String uriOfObj) { - super(ontModel, uriOfSub, uriOfPred, uriOfObj); + Property predicate, String uriOfObj) { + super(ontModel, uriOfSub, predicate, uriOfObj); } public AddObjectPropertyStatement(OntModel ontModel, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java index c994a39e8..016dec38a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Should we allow the user to delete this ObjectPropertyStatement from this @@ -13,7 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; public class DropObjectPropertyStatement extends AbstractObjectPropertyStatementAction { public DropObjectPropertyStatement(OntModel ontModel, String sub, - String pred, String obj) { + Property pred, String obj) { super(ontModel, sub, pred, obj); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java index 732c3fa31..cb65eea0d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; /** * Should we allow the user to edit this ObjectPropertyStatement in this model? @@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; public class EditObjectPropertyStatement extends AbstractObjectPropertyStatementAction { public EditObjectPropertyStatement(OntModel ontModel, String subjectUri, - String keywordPredUri, String objectUri) { - super(ontModel, subjectUri, keywordPredUri, objectUri); + Property keywordPred, String objectUri) { + super(ontModel, subjectUri, keywordPred, objectUri); } public EditObjectPropertyStatement(OntModel ontModel, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java index be5609495..61a195f12 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java @@ -78,10 +78,12 @@ public class ObjectProperty extends Property implements Comparable getAdditionalFauxSubproperties(ObjectProperty op, + Individual subject, + Model tboxModel, + Model union) { + + List additionalProps = new ArrayList(); + String propQuery = "PREFIX rdfs: \n" + + "PREFIX config: \n" + + "PREFIX vitro: \n" + + "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + +// " ?p rdfs:subPropertyOf ?property . \n" + + " ?context config:configContextFor ?property . \n" + + " ?context config:qualifiedBy ?range . \n" + + " ?context config:hasConfiguration ?configuration . \n" + + " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + + " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + + "}"; + + + log.debug("Checking " + op.getURI() + " for additional properties"); + String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">"); + log.debug(queryStr); + Query q = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.create(q, union); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + ObjectProperty newProp = new ObjectProperty(); + newProp.setURI(op.getURI()); + QuerySolution qsoln = rs.nextSolution(); + log.debug(qsoln); + Resource domainRes = qsoln.getResource("domain"); + if(domainRes != null) { + if(!appropriateDomain( + domainRes, subject, tboxModel)) { + continue; + } else { + newProp.setDomainVClassURI(domainRes.getURI()); + } + } else { + newProp.setDomainVClassURI(op.getDomainVClassURI()); + } + Resource rangeRes = qsoln.getResource("range"); + if (rangeRes != null) { + newProp.setRangeVClassURI(rangeRes.getURI()); + } else { + newProp.setRangeVClassURI(op.getRangeVClassURI()); + } + Resource groupRes = qsoln.getResource("group"); + if (groupRes != null) { + newProp.setGroupURI(groupRes.getURI()); + } else { + newProp.setGroupURI(op.getURI()); + } + Literal labelLit = qsoln.getLiteral("label"); + if (labelLit != null) { + newProp.setDomainPublic(labelLit.getLexicalForm()); + } else { + newProp.setDomainPublic(op.getDomainPublic()); + } + Literal customFormLit = qsoln.getLiteral("customForm"); + if (customFormLit != null) { + newProp.setCustomEntryForm(customFormLit.getLexicalForm()); + } else { + newProp.setCustomEntryForm(op.getCustomEntryForm()); + } + Resource displayLevelRes = qsoln.getResource("displayLevel"); + if (displayLevelRes != null) { + newProp.setHiddenFromDisplayBelowRoleLevel( + BaseResourceBean.RoleLevel.getRoleByUri( + displayLevelRes.getURI())); + } + Resource updateLevelRes = qsoln.getResource("updateLevel"); + if (updateLevelRes != null) { + log.info("updateLevel!"); + newProp.setProhibitedFromUpdateBelowRoleLevel( + BaseResourceBean.RoleLevel.getRoleByUri( + updateLevelRes.getURI())); + } + additionalProps.add(newProp); + } + } finally { + qe.close(); + } + return additionalProps; + } + public static List getAdditionalFauxSubpropertiesForList(List propList, Individual subject, Model displayModel, Model tboxModel) { + List additionalProps = new ArrayList(); Model union = ModelFactory.createUnion(displayModel, tboxModel); - String propQuery = "PREFIX rdfs: \n" + - "PREFIX config: \n" + - "PREFIX vitro: \n" + - "SELECT DISTINCT ?range ?domain ?label ?group ?customForm WHERE { \n" + - " ?p rdfs:subPropertyOf ?property . \n" + - " ?context config:configContextFor ?p . \n" + - " ?context config:qualifiedBy ?range . \n" + - " ?context config:hasConfiguration ?configuration . \n" + - " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + - " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + - " OPTIONAL { ?configuration config:displayName ?label } \n" + - " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + - "}"; - - for (ObjectProperty op : propList) { - log.debug("Checking " + op.getURI() + " for additional properties"); - String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">"); - log.debug(queryStr); - Query q = QueryFactory.create(queryStr); - QueryExecution qe = QueryExecutionFactory.create(q, union); - try { - ResultSet rs = qe.execSelect(); - while (rs.hasNext()) { - ObjectProperty newProp = new ObjectProperty(); - newProp.setURI(op.getURI()); - QuerySolution qsoln = rs.nextSolution(); - log.debug(qsoln); - Resource domainRes = qsoln.getResource("domain"); - if(domainRes != null) { - if(!appropriateDomain(domainRes, subject, tboxModel)) { - continue; - } else { - newProp.setDomainVClassURI(domainRes.getURI()); - } - } else { - newProp.setDomainVClassURI(op.getDomainVClassURI()); - } - Resource rangeRes = qsoln.getResource("range"); - if (rangeRes != null) { - newProp.setRangeVClassURI(rangeRes.getURI()); - } else { - newProp.setRangeVClassURI(op.getRangeVClassURI()); - } - Resource groupRes = qsoln.getResource("group"); - if (groupRes != null) { - newProp.setGroupURI(groupRes.getURI()); - } else { - newProp.setGroupURI(op.getURI()); - } - Literal labelLit = qsoln.getLiteral("label"); - if (labelLit != null) { - newProp.setDomainPublic(labelLit.getLexicalForm()); - } else { - newProp.setDomainPublic(op.getDomainPublic()); - } - Literal customFormLit = qsoln.getLiteral("customForm"); - if (customFormLit != null) { - newProp.setCustomEntryForm(customFormLit.getLexicalForm()); - } else { - newProp.setCustomEntryForm(op.getCustomEntryForm()); - } - additionalProps.add(newProp); - } - } finally { - qe.close(); - } - } + for (ObjectProperty op : propList) { + propList.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union)); + } + return additionalProps; } private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) { + if (subject == null) { + return true; + } for (VClass vclass : subject.getVClasses()) { if ((vclass.getURI() != null) && ((vclass.getURI().equals(domainRes.getURI()) || diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index 95b4a80b5..50ab7a098 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -453,13 +453,14 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { String objectKey = vreq.getParameter("objectKey"); statementDisplay.put(objectKey, objectUri); + ObjectProperty predicate = new ObjectProperty(); + predicate.setURI(predicateUri); + //Using object property statement template model here ObjectPropertyStatementTemplateModel osm = new ObjectPropertyStatementTemplateModel( subjectUri, - predicateUri, + predicate, objectKey, - null, - null, statementDisplay, null, vreq); ReadOnlyBeansWrapper wrapper = new ReadOnlyBeansWrapper(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java index 0c4b09e72..f35e0d17d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java @@ -117,7 +117,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel { RequestActionConstants.SOME_URI); AddObjectPropertyStatement aops = new AddObjectPropertyStatement( vreq.getJenaOntModel(), individual.getURI(), - RequestActionConstants.SOME_URI, + RequestActionConstants.SOME_PREDICATE, RequestActionConstants.SOME_URI); return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java index 047854a73..5dcbce7ea 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/CollatedObjectPropertyTemplateModel.java @@ -18,6 +18,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; @@ -58,7 +59,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM postprocess(statementData); /* Collate the data */ - subclasses = collate(subjectUri, propertyUri, statementData, editing); + subclasses = collate(subjectUri, op, statementData, editing); for (SubclassTemplateModel subclass : subclasses) { List list = subclass.getStatements(); @@ -188,7 +189,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM } // Collate the statements by subclass. - private List collate(String subjectUri, String propertyUri, + private List collate(String subjectUri, ObjectProperty property, List> statementData, boolean editing) { String objectKey = getObjectKey(); @@ -218,7 +219,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM } listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri, - propertyUri, domainUri, rangeUri, objectKey, map, getTemplateName(), vreq)); + property, objectKey, map, getTemplateName(), vreq)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java index a7209741a..87a17167d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyStatementTemplateModel.java @@ -13,12 +13,14 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPr import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.RdfLiteralHash; + public class DataPropertyStatementTemplateModel extends PropertyStatementTemplateModel { private static final Log log = LogFactory.getLog(DataPropertyStatementTemplateModel.class); @@ -28,9 +30,10 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat private final String templateName; //Extended to include vitro request to check for special parameters - public DataPropertyStatementTemplateModel(String subjectUri, String propertyUri, Literal literal, + public DataPropertyStatementTemplateModel(String subjectUri, Property property, Literal literal, String templateName, VitroRequest vreq) { - super(subjectUri, propertyUri, vreq); + + super(subjectUri, property, vreq); this.literalValue = literal; this.templateName = templateName; @@ -50,7 +53,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri, + "predicateUri", property.getURI(), "datapropKey", makeHash(dps), "cmd", "delete"); @@ -63,7 +66,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat private String makeEditUrl() { // vitro:moniker is deprecated. We display existing data values so editors can // move them to other properties and delete, but don't allow editing. - if ( propertyUri.equals(VitroVocabulary.MONIKER) ) { + if ( VitroVocabulary.MONIKER.equals(property.getURI()) ) { return ""; } @@ -76,7 +79,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri, + "predicateUri", property.getURI(), "datapropKey", makeHash(dps)); if ( deleteUrl.isEmpty() ) { @@ -89,7 +92,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat } private DataPropertyStatement makeStatement() { - DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, propertyUri, literalValue.getLexicalForm()); + DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, property.getURI(), literalValue.getLexicalForm()); // Language and datatype are needed to get the correct hash value dps.setLanguage(literalValue.getLanguage()); dps.setDatatypeURI(literalValue.getDatatypeURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java index f5036463c..49c4c4d60 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/DataPropertyTemplateModel.java @@ -91,7 +91,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel { DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao(); List values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp, queryString, constructQueries); for (Literal value : values) { - statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, getTemplateName(), vreq)); + statements.add(new DataPropertyStatementTemplateModel(subjectUri, dp, value, getTemplateName(), vreq)); } } else { log.debug("Data property " + getUri() + " is unpopulated."); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java index 87682ba6b..f87635b5e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java @@ -8,6 +8,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; /** @@ -73,22 +74,22 @@ public class EditLinkSuppressor { /** * Should we suppress the Edit link on this property? */ - public boolean isEditLinkSuppressed(String propertyUri) { - if (propertyUri == null) { + public boolean isEditLinkSuppressed(Property property) { + if (property == null || property.getURI() == null) { log.error("Suppressing the edit link on a null property."); return true; } - return suppressEditLinksForThese.contains(propertyUri); + return suppressEditLinksForThese.contains(property.getURI()); } /** * Should we suppress the Delete link on this property? */ - public boolean isDeleteLinkSuppressed(String propertyUri) { - if (propertyUri == null) { + public boolean isDeleteLinkSuppressed(Property property) { + if (property == null || property.getURI() == null) { log.error("Suppressing the delete link on a null property."); return true; } - return suppressDeleteLinksForThese.contains(propertyUri); + return suppressDeleteLinksForThese.contains(property.getURI()); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/NameStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/NameStatementTemplateModel.java index b8a752dc4..cd30bdf40 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/NameStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/NameStatementTemplateModel.java @@ -14,6 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; @@ -37,7 +38,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel { private final String editUrl; NameStatementTemplateModel(String subjectUri, VitroRequest vreq) { - super(subjectUri, VitroVocabulary.LABEL, vreq); + super(subjectUri, new Property(VitroVocabulary.LABEL), vreq); // NIHVIVO-2466 Use the same methods to get the label that are used elsewhere in the // application, to guarantee consistent results for individuals with multiple labels @@ -69,7 +70,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel { ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri, + "predicateUri", property.getURI(), "datapropKey", makeHash(dps), "deleteProhibited", "prohibited"); @@ -80,7 +81,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel { private DataPropertyStatement makeStatement(Literal literalValue) { DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, - propertyUri, literalValue.getLexicalForm()); + property.getURI(), literalValue.getLexicalForm()); // Language and datatype are needed to get the correct hash value dps.setLanguage(literalValue.getLanguage()); dps.setDatatypeURI(literalValue.getDatatypeURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java index ae7e145d5..757fab213 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java @@ -13,8 +13,10 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; @@ -31,14 +33,9 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl private final String editUrl; private final String deleteUrl; - public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String rangeUri, String objectKey, + public ObjectPropertyStatementTemplateModel(String subjectUri, ObjectProperty predicate, String objectKey, Map data, String templateName, VitroRequest vreq) { - this (subjectUri, propertyUri, null, rangeUri, objectKey, data, templateName, vreq); - } - - public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String domainUri, String rangeUri, String objectKey, - Map data, String templateName, VitroRequest vreq) { - super(subjectUri, propertyUri, vreq); + super(subjectUri, predicate, vreq); this.data = Collections.unmodifiableMap(new HashMap(data)); this.objectUri = data.get(objectKey); @@ -46,33 +43,34 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl //to keep track of later this.objectKey = objectKey; - ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri); + ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, property.getURI(), objectUri); + ops.setProperty(predicate); // Do delete url first, since it is used in building edit url this.deleteUrl = makeDeleteUrl(); - this.editUrl = makeEditUrl(ops, domainUri, rangeUri); + this.editUrl = makeEditUrl(ops); } private String makeDeleteUrl() { // Is the delete link suppressed for this property? - if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(propertyUri)) { + if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(property)) { return ""; } // Determine whether the statement can be deleted RequestedAction action = new DropObjectPropertyStatement( - vreq.getJenaOntModel(), subjectUri, propertyUri, objectUri); + vreq.getJenaOntModel(), subjectUri, property, objectUri); if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) { return ""; } - if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) { + if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) { return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete"); } ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri, + "predicateUri", property.getURI(), "objectUri", objectUri, "cmd", "delete", "objectKey", objectKey); @@ -95,9 +93,9 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl return UrlBuilder.getUrl(EDIT_PATH, params); } - private String makeEditUrl(ObjectPropertyStatement ops, String domainUri, String rangeUri) { + private String makeEditUrl(ObjectPropertyStatement ops) { // Is the edit link suppressed for this property? - if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) { + if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(property)) { return ""; } @@ -107,24 +105,24 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl return ""; } - if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) { + if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) { return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit"); } ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri, + "predicateUri", property.getURI(), "objectUri", objectUri); if ( deleteUrl.isEmpty() ) { params.put("deleteProhibited", "prohibited"); } - if (domainUri != null) { - params.put("domainUri", rangeUri); + if (ops.getProperty()!= null && ops.getProperty().getDomainVClassURI() != null) { + params.put("domainUri", ops.getProperty().getDomainVClassURI()); } - if (rangeUri != null) { - params.put("rangeUri", rangeUri); + if (ops.getProperty()!= null && ops.getProperty().getRangeVClassURI() != null) { + params.put("rangeUri", ops.getProperty().getRangeVClassURI()); } params.putAll(UrlBuilder.getModelParams(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 99da9d493..2edc5a1b3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -116,7 +116,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel // Determine whether a new statement can be added RequestedAction action = new AddObjectPropertyStatement( - vreq.getJenaOntModel(), subjectUri, propertyUri, + vreq.getJenaOntModel(), subjectUri, property, RequestActionConstants.SOME_URI); if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) { return; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyStatementTemplateModel.java index 1dfc9d2db..6074a7007 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyStatementTemplateModel.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; @@ -10,12 +11,12 @@ public abstract class PropertyStatementTemplateModel extends BaseTemplateModel { protected final VitroRequest vreq; protected final String subjectUri; - protected final String propertyUri; + protected final Property property; - PropertyStatementTemplateModel(String subjectUri, String propertyUri, VitroRequest vreq) { + PropertyStatementTemplateModel(String subjectUri, Property property, VitroRequest vreq) { this.vreq = vreq; this.subjectUri = subjectUri; - this.propertyUri = propertyUri; + this.property = property; } /* Template properties */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java index 14a4db56b..2815cdc7e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java @@ -28,6 +28,7 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { protected final VitroRequest vreq; protected final String subjectUri; + protected final Property property; protected final String propertyUri; protected String domainUri; protected String rangeUri; @@ -41,6 +42,7 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq) { this.vreq = vreq; subjectUri = subject.getURI(); + this.property = property; propertyUri = property.getURI(); localName = property.getLocalName(); log.debug("Local name for property " + propertyUri + ": " + localName); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java index c6be5211f..f4295118f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/UncollatedObjectPropertyTemplateModel.java @@ -41,7 +41,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat String objectKey = getObjectKey(); for (Map map : statementData) { statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, - propertyUri, rangeUri, objectKey, map, getTemplateName(), vreq)); + op, objectKey, map, getTemplateName(), vreq)); } postprocessStatementList(statements); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java index 08da1960d..9459e6ca5 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java @@ -42,6 +42,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObject import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class SelfEditingPolicyTest extends AbstractTestClass { @@ -55,8 +56,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass { private static final String UNSAFE_RESOURCE = UNSAFE_NS + "otherIndividual99999"; - private static final String SAFE_PREDICATE = SAFE_NS + "hasHairStyle"; - private static final String UNSAFE_PREDICATE = UNSAFE_NS + "hasSuperPowers"; + private static final Property SAFE_PREDICATE = new Property(SAFE_NS + "hasHairStyle"); + private static final Property UNSAFE_PREDICATE = new Property(UNSAFE_NS + "hasSuperPowers"); private ServletContextStub ctx; @@ -95,19 +96,19 @@ public class SelfEditingPolicyTest extends AbstractTestClass { PropertyRestrictionPolicyHelper.setBean(ctx, prph); whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, - "http://mannlib.cornell.edu/bad#prp234", SAFE_RESOURCE); + new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, - "http://mannlib.cornell.edu/bad#prp234", SELFEDITOR_URI); + new Property("http://mannlib.cornell.edu/bad#prp234"), SELFEDITOR_URI); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, - "http://mannlib.cornell.edu/bad#prp999", SAFE_RESOURCE); + new Property("http://mannlib.cornell.edu/bad#prp999"), SAFE_RESOURCE); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, - "http://mannlib.cornell.edu/bad#prp999", SELFEDITOR_URI); + new Property("http://mannlib.cornell.edu/bad#prp999"), SELFEDITOR_URI); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, @@ -132,11 +133,11 @@ public class SelfEditingPolicyTest extends AbstractTestClass { assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI, - SAFE_PREDICATE); + SAFE_PREDICATE.getURI()); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI, - UNSAFE_PREDICATE); + UNSAFE_PREDICATE.getURI()); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); } @@ -218,16 +219,16 @@ public class SelfEditingPolicyTest extends AbstractTestClass { // @Test public void testVisitIdentifierBundleEditDataPropStmt() { - whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE.getURI()); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); - whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE.getURI()); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); - whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE.getURI()); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); - whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI()); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); } @@ -287,7 +288,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass { public void twoSEIsFindDataPropertySubject() { setUpTwoSEIs(); - whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE.getURI()); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); } @@ -295,7 +296,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass { public void twoSEIsDontFindInDataProperty() { setUpTwoSEIs(); - whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE); + whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI()); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java index 0e0ebfef6..aa5aa6ac0 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java @@ -32,6 +32,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPr import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class SelfEditingPolicy_2_Test extends AbstractTestClass { @@ -123,7 +124,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass { @Test public void nullIdentifierBundle() { AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement( - ontModel, SELFEDITOR_URI, SAFE_PREDICATE, SAFE_RESOURCE); + ontModel, SELFEDITOR_URI, new Property(SAFE_PREDICATE), SAFE_RESOURCE); PolicyDecision dec = policy.isAuthorized(null, whatToAuth); Assert.assertNotNull(dec); Assert.assertEquals(Authorization.INCONCLUSIVE, dec.getAuthorized()); @@ -277,7 +278,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass { private void assertAddObjectPropStmt(String uriOfSub, String uriOfPred, String uriOfObj, Authorization expectedAuthorization) { AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement( - ontModel, uriOfSub, uriOfPred, uriOfObj); + ontModel, uriOfSub, new Property(uriOfPred), uriOfObj); PolicyDecision dec = policy.isAuthorized(ids, whatToAuth); log.debug(dec); Assert.assertNotNull(dec); @@ -291,7 +292,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass { private void assertEditObjPropStmt(String uriOfSub, String uriOfPred, String uriOfObj, Authorization expectedAuthorization) { EditObjectPropertyStatement whatToAuth = new EditObjectPropertyStatement( - ontModel, uriOfSub, uriOfPred, uriOfObj); + ontModel, uriOfSub, new Property(uriOfPred), uriOfObj); PolicyDecision dec = policy.isAuthorized(ids, whatToAuth); log.debug(dec); Assert.assertNotNull(dec); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java index a00f136a2..030139d8c 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java @@ -18,7 +18,6 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.log4j.Level; import org.junit.Before; import org.junit.Test; @@ -27,6 +26,8 @@ import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.sdb.util.Pair; +import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; @@ -58,17 +59,25 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { // setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG); } + private void mapPut(String predicateURI, RoleLevel roleLevel, + Map>, RoleLevel> map) { + map.put(new Pair>( + OWL.Thing.getURI(), new Pair( + predicateURI, OWL.Thing.getURI())), roleLevel); + } + @Before public void createTheBean() { - Map displayLevels = new HashMap(); - displayLevels.put("http://predicates#display_self", SELF); - displayLevels.put("http://predicates#display_curator", CURATOR); - displayLevels.put("http://predicates#display_hidden", NOBODY); + Map>, RoleLevel> displayLevels = + new HashMap>, RoleLevel>(); + mapPut("http://predicates#display_curator", CURATOR, displayLevels); + mapPut("http://predicates#display_hidden", NOBODY, displayLevels); - Map modifyLevels = new HashMap(); - modifyLevels.put("http://predicates#modify_self", SELF); - modifyLevels.put("http://predicates#modify_curator", CURATOR); - modifyLevels.put("http://predicates#modify_hidden", NOBODY); + Map>, RoleLevel> modifyLevels = + new HashMap>, RoleLevel>(); + mapPut("http://predicates#modify_self", SELF, modifyLevels); + mapPut("http://predicates#modify_curator", CURATOR, modifyLevels); + mapPut("http://predicates#modify_hidden", NOBODY, modifyLevels); bean = new PropertyRestrictionPolicyHelper( Arrays.asList(PROHIBITED_NAMESPACES), @@ -125,68 +134,75 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { @Test public void displayPredicateNoRestriction() { assertEquals("displayPredicate: open", true, - bean.canDisplayPredicate("http://predicates#open", PUBLIC)); + bean.canDisplayPredicate(createVitroProperty( + "http://predicates#open"), PUBLIC)); } @Test public void displayPredicateRestrictionLower() { assertEquals("displayPredicate: lower restriction", true, - bean.canDisplayPredicate("http://predicates#display_self", - CURATOR)); + bean.canDisplayPredicate(createVitroProperty( + "http://predicates#display_self"), CURATOR)); } @Test public void displayPredicateRestrictionEqual() { assertEquals("displayPredicate: equal restriction", true, - bean.canDisplayPredicate("http://predicates#display_curator", - CURATOR)); + bean.canDisplayPredicate(createVitroProperty( + "http://predicates#display_curator"), CURATOR)); } @Test public void displayPredicateRestrictionHigher() { assertEquals("displayPredicate: higher restriction", false, - bean.canDisplayPredicate("http://predicates#display_hidden", - CURATOR)); + bean.canDisplayPredicate(createVitroProperty( + "http://predicates#display_hidden"), CURATOR)); } @Test public void modifyPredicateNoRestriction() { assertEquals("modifyPredicate: open", true, - bean.canModifyPredicate("http://predicates#open", PUBLIC)); + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + "http://predicates#open"), PUBLIC)); } @Test public void modifyPredicateRestrictionLower() { assertEquals("modifyPredicate: lower restriction", true, - bean.canModifyPredicate("http://predicates#modify_self", + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + "http://predicates#modify_self"), CURATOR)); } @Test public void modifyPredicateRestrictionEqual() { assertEquals("modifyPredicate: equal restriction", true, - bean.canModifyPredicate("http://predicates#modify_curator", + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + "http://predicates#modify_curator"), CURATOR)); } @Test public void modifyPredicateRestrictionHigher() { assertEquals("modifyPredicate: higher restriction", false, - bean.canModifyPredicate("http://predicates#modify_hidden", + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + "http://predicates#modify_hidden"), CURATOR)); } @Test public void modifyPredicateProhibitedNamespace() { assertEquals("modifyPredicate: prohibited namespace", false, - bean.canModifyPredicate(PROHIBITED_NAMESPACES[0] + "randoom", + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + PROHIBITED_NAMESPACES[0] + "randoom"), DB_ADMIN)); } @Test public void modifyPredicatePermittedException() { assertEquals("modifyPredicate: permitted exception", true, - bean.canModifyPredicate(PERMITTED_EXCEPTIONS[0], DB_ADMIN)); + bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property( + PERMITTED_EXCEPTIONS[0]), DB_ADMIN)); } // ---------------------------------------------------------------------- @@ -195,9 +211,10 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { @Test public void buildDisplayThresholds() { - Map expectedMap = new HashMap(); - expectedMap.put("http://thresholds#display_public", PUBLIC); - expectedMap.put("http://thresholds#display_hidden", NOBODY); + Map>, BaseResourceBean.RoleLevel> expectedMap = + new HashMap>, BaseResourceBean.RoleLevel>(); + mapPut("http://thresholds#display_public", PUBLIC, expectedMap); + mapPut("http://thresholds#display_hidden", NOBODY, expectedMap); Map actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD); assertEquals("display thresholds", expectedMap, actualMap); @@ -205,9 +222,10 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { @Test public void buildModifyThresholds() { - Map expectedMap = new HashMap(); - expectedMap.put("http://thresholds#modify_editor", EDITOR); - expectedMap.put("http://thresholds#modify_curator", CURATOR); + Map>, BaseResourceBean.RoleLevel> expectedMap = + new HashMap>, BaseResourceBean.RoleLevel>(); + mapPut("http://thresholds#modify_editor", EDITOR, expectedMap); + mapPut("http://thresholds#modify_curator", CURATOR, expectedMap); Map actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD); assertEquals("modify thresholds", expectedMap, actualMap); @@ -244,4 +262,9 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { model.add(subject, property, object); } } + + private edu.cornell.mannlib.vitro.webapp.beans.Property createVitroProperty( + String propertyURI) { + return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI); + } } diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java index 365ef82d0..bc441e5ad 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java @@ -10,6 +10,8 @@ import java.util.Set; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.sdb.util.Pair; +import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; @@ -43,10 +45,15 @@ public class PropertyRestrictionPolicyHelperStub extends namespaceSet.addAll(Arrays.asList(restrictedNamespaces)); } - Map thresholdMap = new HashMap(); + Map>, RoleLevel> thresholdMap = new HashMap< + Pair>, RoleLevel>(); if (restrictedProperties != null) { for (String prop : restrictedProperties) { - thresholdMap.put(prop, RoleLevel.NOBODY); + thresholdMap.put( + new Pair>( + OWL.Thing.getURI(), new Pair( + prop, OWL.Thing.getURI())), + RoleLevel.NOBODY); } } @@ -57,8 +64,8 @@ public class PropertyRestrictionPolicyHelperStub extends private PropertyRestrictionPolicyHelperStub( Set modifyRestrictedNamespaces, Set modifyPermittedExceptions, - Map displayThresholds, - Map modifyThresholds) { + Map>, RoleLevel> displayThresholds, + Map>, RoleLevel> modifyThresholds) { super(modifyRestrictedNamespaces, modifyPermittedExceptions, displayThresholds, modifyThresholds, ModelFactory.createDefaultModel()); } From abefa1615c6c8fa117a7e644df073fd8437ea4a3 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 3 Sep 2013 09:13:19 -0400 Subject: [PATCH 15/44] removing debug log message --- .../webapp/utils/ApplicationConfigurationOntologyUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 11cd8b5af..22849fb86 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -120,7 +120,6 @@ public class ApplicationConfigurationOntologyUtils { } Resource updateLevelRes = qsoln.getResource("updateLevel"); if (updateLevelRes != null) { - log.info("updateLevel!"); newProp.setProhibitedFromUpdateBelowRoleLevel( BaseResourceBean.RoleLevel.getRoleByUri( updateLevelRes.getURI())); From 355b9e2070b284b77d6223477215e861f138ec0e Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 3 Sep 2013 11:24:05 -0400 Subject: [PATCH 16/44] edit permissions for qualified properties and VIVO-277 --- .../bean/PropertyRestrictionPolicyHelper.java | 78 +++++++++---------- .../dao/jena/ObjectPropertyDaoJena.java | 8 +- ...ApplicationConfigurationOntologyUtils.java | 35 ++++++--- .../individual/EditLinkSuppressor.java | 6 +- .../ObjectPropertyTemplateModel.java | 2 +- 5 files changed, 74 insertions(+), 55 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java index c64006f31..5d94cde73 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -149,12 +149,9 @@ public class PropertyRestrictionPolicyHelper { if (property.getURI() == null) { return RoleLevel.NOBODY; } - String domainURI = (false && property.getDomainVClassURI() == null) - ? OWL.Thing.getURI() : property.getDomainVClassURI(); - String rangeURI = (false && property.getRangeVClassURI() == null) - ? OWL.Thing.getURI() : property.getRangeVClassURI(); RoleLevel roleLevel = getRoleLevelFromMap( - domainURI, property.getURI(), rangeURI, thresholdMap); + property.getDomainVClassURI(), property.getURI(), + property.getRangeVClassURI(), thresholdMap); if (roleLevel == null) { roleLevel = getRoleLevelFromMap( OWL.Thing.getURI(), property.getURI(), OWL.Thing.getURI(), @@ -166,7 +163,8 @@ public class PropertyRestrictionPolicyHelper { private RoleLevel getRoleLevelFromMap(String domainURI, String predicateURI, String rangeURI, - Map>, RoleLevel> map) { + Map>, + RoleLevel> map) { return map.get( new Pair>( domainURI, new Pair( @@ -184,40 +182,42 @@ public class PropertyRestrictionPolicyHelper { com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri); StmtIterator stmts = model.listStatements((Resource) null, property, (Resource) null); - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - Resource subject = stmt.getSubject(); - RDFNode objectNode = stmt.getObject(); - if ((subject == null) || (!(objectNode instanceof Resource))) { - continue; - } - Resource object = (Resource) objectNode; - RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); - map.put(new Pair>( - OWL.Thing.getURI(), new Pair( - subject.getURI(), OWL.Thing.getURI())), role); - ObjectProperty op = new ObjectProperty(); - op.setURI(subject.getURI()); - List fauxOps = ApplicationConfigurationOntologyUtils - .getAdditionalFauxSubproperties(op, null, model, model); - for (ObjectProperty faux : fauxOps) { - role = null; - if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT - .equals(propertyUri)) { - role = faux.getProhibitedFromUpdateBelowRoleLevel(); - } else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT - .equals(propertyUri)) { - role = faux.getHiddenFromDisplayBelowRoleLevel(); - } - if (role != null) { - log.info("Putting D:" + faux.getDomainVClassURI() + " P:" + subject.getURI() + " R:" + faux.getRangeVClassURI() + " ==> L:" + role); - map.put(new Pair>( - faux.getDomainVClassURI(), new Pair( - subject.getURI(), faux.getRangeVClassURI())), role); - } - } + try { + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + Resource subject = stmt.getSubject(); + RDFNode objectNode = stmt.getObject(); + if ((subject == null) || (!(objectNode instanceof Resource))) { + continue; + } + Resource object = (Resource) objectNode; + RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); + map.put(new Pair>( + OWL.Thing.getURI(), new Pair( + subject.getURI(), OWL.Thing.getURI())), role); + } + } finally { + stmts.close(); } - stmts.close(); + List fauxOps = ApplicationConfigurationOntologyUtils + .getAdditionalFauxSubproperties(null, null, model, model); + for (ObjectProperty faux : fauxOps) { + RoleLevel role = null; + if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT + .equals(propertyUri)) { + role = faux.getProhibitedFromUpdateBelowRoleLevel(); + } else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT + .equals(propertyUri)) { + role = faux.getHiddenFromDisplayBelowRoleLevel(); + } + if (role != null) { + log.debug("Putting D:" + faux.getDomainVClassURI() + " P:" + faux.getURI() + " R:" + faux.getRangeVClassURI() + " ==> L:" + role); + map.put(new Pair>( + faux.getDomainVClassURI(), new Pair( + faux.getURI(), faux.getRangeVClassURI())), role); + } + } + } finally { model.leaveCriticalSection(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 0079e8737..0f0be8bf4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -297,7 +297,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT ?range ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + + "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel WHERE { \n" + " ?context config:configContextFor <" + propertyURI + "> . \n"; if (domainURI != null) { propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n"; @@ -310,6 +310,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp propQuery += " ?context config:hasConfiguration ?configuration . \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration vitro:displayRankAnnot ?displayRank } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + @@ -325,6 +326,11 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp if (groupRes != null) { op.setGroupURI(groupRes.getURI()); } + Literal displayRankLit = qsoln.getLiteral("displayRank"); + if(displayRankLit != null) { + op.setDomainDisplayTier( + Integer.parseInt(displayRankLit.getLexicalForm())); + } Resource displayLevelRes = qsoln.getResource("displayLevel"); if (displayLevelRes != null) { op.setHiddenFromDisplayBelowRoleLevel( diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 22849fb86..5ad1fcec2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -10,6 +10,8 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -30,6 +32,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; public class ApplicationConfigurationOntologyUtils { @@ -42,16 +46,16 @@ public class ApplicationConfigurationOntologyUtils { return getAdditionalFauxSubpropertiesForList(propList, subject, displayModel, tboxModel); } - public static List getAdditionalFauxSubproperties(ObjectProperty op, + public static List getAdditionalFauxSubproperties(ObjectProperty prop, Individual subject, Model tboxModel, Model union) { List additionalProps = new ArrayList(); - String propQuery = "PREFIX rdfs: \n" + + String queryStr = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + + "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayLevel ?updateLevel ?property WHERE { \n" + // " ?p rdfs:subPropertyOf ?property . \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + @@ -64,19 +68,30 @@ public class ApplicationConfigurationOntologyUtils { " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + "}"; - - log.debug("Checking " + op.getURI() + " for additional properties"); - String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">"); + if(prop != null) { + log.debug("Checking " + prop.getURI() + " for additional properties"); + queryStr = queryStr.replaceAll("\\?property", "<" + prop.getURI() + ">"); + } log.debug(queryStr); Query q = QueryFactory.create(queryStr); QueryExecution qe = QueryExecutionFactory.create(q, union); try { ResultSet rs = qe.execSelect(); while (rs.hasNext()) { - ObjectProperty newProp = new ObjectProperty(); - newProp.setURI(op.getURI()); QuerySolution qsoln = rs.nextSolution(); log.debug(qsoln); + ObjectProperty op = null; + if (prop == null) { + String opURI = qsoln.getResource("property").getURI(); + OntModel tboxOntModel = ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, tboxModel); + WebappDaoFactory wadf = new WebappDaoFactoryJena(tboxOntModel); + op = wadf.getObjectPropertyDao().getObjectPropertyByURI(opURI); + } else { + op = prop; + } + ObjectProperty newProp = new ObjectProperty(); + newProp.setURI(op.getURI()); Resource domainRes = qsoln.getResource("domain"); if(domainRes != null) { if(!appropriateDomain( @@ -85,9 +100,7 @@ public class ApplicationConfigurationOntologyUtils { } else { newProp.setDomainVClassURI(domainRes.getURI()); } - } else { - newProp.setDomainVClassURI(op.getDomainVClassURI()); - } + } Resource rangeRes = qsoln.getResource("range"); if (rangeRes != null) { newProp.setRangeVClassURI(rangeRes.getURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java index f87635b5e..773d913a5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java @@ -63,12 +63,12 @@ public class EditLinkSuppressor { /** * Should we suppress the Add link on this property? */ - public boolean isAddLinkSuppressed(String propertyUri) { - if (propertyUri == null) { + public boolean isAddLinkSuppressed(Property property) { + if (property == null) { log.error("Suppressing the add link on a null property."); return true; } - return suppressAddLinksForThese.contains(propertyUri); + return suppressAddLinksForThese.contains(property.getURI()); } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 2edc5a1b3..9392de857 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -110,7 +110,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel protected void setAddUrl(Property property) { // Is the add link suppressed for this property? - if (new EditLinkSuppressor(vreq).isAddLinkSuppressed(propertyUri)) { + if (new EditLinkSuppressor(vreq).isAddLinkSuppressed(property)) { return; } From 3204db0be4d9d6a626768d3dc2969a76df158322 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 3 Sep 2013 11:50:22 -0400 Subject: [PATCH 17/44] fixing bugs in ApplicationConfigurationOntologyUtils.java --- .../webapp/utils/ApplicationConfigurationOntologyUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 5ad1fcec2..d8f561a9b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -70,7 +70,7 @@ public class ApplicationConfigurationOntologyUtils { if(prop != null) { log.debug("Checking " + prop.getURI() + " for additional properties"); - queryStr = queryStr.replaceAll("\\?property", "<" + prop.getURI() + ">"); + queryStr = queryStr.replaceAll("For \\?property", "For <" + prop.getURI() + ">"); } log.debug(queryStr); Query q = QueryFactory.create(queryStr); @@ -156,7 +156,7 @@ public class ApplicationConfigurationOntologyUtils { Model union = ModelFactory.createUnion(displayModel, tboxModel); for (ObjectProperty op : propList) { - propList.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union)); + additionalProps.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union)); } return additionalProps; From e75b424c81bb29e4314a9eeb87bd564c716285d0 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 4 Sep 2013 09:59:59 -0400 Subject: [PATCH 18/44] removing EditLinkSuppressor --- .../mannlib/vitro/webapp/beans/Property.java | 30 ++++++ .../vitro/webapp/dao/VitroVocabulary.java | 4 + .../filtering/ObjectPropertyFiltering.java | 30 ++++++ .../vitro/webapp/dao/jena/JenaBaseDaoCon.java | 3 + .../dao/jena/ObjectPropertyDaoJena.java | 25 ++++- ...ApplicationConfigurationOntologyUtils.java | 26 ++++- .../individual/EditLinkSuppressor.java | 95 ------------------- .../ObjectPropertyStatementTemplateModel.java | 4 +- .../ObjectPropertyTemplateModel.java | 2 +- 9 files changed, 118 insertions(+), 101 deletions(-) delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Property.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Property.java index e63d0858e..3eac69b34 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Property.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/Property.java @@ -17,6 +17,9 @@ public class Property extends BaseResourceBean { private final boolean subjectSide = true; // only relevant to ObjectProperty private String domainVClassURI = null; private String rangeVClassURI = null; + private boolean editLinkSuppressed = false; + private boolean addLinkSuppressed = false; + private boolean deleteLinkSuppressed = false; public Property() { this.groupURI = null; @@ -69,6 +72,33 @@ public class Property extends BaseResourceBean { return subjectSide; } + public boolean isEditLinkSuppressed() { + return editLinkSuppressed; + } + + public boolean isAddLinkSuppressed() { + return addLinkSuppressed; + } + + public boolean isDeleteLinkSuppressed() { + return deleteLinkSuppressed; + } + + public void setEditLinkSuppressed(boolean editLinkSuppressed) { + this.editLinkSuppressed = editLinkSuppressed; + } + + public void setAddLinkSuppressed(boolean addLinkSuppressed) { + if (this.addLinkSuppressed) { + throw new RuntimeException("addLinkSuppressed already true"); + } + this.addLinkSuppressed = addLinkSuppressed; + } + + public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) { + this.deleteLinkSuppressed = deleteLinkSuppressed; + } + /** * Sorts Property objects, by property rank, then alphanumeric. * @author bdc34 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java index ae21af42d..a24f26c3e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java @@ -7,6 +7,7 @@ public class VitroVocabulary { public static final String vitroURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#"; + public static final String configURI= "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#"; public static final String VITRO_AUTH = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#"; public static final String VITRO_PUBLIC = "http://vitro.mannlib.cornell.edu/ns/vitro/public#"; @@ -95,6 +96,9 @@ public class VitroVocabulary { public static final String PROPERTY_CUSTOM_LIST_VIEW_ANNOT = vitroURI + "customListViewAnnot"; public static final String PROPERTY_SELECTFROMEXISTINGANNOT = vitroURI+"selectFromExistingAnnot"; public static final String PROPERTY_OFFERCREATENEWOPTIONANNOT = vitroURI+"offerCreateNewOptionAnnot"; + public static final String PROPERTY_EDITLINKSUPPRESSED = configURI + "editLinkSuppressed"; + public static final String PROPERTY_ADDLINKSUPPRESSED = configURI + "addLinkSuppressed"; + public static final String PROPERTY_DELETELINKSUPPRESSED = configURI + "deleteLinkSuppressed"; public static final String PROPERTY_INPROPERTYGROUPANNOT = vitroURI+"inPropertyGroupAnnot"; public static final String PROPERTYGROUP = vitroURI + "PropertyGroup"; public static final String MASKS_PROPERTY = vitroURI + "masksProperty"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyFiltering.java index bf711c970..0706ba42e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyFiltering.java @@ -523,6 +523,36 @@ public class ObjectPropertyFiltering extends ObjectProperty { public void setCollateBySubclass(boolean collate) { innerObjectProperty.setCollateBySubclass(collate); } + + @Override + public boolean isEditLinkSuppressed() { + return innerObjectProperty.isEditLinkSuppressed(); + } + + @Override + public boolean isAddLinkSuppressed() { + return innerObjectProperty.isAddLinkSuppressed(); + } + + @Override + public boolean isDeleteLinkSuppressed() { + return innerObjectProperty.isDeleteLinkSuppressed(); + } + + @Override + public void setEditLinkSuppressed(boolean editLinkSuppressed) { + innerObjectProperty.setEditLinkSuppressed(editLinkSuppressed); + } + + @Override + public void setAddLinkSuppressed(boolean addLinkSuppressed) { + innerObjectProperty.setAddLinkSuppressed(addLinkSuppressed); + } + + @Override + public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) { + innerObjectProperty.setDeleteLinkSuppressed(deleteLinkSuppressed); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java index c315b4856..f8eb9e0cf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java @@ -75,6 +75,9 @@ public class JenaBaseDaoCon { protected AnnotationProperty PROPERTY_INPROPERTYGROUPANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT); protected AnnotationProperty PROPERTY_COLLATEBYSUBCLASSANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_COLLATEBYSUBCLASSANNOT); protected AnnotationProperty PROPERTY_STUBOBJECTPROPERTYANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_STUBOBJECTPROPERTYANNOT); + protected AnnotationProperty PROPERTY_EDITLINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_EDITLINKSUPPRESSED); + protected AnnotationProperty PROPERTY_ADDLINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_ADDLINKSUPPRESSED); + protected AnnotationProperty PROPERTY_DELETELINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_DELETELINKSUPPRESSED); protected OntClass PROPERTYGROUP = _constModel.createClass(VitroVocabulary.PROPERTYGROUP); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 0f0be8bf4..5e8dd058f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -37,6 +37,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.sparql.expr.NodeValue; import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; @@ -224,6 +225,13 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp Boolean collateBySubclass = getPropertyBooleanValue(op,PROPERTY_COLLATEBYSUBCLASSANNOT); p.setCollateBySubclass(collateBySubclass==null ? false : collateBySubclass); + Boolean editLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_EDITLINKSUPPRESSED); + p.setEditLinkSuppressed(editLinkSuppressed == null ? false : editLinkSuppressed); + Boolean addLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_ADDLINKSUPPRESSED); + p.setAddLinkSuppressed(addLinkSuppressed == null ? false : addLinkSuppressed); + Boolean deleteLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_DELETELINKSUPPRESSED); + p.setDeleteLinkSuppressed(deleteLinkSuppressed == null ? false : deleteLinkSuppressed); + Resource groupRes = (Resource) op.getPropertyValue(PROPERTY_INPROPERTYGROUPANNOT); if (groupRes != null) { p.setGroupURI(groupRes.getURI()); @@ -297,7 +305,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel WHERE { \n" + + "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed WHERE { \n" + " ?context config:configContextFor <" + propertyURI + "> . \n"; if (domainURI != null) { propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n"; @@ -310,6 +318,9 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp propQuery += " ?context config:hasConfiguration ?configuration . \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration config:editLinkSuppressed ?editLinkSuppressed } \n" + + " OPTIONAL { ?configuration config:addLinkSuppressed ?addLinkSuppressed } \n" + + " OPTIONAL { ?configuration config:deleteLinkSuppressed ?deleteLinkSuppressed } \n" + " OPTIONAL { ?configuration vitro:displayRankAnnot ?displayRank } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + @@ -351,6 +362,18 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp if (customFormLit != null) { op.setCustomEntryForm(customFormLit.getLexicalForm()); } + Literal editLinkSuppressedLit = qsoln.getLiteral("editLinkSuppressed"); + if (editLinkSuppressedLit != null ) { + op.setEditLinkSuppressed(editLinkSuppressedLit.getBoolean()); + } + Literal addLinkSuppressedLit = qsoln.getLiteral("addLinkSuppressed"); + if (addLinkSuppressedLit != null ) { + op.setAddLinkSuppressed(addLinkSuppressedLit.getBoolean()); + } + Literal deleteLinkSuppressedLit = qsoln.getLiteral("deleteLinkSuppressed"); + if (deleteLinkSuppressedLit != null ) { + op.setDeleteLinkSuppressed(deleteLinkSuppressedLit.getBoolean()); + } } } finally { qe.close(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index d8f561a9b..281916a21 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -23,6 +23,7 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.sparql.expr.NodeValue; import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; @@ -55,7 +56,7 @@ public class ApplicationConfigurationOntologyUtils { String queryStr = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayLevel ?updateLevel ?property WHERE { \n" + + "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed ?property WHERE { \n" + // " ?p rdfs:subPropertyOf ?property . \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + @@ -63,6 +64,10 @@ public class ApplicationConfigurationOntologyUtils { " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration vitro:displayRankAnnot ?displayRank } \n" + + " OPTIONAL { ?configuration config:editLinkSuppressed ?editLinkSuppressed } \n" + + " OPTIONAL { ?configuration config:addLinkSuppressed ?addLinkSuppressed } \n" + + " OPTIONAL { ?configuration config:deleteLinkSuppressed ?deleteLinkSuppressed } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + @@ -125,6 +130,11 @@ public class ApplicationConfigurationOntologyUtils { } else { newProp.setCustomEntryForm(op.getCustomEntryForm()); } + Literal displayRankLit = qsoln.getLiteral("displayRank"); + if(displayRankLit != null) { + op.setDomainDisplayTier( + Integer.parseInt(displayRankLit.getLexicalForm())); + } Resource displayLevelRes = qsoln.getResource("displayLevel"); if (displayLevelRes != null) { newProp.setHiddenFromDisplayBelowRoleLevel( @@ -137,7 +147,19 @@ public class ApplicationConfigurationOntologyUtils { BaseResourceBean.RoleLevel.getRoleByUri( updateLevelRes.getURI())); } - additionalProps.add(newProp); + Literal editLinkSuppressedLit = qsoln.getLiteral("editLinkSuppressed"); + if (editLinkSuppressedLit != null ) { + op.setEditLinkSuppressed(editLinkSuppressedLit.getBoolean()); + } + Literal addLinkSuppressedLit = qsoln.getLiteral("addLinkSuppressed"); + if (addLinkSuppressedLit != null ) { + op.setAddLinkSuppressed(addLinkSuppressedLit.getBoolean()); + } + Literal deleteLinkSuppressedLit = qsoln.getLiteral("deleteLinkSuppressed"); + if (deleteLinkSuppressedLit != null ) { + op.setDeleteLinkSuppressed(deleteLinkSuppressedLit.getBoolean()); + } + additionalProps.add(newProp); } } finally { qe.close(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java deleted file mode 100644 index 773d913a5..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/EditLinkSuppressor.java +++ /dev/null @@ -1,95 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; - -import java.util.Arrays; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; - -/** - * Sometimes we don't want to show an Add, Edit, or Delete link for a particular - * property, no matter who the user is. - * - * TODO These are hard-coded while we wait for the Application Ontology to be - * implemented. - */ -public class EditLinkSuppressor { - private static final Log log = LogFactory.getLog(EditLinkSuppressor.class); - - private static final String CORE = "http://vivoweb.org/ontology/core#"; - private static final String PUB_TO_AUTHORSHIP = core("informationResourceInAuthorship"); - private static final String PERSON_TO_AUTHORSHIP = core("authorInAuthorship"); - private static final String AUTHORSHIP_TO_PERSON = core("linkedAuthor"); - private static final String AUTHORSHIP_TO_PUB = core("linkedInformationResource"); - private static final String INDIVIDUAL_TO_WEBPAGE = core("webpage"); - private static final String WEBPAGE_TO_INDIVIDUAL = core("webpageOf"); - private static final String HAS_RESEARCH_AREA = core("hasResearchArea"); - private static final String HAS_SUBJECT_AREA = core("hasSubjectArea"); - private static final String RESEARCH_AREA_OF = core("researchAreaOf"); - private static final String SUBJECT_AREA_FOR = core("subjectAreaFor"); - - private static String core(String localName) { - return CORE + localName; - } - - private static final List suppressAddLinksForThese = Arrays - .asList(new String[] { AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB, - WEBPAGE_TO_INDIVIDUAL }); - - private static final List suppressEditLinksForThese = Arrays - .asList(new String[] { WEBPAGE_TO_INDIVIDUAL }); - - private static final List suppressDeleteLinksForThese = Arrays - .asList(new String[] { PUB_TO_AUTHORSHIP, PERSON_TO_AUTHORSHIP, - AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB, - INDIVIDUAL_TO_WEBPAGE, WEBPAGE_TO_INDIVIDUAL, - HAS_RESEARCH_AREA, RESEARCH_AREA_OF, HAS_SUBJECT_AREA, - SUBJECT_AREA_FOR }); - - // TODO When we remove the hard-coding, vreq will allow us to find the - // application ontology model. - @SuppressWarnings("unused") - private final VitroRequest vreq; - - public EditLinkSuppressor(VitroRequest vreq) { - this.vreq = vreq; - } - - /** - * Should we suppress the Add link on this property? - */ - public boolean isAddLinkSuppressed(Property property) { - if (property == null) { - log.error("Suppressing the add link on a null property."); - return true; - } - return suppressAddLinksForThese.contains(property.getURI()); - } - - /** - * Should we suppress the Edit link on this property? - */ - public boolean isEditLinkSuppressed(Property property) { - if (property == null || property.getURI() == null) { - log.error("Suppressing the edit link on a null property."); - return true; - } - return suppressEditLinksForThese.contains(property.getURI()); - } - - /** - * Should we suppress the Delete link on this property? - */ - public boolean isDeleteLinkSuppressed(Property property) { - if (property == null || property.getURI() == null) { - log.error("Suppressing the delete link on a null property."); - return true; - } - return suppressDeleteLinksForThese.contains(property.getURI()); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java index 757fab213..c9da36ce8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyStatementTemplateModel.java @@ -53,7 +53,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl private String makeDeleteUrl() { // Is the delete link suppressed for this property? - if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(property)) { + if (property.isDeleteLinkSuppressed()) { return ""; } @@ -95,7 +95,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl private String makeEditUrl(ObjectPropertyStatement ops) { // Is the edit link suppressed for this property? - if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(property)) { + if (property.isEditLinkSuppressed()) { return ""; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 9392de857..2e8c59397 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -110,7 +110,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel protected void setAddUrl(Property property) { // Is the add link suppressed for this property? - if (new EditLinkSuppressor(vreq).isAddLinkSuppressed(property)) { + if (property.isAddLinkSuppressed()) { return; } From e3399d161d396cc4bcd2e569a295c77495f2e225 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 4 Sep 2013 11:56:17 -0400 Subject: [PATCH 19/44] display permissions for domain-qualified predicates --- .../bean/PropertyRestrictionPolicyHelper.java | 22 ++-- .../dao/ObjectPropertyStatementDao.java | 4 +- .../ObjectPropertyStatementDaoFiltering.java | 8 +- .../dao/jena/ObjectPropertyDaoJena.java | 5 +- .../jena/ObjectPropertyStatementDaoJena.java | 6 +- ...ApplicationConfigurationOntologyUtils.java | 103 +++--------------- .../ObjectPropertyTemplateModel.java | 2 +- .../dao/ObjectPropertyStatementDaoStub.java | 2 +- 8 files changed, 42 insertions(+), 110 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java index 5d94cde73..e5163efd2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -345,26 +345,26 @@ public class PropertyRestrictionPolicyHelper { * If display of a predicate is restricted, the user's role must be at least * as high as the restriction level. */ - public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { - //TODO change - String predicateUri = predicate.getURI(); - - if (predicateUri == null) { - log.debug("can't display predicate: predicateUri was null"); + public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { + if (predicate == null) { + log.debug("can't display predicate: predicate was null"); return false; } RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap); if (isAuthorized(userRole, displayThreshold)) { - log.debug("can display predicate: '" + predicateUri - + "', userRole=" + userRole + ", thresholdRole=" - + displayThreshold); + log.debug("can display predicate: '" + predicate.getURI() + "', domain=" + + predicate.getDomainVClassURI() + ", range=" + + predicate.getRangeVClassURI() + ", userRole=" + + userRole + ", thresholdRole=" + displayThreshold); return true; } - log.debug("can't display predicate: '" + predicateUri + "', userRole=" - + userRole + ", thresholdRole=" + displayThreshold); + log.debug("can't display predicate: '" + predicate.getURI() + "', domain=" + + predicate.getDomainVClassURI() + ", range=" + + predicate.getRangeVClassURI() + ", userRole=" + + userRole + ", thresholdRole=" + displayThreshold); return false; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java index 34bd23d46..7f750e7f4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java @@ -41,8 +41,8 @@ public interface ObjectPropertyStatementDao { public Map getMostSpecificTypesInClassgroupsForIndividual(String subjectUri); List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, String rangeUri, - String queryString, Set constructQueryStrings, + String subjectUri, String propertyUri, String objectKey, String domainUri, + String rangeUri, String queryString, Set constructQueryStrings, String sortDirection); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java index de7c93438..9c77892e5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java @@ -86,12 +86,13 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec @Override public List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, String rangeUri, - String query, Set queryStrings, String sortDirection) { + String subjectUri, String propertyUri, String objectKey, String domainUri, + String rangeUri, String query, Set queryStrings, String sortDirection) { List> data = innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty( - subjectUri, propertyUri, objectKey, rangeUri, query, queryStrings,sortDirection); + subjectUri, propertyUri, objectKey, domainUri, rangeUri, query, + queryStrings,sortDirection); /* Filter the data * @@ -107,6 +108,7 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec ObjectPropertyStatement statement = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri); ObjectProperty op = new ObjectProperty(); op.setURI(propertyUri); + op.setDomainVClassURI(domainUri); op.setRangeVClassURI(rangeUri); statement.setProperty(op); stmtsToData.put(statement, map); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 5e8dd058f..a899edea0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -305,7 +305,9 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp String propQuery = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed WHERE { \n" + + "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel " + + " ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" + + " WHERE { \n" + " ?context config:configContextFor <" + propertyURI + "> . \n"; if (domainURI != null) { propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n"; @@ -316,6 +318,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n"; }; propQuery += " ?context config:hasConfiguration ?configuration . \n" + + " ?configuration a config:ObjectPropertyDisplayConfig . \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" + " OPTIONAL { ?configuration config:editLinkSuppressed ?editLinkSuppressed } \n" + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index 7b754f465..9b626d22d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -270,8 +270,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec public List> getObjectPropertyStatementsForIndividualByProperty( String subjectUri, String propertyUri, - String objectKey, - String rangeUri, + String objectKey, String domainUri, String rangeUri, String queryString, Set constructQueryStrings, String sortDirection) { @@ -299,6 +298,9 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec QuerySolutionMap initialBindings = new QuerySolutionMap(); initialBindings.add("subject", ResourceFactory.createResource(subjectUri)); initialBindings.add("property", ResourceFactory.createResource(propertyUri)); + if (domainUri != null && !domainUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) { + initialBindings.add("subjectType", ResourceFactory.createResource(domainUri)); + } if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) { initialBindings.add("objectType", ResourceFactory.createResource(rangeUri)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java index 281916a21..ee25e2c07 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -10,7 +10,6 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; @@ -18,21 +17,19 @@ import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.sparql.expr.NodeValue; import com.hp.hpl.jena.vocabulary.RDFS; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; +import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; @@ -56,21 +53,12 @@ public class ApplicationConfigurationOntologyUtils { String queryStr = "PREFIX rdfs: \n" + "PREFIX config: \n" + "PREFIX vitro: \n" + - "SELECT DISTINCT ?range ?domain ?label ?group ?customForm ?displayRank ?displayLevel ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed ?property WHERE { \n" + -// " ?p rdfs:subPropertyOf ?property . \n" + + "SELECT DISTINCT ?range ?domain ?property WHERE { \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + " ?context config:hasConfiguration ?configuration . \n" + + " ?configuration a config:ObjectPropertyDisplayConfig . \n" + " OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + - " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + - " OPTIONAL { ?configuration config:displayName ?label } \n" + - " OPTIONAL { ?configuration vitro:displayRankAnnot ?displayRank } \n" + - " OPTIONAL { ?configuration config:editLinkSuppressed ?editLinkSuppressed } \n" + - " OPTIONAL { ?configuration config:addLinkSuppressed ?addLinkSuppressed } \n" + - " OPTIONAL { ?configuration config:deleteLinkSuppressed ?deleteLinkSuppressed } \n" + - " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + - " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + - " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + "}"; if(prop != null) { @@ -80,86 +68,23 @@ public class ApplicationConfigurationOntologyUtils { log.debug(queryStr); Query q = QueryFactory.create(queryStr); QueryExecution qe = QueryExecutionFactory.create(q, union); + WebappDaoFactory wadf = new WebappDaoFactoryJena( + ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union)); + ObjectPropertyDao opDao = wadf.getObjectPropertyDao(); try { ResultSet rs = qe.execSelect(); while (rs.hasNext()) { QuerySolution qsoln = rs.nextSolution(); log.debug(qsoln); - ObjectProperty op = null; - if (prop == null) { - String opURI = qsoln.getResource("property").getURI(); - OntModel tboxOntModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, tboxModel); - WebappDaoFactory wadf = new WebappDaoFactoryJena(tboxOntModel); - op = wadf.getObjectPropertyDao().getObjectPropertyByURI(opURI); - } else { - op = prop; - } - ObjectProperty newProp = new ObjectProperty(); - newProp.setURI(op.getURI()); + String opURI = (prop != null) ? prop.getURI() : qsoln.getResource( + "property").getURI(); Resource domainRes = qsoln.getResource("domain"); - if(domainRes != null) { - if(!appropriateDomain( - domainRes, subject, tboxModel)) { - continue; - } else { - newProp.setDomainVClassURI(domainRes.getURI()); - } - } - Resource rangeRes = qsoln.getResource("range"); - if (rangeRes != null) { - newProp.setRangeVClassURI(rangeRes.getURI()); - } else { - newProp.setRangeVClassURI(op.getRangeVClassURI()); + String domainURI = (domainRes != null) ? domainRes.getURI() : null; + String rangeURI = qsoln.getResource("range").getURI(); + if (appropriateDomain(domainRes, subject, tboxModel)) { + additionalProps.add(opDao.getObjectPropertyByURIs( + opURI, domainURI, rangeURI)); } - Resource groupRes = qsoln.getResource("group"); - if (groupRes != null) { - newProp.setGroupURI(groupRes.getURI()); - } else { - newProp.setGroupURI(op.getURI()); - } - Literal labelLit = qsoln.getLiteral("label"); - if (labelLit != null) { - newProp.setDomainPublic(labelLit.getLexicalForm()); - } else { - newProp.setDomainPublic(op.getDomainPublic()); - } - Literal customFormLit = qsoln.getLiteral("customForm"); - if (customFormLit != null) { - newProp.setCustomEntryForm(customFormLit.getLexicalForm()); - } else { - newProp.setCustomEntryForm(op.getCustomEntryForm()); - } - Literal displayRankLit = qsoln.getLiteral("displayRank"); - if(displayRankLit != null) { - op.setDomainDisplayTier( - Integer.parseInt(displayRankLit.getLexicalForm())); - } - Resource displayLevelRes = qsoln.getResource("displayLevel"); - if (displayLevelRes != null) { - newProp.setHiddenFromDisplayBelowRoleLevel( - BaseResourceBean.RoleLevel.getRoleByUri( - displayLevelRes.getURI())); - } - Resource updateLevelRes = qsoln.getResource("updateLevel"); - if (updateLevelRes != null) { - newProp.setProhibitedFromUpdateBelowRoleLevel( - BaseResourceBean.RoleLevel.getRoleByUri( - updateLevelRes.getURI())); - } - Literal editLinkSuppressedLit = qsoln.getLiteral("editLinkSuppressed"); - if (editLinkSuppressedLit != null ) { - op.setEditLinkSuppressed(editLinkSuppressedLit.getBoolean()); - } - Literal addLinkSuppressedLit = qsoln.getLiteral("addLinkSuppressed"); - if (addLinkSuppressedLit != null ) { - op.setAddLinkSuppressed(addLinkSuppressedLit.getBoolean()); - } - Literal deleteLinkSuppressedLit = qsoln.getLiteral("deleteLinkSuppressed"); - if (deleteLinkSuppressedLit != null ) { - op.setDeleteLinkSuppressed(deleteLinkSuppressedLit.getBoolean()); - } - additionalProps.add(newProp); } } finally { qe.close(); @@ -185,7 +110,7 @@ public class ApplicationConfigurationOntologyUtils { } private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) { - if (subject == null) { + if (subject == null || domainRes == null) { return true; } for (VClass vclass : subject.getVClasses()) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 2e8c59397..482c1cd27 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -160,7 +160,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel protected List> getStatementData() { ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao(); - return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeUri, getSelectQuery(), getConstructQueries(), sortDirection); + return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, domainUri, rangeUri, getSelectQuery(), getConstructQueries(), sortDirection); } protected abstract boolean isEmpty(); diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java index d5913a557..4144631e9 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java @@ -216,7 +216,7 @@ public class ObjectPropertyStatementDaoStub implements @Override public List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, String rangeUri, + String subjectUri, String propertyUri, String objectKey, String domainUri, String rangeUri, String query, Set constructQueries, String sortDir) { throw new RuntimeException( "ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented."); From 57055a4efce152fbbe0adca4a9d08d92578657f7 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 4 Sep 2013 12:47:51 -0400 Subject: [PATCH 20/44] keeping uneditable properties from showing up on the page --- .../individual/PropertyGroupTemplateModel.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java index 357faeb40..71e3fa65e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyGroupTemplateModel.java @@ -33,8 +33,13 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel { properties = new ArrayList(propertyList.size()); for (Property p : propertyList) { if (p instanceof ObjectProperty) { - ObjectProperty op = (ObjectProperty)p; - properties.add(ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList)); + ObjectProperty op = (ObjectProperty) p; + ObjectPropertyTemplateModel tm = ObjectPropertyTemplateModel.getObjectPropertyTemplateModel( + op, subject, vreq, editing, populatedObjectPropertyList); + if (!tm.isEmpty() || (editing && !tm.getAddUrl().isEmpty())) { + properties.add(tm); + } + } else { properties.add(new DataPropertyTemplateModel((DataProperty)p, subject, vreq, editing, populatedDataPropertyList)); } From 91aedd5255b84b2a4607526c7af33a53b9e370f1 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 6 Sep 2013 16:40:17 -0400 Subject: [PATCH 21/44] VCard migration --- .../webapp/dao/jena/PropertyDaoJena.java | 22 +- .../ontology/update/KnowledgeBaseUpdater.java | 227 +++++++++--------- .../servlet/setup/UpdateKnowledgeBase.java | 5 +- 3 files changed, 133 insertions(+), 121 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index 1e04c66e0..a7a55f136 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -616,22 +616,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { return classes; } + private static final int DEPTH_LIMIT = 20; + private List getRelatedRestrictions(OntClass ontClass) { - List relatedRestrictions = new ArrayList(); + return getRelatedRestrictions(ontClass, new ArrayList(), DEPTH_LIMIT); + } + + private List getRelatedRestrictions(OntClass ontClass, + List relatedRestrictions, int limit) { + limit--; if (ontClass.isRestriction()) { relatedRestrictions.add(ontClass.as(Restriction.class)); } else if (ontClass.isIntersectionClass()) { IntersectionClass inter = ontClass.as(IntersectionClass.class); Iterator operIt = inter.listOperands(); while (operIt.hasNext()) { - relatedRestrictions.addAll(getRelatedRestrictions(operIt.next())); + OntClass operand = operIt.next(); + if (!relatedRestrictions.contains(operand) && limit > 0) { + relatedRestrictions.addAll( + getRelatedRestrictions( + operand, relatedRestrictions, limit)); + } } } else { List superClasses = listSuperClasses(ontClass); superClasses.addAll(listEquivalentClasses(ontClass)); for (OntClass sup : superClasses) { - if (!sup.equals(ontClass)) { - relatedRestrictions.addAll(getRelatedRestrictions(sup)); + if (sup.isAnon() && !sup.equals(ontClass) + && !relatedRestrictions.contains(ontClass) && limit > 0) { + relatedRestrictions.addAll( + getRelatedRestrictions(sup, relatedRestrictions, limit)); } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 1ae0ddd3e..b8ab33744 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -11,6 +11,8 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -112,126 +114,123 @@ public class KnowledgeBaseUpdater { log.error("unable to migrate migration metadata " + e.getMessage()); } + log.warn("KnowledgeBaseUpdater needs to be modified to work on all graphs!"); + OntModel readModel = settings.getUnionOntModelSelector().getABoxModel(); + OntModel writeModel = settings.getAssertionOntModelSelector().getABoxModel(); + // TODO make sure the ABox update applies to all graphs + log.info("\tupdating the abox"); updateABox(changes); - } - - private void performSparqlConstructAdditions(String sparqlConstructDir, OntModel readModel, OntModel writeModel) throws IOException { - - Model anonModel = performSparqlConstructs(sparqlConstructDir, readModel, true); - - if (anonModel == null) { - return; - } - - writeModel.enterCriticalSection(Lock.WRITE); - try { - JenaIngestUtils jiu = new JenaIngestUtils(); - Model additions = jiu.renameBNodes(anonModel, settings.getDefaultNamespace() + "n", writeModel); - Model actualAdditions = ModelFactory.createDefaultModel(); - StmtIterator stmtIt = additions.listStatements(); - - while (stmtIt.hasNext()) { - Statement stmt = stmtIt.nextStatement(); - if (!writeModel.contains(stmt)) { - actualAdditions.add(stmt); - } - } - - writeModel.add(actualAdditions); - record.recordAdditions(actualAdditions); - } finally { - writeModel.leaveCriticalSection(); - } + + log.info("performing SPARQL CONSTRUCT additions"); + performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), readModel, writeModel, ADD); + + log.info("performing SPARQL CONSTRUCT retractions"); + performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), readModel, writeModel, RETRACT); + } - private void performSparqlConstructRetractions(String sparqlConstructDir, OntModel readModel, OntModel writeModel) throws IOException { - - Model retractions = performSparqlConstructs(sparqlConstructDir, readModel, false); - - if (retractions == null) { - return; - } - - writeModel.enterCriticalSection(Lock.WRITE); - - try { - writeModel.remove(retractions); - record.recordRetractions(retractions); - } finally { - writeModel.leaveCriticalSection(); - } - - } + private static final boolean ADD = true; + private static final boolean RETRACT = !ADD; - /** - * Performs a set of arbitrary SPARQL CONSTRUCT queries on the - * data, for changes that cannot be expressed as simple property - * or class additions, deletions, or renamings. - * Blank nodes created by the queries are given random URIs. - * @param sparqlConstructDir - * @param aboxModel - */ - private Model performSparqlConstructs(String sparqlConstructDir, - OntModel readModel, - boolean add) throws IOException { - - Model anonModel = ModelFactory.createDefaultModel(); - File sparqlConstructDirectory = new File(sparqlConstructDir); - - if (!sparqlConstructDirectory.isDirectory()) { - logger.logError(this.getClass().getName() + - "performSparqlConstructs() expected to find a directory " + - " at " + sparqlConstructDir + ". Unable to execute " + - " SPARQL CONSTRUCTS."); - return null; - } - - File[] sparqlFiles = sparqlConstructDirectory.listFiles(); - for (int i = 0; i < sparqlFiles.length; i ++) { - File sparqlFile = sparqlFiles[i]; - try { - BufferedReader reader = new BufferedReader(new FileReader(sparqlFile)); - StringBuffer fileContents = new StringBuffer(); - String ln; - - while ( (ln = reader.readLine()) != null) { - fileContents.append(ln).append('\n'); - } - - try { - log.debug("\t\tprocessing SPARQL construct query from file " + sparqlFiles[i].getName()); - Query q = QueryFactory.create(fileContents.toString(), Syntax.syntaxARQ); - readModel.enterCriticalSection(Lock.READ); - try { - QueryExecution qe = QueryExecutionFactory.create(q, readModel); - long numBefore = anonModel.size(); - qe.execConstruct(anonModel); - long numAfter = anonModel.size(); - long num = numAfter - numBefore; - - if (num > 0) { - logger.log((add ? "Added " : "Removed ") + num + - " statement" + ((num > 1) ? "s" : "") + - " using the SPARQL construct query from file " + sparqlFiles[i].getParentFile().getName() + "/" + sparqlFiles[i].getName()); + /** + * Performs a set of arbitrary SPARQL CONSTRUCT queries on the + * data, for changes that cannot be expressed as simple property + * or class additions, deletions, or renamings. + * Blank nodes created by the queries are given random URIs. + * @param sparqlConstructDir + * @param readModel + * @param writeModel + * @param add (add = true; retract = false) + */ + private void performSparqlConstructs(String sparqlConstructDir, + OntModel readModel, OntModel writeModel, + boolean add) throws IOException { + File sparqlConstructDirectory = new File(sparqlConstructDir); + log.info("Using SPARQL CONSTRUCT director " + sparqlConstructDirectory); + if (!sparqlConstructDirectory.isDirectory()) { + String logMsg = this.getClass().getName() + + "performSparqlConstructs() expected to find a directory " + + " at " + sparqlConstructDir + ". Unable to execute " + + " SPARQL CONSTRUCTS."; + logger.logError(logMsg); + log.error(logMsg); + return; + } + List sparqlFiles = Arrays.asList(sparqlConstructDirectory.listFiles()); + Collections.sort(sparqlFiles); // queries may depend on being run in a certain order + JenaIngestUtils jiu = new JenaIngestUtils(); + for (File sparqlFile : sparqlFiles) { + Model anonModel = ModelFactory.createDefaultModel(); + StringBuffer fileContents = new StringBuffer(); + try { + BufferedReader reader = new BufferedReader(new FileReader(sparqlFile)); + String ln; + while ( (ln = reader.readLine()) != null) { + fileContents.append(ln).append('\n'); + } + } catch (FileNotFoundException fnfe) { + String logMsg = "WARNING: performSparqlConstructs() could not find " + + " SPARQL CONSTRUCT file " + sparqlFile + ". Skipping."; + logger.log(logMsg); + log.info(logMsg); + continue; + } + try { + log.info("\t\tprocessing SPARQL construct query from file " + sparqlFile.getName()); + Query q = QueryFactory.create(fileContents.toString(), Syntax.syntaxARQ); + readModel.enterCriticalSection(Lock.READ); + try { + QueryExecution qe = QueryExecutionFactory.create(q, readModel); + long numBefore = anonModel.size(); + qe.execConstruct(anonModel); + long numAfter = anonModel.size(); + long num = numAfter - numBefore; + if (num > 0) { + String logMsg = (add ? "Added " : "Removed ") + num + + " statement" + ((num > 1) ? "s" : "") + + " using the SPARQL construct query from file " + + sparqlFile.getParentFile().getName() + + "/" + sparqlFile.getName(); + logger.log(logMsg); + log.info(logMsg); + } + qe.close(); + } finally { + readModel.leaveCriticalSection(); + } + } catch (Exception e) { + logger.logError(this.getClass().getName() + + ".performSparqlConstructs() unable to execute " + + "query at " + sparqlFile + ". Error message is: " + e.getMessage()); + log.error(e,e); + } + writeModel.enterCriticalSection(Lock.WRITE); + try { + if(!add) { + writeModel.remove(anonModel); + record.recordRetractions(anonModel); + //log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs"); + } else { + Model additions = jiu.renameBNodes( + anonModel, settings.getDefaultNamespace() + "n", writeModel); + Model actualAdditions = ModelFactory.createDefaultModel(); + StmtIterator stmtIt = additions.listStatements(); + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.nextStatement(); + if (!writeModel.contains(stmt)) { + actualAdditions.add(stmt); } - qe.close(); - } finally { - readModel.leaveCriticalSection(); - } - } catch (Exception e) { - logger.logError(this.getClass().getName() + - ".performSparqlConstructs() unable to execute " + - "query at " + sparqlFile + ". Error message is: " + e.getMessage()); - } - } catch (FileNotFoundException fnfe) { - logger.log("WARNING: performSparqlConstructs() could not find " + - " SPARQL CONSTRUCT file " + sparqlFile + ". Skipping."); - } - } - - return anonModel; - } + } + writeModel.add(actualAdditions); + //log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs"); + record.recordAdditions(actualAdditions); + } + } finally { + writeModel.leaveCriticalSection(); + } + } + } private List getAtomicOntologyChanges() diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 3c851007f..2a698e4d5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -158,6 +158,8 @@ public class UpdateKnowledgeBase implements ServletContextListener { private void putNonReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) { settings.setAskUpdatedQueryFile(ctx.getRealPath(ASK_QUERY_FILE)); settings.setDiffFile(ctx.getRealPath(DIFF_FILE)); + settings.setSparqlConstructAdditionsDir(ctx.getRealPath(DATA_DIR + "sparqlConstructs/additions")); + settings.setSparqlConstructDeletionsDir(ctx.getRealPath(DATA_DIR + "sparqlConstructs/deletions")); settings.setSuccessAssertionsFile(ctx.getRealPath(SUCCESS_ASSERTIONS_FILE)); settings.setSuccessRDFFormat("N3"); } @@ -174,9 +176,6 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setDataDir(dataDir.toString()); StartupStatus.getBean(ctx).info(this, "Updating knowledge base: reports are in '" + dataDir + "'"); - settings.setSparqlConstructAdditionsDir(createDirectory(dataDir, "sparqlConstructs", "additions").toString()); - settings.setSparqlConstructDeletionsDir(createDirectory(dataDir, "sparqlConstructs", "deletions").toString()); - Path changedDir = createDirectory(dataDir, "changedData"); settings.setAddedDataFile(changedDir.resolve("addedData.n3").toString()); settings.setRemovedDataFile(changedDir.resolve("removedData.n3").toString()); From 6570e3dcc65d1f0658dcb4be71066e3ed2221db5 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 10 Sep 2013 09:08:55 -0400 Subject: [PATCH 22/44] merging develop into dev-isf --- .../testing/VitroTestRunListener.java | 652 +++++++++--------- .../everytime/displayDisplay.n3 | 9 +- .../rdf/displayTbox/everytime/displayTBOX.n3 | 10 +- .../ManageLabelsForIndividualGenerator.java | 23 +- .../servlet/setup/UpdateKnowledgeBase.java | 28 +- .../freemarker/lib/lib-properties.ftl | 2 +- 6 files changed, 356 insertions(+), 368 deletions(-) diff --git a/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunListener.java b/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunListener.java index 01245e92f..acfe6ef71 100644 --- a/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunListener.java +++ b/utilities/buildutils/src/edu/cornell/mannlib/vitro/utilities/testing/VitroTestRunListener.java @@ -1,7 +1,7 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.utilities.testing; - +package edu.cornell.mannlib.vitro.utilities.testing; + import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.BRIEF; import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.FULL; import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.MORE; @@ -20,327 +20,327 @@ import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel; - -/** - * Listen to events as they come from the JUnit test runner. The events from the - * lifecycle methods are broken down into semantic chunks and executed. Three - * levels of output are available. - * - * On the surface, JUnit treats "failures" (failed assertions) the same as - * "errors" (unexpected exceptions). We're going to distinguish between them. - * - * @author jeb228 - */ -public class VitroTestRunListener extends RunListener { - private final ReportLevel reportLevel; - - private int classCount; - private int testsTotal; - private int errorsTotal; - private int failuresTotal; - private int ignoresTotal; - private long overallStartTime; - - private Class currentClass; - private int testsCurrentClass; - private int errorsCurrentClass; - private int failuresCurrentClass; - private int ignoresCurrentClass; - private long classStartTime; - - private String currentTest; - private boolean testHadError; - private boolean testFailed; - private boolean testIgnored; - private long testStartTime; - - public VitroTestRunListener(ReportLevel reportLevel) { - this.reportLevel = reportLevel; - } - - /** Did any of the tests fail or have errors? */ - public boolean didEverythingPass() { - return (failuresTotal == 0) && (errorsTotal == 0); - } - - // ------------------------------------------------------------------------- - // Life-cycle methods that will be called by the test runner. - // ------------------------------------------------------------------------- - - @Override - public void testRunStarted(Description description) throws Exception { - openTestRun(); - reportTestRunStart(); - } - - @Override - public void testStarted(Description description) throws Exception { - if (currentClass != description.getTestClass()) { - if (currentClass != null) { - closeCurrentClass(); - reportCurrentClass(); - } - - openCurrentClass(description); - reportCurrentClassStart(); - } - - openCurrentTest(description); - } - - @Override - public void testAssumptionFailure(Failure failure) { - if (isError(failure)) { - testHadError = true; - reportError(failure); - } else { - testFailed = true; - reportFailure(failure); - } - } - - @Override - public void testFailure(Failure failure) throws Exception { - if (isError(failure)) { - testHadError = true; - reportError(failure); - } else { - testFailed = true; - reportFailure(failure); - } - } - - @Override - public void testFinished(Description description) throws Exception { - closeCurrentTest(); - reportCurrentTest(); - } - - @Override - public void testIgnored(Description description) throws Exception { - testStarted(description); - testIgnored = true; - testFinished(description); - } - - @Override - public void testRunFinished(Result result) throws Exception { - if (currentClass != null) { - closeCurrentClass(); - reportCurrentClass(); - } - closeTestRun(); - reportTestRun(); - System.out.println(); - } - - // ------------------------------------------------------------------------- - // Handling the logical events. - // ------------------------------------------------------------------------- - - private void openTestRun() { - overallStartTime = System.currentTimeMillis(); - } - - private void closeTestRun() { - // Nothing to close. - } - - private void reportTestRunStart() { - if (reportLevel == FULL) { - System.out - .println("Starting test run at " + time(overallStartTime)); - System.out.println(); - } - - if (reportLevel == MORE) { - System.out - .println("Starting test run at " + time(overallStartTime)); - System.out.println(); - System.out.println("Tests Pass Error Fail Ignore Seconds"); - } - } - - private void reportTestRun() { - int successes = testsTotal - errorsTotal - failuresTotal - ignoresTotal; - - if (reportLevel != BRIEF) { - System.out.println(); - } - - System.out.format( - "Tests Pass Error Fail Ignore Seconds TOTAL (%d classes)\n", - classCount); - System.out.format(" %4d %4d %4d %4d %4d %6s\n", testsTotal, - successes, errorsTotal, failuresTotal, ignoresTotal, - elapsed(overallStartTime)); - - if (reportLevel != BRIEF) { - System.out.println("Ending test run at " - + time(System.currentTimeMillis())); - } - } - - private void openCurrentClass(Description description) { - currentClass = description.getTestClass(); - classStartTime = System.currentTimeMillis(); - testsCurrentClass = 0; - errorsCurrentClass = 0; - failuresCurrentClass = 0; - ignoresCurrentClass = 0; - } - - private void closeCurrentClass() { - classCount++; - testsTotal += testsCurrentClass; - errorsTotal += errorsCurrentClass; - failuresTotal += failuresCurrentClass; - ignoresTotal += ignoresCurrentClass; - } - - private void reportCurrentClassStart() { - if (reportLevel == FULL) { - System.out.format("Tests Pass Error Fail Ignore Seconds %s\n", - currentClass.getName()); - } - } - - private void reportCurrentClass() { - int successes = testsCurrentClass - errorsCurrentClass - - failuresCurrentClass - ignoresCurrentClass; - if (reportLevel == MORE) { - System.out.format(" %4d %4d %4d %4d %4d %6s %s\n", - testsCurrentClass, successes, errorsCurrentClass, - failuresCurrentClass, ignoresCurrentClass, - elapsed(classStartTime), currentClass.getSimpleName()); - } - if (reportLevel == FULL) { - System.out.println("-----------------------------------"); - System.out.format(" %4d %4d %4d %4d %4d %6s\n", - testsCurrentClass, successes, errorsCurrentClass, - failuresCurrentClass, ignoresCurrentClass, - elapsed(classStartTime)); - System.out.println(); - } - } - - private void openCurrentTest(Description description) { - currentTest = description.getMethodName(); - testHadError = false; - testFailed = false; - testIgnored = false; - testStartTime = System.currentTimeMillis(); - } - - private void closeCurrentTest() { - if (testHadError) { - errorsCurrentClass++; - } - if (testFailed) { - failuresCurrentClass++; - } - if (testIgnored) { - ignoresCurrentClass++; - } - testsCurrentClass++; - } - - private boolean isError(Failure failure) { - Throwable throwable = failure.getException(); - return (throwable != null) && !(throwable instanceof AssertionError); - } - - private void reportError(Failure error) { - Description description = error.getDescription(); - String methodName = description.getMethodName(); - String className = description.getTestClass().getName(); - String message = error.getMessage(); - System.out.format("EXCEPTION: test %s() in %s: %s\n", - methodName, className, message); - System.out.println(formatStackTrace(error.getException())); - } - - private void reportFailure(Failure failure) { - Description description = failure.getDescription(); - String methodName = description.getMethodName(); - String className = description.getTestClass().getName(); - String message = failure.getMessage(); - System.out.format("TEST FAILED: test %s() in %s: %s\n", methodName, - className, message); - } - - private void reportCurrentTest() { - if (reportLevel == FULL) { - char passFlag = (testIgnored | testFailed | testHadError) ? ' ' - : '1'; - char errorFlag = testHadError ? '1' : ' '; - char failFlag = testFailed ? '1' : ' '; - char ignoreFlag = testIgnored ? '1' : ' '; - System.out.format( - " %c %c %c %c %6s %s()\n", - passFlag, errorFlag, failFlag, ignoreFlag, - elapsed(testStartTime), currentTest); - } - } - - // ------------------------------------------------------------------------- - // Formatting methods. - // ------------------------------------------------------------------------- - - private final SimpleDateFormat formatter = new SimpleDateFormat( - "HH:mm:ss 'on' MMM dd, yyyy"); - - private String time(long time) { - return formatter.format(new Date(time)); - } - - /** Show elapsed time in 6 columns. */ - private String elapsed(long start) { - long interval = System.currentTimeMillis() - start; - return String.format("%6.2f", ((float) interval) / 1000.0); - } - - /** - * Trim the stack trace: don't show the line saying "23 more", and don't - * show the lines about org.junit or java.lang.reflect or sun.reflect. - * - * Once we hit some "client code", we won't trim any futher lines even if - * they belong to org.junit, or the others. - * - * If we have nested exceptions, the process repeats for each "Caused by" - * section. - */ - private String formatStackTrace(Throwable throwable) { - StringWriter w = new StringWriter(); - throwable.printStackTrace(new PrintWriter(w)); - String[] lineArray = w.toString().split("\\n"); - List lines = new ArrayList(Arrays.asList(lineArray)); - - boolean removing = true; - for (int i = lines.size() - 1; i > 0; i--) { - String line = lines.get(i); - if (removing) { - if (line.matches("\\s*[\\.\\s\\d]+more\\s*") - || line.contains("at " - + VitroTestRunner.class.getName()) - || line.contains("at org.junit.") - || line.contains("at java.lang.reflect.") - || line.contains("at sun.reflect.")) { - lines.remove(line); - } else { - removing = false; - } - } else { - if (line.contains("Caused by: ")) { - removing = true; - } - } - } - - StringBuilder result = new StringBuilder(); - for (String line : lines) { - result.append(line).append('\n'); - } - return result.toString().trim(); - } -} + +/** + * Listen to events as they come from the JUnit test runner. The events from the + * lifecycle methods are broken down into semantic chunks and executed. Three + * levels of output are available. + * + * On the surface, JUnit treats "failures" (failed assertions) the same as + * "errors" (unexpected exceptions). We're going to distinguish between them. + * + * @author jeb228 + */ +public class VitroTestRunListener extends RunListener { + private final ReportLevel reportLevel; + + private int classCount; + private int testsTotal; + private int errorsTotal; + private int failuresTotal; + private int ignoresTotal; + private long overallStartTime; + + private Class currentClass; + private int testsCurrentClass; + private int errorsCurrentClass; + private int failuresCurrentClass; + private int ignoresCurrentClass; + private long classStartTime; + + private String currentTest; + private boolean testHadError; + private boolean testFailed; + private boolean testIgnored; + private long testStartTime; + + public VitroTestRunListener(ReportLevel reportLevel) { + this.reportLevel = reportLevel; + } + + /** Did any of the tests fail or have errors? */ + public boolean didEverythingPass() { + return (failuresTotal == 0) && (errorsTotal == 0); + } + + // ------------------------------------------------------------------------- + // Life-cycle methods that will be called by the test runner. + // ------------------------------------------------------------------------- + + @Override + public void testRunStarted(Description description) throws Exception { + openTestRun(); + reportTestRunStart(); + } + + @Override + public void testStarted(Description description) throws Exception { + if (currentClass != description.getTestClass()) { + if (currentClass != null) { + closeCurrentClass(); + reportCurrentClass(); + } + + openCurrentClass(description); + reportCurrentClassStart(); + } + + openCurrentTest(description); + } + + @Override + public void testAssumptionFailure(Failure failure) { + if (isError(failure)) { + testHadError = true; + reportError(failure); + } else { + testFailed = true; + reportFailure(failure); + } + } + + @Override + public void testFailure(Failure failure) throws Exception { + if (isError(failure)) { + testHadError = true; + reportError(failure); + } else { + testFailed = true; + reportFailure(failure); + } + } + + @Override + public void testFinished(Description description) throws Exception { + closeCurrentTest(); + reportCurrentTest(); + } + + @Override + public void testIgnored(Description description) throws Exception { + testStarted(description); + testIgnored = true; + testFinished(description); + } + + @Override + public void testRunFinished(Result result) throws Exception { + if (currentClass != null) { + closeCurrentClass(); + reportCurrentClass(); + } + closeTestRun(); + reportTestRun(); + System.out.println(); + } + + // ------------------------------------------------------------------------- + // Handling the logical events. + // ------------------------------------------------------------------------- + + private void openTestRun() { + overallStartTime = System.currentTimeMillis(); + } + + private void closeTestRun() { + // Nothing to close. + } + + private void reportTestRunStart() { + if (reportLevel == FULL) { + System.out + .println("Starting test run at " + time(overallStartTime)); + System.out.println(); + } + + if (reportLevel == MORE) { + System.out + .println("Starting test run at " + time(overallStartTime)); + System.out.println(); + System.out.println("Tests Pass Error Fail Ignore Seconds"); + } + } + + private void reportTestRun() { + int successes = testsTotal - errorsTotal - failuresTotal - ignoresTotal; + + if (reportLevel != BRIEF) { + System.out.println(); + } + + System.out.format( + "Tests Pass Error Fail Ignore Seconds TOTAL (%d classes)\n", + classCount); + System.out.format(" %4d %4d %4d %4d %4d %6s\n", testsTotal, + successes, errorsTotal, failuresTotal, ignoresTotal, + elapsed(overallStartTime)); + + if (reportLevel != BRIEF) { + System.out.println("Ending test run at " + + time(System.currentTimeMillis())); + } + } + + private void openCurrentClass(Description description) { + currentClass = description.getTestClass(); + classStartTime = System.currentTimeMillis(); + testsCurrentClass = 0; + errorsCurrentClass = 0; + failuresCurrentClass = 0; + ignoresCurrentClass = 0; + } + + private void closeCurrentClass() { + classCount++; + testsTotal += testsCurrentClass; + errorsTotal += errorsCurrentClass; + failuresTotal += failuresCurrentClass; + ignoresTotal += ignoresCurrentClass; + } + + private void reportCurrentClassStart() { + if (reportLevel == FULL) { + System.out.format("Tests Pass Error Fail Ignore Seconds %s\n", + currentClass.getName()); + } + } + + private void reportCurrentClass() { + int successes = testsCurrentClass - errorsCurrentClass + - failuresCurrentClass - ignoresCurrentClass; + if (reportLevel == MORE) { + System.out.format(" %4d %4d %4d %4d %4d %6s %s\n", + testsCurrentClass, successes, errorsCurrentClass, + failuresCurrentClass, ignoresCurrentClass, + elapsed(classStartTime), currentClass.getSimpleName()); + } + if (reportLevel == FULL) { + System.out.println("-----------------------------------"); + System.out.format(" %4d %4d %4d %4d %4d %6s\n", + testsCurrentClass, successes, errorsCurrentClass, + failuresCurrentClass, ignoresCurrentClass, + elapsed(classStartTime)); + System.out.println(); + } + } + + private void openCurrentTest(Description description) { + currentTest = description.getMethodName(); + testHadError = false; + testFailed = false; + testIgnored = false; + testStartTime = System.currentTimeMillis(); + } + + private void closeCurrentTest() { + if (testHadError) { + errorsCurrentClass++; + } + if (testFailed) { + failuresCurrentClass++; + } + if (testIgnored) { + ignoresCurrentClass++; + } + testsCurrentClass++; + } + + private boolean isError(Failure failure) { + Throwable throwable = failure.getException(); + return (throwable != null) && !(throwable instanceof AssertionError); + } + + private void reportError(Failure error) { + Description description = error.getDescription(); + String methodName = description.getMethodName(); + String className = description.getTestClass().getName(); + String message = error.getMessage(); + System.out.format("EXCEPTION: test %s() in %s: %s\n", + methodName, className, message); + System.out.println(formatStackTrace(error.getException())); + } + + private void reportFailure(Failure failure) { + Description description = failure.getDescription(); + String methodName = description.getMethodName(); + String className = description.getTestClass().getName(); + String message = failure.getMessage(); + System.out.format("TEST FAILED: test %s() in %s: %s\n", methodName, + className, message); + } + + private void reportCurrentTest() { + if (reportLevel == FULL) { + char passFlag = (testIgnored | testFailed | testHadError) ? ' ' + : '1'; + char errorFlag = testHadError ? '1' : ' '; + char failFlag = testFailed ? '1' : ' '; + char ignoreFlag = testIgnored ? '1' : ' '; + System.out.format( + " %c %c %c %c %6s %s()\n", + passFlag, errorFlag, failFlag, ignoreFlag, + elapsed(testStartTime), currentTest); + } + } + + // ------------------------------------------------------------------------- + // Formatting methods. + // ------------------------------------------------------------------------- + + private final SimpleDateFormat formatter = new SimpleDateFormat( + "HH:mm:ss 'on' MMM dd, yyyy"); + + private String time(long time) { + return formatter.format(new Date(time)); + } + + /** Show elapsed time in 6 columns. */ + private String elapsed(long start) { + long interval = System.currentTimeMillis() - start; + return String.format("%6.2f", ((float) interval) / 1000.0); + } + + /** + * Trim the stack trace: don't show the line saying "23 more", and don't + * show the lines about org.junit or java.lang.reflect or sun.reflect. + * + * Once we hit some "client code", we won't trim any futher lines even if + * they belong to org.junit, or the others. + * + * If we have nested exceptions, the process repeats for each "Caused by" + * section. + */ + private String formatStackTrace(Throwable throwable) { + StringWriter w = new StringWriter(); + throwable.printStackTrace(new PrintWriter(w)); + String[] lineArray = w.toString().split("\\n"); + List lines = new ArrayList(Arrays.asList(lineArray)); + + boolean removing = true; + for (int i = lines.size() - 1; i > 0; i--) { + String line = lines.get(i); + if (removing) { + if (line.matches("\\s*[\\.\\s\\d]+more\\s*") + || line.contains("at " + + VitroTestRunner.class.getName()) + || line.contains("at org.junit.") + || line.contains("at java.lang.reflect.") + || line.contains("at sun.reflect.")) { + lines.remove(line); + } else { + removing = false; + } + } else { + if (line.contains("Caused by: ")) { + removing = true; + } + } + } + + StringBuilder result = new StringBuilder(); + for (String line : lines) { + result.append(line).append('\n'); + } + return result.toString().trim(); + } +} diff --git a/webapp/rdf/displayDisplay/everytime/displayDisplay.n3 b/webapp/rdf/displayDisplay/everytime/displayDisplay.n3 index 8b30c3945..4323bd43e 100644 --- a/webapp/rdf/displayDisplay/everytime/displayDisplay.n3 +++ b/webapp/rdf/displayDisplay/everytime/displayDisplay.n3 @@ -2,6 +2,7 @@ @prefix xsd: . @prefix owl: . @prefix rdf: . +@prefix display: . rdf:type a owl:ObjectProperty ; @@ -12,16 +13,16 @@ rdf:type "true"^^xsd:boolean ; - "true"^^xsd:boolean ; + "true"^^xsd:boolean . display:requiresAction a owl:ObjectProperty ; rdfs:label "Required Action"@en-US ; - rdfs:comment "Indicates that a resource has a required action that may need to be authorized" . - rdfs:range display:RequiredAction . + rdfs:comment "Indicates that a resource has a required action that may need to be authorized" ; + rdfs:range display:RequiredAction ; "true"^^xsd:boolean ; - "true"^^xsd:boolean ; + "true"^^xsd:boolean . diff --git a/webapp/rdf/displayTbox/everytime/displayTBOX.n3 b/webapp/rdf/displayTbox/everytime/displayTBOX.n3 index dd3bf4ea7..f43eebd8c 100644 --- a/webapp/rdf/displayTbox/everytime/displayTBOX.n3 +++ b/webapp/rdf/displayTbox/everytime/displayTBOX.n3 @@ -12,7 +12,7 @@ owl:Class a owl:Class . owl:Ontology a owl:Class . owl:AnnotationProperty a owl:Class . -owl:DatatypeProperty a owl: +owl:DatatypeProperty a owl:Class . owl:ObjectProperty a owl:Class . ###Display Model @@ -35,11 +35,11 @@ display:InternalClassesPage a owl:Class . display:DataGetter a owl:Class . display:RequiredAction a owl:Class ; - rdfs:comment "Represents a action that may need authorization to perform.". + rdfs:comment "Represents a action that may need authorization to perform." . a owl:Class ; - rdfs:comment "Data getter for running a SPARQL query." + rdfs:comment "Data getter for running a SPARQL query." . a owl:Class ; @@ -55,11 +55,11 @@ display:RequiredAction a owl:Class ; a owl:Class ; - rdfs:comment "A data getter for a VClassGroup page". + rdfs:comment "A data getter for a VClassGroup page" . a owl:Class ; - rdfs:comment "A data getter for a Fixed piece of HTML stored in RDF". + rdfs:comment "A data getter for a Fixed piece of HTML stored in RDF" . a owl:Class . diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java index d34c1c5da..80c20e573 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java @@ -17,33 +17,20 @@ import javax.servlet.http.HttpSession; 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.Dataset; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.shared.Lock; -import com.hp.hpl.jena.sparql.resultset.ResultSetMem; import com.hp.hpl.jena.vocabulary.RDFS; -import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; @@ -51,8 +38,6 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTw import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.FoafNameToRdfsLabelPreprocessor; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.ManageLabelsForIndividualPreprocessor; -import edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionDataGetter; -import edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectorUtilities; import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DataPropertyStatementTemplateModel; @@ -335,7 +320,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen RequestActionConstants.SOME_URI); AddObjectPropertyStatement aops = new AddObjectPropertyStatement( vreq.getJenaOntModel(), individual.getURI(), - RequestActionConstants.SOME_URI, + RequestActionConstants.SOME_PREDICATE, RequestActionConstants.SOME_URI); return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops)); } @@ -401,8 +386,8 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen //This should put the label in the list //Create label information instance with the required information //To generate link - DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(subjectUri, propertyUri, l, - template, vreq); + DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel( + subjectUri, new Property(propertyUri), l, template, vreq); labelsList.add(new LabelInformation( l, dpstm.getEditUrl(), dpstm.getDeleteUrl(), languageTag, languageName)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 2a698e4d5..3defaa3cc 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -58,9 +58,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { private static final String ASK_QUERY_FILE = DATA_DIR + "askUpdated.sparql"; private static final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3"; private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; - private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/"; private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; - private static final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user/tbox/"; //For display model migration private static final String OLD_DISPLAYMODEL_TBOX_PATH = DATA_DIR + "oldDisplayModel/displayTBOX.n3"; private static final String NEW_DISPLAYMODEL_TBOX_PATH = "/WEB-INF/ontologies/app/menuload/displayTBOX.n3"; @@ -85,17 +83,21 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector()); settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector()); settings.setUnionOntModelSelector(ModelAccess.on(ctx).getUnionOntModelSelector()); - boolean tryMigrateDisplay = true; + + ConfigurationProperties props = ConfigurationProperties.getBean(ctx); + Path homeDir = Paths.get(props.getProperty("vitro.home")); + settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel()); + OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); + settings.setOldTBoxModel(oldTBoxModel); + OntModel newTBoxModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "filegraph").toString()); + settings.setNewTBoxModel(newTBoxModel); + OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR)); + settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); + OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "everytime").toString()); + settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); + + boolean tryMigrateDisplay = true; try { - settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel()); - OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); - settings.setOldTBoxModel(oldTBoxModel); - OntModel newTBoxModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_MODEL_DIR)); - settings.setNewTBoxModel(newTBoxModel); - OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR)); - settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); - OntModel newTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_ANNOTATIONS_DIR)); - settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); //Display model tbox and display metadata //old display model tbox model OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH)); @@ -117,7 +119,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH)); settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView); } catch (Exception e) { - log.info("Unable to read display model migration files. " + e.getMessage()); + log.info("Unable to read display model migration files. ", e); tryMigrateDisplay = false; } diff --git a/webapp/web/templates/freemarker/lib/lib-properties.ftl b/webapp/web/templates/freemarker/lib/lib-properties.ftl index ee72732c0..bdfc721d5 100644 --- a/webapp/web/templates/freemarker/lib/lib-properties.ftl +++ b/webapp/web/templates/freemarker/lib/lib-properties.ftl @@ -212,7 +212,7 @@ name will be used as the label. --> <#assign labelPropertyUri = ("http://www.w3.org/2000/01/rdf-schema#label"?url) /> <#assign useEditLink = false /> <#--edit link used if in edit mode and only one label and one language--> - <#if labelCount = 1 && editable && localeCount = 1 > + <#if labelCount = 1 && editable> <#assign useEditLink = true/> <#local label = individual.nameStatement> From f7d03b6de8997a9fdede298148f242a3b791b8e4 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 11 Sep 2013 10:14:59 -0400 Subject: [PATCH 23/44] minor change to JenaBaseDao to display resource URI when local name is zero-length --- .../cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 8de45f9f1..38f6eb578 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -834,7 +834,11 @@ public class JenaBaseDao extends JenaBaseDaoCon { try { String localName = r.getLocalName(); if (localName != null) { - label = localName; + if(localName.trim().length() > 0) { + label = localName; + } else { + label = r.getURI(); + } } else if (r.isAnon()) { label = r.getId().toString(); } else { From d5c032f33e16bf275f18798bc5efc5cbc83bb6a1 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 12 Sep 2013 10:37:24 -0400 Subject: [PATCH 24/44] applying ABox update to all graphs --- .../webapp/ontology/update/ABoxUpdater.java | 453 ++++++++++-------- .../ontology/update/KnowledgeBaseUpdater.java | 123 ++--- .../ontology/update/UpdateSettings.java | 10 + .../servlet/setup/UpdateKnowledgeBase.java | 4 + 4 files changed, 334 insertions(+), 256 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java index 0482750e8..da1af4423 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java @@ -14,6 +14,7 @@ import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; @@ -27,7 +28,9 @@ import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; /** * Performs knowledge base updates to the abox to align with a new ontology version @@ -38,7 +41,8 @@ public class ABoxUpdater { private final Log log = LogFactory.getLog(ABoxUpdater.class); private OntModel oldTboxModel; private OntModel newTboxModel; - private OntModel aboxModel; + private Dataset dataset; + private RDFService rdfService; private OntModel newTBoxAnnotationsModel; private ChangeLogger logger; private ChangeRecord record; @@ -59,14 +63,15 @@ public class ABoxUpdater { */ public ABoxUpdater(OntModel oldTboxModel, OntModel newTboxModel, - OntModel aboxModel, + RDFService rdfService, OntModel newAnnotationsModel, ChangeLogger logger, ChangeRecord record) { this.oldTboxModel = oldTboxModel; this.newTboxModel = newTboxModel; - this.aboxModel = aboxModel; + this.dataset = new RDFServiceDataset(rdfService); + this.rdfService = rdfService; this.newTBoxAnnotationsModel = newAnnotationsModel; this.logger = logger; this.record = record; @@ -126,68 +131,75 @@ public class ABoxUpdater { public void renameClass(AtomicOntologyChange change) throws IOException { //logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI()); - aboxModel.enterCriticalSection(Lock.WRITE); - - try { - - Model additions = ModelFactory.createDefaultModel(); - Model retractions = ModelFactory.createDefaultModel(); - - //TODO - look for these in the models and log error if not found - Resource oldClass = ResourceFactory.createResource(change.getSourceURI()); - Resource newClass = ResourceFactory.createResource(change.getDestinationURI()); - - // Change class references in the subjects of statements - - // BJL 2010-04-09 : In future versions we need to keep track of - // the difference between true direct renamings and "use-insteads." - // For now, the best behavior is to remove any remaining statements - // where the old class is the subject, *unless* the statements - // is part of the new annotations file (see comment below) or the - // predicate is vitro:autolinkedToTab. In the latter case, - // the autolinking annotation should be rewritten using the - // new class name. - - StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null); - - int removeCount = 0; - while (iter.hasNext()) { - Statement oldStatement = iter.next(); - removeCount++; - retractions.add(oldStatement); - } - - //log summary of changes - if (removeCount > 0) { - logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class"); - } - - // Change class references in the objects of rdf:type statements - iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass); - - int renameCount = 0; - while (iter.hasNext()) { - renameCount++; - Statement oldStatement = iter.next(); - Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass); - retractions.add(oldStatement); - additions.add(newStatement); - } - - //log summary of changes - if (renameCount > 0) { - logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI()); - } - - aboxModel.remove(retractions); - record.recordRetractions(retractions); - aboxModel.add(additions); - record.recordAdditions(additions); - - } finally { - aboxModel.leaveCriticalSection(); - } - + + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + aboxModel.enterCriticalSection(Lock.WRITE); + try { + + Model additions = ModelFactory.createDefaultModel(); + Model retractions = ModelFactory.createDefaultModel(); + + //TODO - look for these in the models and log error if not found + Resource oldClass = ResourceFactory.createResource(change.getSourceURI()); + Resource newClass = ResourceFactory.createResource(change.getDestinationURI()); + + // Change class references in the subjects of statements + + // BJL 2010-04-09 : In future versions we need to keep track of + // the difference between true direct renamings and "use-insteads." + // For now, the best behavior is to remove any remaining statements + // where the old class is the subject, *unless* the statements + // is part of the new annotations file (see comment below) or the + // predicate is vitro:autolinkedToTab. In the latter case, + // the autolinking annotation should be rewritten using the + // new class name. + + StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null); + + int removeCount = 0; + while (iter.hasNext()) { + Statement oldStatement = iter.next(); + removeCount++; + retractions.add(oldStatement); + } + + //log summary of changes + if (removeCount > 0) { + logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class"); + } + + // Change class references in the objects of rdf:type statements + iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass); + + int renameCount = 0; + while (iter.hasNext()) { + renameCount++; + Statement oldStatement = iter.next(); + Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass); + retractions.add(oldStatement); + additions.add(newStatement); + } + + //log summary of changes + if (renameCount > 0) { + logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI()); + } + + aboxModel.remove(retractions); + record.recordRetractions(retractions); + aboxModel.add(additions); + record.recordAdditions(additions); + + } finally { + aboxModel.leaveCriticalSection(); + } + } } /** @@ -233,24 +245,26 @@ public class ABoxUpdater { if (!parentOfAddedClass.equals(OWL.Thing)) { - StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass); - - int count = stmtIter.toList().size(); - if (count > 0) { - - String indList = ""; - while (stmtIter.hasNext()) { - Statement stmt = stmtIter.next(); - indList += "\n\t" + stmt.getSubject().getURI(); - } - + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + + StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass); + + int count = stmtIter.toList().size(); + if (count > 0) { //TODO - take out the detailed logging after our internal testing is completed. logger.log("There " + ((count > 1) ? "are" : "is") + " " + count + " individual" + ((count > 1) ? "s" : "") + " in the model that " + ((count > 1) ? "are" : "is") + " of type " + parentOfAddedClass.getURI() + "," + " and a new subclass of that class has been added: " + addedClass.getURI() + ". " + "Please review " + ((count > 1) ? "these" : "this") + " individual" + ((count > 1) ? "s" : "") + " to see whether " + ((count > 1) ? "they" : "it") + " should be of type: " + addedClass.getURI() ); } - } + + } } } } @@ -332,25 +346,33 @@ public class ABoxUpdater { } // Remove instances of the deleted class - aboxModel.enterCriticalSection(Lock.WRITE); - try { - int count = 0; - int refCount = 0; - StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass); - - while (iter.hasNext()) { - count++; - Statement typeStmt = iter.next(); - refCount = deleteIndividual(typeStmt.getSubject()); - } - - if (count > 0) { - logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")"); - } - - } finally { - aboxModel.leaveCriticalSection(); - } + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + aboxModel.enterCriticalSection(Lock.WRITE); + try { + int count = 0; + int refCount = 0; + StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass); + + while (iter.hasNext()) { + count++; + Statement typeStmt = iter.next(); + refCount = deleteIndividual(typeStmt.getSubject()); + } + + if (count > 0) { + logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")"); + } + + } finally { + aboxModel.leaveCriticalSection(); + } + } } protected int deleteIndividual(Resource individual) throws IOException { @@ -358,29 +380,37 @@ public class ABoxUpdater { Model retractions = ModelFactory.createDefaultModel(); int refCount = 0; - aboxModel.enterCriticalSection(Lock.WRITE); - try { - StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null); - - while (iter.hasNext()) { - Statement subjstmt = iter.next(); - retractions.add(subjstmt); - } - - iter = aboxModel.listStatements((Resource) null, (Property) null, individual); - - while (iter.hasNext()) { - Statement objstmt = iter.next(); - retractions.add(objstmt); - refCount++; - } - - aboxModel.remove(retractions); - record.recordRetractions(retractions); - - } finally { - aboxModel.leaveCriticalSection(); - } + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + aboxModel.enterCriticalSection(Lock.WRITE); + try { + StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null); + + while (iter.hasNext()) { + Statement subjstmt = iter.next(); + retractions.add(subjstmt); + } + + iter = aboxModel.listStatements((Resource) null, (Property) null, individual); + + while (iter.hasNext()) { + Statement objstmt = iter.next(); + retractions.add(objstmt); + refCount++; + } + + aboxModel.remove(retractions); + record.recordRetractions(retractions); + + } finally { + aboxModel.leaveCriticalSection(); + } + } return refCount; } @@ -439,37 +469,45 @@ public class ABoxUpdater { if (inverseOfAddedProperty != null) { Model additions = ModelFactory.createDefaultModel(); - aboxModel.enterCriticalSection(Lock.WRITE); - - try { - StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null); - - while (iter.hasNext()) { - - Statement stmt = iter.next(); - - if (stmt.getObject().isResource()) { - Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject()); - additions.add(newStmt); - } else { - logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt)); - } - } - - aboxModel.add(additions); - record.recordAdditions(additions); - - if (additions.size() > 0) { - logger.log("Added " + additions.size() + " statement" + - ((additions.size() > 1) ? "s" : "") + - " with predicate " + addedProperty.getURI() + - " (as an inverse to existing " + inverseOfAddedProperty.getURI() + - " statement" + ((additions.size() > 1) ? "s" : "") + ")"); - } - - } finally { - aboxModel.leaveCriticalSection(); - } + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + aboxModel.enterCriticalSection(Lock.WRITE); + + try { + StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null); + + while (iter.hasNext()) { + + Statement stmt = iter.next(); + + if (stmt.getObject().isResource()) { + Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject()); + additions.add(newStmt); + } else { + logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt)); + } + } + + aboxModel.add(additions); + record.recordAdditions(additions); + + if (additions.size() > 0) { + logger.log("Added " + additions.size() + " statement" + + ((additions.size() > 1) ? "s" : "") + + " with predicate " + addedProperty.getURI() + + " (as an inverse to existing " + inverseOfAddedProperty.getURI() + + " statement" + ((additions.size() > 1) ? "s" : "") + ")"); + } + + } finally { + aboxModel.leaveCriticalSection(); + } + } } } @@ -507,27 +545,35 @@ public class ABoxUpdater { } } - Model deletePropModel = ModelFactory.createDefaultModel(); - - if (replacementProperty == null) { - - aboxModel.enterCriticalSection(Lock.WRITE); - try { - deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null)); - aboxModel.remove(deletePropModel); - } finally { - aboxModel.leaveCriticalSection(); - } - record.recordRetractions(deletePropModel); - boolean plural = (deletePropModel.size() > 1); - if (deletePropModel.size() > 0) { - logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " + - propObj.getSourceURI()); - } - } else { - AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes()); - renameProperty(chg); - } + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); + Model deletePropModel = ModelFactory.createDefaultModel(); + + if (replacementProperty == null) { + + aboxModel.enterCriticalSection(Lock.WRITE); + try { + deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null)); + aboxModel.remove(deletePropModel); + } finally { + aboxModel.leaveCriticalSection(); + } + record.recordRetractions(deletePropModel); + boolean plural = (deletePropModel.size() > 1); + if (deletePropModel.size() > 0) { + logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " + + propObj.getSourceURI()); + } + } else { + AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes()); + renameProperty(chg); + } + } } @@ -548,35 +594,44 @@ public class ABoxUpdater { return; } - Model renamePropAddModel = ModelFactory.createDefaultModel(); - Model renamePropRetractModel = ModelFactory.createDefaultModel(); + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){ + continue; + } + Model aboxModel = dataset.getNamedModel(graph); - aboxModel.enterCriticalSection(Lock.WRITE); - try { - renamePropRetractModel.add( aboxModel.listStatements( - (Resource) null, oldProperty, (RDFNode) null)); - StmtIterator stmItr = renamePropRetractModel.listStatements(); - while(stmItr.hasNext()) { - Statement tempStatement = stmItr.nextStatement(); - renamePropAddModel.add( tempStatement.getSubject(), - newProperty, - tempStatement.getObject() ); - } - aboxModel.remove(renamePropRetractModel); - aboxModel.add(renamePropAddModel); - } finally { - aboxModel.leaveCriticalSection(); - } - - record.recordAdditions(renamePropAddModel); - record.recordRetractions(renamePropRetractModel); - - if (renamePropRetractModel.size() > 0) { - logger.log("Changed " + renamePropRetractModel.size() + " statement" + - ((renamePropRetractModel.size() > 1) ? "s" : "") + - " with predicate " + propObj.getSourceURI() + " to use " + - propObj.getDestinationURI() + " instead"); - } + Model renamePropAddModel = ModelFactory.createDefaultModel(); + Model renamePropRetractModel = ModelFactory.createDefaultModel(); + + aboxModel.enterCriticalSection(Lock.WRITE); + try { + renamePropRetractModel.add( aboxModel.listStatements( + (Resource) null, oldProperty, (RDFNode) null)); + StmtIterator stmItr = renamePropRetractModel.listStatements(); + while(stmItr.hasNext()) { + Statement tempStatement = stmItr.nextStatement(); + renamePropAddModel.add( tempStatement.getSubject(), + newProperty, + tempStatement.getObject() ); + } + aboxModel.remove(renamePropRetractModel); + aboxModel.add(renamePropAddModel); + } finally { + aboxModel.leaveCriticalSection(); + } + + record.recordAdditions(renamePropAddModel); + record.recordRetractions(renamePropRetractModel); + + if (renamePropRetractModel.size() > 0) { + logger.log("Changed " + renamePropRetractModel.size() + " statement" + + ((renamePropRetractModel.size() > 1) ? "s" : "") + + " with predicate " + propObj.getSourceURI() + " to use " + + propObj.getDestinationURI() + " instead"); + } + } } public void logChanges(Statement oldStatement, Statement newStatement) throws IOException { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index b8ab33744..573f03298 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -24,19 +24,16 @@ 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.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.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.shared.Lock; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; @@ -123,10 +120,10 @@ public class KnowledgeBaseUpdater { updateABox(changes); log.info("performing SPARQL CONSTRUCT additions"); - performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), readModel, writeModel, ADD); + performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD); log.info("performing SPARQL CONSTRUCT retractions"); - performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), readModel, writeModel, RETRACT); + performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT); } @@ -144,10 +141,11 @@ public class KnowledgeBaseUpdater { * @param add (add = true; retract = false) */ private void performSparqlConstructs(String sparqlConstructDir, - OntModel readModel, OntModel writeModel, + RDFService rdfService, boolean add) throws IOException { + Dataset dataset = new RDFServiceDataset(rdfService); File sparqlConstructDirectory = new File(sparqlConstructDir); - log.info("Using SPARQL CONSTRUCT director " + sparqlConstructDirectory); + log.info("Using SPARQL CONSTRUCT directory " + sparqlConstructDirectory); if (!sparqlConstructDirectory.isDirectory()) { String logMsg = this.getClass().getName() + "performSparqlConstructs() expected to find a directory " + @@ -161,7 +159,6 @@ public class KnowledgeBaseUpdater { Collections.sort(sparqlFiles); // queries may depend on being run in a certain order JenaIngestUtils jiu = new JenaIngestUtils(); for (File sparqlFile : sparqlFiles) { - Model anonModel = ModelFactory.createDefaultModel(); StringBuffer fileContents = new StringBuffer(); try { BufferedReader reader = new BufferedReader(new FileReader(sparqlFile)); @@ -176,59 +173,68 @@ public class KnowledgeBaseUpdater { log.info(logMsg); continue; } + Model anonModel = ModelFactory.createDefaultModel(); try { log.info("\t\tprocessing SPARQL construct query from file " + sparqlFile.getName()); - Query q = QueryFactory.create(fileContents.toString(), Syntax.syntaxARQ); - readModel.enterCriticalSection(Lock.READ); - try { - QueryExecution qe = QueryExecutionFactory.create(q, readModel); - long numBefore = anonModel.size(); - qe.execConstruct(anonModel); - long numAfter = anonModel.size(); - long num = numAfter - numBefore; - if (num > 0) { - String logMsg = (add ? "Added " : "Removed ") + num + - " statement" + ((num > 1) ? "s" : "") + - " using the SPARQL construct query from file " + - sparqlFile.getParentFile().getName() + - "/" + sparqlFile.getName(); - logger.log(logMsg); - log.info(logMsg); - } - qe.close(); - } finally { - readModel.leaveCriticalSection(); + + anonModel = RDFServiceUtils.parseModel( + rdfService.sparqlConstructQuery(fileContents.toString(), + RDFService.ModelSerializationFormat.NTRIPLE), + ModelSerializationFormat.NTRIPLE); + + long num = anonModel.size(); + if (num > 0) { + String logMsg = (add ? "Added " : "Removed ") + num + + " statement" + ((num > 1) ? "s" : "") + + " using the SPARQL construct query from file " + + sparqlFile.getParentFile().getName() + + "/" + sparqlFile.getName(); + logger.log(logMsg); + log.info(logMsg); } + } catch (Exception e) { logger.logError(this.getClass().getName() + ".performSparqlConstructs() unable to execute " + "query at " + sparqlFile + ". Error message is: " + e.getMessage()); log.error(e,e); } - writeModel.enterCriticalSection(Lock.WRITE); - try { - if(!add) { - writeModel.remove(anonModel); - record.recordRetractions(anonModel); - //log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs"); - } else { - Model additions = jiu.renameBNodes( - anonModel, settings.getDefaultNamespace() + "n", writeModel); - Model actualAdditions = ModelFactory.createDefaultModel(); - StmtIterator stmtIt = additions.listStatements(); - while (stmtIt.hasNext()) { - Statement stmt = stmtIt.nextStatement(); - if (!writeModel.contains(stmt)) { - actualAdditions.add(stmt); + + if(!add) { + StmtIterator sit = anonModel.listStatements(); + while (sit.hasNext()) { + Statement stmt = sit.nextStatement(); + Iterator graphIt = dataset.listNames(); + while(graphIt.hasNext()) { + String graph = graphIt.next(); + if(!isUpdatableABoxGraph(graph)) { + continue; } - } - writeModel.add(actualAdditions); - //log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs"); - record.recordAdditions(actualAdditions); - } - } finally { - writeModel.leaveCriticalSection(); + Model writeModel = dataset.getNamedModel(graph); + if (writeModel.contains(stmt)) { + writeModel.remove(stmt); + } + } + } + record.recordRetractions(anonModel); + //log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs"); + } else { + Model writeModel = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL); + Model additions = jiu.renameBNodes( + anonModel, settings.getDefaultNamespace() + "n", writeModel); + Model actualAdditions = ModelFactory.createDefaultModel(); + StmtIterator stmtIt = additions.listStatements(); + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.nextStatement(); + if (!writeModel.contains(stmt)) { + actualAdditions.add(stmt); + } + } + writeModel.add(actualAdditions); + //log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs"); + record.recordAdditions(actualAdditions); } + } } @@ -245,8 +251,8 @@ public class KnowledgeBaseUpdater { OntModel oldTBoxModel = settings.getOldTBoxModel(); OntModel newTBoxModel = settings.getNewTBoxModel(); - OntModel ABoxModel = settings.getAssertionOntModelSelector().getABoxModel(); - ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, ABoxModel,settings.getNewTBoxAnnotationsModel(), logger, record); + RDFService rdfService = settings.getRDFService(); + ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, rdfService, settings.getNewTBoxAnnotationsModel(), logger, record); aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges()); aboxUpdater.processClassChanges(changes.getAtomicClassChanges()); } @@ -366,8 +372,10 @@ public class KnowledgeBaseUpdater { " update to new ontology version: ", e); } } - - + + public static boolean isUpdatableABoxGraph(String graphName) { + return (!graphName.contains("tbox") && !graphName.contains("filegraph")); + } /** * A class that allows to access two different ontology change lists, @@ -434,5 +442,6 @@ public class KnowledgeBaseUpdater { public List getAtomicPropertyChanges() { return atomicPropertyChanges; } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java index f6e9cf9da..309198e2c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java @@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; public class UpdateSettings { @@ -37,6 +38,8 @@ public class UpdateSettings { private OntModel newDisplayModelFromFile; private OntModel loadedAtStartupDisplayModel; private OntModel oldDisplayModelVivoListViewConfig; + private RDFService rdfService; + public String getDataDir() { return dataDir; } @@ -223,6 +226,13 @@ public class UpdateSettings { return this.oldDisplayModelVivoListViewConfig; } + public RDFService getRDFService() { + return this.rdfService; + } + + public void setRDFService(RDFService rdfService) { + this.rdfService = rdfService; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 3defaa3cc..cf53c8f1f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -41,6 +41,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -95,6 +98,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "everytime").toString()); settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); + settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService()); boolean tryMigrateDisplay = true; try { From d2d813ab62c18f022c3e7d41c3c6c06304b74cfa Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 13 Sep 2013 11:17:08 -0400 Subject: [PATCH 25/44] VIVO-158 fixes ConcurrentModificationException in SimpleReasoner.addedTBoxStatement() --- .../vitro/webapp/reasoner/SimpleReasoner.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index b0cb19d29..11ebcefa3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -251,18 +251,24 @@ public class SimpleReasoner extends StatementListener { return; } - OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI()); - if (subject == null) { - log.debug("didn't find subject class in the tbox: " - + (stmt.getSubject()).getURI()); - return; - } - - OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI()); - if (object == null) { - log.debug("didn't find object class in the tbox: " - + ((Resource)stmt.getObject()).getURI()); - return; + OntClass subject, object; + tboxModel.enterCriticalSection(Lock.READ); + try { + subject = tboxModel.getOntClass((stmt.getSubject()).getURI()); + if (subject == null) { + log.debug("didn't find subject class in the tbox: " + + (stmt.getSubject()).getURI()); + return; + } + + object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI()); + if (object == null) { + log.debug("didn't find object class in the tbox: " + + ((Resource)stmt.getObject()).getURI()); + return; + } + } finally { + tboxModel.leaveCriticalSection(); } if (stmt.getPredicate().equals(RDFS.subClassOf)) { From 772cfe127e82cdfafe672f2d0a977b0d46d55064 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 13 Sep 2013 11:59:27 -0400 Subject: [PATCH 26/44] VIVO-97 removed unconditional cast to WebappDaoFactoryJena in SimpleReasonerSetup --- .../webapp/servlet/setup/SimpleReasonerSetup.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index d8ae881ae..44e00ac53 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -56,7 +56,7 @@ public class SimpleReasonerSetup implements ServletContextListener { OntModelSelector inferencesOms = ModelAccess.on(ctx).getInferenceOntModelSelector(); OntModelSelector unionOms = ModelAccess.on(ctx).getUnionOntModelSelector(); - WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) ModelAccess.on(ctx).getWebappDaoFactory(); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); if (!assertionsOms.getTBoxModel().getProfile().NAMESPACE().equals(OWL.NAMESPACE.getNameSpace())) { log.error("Not connecting Pellet reasoner - the TBox assertions model is not an OWL model"); @@ -75,19 +75,14 @@ public class SimpleReasonerSetup implements ServletContextListener { sce.getServletContext().setAttribute("pelletListener",pelletListener); sce.getServletContext().setAttribute("pelletOntModel", pelletListener.getPelletModel()); - if (wadf != null) { - wadf.setPelletListener(pelletListener); + if (wadf instanceof WebappDaoFactoryJena) { + ((WebappDaoFactoryJena) wadf).setPelletListener(pelletListener); } log.info("Pellet reasoner connected for the TBox"); - // set up simple reasoning for the ABox - - DataSource bds = JenaDataSourceSetupBase - .getApplicationDataSource(ctx); - String dbType = ConfigurationProperties.getBean(ctx).getProperty( // database type - "VitroConnection.DataSource.dbtype","MySQL"); - + // set up simple reasoning for the ABox + RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(); Dataset dataset = new RDFServiceDataset(rdfService); From a74677dae49bb0dfe3570981e01968c1ad9a9d69 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 13 Sep 2013 13:49:19 -0400 Subject: [PATCH 27/44] VIVO-150 avoiding lock contention on login during inference rebuild --- .../vitro/webapp/servlet/setup/SimpleReasonerSetup.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index 44e00ac53..8620dbc7e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -87,11 +87,12 @@ public class SimpleReasonerSetup implements ServletContextListener { Dataset dataset = new RDFServiceDataset(rdfService); Model rebuildModel = dataset.getNamedModel(JENA_INF_MODEL_REBUILD); - Model scratchModel = dataset.getNamedModel(JENA_INF_MODEL_SCRATCHPAD); + Model scratchModel = dataset.getNamedModel(JENA_INF_MODEL_SCRATCHPAD); + Model inferenceModel = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL); // the simple reasoner will register itself as a listener to the ABox assertions SimpleReasoner simpleReasoner = new SimpleReasoner( - unionOms.getTBoxModel(), rdfService, inferencesOms.getABoxModel(), rebuildModel, scratchModel); + unionOms.getTBoxModel(), rdfService, inferenceModel, rebuildModel, scratchModel); sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner); StartupStatus ss = StartupStatus.getBean(ctx); From 73d54999d459d0a98ff714e8310395e783173bd8 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 13 Sep 2013 15:01:57 -0400 Subject: [PATCH 28/44] VIVO-151 remedies missing inverse property inference deletions --- .../webapp/dao/jena/pellet/ReasonerConfiguration.java | 4 ++-- .../mannlib/vitro/webapp/reasoner/SimpleReasoner.java | 4 ++++ .../reasoner/SimpleReasonerInversePropertyTest.java | 9 ++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ReasonerConfiguration.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ReasonerConfiguration.java index 5b833a1a4..970c14e4d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ReasonerConfiguration.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ReasonerConfiguration.java @@ -30,8 +30,7 @@ public class ReasonerConfiguration { /** * The default reasoner configuration is designed to provide acceptable performance on larger knowledge bases. * It will classify and realize, and add inferred disjointWith statements. - * It ignores domain and range "axioms," on the assumption that they are not truly axioms but editing constraints. - * It also ignores "owl:inverseOf." + * It ignores domain and range "axioms," on the assumption that they are not truly axioms but editing constraints. */ public static ReasonerConfiguration DEFAULT; @@ -78,6 +77,7 @@ public class ReasonerConfiguration { defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.first,null)); defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.rest,null)); defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.disjointWith,null)); + defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.inverseOf,null)); DEFAULT.setInferenceDrivingPatternAllowSet(defaultInferenceDrivingPatternAllowSet); Set defaultInferenceReceivingPatternAllowSet = new HashSet(); defaultInferenceReceivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.type,null)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index 11ebcefa3..4374f0b58 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -1678,6 +1678,10 @@ public class SimpleReasoner extends StatementListener { typeURIs = getRemainingAssertedTypeURIs(stmt.getSubject()); } removedABoxTypeAssertion(stmt, inferenceModel, typeURIs); + } else if (doSameAs && stmt.getPredicate().equals(OWL.sameAs)) { + removedABoxSameAsAssertion(stmt, inferenceModel); + } else { + removedABoxAssertion(stmt, inferenceModel); } doPlugins(ModelUpdate.Operation.RETRACT,stmt); } catch (NullPointerException npe) { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java index e0f81bb74..0003d576a 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java @@ -81,7 +81,14 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { aBox.add(a,P,b); Assert.assertTrue(inf.contains(b,Q,a)); aBox.add(c,Q,d); - Assert.assertTrue(inf.contains(d,P,c)); + Assert.assertTrue(inf.contains(d,P,c)); + + // delete assertions and verify that inferences go away + aBox.remove(c,Q,d); + Assert.assertFalse(inf.contains(d,P,c)); + aBox.remove(a,P,b); + Assert.assertFalse(inf.contains(b,Q,a)); + } @Test From 0dc3956b09db1110f05705f5e30af90c21d59593 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 13 Sep 2013 17:03:38 -0400 Subject: [PATCH 29/44] VIVO-187 validation for URIs entered on ontology creation form --- .../vedit/validator/impl/UrlValidator.java | 27 ++++++++++++------- .../edit/OntologyRetryController.java | 12 ++++++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vedit/validator/impl/UrlValidator.java b/webapp/src/edu/cornell/mannlib/vedit/validator/impl/UrlValidator.java index 5d580f58e..b2cb5a3bb 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/validator/impl/UrlValidator.java +++ b/webapp/src/edu/cornell/mannlib/vedit/validator/impl/UrlValidator.java @@ -2,28 +2,37 @@ package edu.cornell.mannlib.vedit.validator.impl; -import edu.cornell.mannlib.vedit.validator.Validator; +import java.util.Iterator; + +import com.hp.hpl.jena.iri.IRI; +import com.hp.hpl.jena.iri.IRIFactory; +import com.hp.hpl.jena.iri.Violation; + import edu.cornell.mannlib.vedit.validator.ValidationObject; -import java.util.regex.*; +import edu.cornell.mannlib.vedit.validator.Validator; public class UrlValidator implements Validator { public ValidationObject validate (Object obj) throws IllegalArgumentException { ValidationObject vo = new ValidationObject(); - String theString = null; if (!(obj instanceof String)){ throw new IllegalArgumentException("Expected instance of String"); } - Pattern pat = Pattern.compile("[a-z]{3,5}*://.*\\.[a-z]{2,4}"); - Matcher mat = pat.matcher(theString); - if (mat.matches()){ - vo.setValid(true); - } else { + IRIFactory factory = IRIFactory.jenaImplementation(); + IRI iri = factory.create((String) obj); + if (iri.hasViolation(false) ) { + String errorStr = ""; + Iterator violIt = iri.violations(false); + while(violIt.hasNext()) { + errorStr += violIt.next().getShortMessage() + " "; + } vo.setValid(false); - vo.setMessage("Please enter a valid URL"); + vo.setMessage("Please enter a valid URL. " + errorStr); + } else { + vo.setValid(true); } vo.setValidatedObject(obj); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/OntologyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/OntologyRetryController.java index e9d5405ee..f9814d647 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/OntologyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/OntologyRetryController.java @@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder; import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vedit.validator.Validator; import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator; +import edu.cornell.mannlib.vedit.validator.impl.UrlValidator; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.Ontology; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; @@ -47,7 +48,13 @@ public class OntologyRetryController extends BaseEditController { epo.setBeanClass(Ontology.class); epo.setBeanMask(testMask); - String action = "insert"; + String action = null; + if (epo.getAction() == null) { + action = "insert"; + epo.setAction("insert"); + } else { + action = epo.getAction(); + } OntologyDao oDao = request.getUnfilteredWebappDaoFactory().getOntologyDao(); epo.setDataAccessObject(oDao); @@ -67,13 +74,12 @@ public class OntologyRetryController extends BaseEditController { epo.setOriginalBean(ontologyForEditing); } else { ontologyForEditing = (Ontology) epo.getNewBean(); - action = "update"; - log.error("using newBean"); } //validators List validatorList = new ArrayList(); validatorList.add(new RequiredFieldValidator()); + validatorList.add(new UrlValidator()); epo.getValidatorMap().put("URI", validatorList); //make a simple mask for the class's id From e739a94222d1208d7254db467b63ebd2bea219ce Mon Sep 17 00:00:00 2001 From: tworrall Date: Wed, 18 Sep 2013 11:34:32 -0400 Subject: [PATCH 30/44] VIVO-112: ISF changes relating to vcard classes --- .../forms/js/customFormWithAutocomplete.js | 2 +- .../freemarker/lib/lib-properties.ftl | 38 ++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js index d02e8e8d0..a25899d85 100644 --- a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js +++ b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js @@ -144,7 +144,7 @@ var customForm = { // Put this case first, because in edit mode with // validation errors we just want initFormFullView. // if ((!this.supportEdit) && (this.editMode == 'edit' || this.editMode == 'repair')) { - if (this.editMode == 'edit' || this.editMode == 'repair') { + if (this.editMode == 'edit' || this.editMode == 'repair' || this.editMode == 'error') { this.initFormWithValidationErrors(); } else if (this.findValidationErrors()) { diff --git a/webapp/web/templates/freemarker/lib/lib-properties.ftl b/webapp/web/templates/freemarker/lib/lib-properties.ftl index bdfc721d5..8c73e8445 100644 --- a/webapp/web/templates/freemarker/lib/lib-properties.ftl +++ b/webapp/web/templates/freemarker/lib/lib-properties.ftl @@ -108,13 +108,13 @@ name will be used as the label. --> <#if editable> <#local url = property.addUrl> <#if url?has_content> - <@showAddLink property.localName label url /> + <@showAddLink property.localName property.name label url /> -<#macro showAddLink propertyLocalName label url> - <#if propertyLocalName == "informationResourceInAuthorship" || propertyLocalName == "webpage" || propertyLocalName == "hasResearchArea"> +<#macro showAddLink propertyLocalName propertyName label url> + <#if propertyName == "informationResourceInAuthorship" || propertyName == "webpage" || propertyLocalName == "hasResearchArea"> ${i18n().manage} <#else> @@ -131,30 +131,42 @@ name will be used as the label. --> <#macro propertyListItem property statement editable >
  • <#nested> - <@editingLinks "${property.localName}" statement editable/> + <@editingLinks "${property.localName}" "${property.name}" statement editable/>
  • -<#macro editingLinks propertyLocalName statement editable> - <#if editable && (propertyLocalName != "informationResourceInAuthorship" && propertyLocalName != "webpage" && propertyLocalName != "hasResearchArea")> - <@editLink propertyLocalName statement /> - <@deleteLink propertyLocalName statement /> +<#macro editingLinks propertyLocalName propertyName statement editable> + <#if editable && (propertyName != "authors" && propertyName != "webpage" && propertyLocalName != "hasResearchArea")> + <@editLink propertyLocalName propertyName statement /> + <@deleteLink propertyLocalName propertyName statement /> - -<#macro editLink propertyLocalName statement> +<#macro editLink propertyLocalName propertyName statement> +<#if propertyLocalName?contains("ARG_2000028")> + <#if propertyName?contains("mailing address")> + <#local url = statement.editUrl + "&addressUri=" + "${statement.address!}"> + <#elseif propertyName?contains("phone")> + <#local url = statement.editUrl + "&phoneUri=" + "${statement.phone!}"> + <#elseif propertyName?contains("primary email") || propertyName?contains("additional emails")> + <#local url = statement.editUrl + "&emailUri=" + "${statement.email!}"> + <#elseif propertyName?contains("full name")> + <#local url = statement.editUrl + "&fullNameUri=" + "${statement.fullName!}"> + +<#else> <#local url = statement.editUrl> + <#if url?has_content> <@showEditLink propertyLocalName url /> + <#macro showEditLink propertyLocalName url> ${i18n().edit_entry} -<#macro deleteLink propertyLocalName statement> +<#macro deleteLink propertyLocalName propertyName statement> <#local url = statement.deleteUrl> <#if url?has_content> <@showDeleteLink propertyLocalName url /> @@ -197,7 +209,7 @@ name will be used as the label. --> ${individual.name} - <@editingLinks "${mainImage.localName}" mainImage.first() editable /> + <@editingLinks "${mainImage.localName}" "" mainImage.first() editable /> <#else> <#local imageLabel><@addLinkWithLabel mainImage editable "${i18n().photo}" /> ${imageLabel} @@ -218,7 +230,7 @@ name will be used as the label. --> <#local label = individual.nameStatement> ${label.value} <#if useEditLink> - <@editingLinks "label" label editable /> + <@editingLinks "label" "" label editable /> <#elseif editable || (labelCount > 1)> <#--We display the link even when the user is not logged in case of multiple labels--> <#if editable> From c062201a9a98109ef8a20ff63fa91ce7590162b8 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 18 Sep 2013 16:21:36 -0400 Subject: [PATCH 31/44] annotation data migration --- .../vitro/webapp/dao/VitroVocabulary.java | 2 + .../dao/jena/ObjectPropertyDaoJena.java | 1 - .../webapp/ontology/update/ABoxUpdater.java | 16 +- .../ontology/update/KnowledgeBaseUpdater.java | 41 +- .../webapp/ontology/update/TBoxUpdater.java | 886 ++++++++++-------- .../ontology/update/UpdateSettings.java | 9 +- .../servlet/setup/UpdateKnowledgeBase.java | 16 +- 7 files changed, 569 insertions(+), 402 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java index a24f26c3e..d06f6ccab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java @@ -12,6 +12,8 @@ public class VitroVocabulary { public static final String VITRO_AUTH = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#"; public static final String VITRO_PUBLIC = "http://vitro.mannlib.cornell.edu/ns/vitro/public#"; public static final String VITRO_PUBLIC_ONTOLOGY = "http://vitro.mannlib.cornell.edu/ns/vitro/public"; + // TODO change the following before 1.6 release + public static final String PROPERTY_CONFIG_DATA = "http://example.org/appConfig/"; /** BJL23 2008-02-25: diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 4ca5fe172..487d2a116 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -949,7 +949,6 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp " { ?property display:listViewConfigFile ?filename \n" + " } UNION { \n" + " ?configuration config:listViewConfigFile ?filename . \n " + -// " ?configuration config:hasListView ?lv . " + " ?context config:hasConfiguration ?configuration . \n" + " ?context config:configContextFor ?property . \n" + " ?context config:qualifiedBy ?range . \n" + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java index da1af4423..7e59ad681 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java @@ -44,6 +44,7 @@ public class ABoxUpdater { private Dataset dataset; private RDFService rdfService; private OntModel newTBoxAnnotationsModel; + private TBoxUpdater tboxUpdater; private ChangeLogger logger; private ChangeRecord record; private OntClass OWL_THING = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createClass(OWL.Thing.getURI()); @@ -61,20 +62,19 @@ public class ABoxUpdater { * and the retractions model. * */ - public ABoxUpdater(OntModel oldTboxModel, - OntModel newTboxModel, - RDFService rdfService, - OntModel newAnnotationsModel, + public ABoxUpdater(UpdateSettings settings, ChangeLogger logger, ChangeRecord record) { - this.oldTboxModel = oldTboxModel; - this.newTboxModel = newTboxModel; + this.oldTboxModel = settings.getOldTBoxModel(); + this.newTboxModel = settings.getNewTBoxModel(); + RDFService rdfService = settings.getRDFService(); this.dataset = new RDFServiceDataset(rdfService); this.rdfService = rdfService; - this.newTBoxAnnotationsModel = newAnnotationsModel; + this.newTBoxAnnotationsModel = settings.getNewTBoxAnnotationsModel(); this.logger = logger; this.record = record; + this.tboxUpdater = new TBoxUpdater(settings, logger, record); } /** @@ -632,6 +632,8 @@ public class ABoxUpdater { propObj.getDestinationURI() + " instead"); } } + + tboxUpdater.renameProperty(propObj); } public void logChanges(Statement oldStatement, Statement newStatement) throws IOException { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 573f03298..ac5cda224 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -64,7 +64,6 @@ public class KnowledgeBaseUpdater { } long startTime = System.currentTimeMillis(); - System.out.println("Migrating the knowledge base"); log.info("Migrating the knowledge base"); logger.log("Started knowledge base migration"); @@ -84,7 +83,6 @@ public class KnowledgeBaseUpdater { logger.closeLogs(); long elapsedSecs = (System.currentTimeMillis() - startTime)/1000; - System.out.println("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : "")); log.info("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : "")); return; @@ -110,20 +108,15 @@ public class KnowledgeBaseUpdater { } catch (Exception e) { log.error("unable to migrate migration metadata " + e.getMessage()); } - - log.warn("KnowledgeBaseUpdater needs to be modified to work on all graphs!"); - OntModel readModel = settings.getUnionOntModelSelector().getABoxModel(); - OntModel writeModel = settings.getAssertionOntModelSelector().getABoxModel(); - // TODO make sure the ABox update applies to all graphs - - log.info("\tupdating the abox"); - updateABox(changes); - + log.info("performing SPARQL CONSTRUCT additions"); performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD); log.info("performing SPARQL CONSTRUCT retractions"); performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT); + + log.info("\tupdating the abox"); + updateABox(changes); } @@ -249,10 +242,8 @@ public class KnowledgeBaseUpdater { private void updateABox(AtomicOntologyChangeLists changes) throws IOException { - OntModel oldTBoxModel = settings.getOldTBoxModel(); - OntModel newTBoxModel = settings.getNewTBoxModel(); - RDFService rdfService = settings.getRDFService(); - ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, rdfService, settings.getNewTBoxAnnotationsModel(), logger, record); + + ABoxUpdater aboxUpdater = new ABoxUpdater(settings, logger, record); aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges()); aboxUpdater.processClassChanges(changes.getAtomicClassChanges()); } @@ -290,14 +281,18 @@ public class KnowledgeBaseUpdater { rdfService.changeSetUpdate(removeChangeSet); } - private void updateTBoxAnnotations() throws IOException { - - TBoxUpdater tboxUpdater = new TBoxUpdater(settings.getOldTBoxAnnotationsModel(), - settings.getNewTBoxAnnotationsModel(), - settings.getAssertionOntModelSelector().getTBoxModel(), logger, record); - - tboxUpdater.updateDefaultAnnotationValues(); - //tboxUpdater.updateAnnotationModel(); + private void updateTBoxAnnotations() { + TBoxUpdater tboxUpdater = new TBoxUpdater(settings, logger, record); + try { + tboxUpdater.modifyPropertyQualifications(); + } catch (Exception e) { + log.error("Unable to modify qualified property config file ", e); + } + try { + tboxUpdater.updateDefaultAnnotationValues(); + } catch (Exception e) { + log.error("Unable to update default annotation values ", e); + } } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java index bf5c27817..9f3930d65 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java @@ -2,11 +2,22 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; +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.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; @@ -14,6 +25,7 @@ import com.hp.hpl.jena.rdf.model.NodeIterator; import com.hp.hpl.jena.rdf.model.Property; 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.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; @@ -21,403 +33,539 @@ import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; /** -* Performs knowledge base updates to the tbox to align with a new ontology version -* -*/ + * Performs knowledge base updates to the tbox to align with a new ontology version + * + */ public class TBoxUpdater { - private OntModel oldTboxAnnotationsModel; - private OntModel newTboxAnnotationsModel; - private OntModel siteModel; - private ChangeLogger logger; - private ChangeRecord record; - private boolean detailLogs = false; - - private static final String classGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#ClassGroup"; - private Resource classGroupClass = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource(classGroupURI); - private static final String inClassGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inClassGroup"; - private Property inClassGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty(inClassGroupURI); + private static final Log log = LogFactory.getLog(TBoxUpdater.class); - /** - * - * Constructor - * - * @param oldTboxAnnotationsModel - previous version of the annotations in the ontology - * @param newTboxAnnotationsModel - new version of the annotations in the ontology - * @param siteModel - the knowledge base to be updated - * @param logger - for writing to the change log - * and the error log. - * @param record - for writing to the additions model - * and the retractions model. - * - */ - public TBoxUpdater(OntModel oldTboxAnnotationsModel, - OntModel newTboxAnnotationsModel, - OntModel siteModel, - ChangeLogger logger, - ChangeRecord record) { - - this.oldTboxAnnotationsModel = oldTboxAnnotationsModel; - this.newTboxAnnotationsModel = newTboxAnnotationsModel; - this.siteModel = siteModel; - this.logger = logger; - this.record = record; - } - - /** - * - * Update a knowledge base to align with changes to vitro annotation property default - * values in a new version of the ontology. The two versions of the ontology and the - * knowledge base to be updated are provided in the class constructor and are - * referenced via class level variables. - * - * If the default value (i.e. the value that is provided in the vivo-core - * annotations files) of a vitro annotation property has been changed for a vivo - * core class, and that default value has not been changed in the site knowledge - * base, then update the value in the site knowledge base to be the new default. - * Also, if a new vitro annotation property setting (i.e. either an existing - * setting applied to an existing class where it wasn't applied before, or - * an existing setting applied to a new class) has been applied to a vivo - * core class then copy that new property statement into the site model. - * If a property setting for a class exists in the old ontology but - * not in the new one, then that statement will be removed from the - * site knowledge base. - * - * Writes to the change log file, the error log file, and the incremental change - * knowledge base. - * - * Note: as specified, this method for now assumes that no new vitro annotation - * properties have been introduced. This should be updated for future versions. - */ - public void updateDefaultAnnotationValues() throws IOException { - - siteModel.enterCriticalSection(Lock.WRITE); - - try { - - Model additions = ModelFactory.createDefaultModel(); - Model retractions = ModelFactory.createDefaultModel(); - - // Update defaults values for vitro annotation properties in the site model - // if the default has changed in the new version of the ontology AND if - // the site hasn't overidden the previous default in their knowledge base. - - if(oldTboxAnnotationsModel == null) { - logger.log("oldTboxAnnotationModel is null; aborting update of annotation values"); - return; - } - - StmtIterator iter = oldTboxAnnotationsModel.listStatements(); - - while (iter.hasNext()) { - - Statement stmt = iter.next(); - Resource subject = stmt.getSubject(); - Property predicate = stmt.getPredicate(); - RDFNode oldObject = stmt.getObject(); - - if (! ( (RDFS.getURI().equals(predicate.getNameSpace())) || - (VitroVocabulary.vitroURI.equals(predicate.getNameSpace())) - ) ) { - // this annotation updater is only concerned with properties - // such as rdfs:comment and properties in the vitro application - // namespace - continue; - } - - NodeIterator newObjects = newTboxAnnotationsModel.listObjectsOfProperty(subject, predicate); - - if ((newObjects == null) || (!newObjects.hasNext()) ) { - // first check to see if the site has a local value change - // that should override the deletion - List siteObjects = siteModel.listObjectsOfProperty(subject, predicate).toList(); - - if (siteObjects.size() > 1) { - /* + private UpdateSettings settings; + private OntModel oldTboxAnnotationsModel; + private OntModel newTboxAnnotationsModel; + private OntModel siteModel; + private ChangeLogger logger; + private ChangeRecord record; + private boolean detailLogs = false; + + private static final String classGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#ClassGroup"; + private Resource classGroupClass = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource(classGroupURI); + private static final String inClassGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inClassGroup"; + private Property inClassGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty(inClassGroupURI); + + /** + * + * Constructor + * + * @param oldTboxAnnotationsModel - previous version of the annotations in the ontology + * @param newTboxAnnotationsModel - new version of the annotations in the ontology + * @param siteModel - the knowledge base to be updated + * @param logger - for writing to the change log + * and the error log. + * @param record - for writing to the additions model + * and the retractions model. + * + */ + public TBoxUpdater(UpdateSettings settings, + ChangeLogger logger, + ChangeRecord record) { + this.settings = settings; + this.oldTboxAnnotationsModel = settings.getOldTBoxAnnotationsModel(); + this.newTboxAnnotationsModel = settings.getNewTBoxAnnotationsModel(); + this.siteModel = settings.getAssertionOntModelSelector().getTBoxModel(); + this.logger = logger; + this.record = record; + } + + /** + * Update application ontology data for domain and range-qualified properties + * to use any applicable settings from obsolete subproperties + */ + public void modifyPropertyQualifications() throws IOException { + + } + + private Model mergeConfigurations(Model oldConfig, Model newConfig) { + return null; + } + + public void updateDefaultAnnotationValues() throws IOException { + updateDefaultAnnotationValues(null); + } + + /** + * + * Update a knowledge base to align with changes to vitro annotation property default + * values in a new version of the ontology. The two versions of the ontology and the + * knowledge base to be updated are provided in the class constructor and are + * referenced via class level variables. + * + * If the default value (i.e. the value that is provided in the vivo-core + * annotations files) of a vitro annotation property has been changed for a vivo + * core class, and that default value has not been changed in the site knowledge + * base, then update the value in the site knowledge base to be the new default. + * Also, if a new vitro annotation property setting (i.e. either an existing + * setting applied to an existing class where it wasn't applied before, or + * an existing setting applied to a new class) has been applied to a vivo + * core class then copy that new property statement into the site model. + * If a property setting for a class exists in the old ontology but + * not in the new one, then that statement will be removed from the + * site knowledge base. + * + * Writes to the change log file, the error log file, and the incremental change + * knowledge base. + * + * Note: as specified, this method for now assumes that no new vitro annotation + * properties have been introduced. This should be updated for future versions. + */ + public void updateDefaultAnnotationValues(String subjectURI) throws IOException { + + siteModel.enterCriticalSection(Lock.WRITE); + + try { + + Model additions = ModelFactory.createDefaultModel(); + Model retractions = ModelFactory.createDefaultModel(); + + // Update defaults values for vitro annotation properties in the site model + // if the default has changed in the new version of the ontology AND if + // the site hasn't overidden the previous default in their knowledge base. + + if(oldTboxAnnotationsModel == null) { + logger.log("oldTboxAnnotationModel is null; aborting update of annotation values"); + return; + } + + Resource subj = (subjectURI == null) ? null : ResourceFactory.createResource(subjectURI); + + StmtIterator iter = oldTboxAnnotationsModel.listStatements(subj, null, (RDFNode) null); + + while (iter.hasNext()) { + + Statement stmt = iter.next(); + Resource subject = stmt.getSubject(); + Property predicate = stmt.getPredicate(); + RDFNode oldObject = stmt.getObject(); + + if (! ( (RDFS.getURI().equals(predicate.getNameSpace())) || + (VitroVocabulary.vitroURI.equals(predicate.getNameSpace())) + ) ) { + // this annotation updater is only concerned with properties + // such as rdfs:comment and properties in the vitro application + // namespace + continue; + } + + NodeIterator newObjects = newTboxAnnotationsModel.listObjectsOfProperty(subject, predicate); + + if ((newObjects == null) || (!newObjects.hasNext()) ) { + // first check to see if the site has a local value change + // that should override the deletion + List siteObjects = siteModel.listObjectsOfProperty(subject, predicate).toList(); + + if (siteObjects.size() > 1) { + /* logger.log("WARNING: found " + siteObjects.size() + " statements with subject = " + subject.getURI() + " and property = " + predicate.getURI() + " in the site database (maximum of one is expected)"); - */ - } - - if (siteObjects.size() > 0) { - RDFNode siteNode = siteObjects.get(0); - if (siteNode.equals(oldObject)) { - retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null)); - } - } - - continue; - } - - RDFNode newObject = newObjects.next(); - - int i = 1; - while (newObjects.hasNext()) { - i++; - newObjects.next(); - } - - if (i > 1) { - /* + */ + } + + if (siteObjects.size() > 0) { + RDFNode siteNode = siteObjects.get(0); + if (siteNode.equals(oldObject)) { + retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null)); + } + } + + continue; + } + + RDFNode newObject = newObjects.next(); + + int i = 1; + while (newObjects.hasNext()) { + i++; + newObjects.next(); + } + + if (i > 1) { + /* logger.log("WARNING: found " + i + " statements with subject = " + subject.getURI() + " and property = " + predicate.getURI() + " in the new version of the annotations ontology (maximum of one is expected)"); - */ - continue; - } - - // If a subject-property pair occurs in the old annotation TBox and the new annotations - // TBox, but not in the site model, then it is considered an erroneous deletion and - // the value from the new TBox is added into the site model. - // sjm: 7-16-2010. We want this here now to add back in annotations mistakenly dropped - // in the .9 to 1.0 migration, but I'm not sure we would want this here permanently. - // Shouldn't a site be allowed to delete annotations if they want to? - - NodeIterator siteObjects = siteModel.listObjectsOfProperty(subject,predicate); - - if (siteObjects == null || !siteObjects.hasNext()) { - try { - additions.add(subject, predicate, newObject); - - if (detailLogs) { - logger.log( "adding Statement: subject = " + subject.getURI() + - " property = " + predicate.getURI() + - " object = " + (newObject.isLiteral() ? ((Literal)newObject).getLexicalForm() - : ((Resource)newObject).getURI())); - } - } catch (Exception e) { - logger.logError("Error trying to add statement with property " + predicate.getURI() + - " of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage()); - } - - continue; - } - - - if (!newObject.equals(oldObject)) { + */ + continue; + } - RDFNode siteObject = siteObjects.next(); + // If a subject-property pair occurs in the old annotation TBox and the new annotations + // TBox, but not in the site model, then it is considered an erroneous deletion and + // the value from the new TBox is added into the site model. + // sjm: 7-16-2010. We want this here now to add back in annotations mistakenly dropped + // in the .9 to 1.0 migration, but I'm not sure we would want this here permanently. + // Shouldn't a site be allowed to delete annotations if they want to? - i = 1; - while (siteObjects.hasNext()) { - i++; - siteObjects.next(); - } + NodeIterator siteObjects = siteModel.listObjectsOfProperty(subject,predicate); - if (i > 1) { - /* + if (siteObjects == null || !siteObjects.hasNext()) { + try { + additions.add(subject, predicate, newObject); + + if (detailLogs) { + logger.log( "adding Statement: subject = " + subject.getURI() + + " property = " + predicate.getURI() + + " object = " + (newObject.isLiteral() ? ((Literal)newObject).getLexicalForm() + : ((Resource)newObject).getURI())); + } + } catch (Exception e) { + logger.logError("Error trying to add statement with property " + predicate.getURI() + + " of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage()); + } + + continue; + } + + + if (!newObject.equals(oldObject)) { + + RDFNode siteObject = siteObjects.next(); + + i = 1; + while (siteObjects.hasNext()) { + i++; + siteObjects.next(); + } + + if (i > 1) { + /* logger.log("WARNING: found " + i + " statements with subject = " + subject.getURI() + " and property = " + predicate.getURI() + " in the site annotations model (maximum of one is expected) "); - */ - continue; - } - - if (siteObject.equals(oldObject)) { - try { - StmtIterator it = siteModel.listStatements(subject, predicate, (RDFNode)null); - while (it.hasNext()) { - retractions.add(it.next()); - } - } catch (Exception e) { - logger.logError("Error removing statement for subject = " + subject.getURI() + - "and property = " + predicate.getURI() + - "from the knowledge base:\n" + e.getMessage()); - } + */ + continue; + } - try { - additions.add(subject, predicate, newObject); - - if (detailLogs) { - logger.log("Changed the value of property " + predicate.getURI() + - " of subject = " + subject.getURI() + - " from " + - (oldObject.isResource() ? ((Resource)oldObject).getURI() : ((Literal)oldObject).getLexicalForm()) + - " to " + - (newObject.isResource() ? ((Resource)newObject).getURI() : ((Literal)newObject).getLexicalForm()) + - " in the knowledge base:\n"); - } - } catch (Exception e) { - logger.logError("Error trying to change the value of property " + predicate.getURI() + - " of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage()); - } - } - } - } - - Model actualAdditions = additions.difference(retractions); - siteModel.add(actualAdditions); - record.recordAdditions(actualAdditions); - Model actualRetractions = retractions.difference(additions); - siteModel.remove(actualRetractions); - record.recordRetractions(actualRetractions); - - long numAdded = actualAdditions.size(); - long numRemoved = actualRetractions.size(); - - // log summary of changes - if (numAdded > 0) { - logger.log("Updated the default vitro annotation value for " + - numAdded + " statements in the knowledge base"); - } - - if (numRemoved > 0) { - logger.log("Removed " + numRemoved + - " outdated vitro annotation property setting" + ((numRemoved > 1) ? "s" : "") + " from the knowledge base"); - } - - // Copy annotation property settings that were introduced in the new ontology - // into the site model. - // + if (siteObject.equals(oldObject)) { + try { + StmtIterator it = siteModel.listStatements(subject, predicate, (RDFNode)null); + while (it.hasNext()) { + retractions.add(it.next()); + } + } catch (Exception e) { + logger.logError("Error removing statement for subject = " + subject.getURI() + + "and property = " + predicate.getURI() + + "from the knowledge base:\n" + e.getMessage()); + } - Model newAnnotationSettings = newTboxAnnotationsModel.difference(oldTboxAnnotationsModel); - Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel(); - StmtIterator newStmtIt = newAnnotationSettings.listStatements(); - while (newStmtIt.hasNext()) { - Statement stmt = newStmtIt.next(); - if (!siteModel.contains(stmt)) { - newAnnotationSettingsToAdd.add(stmt); - - if (detailLogs) { - logger.log( "adding Statement: subject = " + stmt.getSubject().getURI() + - " property = " + stmt.getPredicate().getURI() + - " object = " + (stmt.getObject().isLiteral() ? ((Literal)stmt.getObject()).getLexicalForm() - : ((Resource)stmt.getObject()).getURI())); - } - } - } - - siteModel.add(newAnnotationSettingsToAdd); - record.recordAdditions(newAnnotationSettingsToAdd); - - // log the additions - summary - if (newAnnotationSettingsToAdd.size() > 0) { - boolean plural = (newAnnotationSettingsToAdd.size() > 1); - logger.log("Added " + newAnnotationSettingsToAdd.size() + " new annotation property setting" + (plural ? "s" : "") + " to the knowledge base. This includes only " + - "existing annotation properties applied to existing classes where they weren't applied before, or existing " + - "properties applied to new classes."); - } - - } finally { - siteModel.leaveCriticalSection(); - } -} - -/** - * - * Update a knowledge base to align with changes to the vitro annotation model - * in a new version of the ontology. The two versions of the ontology and the - * knowledge base to be updated are provided in the class constructor and are - * referenced via class level variables. - * - * Currently, this method only handles deletions of a ClassGroup - * - * Writes to the change log file, the error log file, and the incremental change - * knowledge base. - * - */ -public void updateAnnotationModel() throws IOException { - - // for each ClassGroup in the old vitro annotations model: if it is not in - // the new vitro annotations model and the site has no classes asserted to - // be in that class group then delete it. - - removeObsoleteAnnotations(); - - siteModel.enterCriticalSection(Lock.WRITE); - - try { - Model retractions = ModelFactory.createDefaultModel(); - - StmtIterator iter = oldTboxAnnotationsModel.listStatements((Resource) null, RDF.type, classGroupClass); - - while (iter.hasNext()) { - Statement stmt = iter.next(); - - if (!newTboxAnnotationsModel.contains(stmt) && !usesGroup(siteModel, stmt.getSubject())) { - long pre = retractions.size(); - retractions.add(siteModel.listStatements(stmt.getSubject(),(Property) null,(RDFNode)null)); - long post = retractions.size(); - if ((post - pre) > 0) { - logger.log("Removed the " + stmt.getSubject().getURI() + " ClassGroup from the annotations model"); - } - } - } - - if (retractions.size() > 0) { - siteModel.remove(retractions); - record.recordRetractions(retractions); - } - - } finally { - siteModel.leaveCriticalSection(); - } + try { + additions.add(subject, predicate, newObject); - // If we were going to handle add, this is the logic: - // for each ClassGroup in new old vitro annotations model: if it is not in - // the old vitro annotations and it is not in the site model, then - // add it. - -} + if (detailLogs) { + logger.log("Changed the value of property " + predicate.getURI() + + " of subject = " + subject.getURI() + + " from " + + (oldObject.isResource() ? ((Resource)oldObject).getURI() : ((Literal)oldObject).getLexicalForm()) + + " to " + + (newObject.isResource() ? ((Resource)newObject).getURI() : ((Literal)newObject).getLexicalForm()) + + " in the knowledge base:\n"); + } + } catch (Exception e) { + logger.logError("Error trying to change the value of property " + predicate.getURI() + + " of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage()); + } + } + } + } -public boolean usesGroup(Model model, Resource theClassGroup) throws IOException { - - model.enterCriticalSection(Lock.READ); - - try { - return (model.contains((Resource) null, inClassGroupProp, theClassGroup) ? true : false); - } finally { - model.leaveCriticalSection(); - } -} + Model actualAdditions = additions.difference(retractions); + siteModel.add(actualAdditions); + record.recordAdditions(actualAdditions); + Model actualRetractions = retractions.difference(additions); + siteModel.remove(actualRetractions); + record.recordRetractions(actualRetractions); -public void removeObsoleteAnnotations() throws IOException { - - Resource subj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology/florida#StatewideGoalAndFocusArea"); - Resource obj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroClassGrouptopics"); - - Property subj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#divisionOfSponsoredResearchNumber"); - Resource obj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupidentifiers"); - - Property subj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#statewideGoalAndFocusArea"); - Resource obj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupoutreach"); - - Property inPropertyGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inPropertyGroup"); - - siteModel.enterCriticalSection(Lock.WRITE); - - try { - Model retractions = ModelFactory.createDefaultModel(); - - if (siteModel.contains(subj1, inClassGroupProp, obj1) ) { - retractions.add(subj1, inClassGroupProp, obj1); - logger.log("Removed statement " + ABoxUpdater.stmtString(subj1, inClassGroupProp, obj1) + " from the knowledge base (assumed to be obsolete)"); + long numAdded = actualAdditions.size(); + long numRemoved = actualRetractions.size(); + + // log summary of changes + if (numAdded > 0) { + logger.log("Updated the default vitro annotation value for " + + numAdded + " statements in the knowledge base"); + } + + if (numRemoved > 0) { + logger.log("Removed " + numRemoved + + " outdated vitro annotation property setting" + ((numRemoved > 1) ? "s" : "") + " from the knowledge base"); + } + + // Copy annotation property settings that were introduced in the new ontology + // into the site model. + // + + Model newAnnotationSettings = newTboxAnnotationsModel.difference(oldTboxAnnotationsModel); + Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel(); + StmtIterator newStmtIt = newAnnotationSettings.listStatements(); + while (newStmtIt.hasNext()) { + Statement stmt = newStmtIt.next(); + if (!siteModel.contains(stmt)) { + newAnnotationSettingsToAdd.add(stmt); + + if (detailLogs) { + logger.log( "adding Statement: subject = " + stmt.getSubject().getURI() + + " property = " + stmt.getPredicate().getURI() + + " object = " + (stmt.getObject().isLiteral() ? ((Literal)stmt.getObject()).getLexicalForm() + : ((Resource)stmt.getObject()).getURI())); + } + } + } + + siteModel.add(newAnnotationSettingsToAdd); + record.recordAdditions(newAnnotationSettingsToAdd); + + // log the additions - summary + if (newAnnotationSettingsToAdd.size() > 0) { + boolean plural = (newAnnotationSettingsToAdd.size() > 1); + logger.log("Added " + newAnnotationSettingsToAdd.size() + " new annotation property setting" + (plural ? "s" : "") + " to the knowledge base. This includes only " + + "existing annotation properties applied to existing classes where they weren't applied before, or existing " + + "properties applied to new classes."); + } + + } finally { + siteModel.leaveCriticalSection(); + } + } + + /** + * + * Update a knowledge base to align with changes to the vitro annotation model + * in a new version of the ontology. The two versions of the ontology and the + * knowledge base to be updated are provided in the class constructor and are + * referenced via class level variables. + * + * Currently, this method only handles deletions of a ClassGroup + * + * Writes to the change log file, the error log file, and the incremental change + * knowledge base. + * + */ + public void updateAnnotationModel() throws IOException { + + // for each ClassGroup in the old vitro annotations model: if it is not in + // the new vitro annotations model and the site has no classes asserted to + // be in that class group then delete it. + + removeObsoleteAnnotations(); + + siteModel.enterCriticalSection(Lock.WRITE); + + try { + Model retractions = ModelFactory.createDefaultModel(); + + StmtIterator iter = oldTboxAnnotationsModel.listStatements((Resource) null, RDF.type, classGroupClass); + + while (iter.hasNext()) { + Statement stmt = iter.next(); + + if (!newTboxAnnotationsModel.contains(stmt) && !usesGroup(siteModel, stmt.getSubject())) { + long pre = retractions.size(); + retractions.add(siteModel.listStatements(stmt.getSubject(),(Property) null,(RDFNode)null)); + long post = retractions.size(); + if ((post - pre) > 0) { + logger.log("Removed the " + stmt.getSubject().getURI() + " ClassGroup from the annotations model"); + } + } + } + + if (retractions.size() > 0) { + siteModel.remove(retractions); + record.recordRetractions(retractions); + } + + } finally { + siteModel.leaveCriticalSection(); } - if (siteModel.contains(subj2, inPropertyGroupProp, obj2) ) { - retractions.add(subj2, inPropertyGroupProp, obj2); - logger.log("Removed statement " + ABoxUpdater.stmtString(subj2, inPropertyGroupProp, obj2) + " from the knowledge base (assumed to be obsolete)"); - } + // If we were going to handle add, this is the logic: + // for each ClassGroup in new old vitro annotations model: if it is not in + // the old vitro annotations and it is not in the site model, then + // add it. - if (siteModel.contains(subj3, inPropertyGroupProp, obj3) ) { - retractions.add(subj3, inPropertyGroupProp, obj3); - logger.log("Removed statement " + ABoxUpdater.stmtString(subj3, inPropertyGroupProp, obj3) + " from the knowledge base (assumed to be obsolete)"); + } + + public boolean usesGroup(Model model, Resource theClassGroup) throws IOException { + + model.enterCriticalSection(Lock.READ); + + try { + return (model.contains((Resource) null, inClassGroupProp, theClassGroup) ? true : false); + } finally { + model.leaveCriticalSection(); } - - if (retractions.size() > 0) { - siteModel.remove(retractions); - record.recordRetractions(retractions); - } - - } finally { - siteModel.leaveCriticalSection(); - } -} + } + + public void removeObsoleteAnnotations() throws IOException { + + Resource subj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology/florida#StatewideGoalAndFocusArea"); + Resource obj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroClassGrouptopics"); + + Property subj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#divisionOfSponsoredResearchNumber"); + Resource obj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupidentifiers"); + + Property subj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#statewideGoalAndFocusArea"); + Resource obj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupoutreach"); + + Property inPropertyGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inPropertyGroup"); + + siteModel.enterCriticalSection(Lock.WRITE); + + try { + Model retractions = ModelFactory.createDefaultModel(); + + if (siteModel.contains(subj1, inClassGroupProp, obj1) ) { + retractions.add(subj1, inClassGroupProp, obj1); + logger.log("Removed statement " + ABoxUpdater.stmtString(subj1, inClassGroupProp, obj1) + " from the knowledge base (assumed to be obsolete)"); + } + + if (siteModel.contains(subj2, inPropertyGroupProp, obj2) ) { + retractions.add(subj2, inPropertyGroupProp, obj2); + logger.log("Removed statement " + ABoxUpdater.stmtString(subj2, inPropertyGroupProp, obj2) + " from the knowledge base (assumed to be obsolete)"); + } + + if (siteModel.contains(subj3, inPropertyGroupProp, obj3) ) { + retractions.add(subj3, inPropertyGroupProp, obj3); + logger.log("Removed statement " + ABoxUpdater.stmtString(subj3, inPropertyGroupProp, obj3) + " from the knowledge base (assumed to be obsolete)"); + } + + if (retractions.size() > 0) { + siteModel.remove(retractions); + record.recordRetractions(retractions); + } + + } finally { + siteModel.leaveCriticalSection(); + } + } + + public void renameProperty(AtomicOntologyChange changeObj) throws IOException { + if(changeObj.getNotes() != null && changeObj.getNotes().startsWith("cc:")) { + mergePropertyAnnotationsToPropertyConfig(changeObj); + } + + } + + private void mergePropertyAnnotationsToPropertyConfig(AtomicOntologyChange changeObj) throws IOException { + String contextURI = VitroVocabulary.PROPERTY_CONFIG_DATA + changeObj.getNotes().substring(3); + String oldPropertyURI = changeObj.getSourceURI(); + + Model oldAnnotationsModel = settings.getOldTBoxAnnotationsModel(); + Dataset dataset = new RDFServiceDataset(settings.getRDFService()); + Model userAnnotationsModel = dataset.getNamedModel( + JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); + + String propertyAnnotationsQuery = + "PREFIX config: <" + VitroVocabulary.configURI + "> \n" + + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "CONSTRUCT { \n" + + " <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group . \n" + + " <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label . \n" + + " <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank . \n" + + " <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm . \n" + + " <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" + + " <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " + + "} WHERE { \n" + + " { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group } \n" + + " UNION { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label } \n" + + " UNION { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank } \n" + + " UNION { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm } \n" + + " UNION { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + + " UNION { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n " + + "} \n" ; + + Model userChangesModel = construct( + propertyAnnotationsQuery, userAnnotationsModel).difference( + construct(propertyAnnotationsQuery, oldAnnotationsModel)); + + String addQuery = "PREFIX config: <" + VitroVocabulary.configURI + "> \n" + + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "CONSTRUCT { \n" + + " ?configuration config:propertyGroup ?group . \n" + + " ?configuration config:displayName ?label . \n" + + " ?configuration vitro:displayRankAnnot ?displayRank . \n" + + " ?configuration vitro:customEntryFormAnnot ?customForm . \n" + + " ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" + + " ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " + + "} WHERE { \n" + + " <" + contextURI + "> config:hasConfiguration ?configuration . \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group } \n" + + " OPTIONAL { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n " + + "} \n" ; + + String retractQuery = "PREFIX config: <" + VitroVocabulary.configURI + "> \n" + + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "CONSTRUCT { \n" + + " <" + oldPropertyURI + "> config:propertyGroup ?rgroup . \n" + + " ?configuration config:displayName ?rlabel . \n" + + " ?configuration vitro:displayRankAnnot ?rdisplayRank . \n" + + " ?configuration vitro:customEntryFormAnnot ?rcustomForm . \n" + + " ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?rdisplayLevel . \n" + + " ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?rupdateLevel . \n " + + "} WHERE { \n" + + " <" + contextURI + "> config:hasConfiguration ?configuration . \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group . \n" + + " ?configuration config:propertyGroup ?rgroup } \n" + + " OPTIONAL { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label . \n" + + " ?configuration config:displayName ?rlabel } \n " + + " OPTIONAL { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank . \n" + + " ?configuration vitro:displayRantAnnot ?rdisplayRank } \n " + + " OPTIONAL { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm . \n" + + " ?configuration vitro:customEntryFormAnnot ?rcustomForm } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" + + " ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?rdisplayLevel } \n" + + " OPTIONAL { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " + + " ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } " + + "} \n" ; + + Model configModel = ModelFactory.createDefaultModel(); + String configFileName = settings.getQualifiedPropertyConfigFile(); + File file = new File(configFileName); + FileInputStream fis = new FileInputStream(file); + configModel.read(fis, null, "N3"); + + Model union = ModelFactory.createUnion(configModel, + userChangesModel); + + Model additions = construct(addQuery, union); + Model retractions = construct(retractQuery, union); + + if (additions.size() > 0 || retractions.size() > 0) { + configModel.remove(retractions); + log.info("Removing " + retractions.size() + " statements from " + contextURI); + configModel.add(additions); + log.info("Adding " + additions.size() + " statements from " + contextURI); + FileOutputStream fos = new FileOutputStream(file); + configModel.write(fos, "N3"); + } + } + + private Model construct(String queryStr, Model model) { + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.create(query, model); + try { + return qe.execConstruct(); + } finally { + qe.close(); + } + } } \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java index 309198e2c..1e37ded8f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/UpdateSettings.java @@ -21,6 +21,7 @@ public class UpdateSettings { private String errorLogFile; private String addedDataFile; private String removedDataFile; + private String qualifiedPropertyConfigFile; private String defaultNamespace; private OntModelSelector assertionOntModelSelector; private OntModelSelector inferenceOntModelSelector; @@ -121,7 +122,13 @@ public class UpdateSettings { public void setRemovedDataFile(String removedDataFile) { this.removedDataFile = removedDataFile; } - public String getDefaultNamespace() { + public String getQualifiedPropertyConfigFile() { + return qualifiedPropertyConfigFile; + } + public void setQualifiedPropertyConfigFile(String qualifiedPropertyConfigFile) { + this.qualifiedPropertyConfigFile = qualifiedPropertyConfigFile; + } + public String getDefaultNamespace() { return defaultNamespace; } public void setDefaultNamespace(String defaultNamespace) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index cf53c8f1f..569e4dbf4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -96,7 +96,7 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setNewTBoxModel(newTBoxModel); OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR)); settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); - OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "everytime").toString()); + OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "firsttime").toString()); settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService()); @@ -145,6 +145,9 @@ public class UpdateKnowledgeBase implements ServletContextListener { log.warn("unable to successfully update display model: " + e.getMessage()); } } + // reload the display model since the TBoxUpdater may have + // modified it + new ApplicationModelSetup().contextInitialized(sce); } } catch (Exception ioe) { ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe); @@ -189,8 +192,19 @@ public class UpdateKnowledgeBase implements ServletContextListener { Path logDir = createDirectory(dataDir, "logs"); settings.setLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate", "log")).toString()); settings.setErrorLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate.error", "log")).toString()); + + Path qualifiedPropertyConfigFile = getFilePath(homeDir, "rdf", "display", "everytime", "PropertyConfig.n3"); + settings.setQualifiedPropertyConfigFile(qualifiedPropertyConfigFile.toString()); } + private Path getFilePath(Path parent, String... children) throws IOException { + Path path = parent; + for (String child : children) { + path = path.resolve(child); + } + return path; + } + private Path createDirectory(Path parent, String... children) throws IOException { Path dir = parent; for (String child : children) { From 9cff04ce95916d5b6f4f8074d6b72fc0926fca4c Mon Sep 17 00:00:00 2001 From: tworrall Date: Wed, 18 Sep 2013 17:03:09 -0400 Subject: [PATCH 32/44] VIVO-296 autocomplete on concepts will no longer include subclasses such as Award --- .../forms/js/customFormWithAutocomplete.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js index a25899d85..50a0322be 100644 --- a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js +++ b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js @@ -297,6 +297,7 @@ var customForm = { //to the filtering list this.getAcFilterForIndividuals(); this.acCache = {}; + var theType = customForm.acTypes[$(selectedObj).attr('acGroupName')]; $(selectedObj).autocomplete({ minLength: 3, @@ -316,13 +317,17 @@ var customForm = { dataType: 'json', data: { term: request.term, - type: customForm.acTypes[$(selectedObj).attr('acGroupName')], + type: theType, multipleTypes:(customForm.acMultipleTypes == undefined || customForm.acMultipleTypes == null)? null: customForm.acMultipleTypes }, complete: function(xhr, status) { // Not sure why, but we need an explicit json parse here. - var results = $.parseJSON(xhr.responseText), - filteredResults = customForm.filterAcResults(results); + var results = $.parseJSON(xhr.responseText); + var filteredResults = customForm.filterAcResults(results); + + if ( theType == "http://www.w3.org/2004/02/skos/core#Concept" ) { + filteredResults = customForm.removeConceptSubclasses(filteredResults); + } customForm.acCache[request.term] = filteredResults; response(filteredResults); @@ -423,6 +428,16 @@ var customForm = { }, + removeConceptSubclasses: function(array) { + $(array).each(function(i) { + if(this["msType"] != "http://www.w3.org/2004/02/skos/core#Concept") { + //Remove from array + array.splice(i, 1); + } + }); + return array; + }, + showAutocompleteSelection: function(label, uri, selectedObj) { // hide the acSelector field and set it's value to the selected ac item this.hideFields($(selectedObj).parent()); From 3d81c5e1bbb2bcfc3ac58fdd48a2c5474fddc77b Mon Sep 17 00:00:00 2001 From: tworrall Date: Thu, 19 Sep 2013 09:53:16 -0400 Subject: [PATCH 33/44] VIVO-300: some i18n cleanup --- webapp/languages/example/i18n/all_es.properties | 6 ------ webapp/web/i18n/all.properties | 4 ---- 2 files changed, 10 deletions(-) diff --git a/webapp/languages/example/i18n/all_es.properties b/webapp/languages/example/i18n/all_es.properties index b092529ea..c2ea93a5d 100644 --- a/webapp/languages/example/i18n/all_es.properties +++ b/webapp/languages/example/i18n/all_es.properties @@ -199,7 +199,6 @@ remove_selection_title = eliminar la selección external_id_not_provided = Error de acceso - ID externo no se encuentra. external_id_already_in_use = Cuenta de usuario ya existe para'' {0}'' -logins_disabled_for_maintenance = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema. error_no_email = Debe proporcionar una dirección de correo electrónico. error_email_already_exists = Una cuenta con la dirección de correo electrónico ya existe. @@ -208,8 +207,6 @@ error_external_auth_already_exists = Una cuenta con dicho ID de autorización ex error_no_first_name = Debe proporcionar un nombre de pila. error_no_last_name = Debe proporcionar un apellido. error_no_role = Debe seleccionar una función. -error_no_password = Suministrado ninguna contraseña. -error_password_length = La contraseña debe tener entre {0} y {1} caracteres. error_password_mismatch = Las contraseñas no coinciden. logged_in_but_no_profile = Usted ha ingresado, pero el sistema no contiene ningún perfil para usted. @@ -644,7 +641,6 @@ account = cuenta change_password_to_login = Cambiar contraseña para iniciar sesión en new_password_capitalized = Nueva contraseña confirm_password_capitalized = Confirmar Contraseña -minimum_password_length = Mínimo de {0} caracteres de longitud. already_logged_in = Usted ya está registrado # @@ -828,7 +824,6 @@ supply_sparql_query = Debe proporcionar una consulta SPARQL. confirm_page_deletion = ¿Está seguro de que desea eliminar esta página: -hide_subclasses = ocultar subclases show_subclasses = mostrar subclases ontology_capitalized = Ontología subclasses_capitalized = Las subclases @@ -836,7 +831,6 @@ collapse_all = Contraer todo classes_capitalized = Clases display_rank = Mostrar Rango -hide_properties = ocultar las propiedades show_properties = mostrar las propiedades local_name = Nombre local group_capitalized = Grupo diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties index a2ff550d5..bf22b8814 100644 --- a/webapp/web/i18n/all.properties +++ b/webapp/web/i18n/all.properties @@ -211,7 +211,6 @@ remove_selection_title = remove selection external_id_not_provided = Login failed - External ID is not found. external_id_already_in_use = User account already exists for ''{0}'' -logins_disabled_for_maintenance = User logins are temporarily disabled while the system is being maintained. error_no_email = You must supply an email address. error_email_already_exists = An account with that email address already exists. @@ -220,8 +219,6 @@ error_external_auth_already_exists = An account with that external authorization error_no_first_name = You must supply a first name. error_no_last_name = You must supply a last name. error_no_role = You must select a role. -error_no_password = No password supplied. -error_password_length = Password must be between {0} and {1} characters. error_password_mismatch = Passwords do not match. logged_in_but_no_profile = You have logged in, but the system contains no profile for you. @@ -656,7 +653,6 @@ account = account change_password_to_login = Change Password to Log in new_password_capitalized = New Password confirm_password_capitalized = Confirm Password -minimum_password_length = Minimum of {0} characters in length. already_logged_in = You are already logged in. # From 7ad1ac635fe091f0bbaa5257e9b286a0b69495f5 Mon Sep 17 00:00:00 2001 From: tworrall Date: Thu, 19 Sep 2013 10:22:48 -0400 Subject: [PATCH 34/44] VIVO-300: some i18n cleanup --- webapp/web/i18n/all.properties | 84 +++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties index bf22b8814..7814b30f7 100644 --- a/webapp/web/i18n/all.properties +++ b/webapp/web/i18n/all.properties @@ -42,13 +42,13 @@ crop_page_title_with_name = Crop image for {0} current_photo = Current Photo upload_photo = Upload a photo replace_photo = Replace Photo -photo_types = (JPEG, GIF or PNG) +photo_types = (JPEG, GIF or PNG) maximum_file_size = Maximum file size: {0} megabytes minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels cropping_caption = Your profile photo will look like the image below. cropping_note = To make adjustments, you can drag around and resize the photo to the right. \ - When you are happy with your photo click the "Save Photo" button. +When you are happy with your photo click the "Save Photo" button. alt_thumbnail_photo = Individual photo alt_image_to_crop = Image to be cropped @@ -69,7 +69,7 @@ imageUpload.errorFileTooBig = Please upload an image smaller than {0} megabytes. imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only. imageUpload.errorNoPhotoSelected = Please browse and select a photo. imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. -imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." +imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." # # User Accounts pages @@ -84,28 +84,28 @@ last_login = Last Login add_new_account = Add new account edit_account = Edit account external_auth_only = Externally Authenticated Only -reset_password = Reset password +reset_password = Reset password reset_password_note = Note: Instructions for resetting the password will \ - be emailed to the address entered above. The password will not \ - be reset until the user follows the link provided in this email. +be emailed to the address entered above. The password will not \ +be reset until the user follows the link provided in this email. new_password = New password confirm_password = Confirm new password minimum_password_length = Minimum of {0} characters in length. leave_password_unchanged = Leaving this blank means that the password will not be changed. confirm_initial_password = Confirm initial password -new_account_1 = A new account for +new_account_1 = A new account for new_account_2 = was successfully created. new_account_title = new account new_account_notification = A notification email has been sent to {0} \ - with instructions for activating the account and creating a password. +with instructions for activating the account and creating a password. updated_account_1 = The account for updated_account_2 = has been updated. updated_account_title = updated account updated_account_notification = A confirmation email has been sent to {0} \ - with instructions for resetting a password. \ - The password will not be reset until the user follows the link provided in this email. -deleted_accounts = Deleted {0} {0, choice, 0#accounts |1#account |1 Date: Thu, 19 Sep 2013 10:29:23 -0400 Subject: [PATCH 35/44] VIVO-300: some i18n cleanup --- .../languages/example/i18n/all_es.properties | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/webapp/languages/example/i18n/all_es.properties b/webapp/languages/example/i18n/all_es.properties index c2ea93a5d..0688a577f 100644 --- a/webapp/languages/example/i18n/all_es.properties +++ b/webapp/languages/example/i18n/all_es.properties @@ -199,6 +199,7 @@ remove_selection_title = eliminar la selección external_id_not_provided = Error de acceso - ID externo no se encuentra. external_id_already_in_use = Cuenta de usuario ya existe para'' {0}'' +logins_disabled_for_maintenance = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema. error_no_email = Debe proporcionar una dirección de correo electrónico. error_email_already_exists = Una cuenta con la dirección de correo electrónico ya existe. @@ -207,6 +208,8 @@ error_external_auth_already_exists = Una cuenta con dicho ID de autorización ex error_no_first_name = Debe proporcionar un nombre de pila. error_no_last_name = Debe proporcionar un apellido. error_no_role = Debe seleccionar una función. +error_no_password = Suministrado ninguna contraseña. +error_password_length = La contraseña debe tener entre {0} y {1} caracteres. error_password_mismatch = Las contraseñas no coinciden. logged_in_but_no_profile = Usted ha ingresado, pero el sistema no contiene ningún perfil para usted. @@ -505,6 +508,18 @@ previous = Anterior page_link = enlace de la página next_capitalized = Próximo +# +# search controller ( PagedSearchController.java ) +# +error_in_search_request = La peticin de bsqueda contena errores. +enter_search_term = Por favor introduzca un trmino de bsqueda. +invalid_search_term = Criterio de bsqueda no es vlido +paging_link_more = ms ... +no_matching_results = No hay resultados que coincidan. +search_failed = Buscar fall. +search_term_error_near = El trmino de bsqueda tuvo un error cerca +search_for = Buscar ''{0}'' + # # shortview templates ( /templates/freemarker/body/partials/shortview ) # @@ -641,6 +656,7 @@ account = cuenta change_password_to_login = Cambiar contraseña para iniciar sesión en new_password_capitalized = Nueva contraseña confirm_password_capitalized = Confirmar Contraseña +minimum_password_length = Mínimo de {0} caracteres de longitud. already_logged_in = Usted ya está registrado # @@ -824,6 +840,7 @@ supply_sparql_query = Debe proporcionar una consulta SPARQL. confirm_page_deletion = ¿Está seguro de que desea eliminar esta página: +hide_subclasses = ocultar subclases show_subclasses = mostrar subclases ontology_capitalized = Ontología subclasses_capitalized = Las subclases @@ -831,6 +848,7 @@ collapse_all = Contraer todo classes_capitalized = Clases display_rank = Mostrar Rango +hide_properties = ocultar las propiedades show_properties = mostrar las propiedades local_name = Nombre local group_capitalized = Grupo From eb1c2d489098dc266625c04206e10e9971950189 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 19 Sep 2013 13:05:00 -0400 Subject: [PATCH 36/44] various migration issues and VIVO-265 blank node deletion optimization --- .../webapp/ontology/update/ABoxUpdater.java | 10 +-- .../ontology/update/KnowledgeBaseUpdater.java | 8 +- .../webapp/ontology/update/TBoxUpdater.java | 15 ++-- .../rdfservice/impl/jena/RDFServiceJena.java | 75 ++++++++++++++++--- .../impl/sparql/RDFServiceSparql.java | 57 ++++++++++++-- .../servlet/setup/UpdateKnowledgeBase.java | 5 +- 6 files changed, 139 insertions(+), 31 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java index 7e59ad681..74de6f79e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ABoxUpdater.java @@ -420,7 +420,7 @@ public class ABoxUpdater { Iterator propItr = changes.iterator(); while(propItr.hasNext()){ AtomicOntologyChange propChangeObj = propItr.next(); - log.info("processing " + propChangeObj); + log.debug("processing " + propChangeObj); try { if (propChangeObj.getAtomicChangeType() == null) { log.error("Missing change type; skipping " + propChangeObj); @@ -428,19 +428,19 @@ public class ABoxUpdater { } switch (propChangeObj.getAtomicChangeType()){ case ADD: - log.info("add"); + log.debug("add"); addProperty(propChangeObj); break; case DELETE: - log.info("delete"); + log.debug("delete"); deleteProperty(propChangeObj); break; case RENAME: - log.info("rename"); + log.debug("rename"); renameProperty(propChangeObj); break; default: - log.info("unknown"); + log.debug("unknown"); logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType()); break; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index ac5cda224..8854a011b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -96,7 +96,7 @@ public class KnowledgeBaseUpdater { //process the TBox before the ABox try { - log.info("\tupdating tbox annotations"); + log.debug("\tupdating tbox annotations"); updateTBoxAnnotations(); } catch (Exception e) { log.error(e,e); @@ -396,13 +396,13 @@ public class KnowledgeBaseUpdater { while(listItr.hasNext()) { AtomicOntologyChange changeObj = listItr.next(); if (changeObj.getSourceURI() != null){ - log.info("triaging " + changeObj); + log.debug("triaging " + changeObj); if (oldTboxModel.getOntProperty(changeObj.getSourceURI()) != null){ atomicPropertyChanges.add(changeObj); - log.info("added to property changes"); + log.debug("added to property changes"); } else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) { atomicClassChanges.add(changeObj); - log.info("added to class changes"); + log.debug("added to class changes"); } else if ("Prop".equals(changeObj.getNotes())) { atomicPropertyChanges.add(changeObj); } else if ("Class".equals(changeObj.getNotes())) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java index 9f3930d65..a9616cefa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java @@ -454,20 +454,23 @@ public class TBoxUpdater { } public void renameProperty(AtomicOntologyChange changeObj) throws IOException { + Dataset dataset = new RDFServiceDataset(settings.getRDFService()); + Model userAnnotationsModel = dataset.getNamedModel( + JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); if(changeObj.getNotes() != null && changeObj.getNotes().startsWith("cc:")) { - mergePropertyAnnotationsToPropertyConfig(changeObj); + mergePropertyAnnotationsToPropertyConfig(changeObj, userAnnotationsModel); } - + Resource renamedProperty = userAnnotationsModel.getResource(changeObj.getSourceURI()); + userAnnotationsModel.removeAll(renamedProperty, null, (RDFNode) null); + userAnnotationsModel.removeAll(null, null, renamedProperty); } - private void mergePropertyAnnotationsToPropertyConfig(AtomicOntologyChange changeObj) throws IOException { + private void mergePropertyAnnotationsToPropertyConfig(AtomicOntologyChange changeObj, + Model userAnnotationsModel) throws IOException { String contextURI = VitroVocabulary.PROPERTY_CONFIG_DATA + changeObj.getNotes().substring(3); String oldPropertyURI = changeObj.getSourceURI(); Model oldAnnotationsModel = settings.getOldTBoxAnnotationsModel(); - Dataset dataset = new RDFServiceDataset(settings.getRDFService()); - Model userAnnotationsModel = dataset.getNamedModel( - JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); String propertyAnnotationsQuery = "PREFIX config: <" + VitroVocabulary.configURI + "> \n" + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java index e9461099a..b851fab9b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java @@ -6,13 +6,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.query.DataSource; import com.hp.hpl.jena.query.Dataset; @@ -21,11 +24,9 @@ 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.QueryParseException; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSetFormatter; -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.RDFNode; @@ -129,7 +130,7 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic Resource s2 = (Resource) n; // now run yet another describe query String smallerTree = makeDescribe(s2); - log.info(smallerTree); + log.debug(smallerTree); Query smallerTreeQuery = QueryFactory.create(smallerTree); QueryExecution qe3 = QueryExecutionFactory.create( smallerTreeQuery, tree); @@ -173,19 +174,23 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic StringBuffer queryBuff = new StringBuffer(); queryBuff.append("CONSTRUCT { \n"); - addStatementPatterns(stmtIt, queryBuff, !WHERE_CLAUSE); + List stmts = stmtIt.toList(); + stmts = sort(stmts); + addStatementPatterns(stmts, queryBuff, !WHERE_CLAUSE); queryBuff.append("} WHERE { \n"); if (graphURI != null) { queryBuff.append(" GRAPH <" + graphURI + "> { \n"); } stmtIt = model.listStatements(); - addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE); + stmts = stmtIt.toList(); + stmts = sort(stmts); + addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE); if (graphURI != null) { queryBuff.append(" } \n"); } queryBuff.append("} \n"); - log.info(queryBuff.toString()); + log.debug(queryBuff.toString()); Query construct = QueryFactory.create(queryBuff.toString()); // make a plain dataset to force the query to be run in a way that @@ -209,11 +214,61 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic } } + private List sort(List stmts) { + List output = new ArrayList(); + int originalSize = stmts.size(); + List remaining = stmts; + ConcurrentLinkedQueue subjQueue = new ConcurrentLinkedQueue(); + for(Statement stmt : remaining) { + if(stmt.getSubject().isURIResource()) { + subjQueue.add(stmt.getSubject()); + break; + } + } + if (subjQueue.isEmpty()) { + throw new RuntimeException("No named subject in statement patterns"); + } + while(remaining.size() > 0) { + if(subjQueue.isEmpty()) { + subjQueue.add(remaining.get(0).getSubject()); + } + while(!subjQueue.isEmpty()) { + Resource subj = subjQueue.poll(); + List temp = new ArrayList(); + for (Statement stmt : remaining) { + if(stmt.getSubject().equals(subj)) { + output.add(stmt); + if (stmt.getObject().isResource()) { + subjQueue.add((Resource) stmt.getObject()); + } + } else { + temp.add(stmt); + } + } + remaining = temp; + } + } + if(output.size() != originalSize) { + throw new RuntimeException("original list size was " + originalSize + + " but sorted size is " + output.size()); + } + return output; + } + + private String getHexString(Node node) { + String label = node.getBlankNodeLabel().replaceAll("\\W", "").toUpperCase(); + if (label.length() > 7) { + return label.substring(label.length() - 7); + } else { + return label; + } + } + private static final boolean WHERE_CLAUSE = true; - private void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) { - while(stmtIt.hasNext()) { - Triple t = stmtIt.next().asTriple(); + private void addStatementPatterns(List stmts, StringBuffer patternBuff, boolean whereClause) { + for(Statement stmt : stmts) { + Triple t = stmt.asTriple(); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); patternBuff.append(" "); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java index 929303d4a..d890a1625 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java @@ -9,6 +9,7 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; @@ -715,7 +716,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { if (graphURI != null) { queryBuff.append(" GRAPH <" + graphURI + "> { \n"); } - addStatementPatterns(stmtIt, queryBuff, !WHERE_CLAUSE); + List stmts = stmtIt.toList(); + sort(stmts); + addStatementPatterns(stmts, queryBuff, !WHERE_CLAUSE); if (graphURI != null) { queryBuff.append(" } \n"); } @@ -724,7 +727,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { queryBuff.append(" GRAPH <" + graphURI + "> { \n"); } stmtIt = model.listStatements(); - addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE); + stmts = stmtIt.toList(); + sort(stmts); + addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE); if (graphURI != null) { queryBuff.append(" } \n"); } @@ -736,11 +741,53 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { executeUpdate(queryBuff.toString()); } + private List sort(List stmts) { + List output = new ArrayList(); + int originalSize = stmts.size(); + List remaining = stmts; + ConcurrentLinkedQueue subjQueue = + new ConcurrentLinkedQueue(); + for(Statement stmt : remaining) { + if(stmt.getSubject().isURIResource()) { + subjQueue.add(stmt.getSubject()); + break; + } + } + if (subjQueue.isEmpty()) { + throw new RuntimeException("No named subject in statement patterns"); + } + while(remaining.size() > 0) { + if(subjQueue.isEmpty()) { + subjQueue.add(remaining.get(0).getSubject()); + } + while(!subjQueue.isEmpty()) { + com.hp.hpl.jena.rdf.model.Resource subj = subjQueue.poll(); + List temp = new ArrayList(); + for (Statement stmt : remaining) { + if(stmt.getSubject().equals(subj)) { + output.add(stmt); + if (stmt.getObject().isResource()) { + subjQueue.add((com.hp.hpl.jena.rdf.model.Resource) stmt.getObject()); + } + } else { + temp.add(stmt); + } + } + remaining = temp; + } + } + if(output.size() != originalSize) { + throw new RuntimeException("original list size was " + originalSize + + " but sorted size is " + output.size()); + } + return output; + } + private static final boolean WHERE_CLAUSE = true; - private void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) { - while(stmtIt.hasNext()) { - Triple t = stmtIt.next().asTriple(); + private void addStatementPatterns(List stmts, StringBuffer patternBuff, boolean whereClause) { + for(Statement stmt : stmts) { + Triple t = stmt.asTriple(); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); patternBuff.append(" "); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 569e4dbf4..a218a8dfa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -122,7 +122,10 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setLoadedAtStartupDisplayModel(loadedAtStartupFiles); OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH)); settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView); - } catch (Exception e) { + } catch (ModelFileNotFoundException e) { + // expected if no display migration was intended + tryMigrateDisplay = false; + } catch (Exception e) { log.info("Unable to read display model migration files. ", e); tryMigrateDisplay = false; } From 499630bc3be0e440aed3c3931386b98a24ae4cf3 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 19 Sep 2013 14:17:35 -0400 Subject: [PATCH 37/44] adding post-processing sparql construct step to data migration --- .../webapp/ontology/update/KnowledgeBaseUpdater.java | 9 +++++++++ .../webapp/ontology/update/OntologyChangeParser.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 8854a011b..a92e81f51 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -117,6 +117,15 @@ public class KnowledgeBaseUpdater { log.info("\tupdating the abox"); updateABox(changes); + + log.info("performing post-processing SPARQL CONSTRUCT additions"); + performSparqlConstructs(settings.getSparqlConstructAdditionsDir() + "/post/", + settings.getRDFService(), ADD); + + log.info("performing post-processing SPARQL CONSTRUCT retractions"); + performSparqlConstructs(settings.getSparqlConstructDeletionsDir() + "/post/", + settings.getRDFService(), RETRACT); + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java index a966de494..6a92b213c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/OntologyChangeParser.java @@ -89,7 +89,7 @@ public class OntologyChangeParser { } - log.info(changeObj); + log.debug(changeObj); changeObjects.add(changeObj); From 6dbd2faa8ea21eae97390c3a8ca48ae273f4a76d Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 19 Sep 2013 16:04:43 -0400 Subject: [PATCH 38/44] minor tweak to data migration sparql construct code --- .../vitro/webapp/ontology/update/KnowledgeBaseUpdater.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index a92e81f51..1dd5012b5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -160,7 +160,10 @@ public class KnowledgeBaseUpdater { List sparqlFiles = Arrays.asList(sparqlConstructDirectory.listFiles()); Collections.sort(sparqlFiles); // queries may depend on being run in a certain order JenaIngestUtils jiu = new JenaIngestUtils(); - for (File sparqlFile : sparqlFiles) { + for (File sparqlFile : sparqlFiles) { + if(sparqlFile.isDirectory()) { + continue; + } StringBuffer fileContents = new StringBuffer(); try { BufferedReader reader = new BufferedReader(new FileReader(sparqlFile)); From 500bb456c34a6b678a6274b707f76eca03463c11 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Fri, 20 Sep 2013 15:41:45 -0400 Subject: [PATCH 39/44] changing behavior of reasoning wrt migration --- .../webapp/ontology/update/ChangeRecord.java | 2 + .../ontology/update/KnowledgeBaseUpdater.java | 4 +- .../ontology/update/SimpleChangeRecord.java | 10 +++- .../servlet/setup/SimpleReasonerSetup.java | 52 ++++++------------- .../servlet/setup/UpdateKnowledgeBase.java | 44 ++++++++++++++-- .../WEB-INF/resources/startup_listeners.txt | 4 +- 6 files changed, 70 insertions(+), 46 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ChangeRecord.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ChangeRecord.java index 8845e1f43..3c9029839 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ChangeRecord.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/ChangeRecord.java @@ -12,4 +12,6 @@ public interface ChangeRecord { public void writeChanges(); + public boolean hasRecordedChanges(); + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 1dd5012b5..6f46af050 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -57,7 +57,7 @@ public class KnowledgeBaseUpdater { this.record = new SimpleChangeRecord(settings.getAddedDataFile(), settings.getRemovedDataFile()); } - public void update(ServletContext servletContext) throws IOException { + public boolean update(ServletContext servletContext) throws IOException { if (this.logger == null) { this.logger = new SimpleChangeLogger(settings.getLogFile(), settings.getErrorLogFile()); @@ -85,7 +85,7 @@ public class KnowledgeBaseUpdater { long elapsedSecs = (System.currentTimeMillis() - startTime)/1000; log.info("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : "")); - return; + return record.hasRecordedChanges(); } private void performUpdate(ServletContext servletContext) throws Exception { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/SimpleChangeRecord.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/SimpleChangeRecord.java index d0ca316e0..78a5c6ba7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/SimpleChangeRecord.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/SimpleChangeRecord.java @@ -26,6 +26,9 @@ public class SimpleChangeRecord implements ChangeRecord { private File additionsFile; private File retractionsFile; + private int additionsCount = 0; + private int retractionsCount = 0; + public SimpleChangeRecord( String additionsFile, String retractionsFile) { this.additionsFile = new File(additionsFile); @@ -46,11 +49,12 @@ public class SimpleChangeRecord implements ChangeRecord { public void recordAdditions(Model incrementalAdditions) { additionsModel.add(incrementalAdditions); - + additionsCount += incrementalAdditions.size(); } public void recordRetractions(Model incrementalRetractions) { retractionsModel.add(incrementalRetractions); + retractionsCount += incrementalRetractions.size(); } private void write(Model model, File file) { @@ -71,5 +75,9 @@ public class SimpleChangeRecord implements ChangeRecord { write(retractionsModel, retractionsFile); } } + + public boolean hasRecordedChanges() { + return additionsCount > 0 || retractionsCount > 0; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index 8620dbc7e..c5b6cbf3d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -110,19 +110,6 @@ public class SimpleReasonerSetup implements ServletContextListener { } simpleReasoner.setPluginList(pluginList); - - if (isRecomputeRequired(sce.getServletContext())) { - log.info("ABox inference recompute required."); - waitForTBoxReasoning(pelletListener); - if (JenaDataSourceSetupBase.isFirstStartup()) { - simpleReasoner.recompute(); - } else { - log.info("starting ABox inference recompute in a separate thread."); - new Thread(new ABoxRecomputer(simpleReasoner),"ABoxRecomputer").start(); - } - - } - SimpleReasonerTBoxListener simpleReasonerTBoxListener = new SimpleReasonerTBoxListener(simpleReasoner); sce.getServletContext().setAttribute(SimpleReasonerTBoxListener.class.getName(),simpleReasonerTBoxListener); assertionsOms.getTBoxModel().register(simpleReasonerTBoxListener); @@ -135,17 +122,21 @@ public class SimpleReasonerSetup implements ServletContextListener { } } - private void waitForTBoxReasoning(PelletListener pelletListener) + public static void waitForTBoxReasoning(ServletContextEvent sce) throws InterruptedException { - int sleeps = 0; - // sleep at least once to make sure the TBox reasoning gets started - while ((0 == sleeps) || ((sleeps < 1000) && pelletListener.isReasoning())) { - if ((sleeps % 10) == 0) { // print message at 10 second intervals - log.info("Waiting for initial TBox reasoning to complete"); - } - Thread.sleep(1000); - sleeps++; - } + PelletListener pelletListener = (PelletListener) sce.getServletContext().getAttribute("pelletListener"); + if (pelletListener == null) { + return ; + } + int sleeps = 0; + // sleep at least once to make sure the TBox reasoning gets started + while ((0 == sleeps) || ((sleeps < 1000) && pelletListener.isReasoning())) { + if ((sleeps % 10) == 0) { // print message at 10 second intervals + log.info("Waiting for initial TBox reasoning to complete"); + } + Thread.sleep(1000); + sleeps++; + } } @Override @@ -193,7 +184,7 @@ public class SimpleReasonerSetup implements ServletContextListener { ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, true); } - private static boolean isRecomputeRequired(ServletContext ctx) { + public static boolean isRecomputeRequired(ServletContext ctx) { return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null); } @@ -207,19 +198,6 @@ public class SimpleReasonerSetup implements ServletContextListener { private static boolean isMSTComputeRequired(ServletContext ctx) { return (ctx.getAttribute(MSTCOMPUTE_REQUIRED_ATTR) != null); } - - private class ABoxRecomputer implements Runnable { - - private SimpleReasoner simpleReasoner; - - public ABoxRecomputer(SimpleReasoner simpleReasoner) { - this.simpleReasoner = simpleReasoner; - } - - public void run() { - simpleReasoner.recompute(); - } - } /** * Read the names of the plugin classes classes. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index a218a8dfa..f24e62632 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -41,9 +41,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.reasoner.ABoxRecomputer; +import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -76,11 +76,15 @@ public class UpdateKnowledgeBase implements ServletContextListener { ServletContext ctx = sce.getServletContext(); StartupStatus ss = StartupStatus.getBean(ctx); + boolean migrationChangesMade = false; + try { UpdateSettings settings = new UpdateSettings(); putReportingPathsIntoSettings(ctx, settings); putNonReportingPathsIntoSettings(ctx, settings); + SimpleReasonerSetup.waitForTBoxReasoning(sce); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); settings.setDefaultNamespace(wadf.getDefaultNamespace()); settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector()); @@ -132,14 +136,14 @@ public class UpdateKnowledgeBase implements ServletContextListener { try { KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings); - + try { if (!ontologyUpdater.updateRequired(ctx)) { log.info("No data migration required."); } else { ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); log.info("Data migration required"); - ontologyUpdater.update(ctx); + migrationChangesMade = ontologyUpdater.update(ctx); if (tryMigrateDisplay) { try { migrateDisplayModel(settings); @@ -161,8 +165,40 @@ public class UpdateKnowledgeBase implements ServletContextListener { } catch (Throwable t) { ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); } + + if (SimpleReasonerSetup.isRecomputeRequired(sce.getServletContext())) { + log.info("ABox inference recompute required."); + + SimpleReasoner simpleReasoner = (SimpleReasoner) sce.getServletContext() + .getAttribute(SimpleReasoner.class.getName()); + if (simpleReasoner != null) { + if (JenaDataSourceSetupBase.isFirstStartup() || migrationChangesMade) { + simpleReasoner.recompute(); + } else { + log.info("starting ABox inference recompute in a separate thread."); + new Thread( + new ABoxRecomputer( + simpleReasoner),"ABoxRecomputer").start(); + } + } + + } + } + private class ABoxRecomputer implements Runnable { + + private SimpleReasoner simpleReasoner; + + public ABoxRecomputer(SimpleReasoner simpleReasoner) { + this.simpleReasoner = simpleReasoner; + } + + public void run() { + simpleReasoner.recompute(); + } + } + /** * Set the paths for the files that specify how to perform the update diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index 98a3fac21..657915abc 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -25,8 +25,6 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelMakerSetup -edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase - edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup @@ -38,6 +36,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup +edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase + # Must run after JenaDataSourceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup From f76ee886d539b291ec744d4e7e643f0dd2ab15d9 Mon Sep 17 00:00:00 2001 From: tworrall Date: Mon, 23 Sep 2013 08:58:24 -0400 Subject: [PATCH 40/44] VIVO-112 --- .../templates/freemarker/body/individual/individual-menu.ftl | 2 +- .../freemarker/edit/forms/js/customFormWithAutocomplete.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/webapp/web/templates/freemarker/body/individual/individual-menu.ftl b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl index 039e59d17..2099c0c96 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-menu.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl @@ -18,7 +18,7 @@ <#-- List the menu items --> diff --git a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js index 50a0322be..8ef3746b0 100644 --- a/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js +++ b/webapp/web/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js @@ -297,7 +297,6 @@ var customForm = { //to the filtering list this.getAcFilterForIndividuals(); this.acCache = {}; - var theType = customForm.acTypes[$(selectedObj).attr('acGroupName')]; $(selectedObj).autocomplete({ minLength: 3, @@ -317,7 +316,7 @@ var customForm = { dataType: 'json', data: { term: request.term, - type: theType, + type: customForm.acTypes[$(selectedObj).attr('acGroupName')], multipleTypes:(customForm.acMultipleTypes == undefined || customForm.acMultipleTypes == null)? null: customForm.acMultipleTypes }, complete: function(xhr, status) { @@ -325,7 +324,7 @@ var customForm = { var results = $.parseJSON(xhr.responseText); var filteredResults = customForm.filterAcResults(results); - if ( theType == "http://www.w3.org/2004/02/skos/core#Concept" ) { + if ( customForm.acTypes[$(selectedObj).attr('acGroupName')] == "http://www.w3.org/2004/02/skos/core#Concept" ) { filteredResults = customForm.removeConceptSubclasses(filteredResults); } From dbf6f18e3546fec0f23ef4b1118e780d7374f1f1 Mon Sep 17 00:00:00 2001 From: Brian Caruso Date: Thu, 5 Sep 2013 17:04:07 -0400 Subject: [PATCH 41/44] Adding content negotiation to sparql servlet VIVO-282 --- .../webapp/controller/SparqlQueryServlet.java | 280 ++++++++++-------- .../individual/IndividualRequestAnalyzer.java | 9 +- 2 files changed, 164 insertions(+), 125 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java index ab6d52616..72bb31f37 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java @@ -9,9 +9,11 @@ import java.io.PrintWriter; import java.io.Writer; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -40,6 +42,7 @@ import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.Ontology; +import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualController; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; @@ -47,12 +50,14 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; +import edu.cornell.mannlib.vitro.webapp.web.ContentType; /** - * Services a sparql query. This will return a simple error message and a 501 if + * Services a SPARQL query. This will return a simple error message and a 501 if * there is no Model. * + * * @author bdc34 * */ @@ -86,6 +91,12 @@ public class SparqlQueryServlet extends BaseEditController { new ModelFormatConfig("TTL", CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ), new ModelFormatConfig("JSON-LD", CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) }; + /** + * Use this map to decide which MIME type is suited for the "accept" header. + */ + public static final Map ACCEPTED_CONTENT_TYPES; + + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException @@ -113,100 +124,90 @@ public class SparqlQueryServlet extends BaseEditController { String queryParam = vreq.getParameter("query"); log.debug("queryParam was : " + queryParam); - String resultFormatParam = vreq.getParameter("resultFormat"); - log.debug("resultFormat was: " + resultFormatParam); - - String rdfResultFormatParam = vreq.getParameter("rdfResultFormat"); - if (rdfResultFormatParam == null) { - rdfResultFormatParam = "RDF/XML-ABBREV"; - } - log.debug("rdfResultFormat was: " + rdfResultFormatParam); - - if( queryParam == null || "".equals(queryParam) || - resultFormatParam == null || "".equals(resultFormatParam) || - !rsFormats.containsKey( resultFormatParam ) || - rdfResultFormatParam == null || "".equals(rdfResultFormatParam) || - !modelFormats.containsKey( rdfResultFormatParam ) ) { + if( queryParam == null || "".equals(queryParam) ){ doHelp(request,response); return; } - - executeQuery(response, resultFormatParam, rdfResultFormatParam, - queryParam, vreq.getUnfilteredRDFService()); + + String contentType = checkForContentType(vreq.getHeader("Accept")); + + Query query = SparqlQueryUtils.create(queryParam); + if( query.isSelectType() ){ + String format = contentType!=null ? contentType:vreq.getParameter("resultFormat"); + RSFormatConfig formatConf = rsFormats.get(format); + doSelect(response, queryParam, formatConf, vreq.getRDFService()); + }else if( query.isAskType()){ + doAsk( queryParam, vreq.getRDFService(), response ); + }else if( query.isConstructType() ){ + String format = contentType != null ? contentType : vreq.getParameter("rdfResultFormat"); + if (format== null) { + format= "RDF/XML-ABBREV"; + } + ModelFormatConfig formatConf = modelFormats.get(format); + doConstruct(response, query, formatConf, vreq.getRDFService()); + }else{ + doHelp(request,response); + } return; } - private void executeQuery(HttpServletResponse response, - String resultFormatParam, - String rdfResultFormatParam, - String queryParam, - RDFService rdfService ) throws IOException { - /* BJL23 2008-11-06 - * modified to support CSV output. - * Unfortunately, ARQ doesn't make it easy to - * do this by implementing a new ResultSetFormat, because - * ResultSetFormatter is hardwired with expected values. - * This slightly ugly approach will have to do for now. - */ -// if ( !("vitro:csv").equals(resultFormatParam) ) { -// rsf = selectFormatSymbols.get(resultFormatParam); -// } -// String mimeType = rdfFormatToMimeType.get(resultFormatParam); - - try{ - Query query = SparqlQueryUtils.create(queryParam); - if( query.isSelectType() ){ - doSelectQuery( queryParam, rdfService, resultFormatParam, response); - } else if(query.isAskType()){ - // Irrespective of the ResultFormatParam, - // this always prints a boolean to the default OutputStream. - String result = (rdfService.sparqlAskQuery(queryParam) == true) - ? "true" - : "false"; - PrintWriter p = response.getWriter(); - p.write(result); - return; - } else { - doModelResultQuery( query, rdfService, rdfResultFormatParam, response); - } - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } + private void doAsk(String queryParam, RDFService rdfService, + HttpServletResponse response) throws ServletException, IOException { + + // Irrespective of the ResultFormatParam, + // this always prints a boolean to the default OutputStream. + String result; + try { + result = (rdfService.sparqlAskQuery(queryParam) == true) + ? "true" + : "false"; + } catch (RDFServiceException e) { + throw new ServletException( "Could not execute ask query ", e ); + } + PrintWriter p = response.getWriter(); + p.write(result); + return; + } + /** * Execute the query and send the result to out. Attempt to * send the RDFService the same format as the rdfResultFormatParam * so that the results from the RDFService can be directly piped to the client. - * @param rdfService - * @throws IOException - * @throws RDFServiceException */ - private void doSelectQuery( String queryParam, - RDFService rdfService, String resultFormatParam, - HttpServletResponse response) throws IOException, RDFServiceException{ - RSFormatConfig config = rsFormats.get( resultFormatParam ); + private void doSelect(HttpServletResponse response, + String queryParam, + RSFormatConfig formatConf, + RDFService rdfService + ) throws ServletException { + try { + if( ! formatConf.converstionFromWireFormat ){ + response.setContentType( formatConf.responseMimeType ); + InputStream results; + results = rdfService.sparqlSelectQuery(queryParam, formatConf.wireFormat ); + pipe( results, response.getOutputStream() ); + }else{ + //always use JSON when conversion is needed. + InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON ); - if( ! config.converstionFromWireFormat ){ - response.setContentType( config.responseMimeType ); - InputStream results = rdfService.sparqlSelectQuery(queryParam, config.wireFormat ); - pipe( results, response.getOutputStream() ); - }else{ - //always use JSON when conversion is needed. - InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON ); - - response.setContentType( config.responseMimeType ); - - ResultSet rs = ResultSetFactory.fromJSON( results ); - OutputStream out = response.getOutputStream(); - ResultSetFormatter.output(out, rs, config.jenaResponseFormat); - - // } else { - // Writer out = response.getWriter(); - // toCsv(out, results); - //} + response.setContentType( formatConf.responseMimeType ); + + ResultSet rs = ResultSetFactory.fromJSON( results ); + OutputStream out = response.getOutputStream(); + ResultSetFormatter.output(out, rs, formatConf.jenaResponseFormat); + + // } else { + // Writer out = response.getWriter(); + // toCsv(out, results); + //} + } + } catch (RDFServiceException e) { + throw new ServletException("Cannot get result from the RDFService",e); + } catch (IOException e) { + throw new ServletException("Cannot perform SPARQL SELECT",e); } } + /** * Execute the query and send the result to out. Attempt to @@ -217,40 +218,44 @@ public class SparqlQueryServlet extends BaseEditController { * @throws RDFServiceException * @throws */ - private void doModelResultQuery( Query query, - RDFService rdfService, String rdfResultFormatParam, - HttpServletResponse response) throws IOException, RDFServiceException{ - - //config drives what formats and conversions to use - ModelFormatConfig config = modelFormats.get( rdfResultFormatParam ); - - InputStream rawResult = null; - if( query.isConstructType() ){ - rawResult= rdfService.sparqlConstructQuery( query.toString(), config.wireFormat ); - }else if ( query.isDescribeType() ){ - rawResult = rdfService.sparqlDescribeQuery( query.toString(), config.wireFormat ); - } - - response.setContentType( config.responseMimeType ); - - if( config.converstionFromWireFormat ){ - Model resultModel = RDFServiceUtils.parseModel( rawResult, config.wireFormat ); - if( "JSON-LD".equals( config.jenaResponseFormat )){ - //since jena 2.6.4 doesn't support JSON-LD we do it - try { - JenaRDFParser parser = new JenaRDFParser(); - Object json = JSONLD.fromRDF(resultModel, parser); - JSONUtils.write(response.getWriter(), json); - } catch (JSONLDProcessingError e) { - throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e); + private void doConstruct( HttpServletResponse response, + Query query, + ModelFormatConfig formatConfig, + RDFService rdfService + ) throws ServletException{ + try{ + InputStream rawResult = null; + if( query.isConstructType() ){ + rawResult= rdfService.sparqlConstructQuery( query.toString(), formatConfig.wireFormat ); + }else if ( query.isDescribeType() ){ + rawResult = rdfService.sparqlDescribeQuery( query.toString(), formatConfig.wireFormat ); + } + + response.setContentType( formatConfig.responseMimeType ); + + if( formatConfig.converstionFromWireFormat ){ + Model resultModel = RDFServiceUtils.parseModel( rawResult, formatConfig.wireFormat ); + if( "JSON-LD".equals( formatConfig.jenaResponseFormat )){ + //since jena 2.6.4 doesn't support JSON-LD we do it + try { + JenaRDFParser parser = new JenaRDFParser(); + Object json = JSONLD.fromRDF(resultModel, parser); + JSONUtils.write(response.getWriter(), json); + } catch (JSONLDProcessingError e) { + throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e); + } + }else{ + OutputStream out = response.getOutputStream(); + resultModel.write(out, formatConfig.jenaResponseFormat ); } }else{ OutputStream out = response.getOutputStream(); - resultModel.write(out, config.jenaResponseFormat ); + pipe( rawResult, out ); } - }else{ - OutputStream out = response.getOutputStream(); - pipe( rawResult, out ); + }catch( IOException ex){ + throw new ServletException("could not run SPARQL CONSTRUCT",ex); + } catch (RDFServiceException ex) { + throw new ServletException("could not run SPARQL CONSTRUCT",ex); } } @@ -362,13 +367,15 @@ public class SparqlQueryServlet extends BaseEditController { rd.forward(req,res); } - - public static class ModelFormatConfig{ + public static class FormatConfig{ public String valueFromForm; public boolean converstionFromWireFormat; - public RDFService.ModelSerializationFormat wireFormat; - public String jenaResponseFormat; public String responseMimeType; + } + + public static class ModelFormatConfig extends FormatConfig{ + public RDFService.ModelSerializationFormat wireFormat; + public String jenaResponseFormat; public ModelFormatConfig( String valueFromForm, boolean converstionFromWireFormat, @@ -383,12 +390,9 @@ public class SparqlQueryServlet extends BaseEditController { } } - public static class RSFormatConfig{ - public String valueFromForm; - public boolean converstionFromWireFormat; + public static class RSFormatConfig extends FormatConfig{ public ResultFormat wireFormat; public ResultSetFormat jenaResponseFormat; - public String responseMimeType; public RSFormatConfig( String valueFromForm, boolean converstionFromWireFormat, @@ -403,14 +407,48 @@ public class SparqlQueryServlet extends BaseEditController { } } - static{ - /* move the lists of configs into maps for easy lookup */ + static{ + HashMap map = new HashMap(); + + /* move the lists of configurations into maps for easy lookup + * by both MIME content type and the parameters from the form */ for( RSFormatConfig rsfc : rsfs ){ rsFormats.put( rsfc.valueFromForm, rsfc ); + rsFormats.put( rsfc.responseMimeType, rsfc); + map.put(rsfc.responseMimeType, 1.0f); } for( ModelFormatConfig mfc : fmts ){ modelFormats.put( mfc.valueFromForm, mfc); - } + modelFormats.put(mfc.responseMimeType, mfc); + map.put(mfc.responseMimeType, 1.0f); + } + + ACCEPTED_CONTENT_TYPES = Collections.unmodifiableMap(map); } + + /** + * Get the content type based on content negotiation. + * Returns null of no content type can be agreed on or + * if there is no accept header. + */ + protected String checkForContentType( String acceptHeader ) { + if (acceptHeader == null) + return null; + + try { + Map typesAndQ = ContentType + .getTypesAndQ(acceptHeader); + + String ctStr = ContentType + .getBestContentType(typesAndQ,ACCEPTED_CONTENT_TYPES); + + if( ACCEPTED_CONTENT_TYPES.containsKey( ctStr )){ + return ctStr; + } + } catch (Throwable th) { + log.error("Problem while checking accept header ", th); + } + return null; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java index d89766164..c0e8561d9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java @@ -132,10 +132,11 @@ public class IndividualRequestAnalyzer { * only provide a set of bytes. */ protected ContentType checkAcceptHeaderForLinkedDataRequest() { - String acceptHeader = vreq.getHeader("accept"); - if (acceptHeader == null) { - return null; - } + String acceptHeader = vreq.getHeader("Accept"); + if (acceptHeader == null) + acceptHeader = vreq.getHeader("accept"); + if (acceptHeader == null) + return null; try { Map typesAndQ = ContentType From cc95211afca268759417034fb92df2ee65bef973 Mon Sep 17 00:00:00 2001 From: Brian Caruso Date: Mon, 23 Sep 2013 11:44:32 -0400 Subject: [PATCH 42/44] minor changes to content negotiation for sparql servlet VIVO-282 --- .../webapp/controller/SparqlQueryServlet.java | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java index 72bb31f37..ec6d1d1eb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java @@ -63,34 +63,18 @@ import edu.cornell.mannlib.vitro.webapp.web.ContentType; */ public class SparqlQueryServlet extends BaseEditController { private static final Log log = LogFactory.getLog(SparqlQueryServlet.class.getName()); - - private final static boolean CONVERT = true; /** * format configurations for SELECT queries. */ protected static HashMap rsFormats = new HashMap(); - - private static RSFormatConfig[] rsfs = { - new RSFormatConfig( "RS_XML", !CONVERT, ResultFormat.XML, null, "text/xml"), - new RSFormatConfig( "RS_TEXT", !CONVERT, ResultFormat.TEXT, null, "text/plain"), - new RSFormatConfig( "vitro:csv", !CONVERT, ResultFormat.CSV, null, "text/csv"), - new RSFormatConfig( "RS_JSON", !CONVERT, ResultFormat.JSON, null, "application/javascript") }; - + /** * format configurations for CONSTRUCT/DESCRIBE queries. */ protected static HashMap modelFormats = new HashMap(); - private static ModelFormatConfig[] fmts = { - new ModelFormatConfig("RDF/XML", !CONVERT, ModelSerializationFormat.RDFXML, null, "application/rdf+xml" ), - new ModelFormatConfig("RDF/XML-ABBREV", CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ), - new ModelFormatConfig("N3", !CONVERT, ModelSerializationFormat.N3, null, "text/n3" ), - new ModelFormatConfig("N-TRIPLE", !CONVERT, ModelSerializationFormat.NTRIPLE, null, "text/plain" ), - new ModelFormatConfig("TTL", CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ), - new ModelFormatConfig("JSON-LD", CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) }; - /** * Use this map to decide which MIME type is suited for the "accept" header. */ @@ -194,12 +178,7 @@ public class SparqlQueryServlet extends BaseEditController { ResultSet rs = ResultSetFactory.fromJSON( results ); OutputStream out = response.getOutputStream(); - ResultSetFormatter.output(out, rs, formatConf.jenaResponseFormat); - - // } else { - // Writer out = response.getWriter(); - // toCsv(out, results); - //} + ResultSetFormatter.output(out, rs, formatConf.jenaResponseFormat); } } catch (RDFServiceException e) { throw new ServletException("Cannot get result from the RDFService",e); @@ -367,12 +346,32 @@ public class SparqlQueryServlet extends BaseEditController { rd.forward(req,res); } + /** Simple boolean vaule to improve the legibility of confiugrations. */ + private final static boolean CONVERT = true; + + /** Simple vaule to improve the legibility of confiugrations. */ + private final static String NO_CONVERSION = null; + public static class FormatConfig{ public String valueFromForm; public boolean converstionFromWireFormat; public String responseMimeType; } + private static ModelFormatConfig[] fmts = { + new ModelFormatConfig("RDF/XML", + !CONVERT, ModelSerializationFormat.RDFXML, NO_CONVERSION, "application/rdf+xml" ), + new ModelFormatConfig("RDF/XML-ABBREV", + CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ), + new ModelFormatConfig("N3", + !CONVERT, ModelSerializationFormat.N3, NO_CONVERSION, "text/n3" ), + new ModelFormatConfig("N-TRIPLE", + !CONVERT, ModelSerializationFormat.NTRIPLE, NO_CONVERSION, "text/plain" ), + new ModelFormatConfig("TTL", + CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ), + new ModelFormatConfig("JSON-LD", + CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) }; + public static class ModelFormatConfig extends FormatConfig{ public RDFService.ModelSerializationFormat wireFormat; public String jenaResponseFormat; @@ -390,6 +389,17 @@ public class SparqlQueryServlet extends BaseEditController { } } + + private static RSFormatConfig[] rsfs = { + new RSFormatConfig( "RS_XML", + !CONVERT, ResultFormat.XML, null, "text/xml"), + new RSFormatConfig( "RS_TEXT", + !CONVERT, ResultFormat.TEXT, null, "text/plain"), + new RSFormatConfig( "vitro:csv", + !CONVERT, ResultFormat.CSV, null, "text/csv"), + new RSFormatConfig( "RS_JSON", + !CONVERT, ResultFormat.JSON, null, "application/javascript") }; + public static class RSFormatConfig extends FormatConfig{ public ResultFormat wireFormat; public ResultSetFormat jenaResponseFormat; From 32925441bc6cc4ab172230a9380eab2ab9fb5071 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Mon, 23 Sep 2013 15:56:27 -0400 Subject: [PATCH 43/44] data migration improvements --- .../servlet/setup/UpdateKnowledgeBase.java | 144 +++++++++--------- 1 file changed, 69 insertions(+), 75 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index f24e62632..d02bbeceb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -103,86 +103,80 @@ public class UpdateKnowledgeBase implements ServletContextListener { OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "firsttime").toString()); settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService()); - - boolean tryMigrateDisplay = true; + + boolean tryMigrateDisplay = true; try { - //Display model tbox and display metadata - //old display model tbox model - OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH)); - settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel); - //new display model tbox model - OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH)); - settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel); - //old display model display model metadata - OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH)); - settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel); - //new display model display model metadata - OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH)); - settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel); - //Get new display model - OntModel newDisplayModelFromFile = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_PATH)); - settings.setNewDisplayModelFromFile(newDisplayModelFromFile); - OntModel loadedAtStartupFiles = loadModelFromDirectory(ctx.getRealPath(LOADED_STARTUPT_DISPLAYMODEL_DIR)); - settings.setLoadedAtStartupDisplayModel(loadedAtStartupFiles); - OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH)); - settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView); + //Display model tbox and display metadata + //old display model tbox model + OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH)); + settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel); + //new display model tbox model + OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH)); + settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel); + //old display model display model metadata + OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH)); + settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel); + //new display model display model metadata + OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH)); + settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel); + //Get new display model + OntModel newDisplayModelFromFile = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_PATH)); + settings.setNewDisplayModelFromFile(newDisplayModelFromFile); + OntModel loadedAtStartupFiles = loadModelFromDirectory(ctx.getRealPath(LOADED_STARTUPT_DISPLAYMODEL_DIR)); + settings.setLoadedAtStartupDisplayModel(loadedAtStartupFiles); + OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH)); + settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView); } catch (ModelFileNotFoundException e) { - // expected if no display migration was intended - tryMigrateDisplay = false; - } catch (Exception e) { - log.info("Unable to read display model migration files. ", e); - tryMigrateDisplay = false; + // expected if no display migration was intended + tryMigrateDisplay = false; + } catch (Exception e) { + log.info("Unable to read display model migration files. ", e); + tryMigrateDisplay = false; } - - try { - KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings); - - try { - if (!ontologyUpdater.updateRequired(ctx)) { - log.info("No data migration required."); - } else { - ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); - log.info("Data migration required"); - migrationChangesMade = ontologyUpdater.update(ctx); - if (tryMigrateDisplay) { - try { - migrateDisplayModel(settings); - log.info("Migrated display model"); - } catch (Exception e) { - log.warn("unable to successfully update display model: " + e.getMessage()); - } - } - // reload the display model since the TBoxUpdater may have - // modified it - new ApplicationModelSetup().contextInitialized(sce); - } - } catch (Exception ioe) { - ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe); - } - } catch (Throwable t){ - ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); - } - } catch (Throwable t) { - ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); + + + KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings); + boolean requiredUpdate = ontologyUpdater.updateRequired(ctx); + + try { + ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); + log.info("Data migration required"); + migrationChangesMade = ontologyUpdater.update(ctx); + if (tryMigrateDisplay) { + try { + migrateDisplayModel(settings); + log.info("Migrated display model"); + } catch (Exception e) { + log.warn("unable to successfully update display model: " + e.getMessage()); + } + } + // reload the display model since the TBoxUpdater may have + // modified it + new ApplicationModelSetup().contextInitialized(sce); + } catch (Exception ioe) { + ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe); + } + + SimpleReasoner simpleReasoner = (SimpleReasoner) sce.getServletContext() + .getAttribute(SimpleReasoner.class.getName()); + if (simpleReasoner != null) { + if ( (requiredUpdate && migrationChangesMade) + || JenaDataSourceSetupBase.isFirstStartup()) { + log.info("ABox inference recompute required."); + simpleReasoner.recompute(); + } else if (SimpleReasonerSetup.isRecomputeRequired(sce.getServletContext()) || migrationChangesMade) { + log.info("starting ABox inference recompute in a separate thread."); + new Thread( + new ABoxRecomputer( + simpleReasoner),"ABoxRecomputer").start(); + } + } + + } catch (Throwable t){ + ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); } - if (SimpleReasonerSetup.isRecomputeRequired(sce.getServletContext())) { - log.info("ABox inference recompute required."); - - SimpleReasoner simpleReasoner = (SimpleReasoner) sce.getServletContext() - .getAttribute(SimpleReasoner.class.getName()); - if (simpleReasoner != null) { - if (JenaDataSourceSetupBase.isFirstStartup() || migrationChangesMade) { - simpleReasoner.recompute(); - } else { - log.info("starting ABox inference recompute in a separate thread."); - new Thread( - new ABoxRecomputer( - simpleReasoner),"ABoxRecomputer").start(); - } - } - - } + } From e36491179546da681bc07f61761d506ff9ec62f8 Mon Sep 17 00:00:00 2001 From: tworrall Date: Tue, 24 Sep 2013 14:58:20 -0400 Subject: [PATCH 44/44] VIVO-289: fixed capitalization issues --- .../languages/example/i18n/all_es.properties | 550 +++++++++--------- webapp/web/i18n/all.properties | 6 +- .../siteAdmin/siteAdmin-siteConfiguration.ftl | 2 +- 3 files changed, 279 insertions(+), 279 deletions(-) diff --git a/webapp/languages/example/i18n/all_es.properties b/webapp/languages/example/i18n/all_es.properties index 0688a577f..0cfe0d066 100644 --- a/webapp/languages/example/i18n/all_es.properties +++ b/webapp/languages/example/i18n/all_es.properties @@ -9,9 +9,9 @@ cancel_title = cancelar required_fields = campos obligatorios or = o alt_error_alert = Icono de alerta con error -alt_confirmation = Icono de confirmación +alt_confirmation = Icono de confirmaci√≥n -email_address = Dirección de correo electrónico +email_address = Direcci√≥n de correo electr√≥nico first_name = Primer nombre last_name = Apellido roles = Roles @@ -21,10 +21,10 @@ ascending_order = orden ascendente descending_order = orden descendente select_one = Seleccione uno -type_more_characters = escribir más caracteres +type_more_characters = escribir m√°s caracteres no_match = No hay resultados -request_failed = Error en la solicitud. Por favor, póngase en contacto con el administrador del sistema. +request_failed = Error en la solicitud. Por favor, p√≥ngase en contacto con el administrador del sistema. # # Image upload pages @@ -43,11 +43,11 @@ current_photo = Foto actual upload_photo = Suba foto replace_photo = Reemplace foto photo_types = (JPEG, GIF, o PNG) -maximum_file_size = Tamaño máximo de archivo: {0} megabytes -minimum_image_dimensions = Dimensiones mínimas de imagen: {0} x {1} pixels +maximum_file_size = Tama√±o m√°ximo de archivo: {0} megabytes +minimum_image_dimensions = Dimensiones m√≠nimas de imagen: {0} x {1} pixels -cropping_caption = La foto de tu perfil se verá como la imagen de abajo. -cropping_note = Para realizar ajustes, arrastre alrededor y cambie el tamaño de la foto de la derecha. Cuando esté satisfecho con su foto, haga clic en el botón "Guardar foto". +cropping_caption = La foto de tu perfil se ver√° como la imagen de abajo. +cropping_note = Para realizar ajustes, arrastre alrededor y cambie el tama√±o de la foto de la derecha. Cuando est√© satisfecho con su foto, haga clic en el bot√≥n "Guardar foto". alt_thumbnail_photo = Foto de individuo alt_image_to_crop = Imagen que desea recortar @@ -57,14 +57,14 @@ delete_link = Borrar foto submit_upload = Subir foto submit_save = Guardar foto -confirm_delete = ¿Seguro que quiere borrar esta foto? +confirm_delete = ¬øSeguro que quiere borrar esta foto? -imageUpload.errorNoURI = No se proporcionó ninguna entidad URI +imageUpload.errorNoURI = No se proporcion√≥ ninguna entidad URI imageUpload.errorUnrecognizedURI = Este URI no se reconoce como perteneciente a cualquiera:'' {0}'' imageUpload.errorNoImageForCropping = No hay archivo de imagen que desea recortar. -imageUpload.errorImageTooSmall = La imagen cargada debe ser al menos {0} píxeles de alto y {1} píxeles de ancho. +imageUpload.errorImageTooSmall = La imagen cargada debe ser al menos {0} p√≠xeles de alto y {1} p√≠xeles de ancho. imageUpload.errorUnknown = Lo sentimos, no pudimos procesar la foto que nos ha facilitado. Por favor, intente otra foto. -imageUpload.errorFileTooBig = Por favor, sube una imagen más pequeña que {0} megabytes. +imageUpload.errorFileTooBig = Por favor, sube una imagen m√°s peque√±a que {0} megabytes. imageUpload.errorUnrecognizedFileType = '' {0}'' no es un tipo de archivo de imagen reconocida. Por favor, sube JPEG, GIF o PNG solamente. imageUpload.errorNoPhotoSelected = Por favor, busque y seleccione una foto. imageUpload.errorBadMultipartRequest = Error al analizar la solicitud de varias partes para subir una imagen. @@ -73,56 +73,56 @@ imageUpload.errorFormFieldMissing = El formulario no contiene a {0}'' campo'' ". # # User Accounts pages # -account_management = Gestión de cuentas +account_management = Gesti√≥n de cuentas user_accounts_link = Las cuentas de usuario user_accounts_title = cuentas de usuario login_count = Ingresa contar -last_login = Última sesión +last_login = √öltima sesi√≥n -add_new_account = Añadir nueva cuenta +add_new_account = A√±adir nueva cuenta edit_account = Edit cuenta external_auth_only = Externamente autenticados -reset_password = Restablecer contraseña -reset_password_note = Nota: Las instrucciones para restablecer la contraseña serán enviados por correo electrónico a la dirección indicada anteriormente. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico. -new_password = Nueva contraseña -confirm_password = Confirmar nueva contraseña -minimum_password_length = Mínimo de {0} caracteres de longitud. -leave_password_unchanged = Dejando esto en blanco significa que no se puede cambiar la contraseña. -confirm_initial_password = Confirmar contraseña inicial +reset_password = Restablecer contrase√±a +reset_password_note = Nota: Las instrucciones para restablecer la contrase√±a ser√°n enviados por correo electr√≥nico a la direcci√≥n indicada anteriormente. La contrase√±a no se restablecer√° hasta que el usuario sigue el enlace que aparece en este correo electr√≥nico. +new_password = Nueva contrase√±a +confirm_password = Confirmar nueva contrase√±a +minimum_password_length = M√≠nimo de {0} caracteres de longitud. +leave_password_unchanged = Dejando esto en blanco significa que no se puede cambiar la contrase√±a. +confirm_initial_password = Confirmar contrase√±a inicial new_account_1 = Una nueva cuenta -new_account_2 = fue creado con éxito. +new_account_2 = fue creado con √©xito. new_account_title = nueva cuenta -new_account_notification = Un correo electrónico de notificación ha sido enviada a {0} con las instrucciones para activar la cuenta y una contraseña. +new_account_notification = Un correo electr√≥nico de notificaci√≥n ha sido enviada a {0} con las instrucciones para activar la cuenta y una contrase√±a. updated_account_1 = La cuenta para el updated_account_2 = se ha actualizado. -updated_account_title = descripción actualizada -updated_account_notification = Un correo electrónico de confirmación ha sido enviado a {0} con instrucciones para restablecer la contraseña. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico. +updated_account_title = descripci√≥n actualizada +updated_account_notification = Un correo electr√≥nico de confirmaci√≥n ha sido enviado a {0} con instrucciones para restablecer la contrase√±a. La contrase√±a no se restablecer√° hasta que el usuario sigue el enlace que aparece en este correo electr√≥nico. deleted_accounts = Suprimido {0} {0, choice, 0#cuentas | 1#cuenta | 1 <#if siteConfig.internalClass?has_content> -
  • ${i18n().internal_class}
  • +
  • ${i18n().internal_class_i_capped}
  • <#if siteConfig.manageProxies?has_content>