Merge branch 'develop' of https://github.com/vivo-project/Vitro into develop

This commit is contained in:
hudajkhan 2013-10-31 15:08:25 -04:00
commit 39d7818ba1
26 changed files with 903 additions and 215 deletions

View file

@ -34,6 +34,13 @@ public interface Individual extends ResourceBean, Comparable<Individual> {
List<ObjectProperty> getObjectPropertyList();
void setPropertyList(List<ObjectProperty> propertyList);
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
List<ObjectProperty> getPopulatedObjectPropertyList();
void setPopulatedObjectPropertyList(List<ObjectProperty> propertyList);

View file

@ -22,7 +22,7 @@ import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
* a class representing an object property
*
*/
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable
{
private static final Log log = LogFactory.getLog(ObjectProperty.class.getName());
@ -610,6 +610,55 @@ public class ObjectProperty extends Property implements Comparable<ObjectPropert
"selectFromExisting" + getSelectFromExisting() + "\n\t" +
"offerCreateNewOption" + getOfferCreateNewOption() + "\n\t" +
"** object property statements: " + list + "\n";
}
@Override
public ObjectProperty clone()
{
ObjectProperty clone = new ObjectProperty();
clone.setAddLinkSuppressed(this.isAddLinkSuppressed());
clone.setCollateBySubclass(this.getCollateBySubclass());
clone.setCustomEntryForm(this.getCustomEntryForm());
clone.setDeleteLinkSuppressed(this.isDeleteLinkSuppressed());
clone.setDescription(this.getDescription());
clone.setDomainDisplayLimit(this.getDomainDisplayLimitInteger());
clone.setDomainDisplayTier(this.getDomainDisplayTier());
clone.setDomainEntitySortDirection(this.getDomainEntitySortDirection());
clone.setDomainEntityURI(this.getDomainEntityURI());
clone.setDomainPublic(this.getDomainPublic());
clone.setDomainVClass(this.getDomainVClass());
clone.setDomainVClassURI(this.getDomainVClassURI());
clone.setEditLinkSuppressed(this.isEditLinkSuppressed());
clone.setExample(this.getExample());
clone.setFunctional(this.getFunctional());
clone.setGroupURI(this.getGroupURI());
clone.setHiddenFromDisplayBelowRoleLevel(this.getHiddenFromDisplayBelowRoleLevel());
clone.setInverseFunctional(this.getInverseFunctional());
clone.setLabel(this.getLabel());
clone.setLocalName(this.getLocalName());
clone.setLocalNameInverse(this.getLocalNameInverse());
clone.setLocalNameWithPrefix(this.getLocalNameWithPrefix());
clone.setNamespace(this.getNamespace());
clone.setNamespaceInverse(this.getNamespaceInverse());
clone.setObjectIndividualSortPropertyURI(this.getObjectIndividualSortPropertyURI());
clone.setOfferCreateNewOption(this.getOfferCreateNewOption());
clone.setParentURI(this.getParentURI());
clone.setPickListName(this.getPickListName());
clone.setProhibitedFromUpdateBelowRoleLevel(this.getProhibitedFromUpdateBelowRoleLevel());
clone.setPublicDescription(this.getPublicDescription());
clone.setRangeDisplayLimit(this.getRangeDisplayLimit());
clone.setRangeDisplayTier(this.getRangeDisplayTier());
clone.setRangeEntitySortDirection(this.getRangeEntitySortDirection());
clone.setRangeEntityURI(this.getRangeEntityURI());
clone.setRangePublic(this.getRangePublic());
clone.setRangeVClass(this.getRangeVClass());
clone.setRangeVClassURI(this.getRangeVClassURI());
clone.setSelectFromExisting(this.getSelectFromExisting());
clone.setStubObjectRelation(this.getStubObjectRelation());
clone.setSymmetric(this.getSymmetric());
clone.setTransitive(this.getTransitive());
clone.setURI(this.getURI());
clone.setURIInverse(this.getURIInverse());
return clone;
}
}

View file

@ -4,11 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.individual;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -22,18 +17,13 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
*/
public class IndividualRequestAnalysisContextImpl implements
IndividualRequestAnalysisContext {
private static final Log log = LogFactory
.getLog(IndividualRequestAnalysisContextImpl.class);
private final VitroRequest vreq;
private final ServletContext ctx;
private final VitroRequest vreq;
private final WebappDaoFactory wadf;
private final IndividualDao iDao;
public IndividualRequestAnalysisContextImpl(VitroRequest vreq) {
this.vreq = vreq;
this.ctx = vreq.getSession().getServletContext();
this.vreq = vreq;
this.wadf = vreq.getWebappDaoFactory();
this.iDao = wadf.getIndividualDao();
}

View file

@ -16,6 +16,18 @@ public interface ObjectPropertyDao extends PropertyDao {
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI);
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI);
/**
* Use this method to supply a base ObjectProperty whose fields will be updated
* as necessary to correspond to the configuration for the specified Domain
* and Range.
* @param objectPropertyURI
* @param domainURI
* @param rangeURI
* @param base
* @return ObjectProperty
*/
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI, ObjectProperty base);
public List <ObjectProperty> getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements);
@ -54,8 +66,22 @@ public interface ObjectPropertyDao extends PropertyDao {
List <ObjectProperty> getRootObjectProperties();
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
public List<ObjectProperty> getObjectPropertyList(Individual subject);
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
public List<ObjectProperty> getObjectPropertyList(String subjectUri);
public String getCustomListViewConfigFileName(ObjectProperty objectProperty);

View file

@ -5,14 +5,20 @@ package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openjena.atlas.lib.Pair;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
public class WebappDaoFactoryConfig {
private List<String> preferredLanguages;
private String defaultNamespace;
private Set<String> nonUserNamespaces;
private boolean isUnderlyingStoreReasoned = false;
public Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap;
public WebappDaoFactoryConfig() {
preferredLanguages = Arrays.asList("en-US", "en", "EN");
@ -53,4 +59,13 @@ public class WebappDaoFactoryConfig {
return this.isUnderlyingStoreReasoned;
}
public Map<Pair<String,Pair<ObjectProperty, String>>, String> getCustomListViewConfigFileMap() {
return this.getCustomListViewConfigFileMap();
}
public void setCustomListViewConfigFileMap(
Map<Pair<String,Pair<ObjectProperty, String>>, String> map) {
this.customListViewConfigFileMap = map;
}
}

View file

@ -54,6 +54,11 @@ class ObjectPropertyDaoFiltering extends BaseFiltering implements ObjectProperty
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
}
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI, ObjectProperty base) {
ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIs(objectPropertyURI, domainURI, rangeURI, base);
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
}
public List<ObjectPropertyStatement> getStatementsUsingObjectProperty(ObjectProperty op) {
return ObjectPropertyStatementDaoFiltering.filterAndWrapList(innerObjectPropertyDao.getStatementsUsingObjectProperty(op),filters);
}

View file

@ -45,15 +45,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
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.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class DataPropertyDaoJena extends PropertyDaoJena implements
DataPropertyDao {
@ -71,9 +70,10 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
}
public DataPropertyDaoJena(DatasetWrapperFactory dwf,
public DataPropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(dwf, wadf);
super(rdfService, dwf, wadf);
}
public void deleteDataProperty(DataProperty dtp) {
@ -672,7 +672,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
PREFIXES + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?property a owl:DatatypeProperty . \n" +
//" ?property a owl:DatatypeProperty . \n" +
" FILTER ( \n" +
" isLiteral(?object) && \n" +
" ( !regex(str(?property), \"^" + VitroVocabulary.PUBLIC + "\" )) && \n" +
@ -708,7 +708,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
log.debug("Data property query string:\n" + query);
ResultSet results = getPropertyQueryResults(query);
ResultSet results = getPropertyQueryResults(queryString);
List<DataProperty> properties = new ArrayList<DataProperty>();
while (results.hasNext()) {
QuerySolution sol = results.next();

View file

@ -13,11 +13,13 @@ import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openjena.atlas.lib.Pair;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.ontology.ConversionException;
import com.hp.hpl.jena.ontology.DatatypeProperty;
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.ontology.OntResource;
import com.hp.hpl.jena.ontology.ProfileException;
@ -28,7 +30,6 @@ 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.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
@ -37,30 +38,31 @@ 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;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.sdb.util.Pair;
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.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectPropertyDao {
private static final Log log = LogFactory.getLog(ObjectPropertyDaoJena.class.getName());
public ObjectPropertyDaoJena(DatasetWrapperFactory dwf,
public ObjectPropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
Map<Pair<String,Pair<ObjectProperty, String>>, String>
customListViewConfigFileMap,
WebappDaoFactoryJena wadf) {
super(dwf, wadf);
super(rdfService, dwf, wadf);
this.customListViewConfigFileMap = customListViewConfigFileMap;
}
@Override
@ -69,7 +71,6 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
public void deleteObjectProperty(String propertyURI) {
OntProperty p = getOntModel().getOntProperty(propertyURI);
ObjectProperty op = new ObjectProperty();
op.setURI(propertyURI);
deleteObjectProperty(op);
@ -269,22 +270,35 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
public ObjectProperty getObjectPropertyByURI(String propertyURI) {
long start = System.currentTimeMillis();
if( propertyURI == null ) return null;
getOntModel().enterCriticalSection(Lock.READ);
OntModel ontModel = getOntModel();
OntModel localModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
ontModel.enterCriticalSection(Lock.READ);
try {
OntProperty op = getOntModel().getObjectProperty(propertyURI);
localModel.add(ontModel.listStatements(ontModel.getResource(propertyURI), null, (RDFNode) null));
OntProperty op = localModel.getObjectProperty(propertyURI);
return propertyFromOntProperty(op);
} finally {
getOntModel().leaveCriticalSection();
ontModel.leaveCriticalSection();
}
}
public ObjectProperty getObjectPropertyByURIs(String propertyURI, String domainURI, String rangeURI) {
public ObjectProperty getObjectPropertyByURIs(String propertyURI,
String domainURI, String rangeURI) {
return getObjectPropertyByURIs(propertyURI, domainURI, rangeURI, null);
}
public ObjectProperty getObjectPropertyByURIs(String propertyURI,
String domainURI, String rangeURI, ObjectProperty base) {
if(log.isDebugEnabled()) {
log.debug("Getting " + propertyURI + " with domain " + domainURI + " and range " + rangeURI);
}
ObjectProperty op = getObjectPropertyByURI(propertyURI);
long start = System.currentTimeMillis();
ObjectProperty op = (base != null) ? base : getObjectPropertyByURI(propertyURI);
if (op == null || rangeURI == null) {
return op;
}
@ -293,7 +307,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel " +
"SELECT ?range ?rangeRoot ?label ?group ?customForm ?displayRank ?displayLevel " +
" ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" ?collateBySubclass ?displayLimit ?individualSortProperty \n" +
" ?entitySortDirection ?selectFromExisting ?offerCreateNew \n" +
@ -308,7 +322,8 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (rangeURI != null) {
propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n";
};
propQuery += " ?context config:hasConfiguration ?configuration . \n" +
propQuery += " OPTIONAL { ?context config:qualifiedByRoot ?rangeRoot } \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?configuration config:propertyGroup ?group } \n" +
" OPTIONAL { ?configuration config:displayName ?label } \n" +
@ -334,6 +349,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
ResultSet rs = qe.execSelect();
if (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
// This is a bit of hack, used for things where the type of the
// immediately-related object ("root," for lack of a better term)
// is important to record but not the type directly associated with
// a configuration
Resource rangeRootRes = qsoln.getResource("rangeRoot");
if (rangeRootRes != null) {
// reusing this obsolete field for now
op.setRangeEntityURI(rangeRootRes.getURI());
}
Resource groupRes = qsoln.getResource("group");
if (groupRes != null) {
op.setGroupURI(groupRes.getURI());
@ -407,7 +431,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
} finally {
qe.close();
}
}
return op;
}
@ -918,24 +942,30 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
"?property = vitro:additionalLink ||" +
"!regex(str(?property), \"^http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" ))");
PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && ");
}
}
protected static final String OBJECT_PROPERTY_QUERY_STRING =
PREFIXES + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
"SELECT DISTINCT ?property ?objType WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?object a ?objType . \n" +
// " ?property a owl:ObjectProperty . \n" +
" FILTER ( \n" +
" isURI(?object) && \n" +
PROPERTY_FILTERS + "\n" +
" ) \n" +
"}";
"} ORDER BY ?property ?objType";
@Override
public List<ObjectProperty> getObjectPropertyList(Individual subject) {
return getObjectPropertyList(subject.getURI());
}
// Returns a list of ObjectProperty objects for which statements exist about
// the individual. Note that this method now returns additional copies of
// a given predicate, with the rangeVClassURI changed to indicate the distinct
// types of the related objects. This supports finding the approriate list
// views for the "faux" qualified properties.
@Override
public List<ObjectProperty> getObjectPropertyList(String subjectUri) {
@ -954,15 +984,35 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
log.debug("Object property query:\n" + query);
ResultSet results = getPropertyQueryResults(query);
ObjectProperty propRegister = new ObjectProperty();
propRegister.setURI("");
ResultSet results = getPropertyQueryResults(queryString);
List<ObjectProperty> properties = new ArrayList<ObjectProperty>();
while (results.hasNext()) {
QuerySolution soln = results.next();
Resource resource = soln.getResource("property");
String uri = resource.getURI();
log.debug("Found populated object property " + uri);
ObjectProperty property = getObjectPropertyByURI(uri);
Resource objType = soln.getResource("objType");
String objTypeUri = objType.getURI();
log.debug("Found populated object property " + uri +
" with object type " + objType);
ObjectProperty property = null;
if (uri.equals(propRegister.getURI())) {
property = propRegister.clone();
} else {
property = getObjectPropertyByURI(uri);
if (property != null) {
propRegister = property;
// add canonical instance of the property first in the list
// before the range-changed versions
properties.add(property);
// isolate the canonical prop from what's about to happen next
property = property.clone();
}
}
if (property != null) {
property.setRangeVClassURI(objTypeUri);
properties.add(property);
}
}
@ -998,12 +1048,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
// 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<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap = null;
Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap;
@Override
public String getCustomListViewConfigFileName(ObjectProperty op) {
if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
}
if (customListViewConfigFileMap.isEmpty()) {
long start = System.currentTimeMillis();
OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
@ -1036,10 +1089,19 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
domainUri, new Pair<ObjectProperty, String>(
prop, rangeUri)), filename);
}
}
}
// If there are no custom list views, put a bogus entry in the map
// to avoid further recomputation
if (customListViewConfigFileMap.isEmpty()) {
ObjectProperty bottom = new ObjectProperty();
bottom.setURI(OWL.NS + "bottomObjectProperty");
customListViewConfigFileMap.put(
new Pair<String,Pair<ObjectProperty,String>>(
null, new Pair<ObjectProperty, String>(
bottom, null)), "nothing");
}
qexec.close();
}
}
String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<String, Pair<ObjectProperty, String>>(op.getDomainVClassURI(), new Pair<ObjectProperty,String>(op, op.getRangeVClassURI())));
if (customListViewConfigFileName == null) {
log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI() + " and domain " + op.getDomainVClassURI());

View file

@ -11,7 +11,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -25,6 +24,7 @@ import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
@ -35,6 +35,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.resultset.ResultSetMem;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
@ -46,6 +47,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements ObjectPropertyStatementDao {
@ -92,7 +94,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
else {
Map<String, ObjectProperty> uriToObjectProperty = new HashMap<String,ObjectProperty>();
ObjectPropertyDaoJena opDaoJena = new ObjectPropertyDaoJena(dwf, getWebappDaoFactory());
ObjectPropertyDaoJena opDaoJena = (ObjectPropertyDaoJena) getWebappDaoFactory().getObjectPropertyDao();
//new ObjectPropertyDaoJena(rdfService, dwf, getWebappDaoFactory());
OntModel ontModel = getOntModelSelector().getABoxModel();
ontModel.enterCriticalSection(Lock.READ);
@ -278,26 +281,77 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Set<String> constructQueryStrings,
String sortDirection) {
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
long start = System.currentTimeMillis();
try {
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, rangeUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
}
if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC(");
}
ResultSet results = (constructedModel == null) ? selectFromRDFService(
queryString, subjectUri, propertyUri, domainUri, rangeUri) : selectFromConstructedModel(
queryString, subjectUri, propertyUri, domainUri, rangeUri, constructedModel);
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
RDFNode node = soln.get(objectKey);
if (node.isURIResource()) {
list.add(QueryUtils.querySolutionToStringValueMap(soln));
}
}
if(log.isDebugEnabled()) {
long duration = System.currentTimeMillis() - start;
log.debug(duration + " to do list view for " +
propertyUri + " / " + domainUri + " / " + rangeUri);
}
} catch (Exception e) {
log.error("Error getting object property values for subject " + subjectUri + " and property " + propertyUri, e);
return Collections.emptyList();
}
if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC(");
}
return list;
}
private ResultSet selectFromRDFService(String queryString, String subjectUri,
String propertyUri, String domainUri, String rangeUri) {
String[] part = queryString.split("[Ww][Hh][Ee][Rr][Ee]");
part[1] = part[1].replace("?subject", "<" + subjectUri + ">");
part[1] = part[1].replace("?property", "<" + propertyUri + ">");
if (domainUri != null && !domainUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
part[1] = part[1].replace("?subjectType", "<" + domainUri + ">");
}
if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
part[1] = part[1].replace("?objectType", "<" + rangeUri + ">");
}
queryString = part[0] + "WHERE" + part[1];
try {
return ResultSetFactory.fromJSON(
rdfService.sparqlSelectQuery(queryString, RDFService.ResultFormat.JSON));
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
}
private ResultSet selectFromConstructedModel(String queryString,
String subjectUri, String propertyUri, String domainUri, String rangeUri,
Model constructedModel) {
Query query = null;
try {
query = QueryFactory.create(queryString, Syntax.syntaxARQ);
} catch(Throwable th){
log.error("Could not create SPARQL query for query string. " + th.getMessage());
log.error(queryString);
return Collections.emptyList();
throw new RuntimeException(th);
}
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
initialBindings.add("property", ResourceFactory.createResource(propertyUri));
@ -307,52 +361,31 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
initialBindings.add("objectType", ResourceFactory.createResource(rangeUri));
}
log.debug("Query string for object property " + propertyUri + ": " + queryString);
if(log.isDebugEnabled()) {
log.debug("Query string for object property " + propertyUri + ": " + queryString);
}
// Run the SPARQL query to get the properties
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
QueryExecution qexec = null;
try {
qexec = (constructedModel == null)
? QueryExecutionFactory.create(
query, dataset, initialBindings)
: QueryExecutionFactory.create(
query, constructedModel, initialBindings);
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
RDFNode node = soln.get(objectKey);
if (node.isURIResource()) {
list.add(QueryUtils.querySolutionToStringValueMap(soln));
}
}
return list;
} catch (Exception e) {
log.error("Error getting object property values for subject " + subjectUri + " and property " + propertyUri);
return Collections.emptyList();
qexec = QueryExecutionFactory.create(
query, constructedModel, initialBindings);
return new ResultSetMem(qexec.execSelect());
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
if (qexec != null) {
qexec.close();
}
}
}
}
private Model constructModelForSelectQueries(String subjectUri,
String propertyUri,
String propertyUri,
String rangeUri,
Set<String> constructQueries) {
if (constructQueries == null) {
if (constructQueries.size() == 0 || constructQueries == null) {
return null;
}
@ -362,24 +395,18 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
queryString = queryString.replace("?subject", "<" + subjectUri + ">");
queryString = queryString.replace("?property", "<" + propertyUri + ">");
if (rangeUri != null) {
queryString = queryString.replace("?objectType", "<" + rangeUri + ">");
}
log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
if (log.isDebugEnabled()) {
log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
}
// 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
// try {
// QueryFactory.create(queryString, Syntax.syntaxARQ);
// } catch(Throwable th){
// log.error("Could not create CONSTRUCT SPARQL query for query " +
// "string. " + th.getMessage());
// log.error(queryString);
// return constructedModel;
// }
try {
//If RDFService is null, will do what code used to do before, otherwise employ rdfservice
//If RDFService is null, will do what code used to do before,
//otherwise employ rdfservice
if(rdfService == null) {
log.debug("RDF Service null, Using CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
@ -402,7 +429,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
query, dataset);
qe.execConstruct(constructedModel);
} catch (Exception e) {
log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri);
log.error("Error getting constructed model for subject "
+ subjectUri + " and property " + propertyUri);
} finally {
if (qe != null) {
qe.close();
@ -412,28 +440,31 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
}
} else {
String parseFormat = "N3";
RDFService.ModelSerializationFormat resultFormat = RDFService.ModelSerializationFormat.N3;
RDFService.ModelSerializationFormat resultFormat = RDFService
.ModelSerializationFormat.N3;
/* If the test ObjectPropertyStatementDaoJenaTest.testN3WithSameAs() fails
* this code can be removed: */
/* If the test ObjectPropertyStatementDaoJenaTest.testN3WithSameAs()
* fails this code can be removed: */
if( OWL.sameAs.getURI().equals( propertyUri )){
// VIVO-111: owl:sameAs can be represented as = in n3 but Jena's parser does not recognize it.
// Switch to rdf/xml only for sameAs since it seems like n3 would be faster the rest of the time.
// VIVO-111: owl:sameAs can be represented as = in n3 but
// Jena's parser does not recognize it.
// Switch to rdf/xml only for sameAs since it seems like n3
// would be faster the rest of the time.
parseFormat = "RDF/XML";
resultFormat = RDFService.ModelSerializationFormat.RDFXML;
}
/* end of removal */
InputStream is = rdfService.sparqlConstructQuery(queryString, resultFormat);
InputStream is = rdfService.sparqlConstructQuery(
queryString, resultFormat);
constructedModel.read( is, null, parseFormat);
}
} catch (Exception e) {
log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri, e);
log.error("Error getting constructed model for subject "
+ subjectUri + " and property " + propertyUri, e);
}
}
return constructedModel;
return constructedModel;
}
protected static final String MOST_SPECIFIC_TYPE_QUERY = ""

View file

@ -21,13 +21,13 @@ import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.Restriction;
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.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
@ -36,7 +36,6 @@ 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;
import com.hp.hpl.jena.vocabulary.RDFS;
@ -49,6 +48,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
@ -74,11 +75,14 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
log.debug("Query prefixes: " + PREFIXES);
}
protected RDFService rdfService;
protected DatasetWrapperFactory dwf;
public PropertyDaoJena(DatasetWrapperFactory dwf,
public PropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(wadf);
this.rdfService = rdfService;
this.dwf = dwf;
}
@ -86,6 +90,10 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
protected OntModel getOntModel() {
return getOntModelSelector().getTBoxModel();
}
protected RDFService getRDFService() {
return this.rdfService;
}
public void addSuperproperty(ObjectProperty property, ObjectProperty superproperty) {
addSuperproperty(property.getURI(),superproperty.getURI());
@ -414,8 +422,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return classSet;
}
protected ResultSet getPropertyQueryResults(Query query) {
log.debug("SPARQL query:\n" + query.toString());
protected ResultSet getPropertyQueryResults(String queryString) {
log.debug("SPARQL query:\n" + queryString);
// RY Removing prebinding due to Jena bug: when isLiteral(?object) or
// isURI(?object) is added to the query as a filter, the query fails with prebinding
@ -424,23 +432,32 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
//subjectBinding.add("subject", ResourceFactory.createResource(subjectUri));
// Run the SPARQL query to get the properties
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
ResultSet rs = null;
try {
QueryExecution qexec = QueryExecutionFactory.create(
query, dataset); //, subjectBinding);
try {
rs = new ResultSetMem(qexec.execSelect());
} finally {
qexec.close();
}
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
return ResultSetFactory.fromJSON(
getRDFService().sparqlSelectQuery(
queryString, RDFService.ResultFormat.JSON));
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
return rs;
// DatasetWrapper w = dwf.getDatasetWrapper();
// Dataset dataset = w.getDataset();
// dataset.getLock().enterCriticalSection(Lock.READ);
// ResultSet rs = null;
// try {
// QueryExecution qexec = QueryExecutionFactory.create(
// query, dataset); //, subjectBinding);
// try {
// rs = new ResultSetMem(qexec.execSelect());
// } finally {
// qexec.close();
// }
// } finally {
// dataset.getLock().leaveCriticalSection();
// w.close();
// }
// return rs;
}
/**
@ -865,20 +882,6 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
}
return domainAndRangeURIs;
}
private String getURIStr(Resource res) {
String URIStr;
if (res == null) {
URIStr = OWL.Thing.getURI(); // TODO: rdf:Resource if using RDF model; or option to turn off entirely
} else {
if (res.isAnon()) {
URIStr = PSEUDO_BNODE_NS+res.getId().toString();
} else {
URIStr = res.getURI();
}
}
return URIStr;
}
}

View file

@ -29,11 +29,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class PropertyInstanceDaoJena extends PropertyDaoJena implements
PropertyInstanceDao {
public PropertyInstanceDaoJena(DatasetWrapperFactory dwf, WebappDaoFactoryJena wadf) {
super(dwf, wadf);
public PropertyInstanceDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(rdfService, dwf, wadf);
}
public void deleteObjectPropertyStatement(String subjectURI, String propertyURI, String objectURI) {

View file

@ -50,6 +50,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.utils.jena.URIUtils;
@ -109,6 +110,8 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
Dataset dataset = makeInMemoryDataset(assertions, inferences);
this.dwf = new StaticDatasetFactory(dataset);
this.rdfService = new RDFServiceModel(ontModelSelector.getFullModel());
}
public WebappDaoFactoryJena(OntModelSelector ontModelSelector,
@ -327,7 +330,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
DataPropertyDao dataPropertyDao = null;
public DataPropertyDao getDataPropertyDao() {
if( dataPropertyDao == null )
dataPropertyDao = new DataPropertyDaoJena(dwf, this);
dataPropertyDao = new DataPropertyDaoJena(rdfService, dwf, this);
return dataPropertyDao;
}
@ -358,14 +361,15 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
private ObjectPropertyDao objectPropertyDao = null;
public ObjectPropertyDao getObjectPropertyDao() {
if( objectPropertyDao == null )
objectPropertyDao = new ObjectPropertyDaoJena(dwf, this);
objectPropertyDao = new ObjectPropertyDaoJena(
rdfService, dwf, config.customListViewConfigFileMap, this);
return objectPropertyDao;
}
private PropertyInstanceDao propertyInstanceDao = null;
public PropertyInstanceDao getPropertyInstanceDao() {
if( propertyInstanceDao == null )
propertyInstanceDao = new PropertyInstanceDaoJena(dwf, this);
propertyInstanceDao = new PropertyInstanceDaoJena(rdfService, dwf, this);
return propertyInstanceDao;
}

View file

@ -10,6 +10,8 @@ import java.text.Collator;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import javax.servlet.Filter;
@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openjena.atlas.lib.Pair;
import com.hp.hpl.jena.graph.BulkUpdateHandler;
import com.hp.hpl.jena.graph.Graph;
@ -35,6 +38,7 @@ import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -311,6 +315,8 @@ public class RequestModelsPrep implements Filter {
config.setDefaultNamespace(defaultNamespace);
config.setPreferredLanguages(langs);
config.setUnderlyingStoreReasoned(isStoreReasoned(req));
config.setCustomListViewConfigFileMap(getCustomListViewConfigFileMap(
req.getSession().getServletContext()));
return config;
}
@ -365,6 +371,18 @@ public class RequestModelsPrep implements Filter {
"VitroConnection.DataSource.isStoreReasoned", "true");
return ("true".equals(isStoreReasoned));
}
private Map<Pair<String,Pair<ObjectProperty, String>>, String>
getCustomListViewConfigFileMap(ServletContext ctx) {
Map<Pair<String,Pair<ObjectProperty, String>>, String> map =
(Map<Pair<String,Pair<ObjectProperty, String>>, String>)
ctx.getAttribute("customListViewConfigFileMap");
if (map == null) {
map = new ConcurrentHashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
ctx.setAttribute("customListViewConfigFileMap", map);
}
return map;
}
@Override
public void destroy() {

View file

@ -31,6 +31,8 @@ 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;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
/**
* Performs knowledge base updates to the abox to align with a new ontology version
@ -594,9 +596,11 @@ public class ABoxUpdater {
return;
}
long start = System.currentTimeMillis();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
//log.info(System.currentTimeMillis() - start + " to get graph");
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
@ -604,11 +608,23 @@ public class ABoxUpdater {
Model renamePropAddModel = ModelFactory.createDefaultModel();
Model renamePropRetractModel = ModelFactory.createDefaultModel();
log.info("renaming " + oldProperty.getURI() + " in graph " + graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
start = System.currentTimeMillis();
// String queryStr = "CONSTRUCT { ?s <" + oldProperty.getURI() + "> ?o } WHERE { GRAPH<" + graph + "> { ?s <" + oldProperty.getURI() + "> ?o } } ";
// try {
// renamePropRetractModel = RDFServiceUtils.parseModel(rdfService.sparqlConstructQuery(queryStr, RDFService.ModelSerializationFormat.NTRIPLE), RDFService.ModelSerializationFormat.NTRIPLE);
// } catch (RDFServiceException e) {
// log.error(e,e);
// }
// log.info(System.currentTimeMillis() - start + " to run sparql construct for " + renamePropRetractModel.size() + " statements" );
start = System.currentTimeMillis();
renamePropRetractModel.add( aboxModel.listStatements(
(Resource) null, oldProperty, (RDFNode) null));
log.info(System.currentTimeMillis() - start + " to list " + renamePropRetractModel.size() + " old statements");
start = System.currentTimeMillis();
StmtIterator stmItr = renamePropRetractModel.listStatements();
while(stmItr.hasNext()) {
Statement tempStatement = stmItr.nextStatement();
@ -616,8 +632,13 @@ public class ABoxUpdater {
newProperty,
tempStatement.getObject() );
}
log.info(System.currentTimeMillis() - start + " to make new statements");
start = System.currentTimeMillis();
aboxModel.remove(renamePropRetractModel);
log.info(System.currentTimeMillis() - start + " to retract old statements");
start = System.currentTimeMillis();
aboxModel.add(renamePropAddModel);
log.info(System.currentTimeMillis() - start + " to add new statements");
} finally {
aboxModel.leaveCriticalSection();
}

View file

@ -96,10 +96,10 @@ public class KnowledgeBaseUpdater {
// update ABox data any time
log.info("performing SPARQL CONSTRUCT additions");
performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
//performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
log.info("performing SPARQL CONSTRUCT retractions");
performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
//performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
log.info("\tupdating the abox");
updateABox(changes);
@ -207,9 +207,11 @@ public class KnowledgeBaseUpdater {
StmtIterator sit = anonModel.listStatements();
while (sit.hasNext()) {
Statement stmt = sit.nextStatement();
long start = System.currentTimeMillis();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
log.info(System.currentTimeMillis() - start + " to get graph");
if(!isUpdatableABoxGraph(graph)) {
continue;
}

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerialization
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
public class RDFServiceUtils {
@ -34,7 +35,18 @@ public class RDFServiceUtils {
public static RDFServiceFactory getRDFServiceFactory(ServletContext context) {
Object o = context.getAttribute(RDFSERVICEFACTORY_ATTR);
return (o instanceof RDFServiceFactory) ? (RDFServiceFactory) o : null;
if (o instanceof RDFServiceFactory) {
RDFServiceFactory factory = (RDFServiceFactory) o;
/*
* Every factory is wrapped in a logger, so we can dynamically
* enable or disable logging.
*/
return new LoggingRDFServiceFactory(context, factory);
} else {
log.error("Expecting an RDFServiceFactory on the context, but found " + o);
return null;
}
}
public static void setRDFServiceFactory(ServletContext context,

View file

@ -0,0 +1,125 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
/**
* This RDFService wrapper adds instrumentation to the time-consuming methods of
* the inner RDFService.
*
* For the other methods, it just delegates to the inner RDFService.
*/
public class LoggingRDFService implements RDFService {
private final ServletContext ctx;
private final RDFService innerService;
LoggingRDFService(ServletContext ctx, RDFService innerService) {
this.ctx = ctx;
this.innerService = innerService;
}
// ----------------------------------------------------------------------
// Timed methods
// ----------------------------------------------------------------------
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, changeSet)) {
return innerService.changeSetUpdate(changeSet);
}
}
@Override
public InputStream sparqlConstructQuery(String query,
ModelSerializationFormat resultFormat) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlConstructQuery(query, resultFormat);
}
}
@Override
public InputStream sparqlDescribeQuery(String query,
ModelSerializationFormat resultFormat) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlDescribeQuery(query, resultFormat);
}
}
@Override
public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat)
throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlSelectQuery(query, resultFormat);
}
}
@Override
public boolean sparqlAskQuery(String query) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, query)) {
return innerService.sparqlAskQuery(query);
}
}
// ----------------------------------------------------------------------
// Untimed methods
// ----------------------------------------------------------------------
@Override
public void newIndividual(String individualURI, String individualTypeURI)
throws RDFServiceException {
innerService.newIndividual(individualURI, individualTypeURI);
}
@Override
public void newIndividual(String individualURI, String individualTypeURI,
String graphURI) throws RDFServiceException {
innerService.newIndividual(individualURI, individualTypeURI, graphURI);
}
@Override
public List<String> getGraphURIs() throws RDFServiceException {
return innerService.getGraphURIs();
}
@Override
public void getGraphMetadata() throws RDFServiceException {
innerService.getGraphMetadata();
}
@Override
public String getDefaultWriteGraphURI() throws RDFServiceException {
return innerService.getDefaultWriteGraphURI();
}
@Override
public void registerListener(ChangeListener changeListener)
throws RDFServiceException {
innerService.registerListener(changeListener);
}
@Override
public void unregisterListener(ChangeListener changeListener)
throws RDFServiceException {
innerService.unregisterListener(changeListener);
}
@Override
public ChangeSet manufactureChangeSet() {
return innerService.manufactureChangeSet();
}
@Override
public void close() {
innerService.close();
}
}

View file

@ -0,0 +1,48 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
/**
* If the RDFServiceFactory is wrapped in this, then all RDFServices will be
* wrapped in a LoggingRDFService.
*/
public class LoggingRDFServiceFactory implements RDFServiceFactory {
private final ServletContext ctx;
private final RDFServiceFactory factory;
public LoggingRDFServiceFactory(ServletContext ctx,
RDFServiceFactory factory) {
this.ctx = ctx;
this.factory = factory;
}
@Override
public RDFService getRDFService() {
return new LoggingRDFService(ctx, factory.getRDFService());
}
@Override
public RDFService getShortTermRDFService() {
return new LoggingRDFService(ctx, factory.getShortTermRDFService());
}
@Override
public void registerListener(ChangeListener changeListener)
throws RDFServiceException {
factory.registerListener(changeListener);
}
@Override
public void unregisterListener(ChangeListener changeListener)
throws RDFServiceException {
factory.unregisterListener(changeListener);
}
}

View file

@ -0,0 +1,175 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
/**
* Writes the log message for the LoggingRDFService.
*
* If not enabled, or if the logging level is insufficient, this does nothing.
*
* If enabled, it checks for restrictions. If there is a restriction pattern
* (regular expression), the a log message will only be printed if one of the
* fully-qualified class names in the stack trace matches that pattern.
*
* If everything passes muster, the constructor will record the time that the
* instance was created.
*
* When close() is called, if a start time was recorded, then a log record is
* produced. This contains the elapsed time, the name of the method, and any
* arguments passed to the constructor. It may also include a stack trace, if
* requested.
*
* The stack trace is abbreviated. It will reach into this class, and will not
* extend past the first reference to the ApplicationFilterChain. Perhaps it
* should be abbreviated further?
*/
public class RDFServiceLogger implements AutoCloseable {
private static final Log log = LogFactory.getLog(RDFServiceLogger.class);
private static final String PROPERTY_ENABLED = "developer.loggingRDFService.enable";
private static final String PROPERTY_STACK_TRACE = "developer.loggingRDFService.stackTrace";
private static final String PROPERTY_RESTRICTION = "developer.loggingRDFService.restriction";
private final ServletContext ctx;
private final Object[] args;
private boolean isEnabled;
private boolean traceRequested;
private Pattern restriction;
private String methodName;
private List<StackTraceElement> trace = Collections.emptyList();
private long startTime;
public RDFServiceLogger(ServletContext ctx, Object... args) {
this.ctx = ctx;
this.args = args;
getProperties();
if (isEnabled && log.isInfoEnabled()) {
loadStackTrace();
if (passesRestrictions()) {
this.startTime = System.currentTimeMillis();
}
}
}
private void getProperties() {
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
isEnabled = Boolean.valueOf(props.getProperty(PROPERTY_ENABLED));
traceRequested = Boolean.valueOf(props
.getProperty(PROPERTY_STACK_TRACE));
String restrictionString = props.getProperty(PROPERTY_RESTRICTION);
if (StringUtils.isNotBlank(restrictionString)) {
try {
restriction = Pattern.compile(restrictionString);
} catch (Exception e) {
log.error("Failed to compile the pattern for "
+ PROPERTY_RESTRICTION + " = " + restriction + " " + e);
isEnabled = false;
}
}
}
private void loadStackTrace() {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
List<StackTraceElement> list = new ArrayList<StackTraceElement>(
Arrays.asList(stack));
trimStackTraceAtBeginning(list);
trimStackTraceAtEnd(list);
if (list.isEmpty()) {
this.methodName = "UNKNOWN";
} else {
this.methodName = list.get(0).getMethodName();
}
this.trace = list;
}
private void trimStackTraceAtBeginning(List<StackTraceElement> list) {
ListIterator<StackTraceElement> iter = list.listIterator();
while (iter.hasNext()) {
StackTraceElement ste = iter.next();
if (ste.getClassName().equals(LoggingRDFService.class.getName())) {
break;
} else {
iter.remove();
}
}
}
private void trimStackTraceAtEnd(List<StackTraceElement> list) {
ListIterator<StackTraceElement> iter = list.listIterator();
boolean trimming = false;
while (iter.hasNext()) {
StackTraceElement ste = iter.next();
if (trimming) {
iter.remove();
} else if (ste.getClassName().contains("ApplicationFilterChain")) {
trimming = true;
}
}
}
private boolean passesRestrictions() {
if (restriction == null) {
return true;
}
for (StackTraceElement ste : trace) {
if (restriction.matcher(ste.getClassName()).matches()) {
return true;
}
}
return false;
}
@Override
public void close() {
if (startTime != 0L) {
long endTime = System.currentTimeMillis();
float elapsedSeconds = (endTime - startTime) / 1000.0F;
String cleanArgs = Arrays.deepToString(args).replaceAll(
"[\\n\\r\\t]+", " ");
String formattedTrace = formatStackTrace();
log.info(String.format("%8.3f %s %s %s", elapsedSeconds,
methodName, cleanArgs, formattedTrace));
}
}
private String formatStackTrace() {
StringBuilder sb = new StringBuilder();
if (traceRequested) {
for (StackTraceElement ste : trace) {
sb.append(String.format("\n %d %s", ste.getLineNumber(),
ste.getClassName()));
}
sb.append("\n ...");
}
return sb.toString();
}
}

View file

@ -79,7 +79,8 @@ public class FileGraphSetup implements ServletContextListener {
cleanupDB(dataset, pathsToURIs(paths, ABOX), ABOX);
OntModel aboxBaseModel = baseOms.getABoxModel();
aboxChanged = readGraphs(paths, maker, ABOX, aboxBaseModel);
// Just update the ABox filegraphs in the DB; don't attach them to a base model.
aboxChanged = readGraphs(paths, maker, ABOX, /* aboxBaseModel */ null);
// TBox files
paths = getFilegraphPaths(ctx, RDF, TBOX, FILEGRAPH);
@ -108,7 +109,7 @@ public class FileGraphSetup implements ServletContextListener {
if ( (aboxChanged || tboxChanged) && !isUpdateRequired(sce.getServletContext())) {
log.info("a full recompute of the Abox will be performed because" +
" the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." );
SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext());
SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext(), SimpleReasonerSetup.RecomputeMode.BACKGROUND);
}
}
@ -140,6 +141,14 @@ public class FileGraphSetup implements ServletContextListener {
return paths;
}
/*
* Reads graphs without using submodels to separate filegraph content from the
* base model.
*/
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel) {
return readGraphs(pathSet, dataset, type, baseModel, false);
}
/*
* Reads the graphs stored as files in sub-directories of
* 1. updates the SDB store to reflect the current contents of the graph.
@ -148,7 +157,7 @@ public class FileGraphSetup implements ServletContextListener {
* Note: no connection needs to be maintained between the in-memory copy of the
* graph and the DB copy.
*/
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel) {
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel, boolean useSubmodels) {
int count = 0;
@ -172,9 +181,14 @@ public class FileGraphSetup implements ServletContextListener {
log.warn("Ignoring " + type + " file graph " + p + " because the file extension is unrecognized.");
}
if ( !model.isEmpty() ) {
baseModel.addSubModel(model);
log.debug("Attached file graph as " + type + " submodel " + p.getFileName());
if ( !model.isEmpty() && baseModel != null ) {
if (useSubmodels) {
baseModel.addSubModel(model);
} else {
baseModel.add(model);
}
log.info("Attached file graph as " + type + " submodel " + p.getFileName());
}
modelChanged = modelChanged | updateGraphInDB(dataset, model, type, p);

View file

@ -12,7 +12,6 @@ import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -21,7 +20,6 @@ import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
@ -117,7 +115,16 @@ public class SimpleReasonerSetup implements ServletContextListener {
assertionsOms.getTBoxModel().register(simpleReasonerTBoxListener);
inferencesOms.getTBoxModel().register(simpleReasonerTBoxListener);
log.info("Simple reasoner connected for the ABox");
RecomputeMode mode = getRecomputeRequired(ctx);
if (RecomputeMode.FOREGROUND.equals(mode)) {
log.info("ABox inference recompute required.");
simpleReasoner.recompute();
} else if (RecomputeMode.BACKGROUND.equals(mode)) {
log.info("starting ABox inference recompute in a separate thread.");
new Thread(
new ABoxRecomputer(
simpleReasoner),"ABoxRecomputer").start();
}
} catch (Throwable t) {
t.printStackTrace();
@ -179,15 +186,19 @@ public class SimpleReasonerSetup implements ServletContextListener {
}
}
public enum RecomputeMode {
FOREGROUND, BACKGROUND
}
private static final String RECOMPUTE_REQUIRED_ATTR =
SimpleReasonerSetup.class.getName() + ".recomputeRequired";
public static void setRecomputeRequired(ServletContext ctx) {
ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, true);
public static void setRecomputeRequired(ServletContext ctx, RecomputeMode mode) {
ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, mode);
}
public static boolean isRecomputeRequired(ServletContext ctx) {
return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null);
public static RecomputeMode getRecomputeRequired(ServletContext ctx) {
return (RecomputeMode) ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR);
}
private static final String MSTCOMPUTE_REQUIRED_ATTR =
@ -249,6 +260,18 @@ public class SimpleReasonerSetup implements ServletContextListener {
log.debug("Classnames of reasoner plugins = " + list);
return list;
}
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
}

View file

@ -157,42 +157,24 @@ public class UpdateKnowledgeBase implements ServletContextListener {
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();
}
}
log.info("Simple reasoner connected for the ABox");
if(JenaDataSourceSetupBase.isFirstStartup()
|| (migrationChangesMade && requiredUpdate)) {
SimpleReasonerSetup.setRecomputeRequired(
ctx, SimpleReasonerSetup.RecomputeMode.FOREGROUND);
} else if (migrationChangesMade) {
SimpleReasonerSetup.setRecomputeRequired(
ctx, SimpleReasonerSetup.RecomputeMode.BACKGROUND);
}
} catch (Throwable t){
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
}
}
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
/**

View file

@ -83,7 +83,7 @@ public class ApplicationConfigurationOntologyUtils {
String rangeURI = qsoln.getResource("range").getURI();
if (appropriateDomain(domainRes, subject, tboxModel)) {
ObjectProperty faux = opDao.getObjectPropertyByURIs(
opURI, domainURI, rangeURI);
opURI, domainURI, rangeURI, (prop != null) ? prop.clone() : null);
if (faux != null) {
additionalProps.add(faux);
} else {

View file

@ -6,8 +6,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -73,13 +75,23 @@ public class GroupedPropertyList extends BaseTemplateModel {
// so we cannot just rely on getting that list.
List<ObjectProperty> populatedObjectPropertyList = subject
.getPopulatedObjectPropertyList();
Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap(
populatedObjectPropertyList);
// save applicable ranges before deduping to filter later
populatedObjectPropertyList = dedupe(populatedObjectPropertyList);
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, subject, vreq);
additions = filterAdditions(additions, populatedObjTypes);
if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) {
log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " + t.getDomainVClassURI());
log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " +
t.getDomainVClassURI());
}
log.debug("Added " + additions.size() +
" properties due to application configuration ontology");
@ -110,12 +122,15 @@ public class GroupedPropertyList extends BaseTemplateModel {
mergeAllPossibleDataProperties(propertyList);
}
propertyList = correctLanguageForProperties(propertyList);
if (editing) {
propertyList = correctLanguageForProperties(propertyList);
}
sort(propertyList);
// Put the list into groups
List<PropertyGroup> propertyGroupList = addPropertiesToGroups(propertyList);
// Build the template data model from the groupList
groups = new ArrayList<PropertyGroupTemplateModel>(
propertyGroupList.size());
@ -131,6 +146,34 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
private Map<String, List<String>> makePopulatedObjTypeMap(List<ObjectProperty> props) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (ObjectProperty prop : props) {
if(prop.getRangeVClassURI() != null) {
List<String> typeList = map.get(prop.getURI());
if(typeList == null) {
typeList = new ArrayList<String>();
map.put(prop.getURI(), typeList);
}
typeList.add(prop.getRangeVClassURI());
}
}
return map;
}
private List<ObjectProperty> filterAdditions(Collection<ObjectProperty> additions,
Map<String, List<String>> populatedObjTypes) {
List<ObjectProperty> filteredAdditions = new ArrayList<ObjectProperty>();
for (ObjectProperty prop : additions) {
List<String> allowedTypes = populatedObjTypes.get(prop.getURI());
if(allowedTypes != null && (allowedTypes.contains(prop.getRangeVClassURI())
|| allowedTypes.contains(prop.getRangeEntityURI()) ) ) {
filteredAdditions.add(prop);
}
}
return filteredAdditions;
}
// Use the language-filtering WebappDaoFactory to get the right version of
// each property. When editing, the methods that add to the property list
// are blissfully (and intentionally) language-unaware.
@ -187,6 +230,19 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
}
}
//assumes sorted list
protected List<ObjectProperty> dedupe(List<ObjectProperty> propList) {
List<ObjectProperty> dedupedList = new ArrayList<ObjectProperty>();
String uriRegister = "";
for (ObjectProperty prop : propList) {
if(!uriRegister.equals(prop.getURI())) {
uriRegister = prop.getURI();
dedupedList.add(prop);
}
}
return dedupedList;
}
protected void sort(List<Property> propertyList) {
try {
@ -325,10 +381,12 @@ public class GroupedPropertyList extends BaseTemplateModel {
// Get the property groups
PropertyGroupDao pgDao = wdf.getPropertyGroupDao();
long start = System.currentTimeMillis();
List<PropertyGroup> groupList = pgDao.getPublicGroups(false); // may be returned empty but not null
// To test no property groups defined, use:
// List<PropertyGroup> groupList = new ArrayList<PropertyGroup>();
start = System.currentTimeMillis();
int groupCount = groupList.size();
/*
@ -353,7 +411,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
*/
PropertyGroup groupForUnassignedProperties = pgDao
.createDummyPropertyGroup("", MAX_GROUP_DISPLAY_RANK);
if (groupCount > 1) {
try {
Collections.sort(groupList);
@ -377,6 +435,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
log.error("Exception on trying to prune unpopulated groups from group list: "
+ ex.getMessage());
}
log.debug(System.currentTimeMillis() - start + " to remove unpopulated groups");
// If the group for unassigned properties is populated, add it to the
// group list.

View file

@ -8,6 +8,9 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
@ -37,6 +40,10 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel {
for (Property p : propertyList) {
if (p instanceof ObjectProperty) {
ObjectProperty op = (ObjectProperty) p;
RequestedAction dop = new DisplayObjectProperty(op);
if (!PolicyHelper.isAuthorizedForActions(vreq, dop)) {
continue;
}
ObjectPropertyTemplateModel tm = ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(
op, subject, vreq, editing, populatedObjectPropertyList);
if (!tm.isEmpty() || (editing && !tm.getAddUrl().isEmpty())) {

View file

@ -67,7 +67,14 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
}
@Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) {
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI) {
return getObjectPropertyByURI(objectPropertyURI);
}
@Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI, ObjectProperty base) {
return getObjectPropertyByURI(objectPropertyURI);
}