diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java index 5c836281db..410a3fa0f4 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java @@ -73,9 +73,9 @@ public int compare (DataProperty dp1, DataProperty dp2) { } public DataPropertyDaoJena(RDFService rdfService, - DatasetWrapperFactory dwf, + DatasetWrapper dw, WebappDaoFactoryJena wadf) { - super(rdfService, dwf, wadf); + super(rdfService, dw, wadf); } public void deleteDataProperty(DataProperty dtp) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoDB.java new file mode 100644 index 0000000000..b980e139de --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoDB.java @@ -0,0 +1,113 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.OntModelSpec; +import org.apache.jena.query.Dataset; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.shared.Lock; +import org.apache.jena.vocabulary.RDF; + +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; + +/** + * An extension of {@link DataPropertyStatementDaoJena} for databases, such as TDB. + */ +public class DataPropertyStatementDaoDB extends DataPropertyStatementDaoJena implements DataPropertyStatementDao { + + /** + * Initialize the data property statement DAO. + * + * @param dw The data wrapper. + * @param wadf The web application DAO factory. + */ + public DataPropertyStatementDaoDB(DatasetWrapper dw, WebappDaoFactoryDB wadf) { + super (dw, wadf); + } + + /** + * Fill existing data property statements for an individual. + * + * @param entity The individual. + * + * @return A filled out individual. + */ + public Individual fillExistingDataPropertyStatementsForIndividual(Individual entity) { + if (entity.getURI() == null) { + return entity; + } + + String query = + "CONSTRUCT { \n" + + " <" + entity.getURI() + "> ?p ?o . \n" + + "} WHERE { \n" + + " <" + entity.getURI() + "> ?p ?o . \n" + + " FILTER(isLiteral(?o)) \n" + + "}" ; + Model results = null; + Dataset dataset = getDataWrapper().getDataset(); + QueryExecution qexec = null; + + dataset.getLock().enterCriticalSection(Lock.READ); + try { + qexec = QueryExecutionFactory.create(QueryFactory.create(query), dataset); + results = qexec.execConstruct(); + } finally { + if (qexec != null) qexec.close(); + dataset.getLock().leaveCriticalSection(); + getDataWrapper().close(); + } + + OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, results); + ontModel.enterCriticalSection(Lock.READ); + try { + Resource ind = ontModel.getResource(entity.getURI()); + List edList = new ArrayList<>(); + StmtIterator stmtIt = ind.listProperties(); + + while (stmtIt.hasNext()) { + Statement st = stmtIt.next(); + boolean addToList = st.getObject().isLiteral() && + ( + ( + RDF.value.equals(st.getPredicate()) + || VitroVocabulary.value.equals(st.getPredicate().getURI())) + || MONIKER.equals(st.getPredicate()) + || !(NONUSER_NAMESPACES.contains(st.getPredicate().getNameSpace()) + ) + ); + + if (addToList) { + DataPropertyStatement ed = new DataPropertyStatementImpl(); + Literal lit = (Literal)st.getObject(); + fillDataPropertyStatementWithJenaLiteral(ed,lit); + ed.setDatapropURI(st.getPredicate().getURI()); + ed.setIndividualURI(ind.getURI()); + ed.setIndividual(entity); + edList.add(ed); + } + } + + entity.setDataPropertyStatements(edList); + return entity; + } finally { + ontModel.leaveCriticalSection(); + } + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java index fbebef2c2f..5f3394227b 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java @@ -50,15 +50,22 @@ public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPro { private static final Log log = LogFactory.getLog(DataPropertyStatementDaoJena.class); + private DatasetWrapper dw; - private DatasetWrapperFactory dwf; - - public DataPropertyStatementDaoJena(DatasetWrapperFactory dwf, + public DataPropertyStatementDaoJena(DatasetWrapper dw, WebappDaoFactoryJena wadf) { super(wadf); - this.dwf = dwf; + this.dw = dw; } + /** + * Get the data wrapper. + * + * @return The data wrapper. + */ + public DatasetWrapper getDataWrapper() { + return dw; + } public void deleteDataPropertyStatement( DataPropertyStatement dataPropertyStatement ) { @@ -366,13 +373,11 @@ public List getDataPropertyValuesForIndividualByProperty(String subject // Run the SPARQL query to get the properties List values = new ArrayList(); - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); + Dataset dataset = dw.getDataset(); dataset.getLock().enterCriticalSection(Lock.READ); QueryExecution qexec = null; try { - qexec = QueryExecutionFactory.create( - queryString, dataset); + qexec = QueryExecutionFactory.create(queryString, dataset); ResultSet results = qexec.execSelect(); while (results.hasNext()) { @@ -388,7 +393,7 @@ public List getDataPropertyValuesForIndividualByProperty(String subject } finally { dataset.getLock().leaveCriticalSection(); - w.close(); + dw.close(); if (qexec != null) { qexec.close(); } @@ -430,8 +435,7 @@ public List getDataPropertyValuesForIndividualByProperty( // Run the SPARQL query to get the properties List values = new ArrayList(); - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); + Dataset dataset = dw.getDataset(); dataset.getLock().enterCriticalSection(Lock.READ); QueryExecution qexec = null; try { @@ -459,7 +463,7 @@ public List getDataPropertyValuesForIndividualByProperty( return Collections.emptyList(); } finally { dataset.getLock().leaveCriticalSection(); - w.close(); + dw.close(); if (qexec != null) { qexec.close(); } @@ -497,8 +501,7 @@ private Model constructModelForSelectQueries(String subjectUri, initialBindings.add( "property", ResourceFactory.createResource(propertyUri)); - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); + Dataset dataset = dw.getDataset(); dataset.getLock().enterCriticalSection(Lock.READ); QueryExecution qe = null; try { @@ -512,7 +515,7 @@ private Model constructModelForSelectQueries(String subjectUri, qe.close(); } dataset.getLock().leaveCriticalSection(); - w.close(); + dw.close(); } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java deleted file mode 100644 index 4921b5ea83..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java +++ /dev/null @@ -1,118 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.jena.ontology.OntModel; -import org.apache.jena.ontology.OntModelSpec; -import org.apache.jena.query.Dataset; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.shared.Lock; -import org.apache.jena.vocabulary.RDF; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; - -public class DataPropertyStatementDaoSDB extends DataPropertyStatementDaoJena - implements DataPropertyStatementDao { - - private DatasetWrapperFactory dwf; - private SDBDatasetMode datasetMode; - - public DataPropertyStatementDaoSDB( - DatasetWrapperFactory datasetWrapperFactory, - SDBDatasetMode datasetMode, - WebappDaoFactoryJena wadf) { - super (datasetWrapperFactory, wadf); - this.dwf = datasetWrapperFactory; - this.datasetMode = datasetMode; - } - - @Override - public Individual fillExistingDataPropertyStatementsForIndividual( Individual entity/*, boolean allowAnyNameSpace*/) - { - if( entity.getURI() == null ) - { - return entity; - } - else - { - String query = - "CONSTRUCT { \n" + - " <" + entity.getURI() + "> ?p ?o . \n" + - "} WHERE { \n" + - " <" + entity.getURI() + "> ?p ?o . \n" + - " FILTER(isLiteral(?o)) \n" + - "}" ; - Model results = null; - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - QueryExecution qexec = null; - try { - qexec = QueryExecutionFactory.create(QueryFactory.create(query), dataset); - results = qexec.execConstruct(); - } finally { - if(qexec!=null) qexec.close(); - dataset.getLock().leaveCriticalSection(); - w.close(); - } - OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, results); - ontModel.enterCriticalSection(Lock.READ); - try { - Resource ind = ontModel.getResource(entity.getURI()); - List edList = new ArrayList(); - StmtIterator stmtIt = ind.listProperties(); - while( stmtIt.hasNext() ) - { - Statement st = stmtIt.next(); - boolean addToList = /*allowAnyNameSpace ? st.getObject().canAs(Literal.class) :*/ st.getObject().isLiteral() && - ( - (RDF.value.equals(st.getPredicate()) || VitroVocabulary.value.equals(st.getPredicate().getURI())) - || this.MONIKER.equals(st.getPredicate()) - || !(NONUSER_NAMESPACES.contains(st.getPredicate().getNameSpace())) - ); - if( addToList ) - { /* now want to expose Cornellemailnetid and potentially other properties so can at least control whether visible - boolean isExternalId = false; - ClosableIterator externalIdStmtIt = getOntModel().listStatements(st.getPredicate(), DATAPROPERTY_ISEXTERNALID, (Literal)null); - try { - if (externalIdStmtIt.hasNext()) { - isExternalId = true; - } - } finally { - externalIdStmtIt.close(); - } - if (!isExternalId) { */ - DataPropertyStatement ed = new DataPropertyStatementImpl(); - Literal lit = (Literal)st.getObject(); - fillDataPropertyStatementWithJenaLiteral(ed,lit); - ed.setDatapropURI(st.getPredicate().getURI()); - ed.setIndividualURI(ind.getURI()); - ed.setIndividual(entity); - edList.add(ed); - /* } */ - } - } - entity.setDataPropertyStatements(edList); - return entity; - } finally { - ontModel.leaveCriticalSection(); - } - } - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetMode.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetMode.java new file mode 100644 index 0000000000..634c45c7a3 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetMode.java @@ -0,0 +1,22 @@ +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +/** + * Modes for optimizing database queries. + */ +public enum DatasetMode { + + /** + * Only perform assertions. + */ + ASSERTIONS_ONLY, + + /** + * Only perform inferences. + */ + INFERENCES_ONLY, + + /** + * Perform both assertions and inferences. + */ + ASSERTIONS_AND_INFERENCES, +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapper.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapper.java index 42457cd566..264a1873d1 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapper.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapper.java @@ -3,37 +3,65 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import org.apache.jena.query.Dataset; -import org.apache.jena.sdb.sql.SDBConnection; +import org.apache.jena.shared.ClosedException; public class DatasetWrapper { - private SDBConnection conn; private Dataset dataset; private boolean closed = false; + /** + * Initialize the data set. + * + * @param dataset The data set. + */ public DatasetWrapper(Dataset dataset) { this.dataset = dataset; } - public DatasetWrapper(Dataset dataset, SDBConnection conn) { - this.dataset = dataset; - this.conn = conn; - } - + /** + * Get the data set. + * + * @return The data set + */ public Dataset getDataset() { if (!closed) { return dataset; } else throw new RuntimeException("No operations on a closed dataset"); } + /** + * Set the data set closed boolean. + * + * This is normally handled internally. + * This should only be used for exceptional cases. + * + * Setting this to true or false neither opens nor closes the data set. + * + * @param closed The data set closed state. + */ + public void setClosed(boolean closed) { + this.closed = closed; + } + + /** + * Close the data. + * + * This does nothing if already closed according to the closed boolean. + * + * This sets the closed state to true. + */ public void close() { - if (!closed) { + // FIXME: This is causing NPEs and connection already closed errors in tests. + // Not closing the dataset can result in excessive memory or other resource usage. + /*if (!closed) { closed = true; - if (conn != null) { + try { dataset.close(); - conn.close(); + } catch (ClosedException e) { + // Do nothing. } - } + }*/ } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapperFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapperFactory.java deleted file mode 100644 index a569b17581..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/DatasetWrapperFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -public interface DatasetWrapperFactory { - - public DatasetWrapper getDatasetWrapper(); - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDB.java new file mode 100644 index 0000000000..ef540e7cbd --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDB.java @@ -0,0 +1,777 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; +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.VClass; +import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.exception.IndividualNotFoundException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.OntModelSpec; +import org.apache.jena.ontology.OntResource; +import org.apache.jena.query.Dataset; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.shared.Lock; +import org.apache.jena.vocabulary.RDF; +import org.apache.jena.vocabulary.RDFS; + +/** + * An extension of {@link IndividualJena} for databases, such as TDB. + */ +public class IndividualDB extends IndividualJena { + + private static final Log LOG = LogFactory.getLog(IndividualJena.class.getName()); + private static final String VITRO = "http://vitro.mannlib.cornell.edu/ns/vitro/public"; + + private String indURI; + private DatasetWrapper dw; + private DatasetMode mode; + private Model model; + private Boolean hasThumb; + + /** + * Initialize the individual based on an initialization model. + * + * @param indURI The URI representing the individual. + * @param dw The data set wrapper. + * @param mode The database mode filter to utilize. + * @param wadf The DAO factory. + * @param initModel The model to use in order to initialize the individual. + */ + public IndividualDB(String indURI, DatasetWrapper dw, DatasetMode mode, + WebappDaoFactoryDB wadf, Model initModel) { + + super(null, wadf); + + this.indURI = indURI; + this.dw = dw; + this.mode = mode; + this.model = null; + this.hasThumb = null; + + try { + initModel.getLock().enterCriticalSection(Lock.READ); + + String getStatements = + "CONSTRUCT \n" + + "{ <" + indURI + "> <" + RDFS.label.getURI() + "> ?ooo. \n" + + "<" + indURI + "> a ?type . \n" + + "} \n" + + "WHERE { \n" + + "{ <" + indURI + "> <" + RDFS.label.getURI() + "> ?ooo } \n" + + " UNION { <" + indURI + "> a ?type } \n" + + "} "; + + model = QueryExecutionFactory.create( + QueryFactory.create(getStatements), initModel).execConstruct(); + } finally { + initModel.getLock().leaveCriticalSection(); + } + + setInd(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, model) + .createOntResource(indURI)); + + setupURIParts(getInd()); + } + + /** + * Initialize the individual. + * + * @param indURI The URI representing the individual. + * @param dw The data set wrapper. + * @param mode The database mode filter to utilize. + * @param wadf The DAO factory. + * + * @throws IndividualNotFoundException + */ + public IndividualDB(String indURI, DatasetWrapper dw, DatasetMode mode, + WebappDaoFactoryDB wadf) + throws IndividualNotFoundException { + + this(indURI, dw, mode, wadf, false); + } + + /** + * Initialize the individual, possibly skipping the model initialization. + * + * @param indURI The URI representing the individual. + * @param dw The data set wrapper. + * @param mode The database mode filter to utilize. + * @param wadf The DAO factory. + * @param skipInitialization True to skip model initialize, False to + * perform model initialization. + * + * @throws IndividualNotFoundException + */ + public IndividualDB(String indURI, DatasetWrapper dw, DatasetMode mode, + WebappDaoFactoryDB wadf, boolean skipInitialization) + throws IndividualNotFoundException { + + super(null, wadf); + + this.indURI = indURI; + this.dw = dw; + this.mode = mode; + this.model = null; + this.hasThumb = null; + + validateIndividualURI(indURI); + + if (skipInitialization) { + setInd(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM) + .createOntResource(indURI)); + } else { + try { + String getStatements = + "CONSTRUCT " + + "{ <" + indURI + "> <" + RDFS.label.getURI() + "> ?ooo \n" + + "} WHERE {" + + "{ <" + indURI + "> <" + RDFS.label.getURI() + "> ?ooo } \n" + + "}"; + + model = ModelFactory.createDefaultModel(); + getWebappDaoFactory().getRDFService().sparqlConstructQuery(getStatements, model); + } catch (RDFServiceException e) { + LOG.debug(e); + } + + setInd(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, model) + .createOntResource(indURI)); + + if (model == null || model.isEmpty() && noTriplesForUri()) { + throw new IndividualNotFoundException(); + } + } + + setupURIParts(getInd()); + } + + /** + * Get the most specific type URI, using the RDF service. + * + * @return The list of URIs. + */ + public List getMostSpecificTypeURIs() { + final List typeURIs = new ArrayList(); + + if (this.getURI() == null) { + return typeURIs; + } + + String queryStr = "SELECT ?type WHERE { <" + this.getURI() + "> <" + + VitroVocabulary.MOST_SPECIFIC_TYPE + "> ?type }"; + + try { + getWebappDaoFactory().getRDFService().sparqlSelectQuery(queryStr, + new ResultSetConsumer() { + protected void processQuerySolution(QuerySolution qs) { + RDFNode node = qs.get("type"); + if (node.isURIResource()) { + typeURIs.add(node.asResource().getURI()); + } + } + } + ); + + return typeURIs; + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + + /** + * Determine if individual has a thumbnail URI. + * + * @return True if has thumbnail, false otherwise. + */ + public boolean hasThumb() { + if (hasThumb != null) { + return hasThumb; + } + + String ask = + "ASK { " + + " <" + indURI + "> <" + VITRO + "#mainImage> ?mainImage . \n" + + " ?mainImage <" + VITRO + "#thumbnailImage> ?thumbImage . }\n" ; + try { + hasThumb = getWebappDaoFactory().getRDFService().sparqlAskQuery(ask); + } catch (Exception e) { + LOG.error(e, e); + hasThumb = false; + } + + return hasThumb; + } + + /** + * Get data property statements for the given property URI. + * + * @param propertyUri The URI. + * + * @return The found list of statements. + */ + public List getDataPropertyStatements(String propertyUri) { + List stmts = this.dataPropertyStatements; + if (stmts == null) { + return sparqlForDataPropertyStatements(propertyUri); + } + + List stmtsForProp = new ArrayList<>(); + for (DataPropertyStatement stmt : stmts) { + if (stmt.getDatapropURI().equals(propertyUri)) { + stmtsForProp.add(stmt); + } + } + + return stmtsForProp; + } + + /** + * Get the search boost. + * + * @return The search boost. + */ + public Float getSearchBoost() { + String getPropertyValue = + "SELECT ?value \n" + + "WHERE { \n" + + "<" + indURI + "> <" + getWebappDaoFactory().getJenaBaseDao().SEARCH_BOOST_ANNOT + + "> ?value \n" + + "}"; + + Dataset dataset = dw.getDataset(); + dataset.getLock().enterCriticalSection(Lock.READ); + QueryExecution qe = QueryExecutionFactory.create( + QueryFactory.create(getPropertyValue), dataset); + + try { + ResultSet rs = qe.execSelect(); + if (rs.hasNext()) { + QuerySolution qs = rs.nextSolution(); + if (qs.get("value") != null) { + Literal value = qs.get("value").asLiteral(); + searchBoost = Float.parseFloat(value.getLexicalForm()); + return searchBoost; + } + } + } catch (Exception e) { + LOG.error(e); + } finally { + qe.close(); + dataset.getLock().leaveCriticalSection(); + } + + return null; + } + + /** + * Get VClasses. + * + * @param direct Only get direct VClasses rather than all. + * + * @return List of VClasses. + */ + public List getVClasses(boolean direct) { + if (direct) { + if (directVClasses == null) { + directVClasses = getMyVClasses(true); + } + + return directVClasses; + } + + if (allVClasses == null) { + allVClasses = getMyVClasses(false); + } + + return allVClasses; + } + + /** + * Get the data values for the property URI. + * + * This is overridden to use Sparql queries from the RDF service. + * + * @param propertyUri The URI. + * + * @return The found list of values. + * Null is returned if propertyUri or getURI() is null. + */ + public List getDataValues(String propertyUri) { + if (propertyUri == null) { + LOG.error("Cannot retrieve value for null property"); + return null; + } + + if (this.getURI() == null) { + LOG.error("Cannot retrieve value of property " + propertyUri + + " for anonymous individual"); + return null; + } + + List values = new ArrayList<>(); + List stmts = sparqlForDataPropertyStatements(propertyUri); + + if (stmts != null) { + for (DataPropertyStatement stmt : stmts) { + values.add(stmt.getData()); + } + } + + return values; + } + + /** + * Check if the URI is a VClass. + * + * The base method in {@link IndividualImpl} is adequate if the reasoner is up to date. + * + * If the base method returns false, check directly to see if any of the super classes of the + * direct classes will satisfy this request. + * + * @param uri The URI to check. + * + * @return True if URI is a VClass, false otherwise. + */ + public boolean isVClass(String uri) { + if (uri == null || this.getURI() == null) { + return false; + } + + String queryString = "ASK { <" + this.getURI() + "> a <" + uri + "> }"; + try { + return getWebappDaoFactory().getRDFService().sparqlAskQuery(queryString); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + + /** + * Get web application DAO factory for databases, such as TDB. + * + * @return The web application DAO factory. + */ + protected WebappDaoFactoryDB getWebappDaoFactory() { + return (WebappDaoFactoryDB) super.getWebappDaoFactory(); + } + + /** + * Check that indURI is valid. + * + * This is used to help prevent SPARQL injection attacks. + * + * @param indURI + * @throws IndividualNotFoundException + * + * @see "https://www.w3.org/TR/rdf-sparql-query/#rIRI_REF" + */ + private void validateIndividualURI(String indURI) + throws IndividualNotFoundException { + + // Check that indURI is valid. (Prevent SPARQL injection attack.) + // Valid syntax is defined here: https://www.w3.org/TR/rdf-sparql-query/#rIRI_REF + if (!indURI.matches("[^<>\"{}|^`\\\\\u0000-\u0020]*")) { + throw new IndividualNotFoundException(); + } + } + + /** + * Determine if there are any triples for the given URI. + * + * @return True if there are no triples, false otherwise. + */ + private boolean noTriplesForUri() { + try { + return !getWebappDaoFactory().getRDFService() + .sparqlAskQuery("ASK { <" + indURI + "> ?p ?o }"); + } catch (RDFServiceException e) { + LOG.debug(e); + } + + return true; + } + + /** + * Execute sparql to select statements for the given property URI. + * + * @param propertyUri The URI. + * + * @return The found list of statements. + */ + private List sparqlForDataPropertyStatements(final String propertyUri) { + final List stmts = new ArrayList<>(); + final IndividualDB individualDB = this; + + String queryStr = "SELECT (str(?value) as ?valueString) WHERE { <" + this.getURI() + + "> <" + propertyUri + "> ?value }"; + + try { + getWebappDaoFactory().getRDFService().sparqlSelectQuery( + queryStr, new ResultSetConsumer() { + + protected void processQuerySolution(QuerySolution qs) { + RDFNode node = qs.get("valueString"); + if (!node.isLiteral()) { + LOG.debug("Ignoring non-literal value for " + node + " for property " + + propertyUri); + } else { + Literal lit = node.asLiteral(); + DataPropertyStatement stmt = new DataPropertyStatementImpl(); + + stmt.setData(lit.getLexicalForm()); + stmt.setDatatypeURI(lit.getDatatypeURI()); + stmt.setLanguage(lit.getLanguage()); + stmt.setDatapropURI(propertyUri); + stmt.setIndividualURI(individualDB.getURI()); + stmt.setIndividual(individualDB); + stmts.add(stmt); + } + } + }); + } catch (RDFServiceException e) { + LOG.error(e,e); + throw new RuntimeException(e); + } + + return stmts; + } + + /** + * Get object property statements for some property URI. + * + * @param propertyUri The URI. + * + * @return list of statements. + */ + public List getObjectPropertyStatements(String propertyUri) { + if (propertyUri == null) { + return null; + } + + List objectPropertyStatements = new ArrayList<>(); + Model tempModel = ModelFactory.createDefaultModel(); + OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + Dataset dataset = dw.getDataset(); + QueryExecution qexec = null; + + dataset.getLock().enterCriticalSection(Lock.READ); + try { + String valuesOfProperty = + "CONSTRUCT{ <" + this.indURI + "> <" + propertyUri + "> ?object }" + + "WHERE{ <" + this.indURI + "> <" + propertyUri + "> ?object } \n"; + + qexec = QueryExecutionFactory.create(QueryFactory.create(valuesOfProperty), dataset); + tempModel = qexec.execConstruct(); + ontModel.add(tempModel.listStatements()); + + Resource ontRes = ontModel.getResource(this.indURI); + StmtIterator sit = ontRes.listProperties(ontRes.getModel().getProperty(propertyUri)); + + while (sit.hasNext()) { + Statement s = sit.nextStatement(); + if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { + continue; + } + + Individual subj = null; + Individual obj = null; + + try { + subj = new IndividualDB(s.getSubject() + .as(OntResource.class).getURI(), dw, mode, getWebappDaoFactory()); + } catch (IndividualNotFoundException e) { + // leave null subject + } + + try { + obj = new IndividualDB(s.getObject() + .as(OntResource.class).getURI(), dw, mode, getWebappDaoFactory()); + } catch (IndividualNotFoundException e) { + // leave null object + } + + ObjectProperty op = getWebappDaoFactory().getObjectPropertyDao() + .getObjectPropertyByURI(s.getPredicate().getURI()); + // We don't want to filter out statements simply because we + // can't find a type for the property, so we'll just make a + // new ObjectProperty bean if we can't get one from the DAO. + if (op == null) { + op = new ObjectProperty(); + op.setURI(propertyUri); + } + + if (subj != null && obj != null) { + ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(); + ops.setSubject(subj); + ops.setSubjectURI(subj.getURI()); + ops.setObject(obj); + ops.setObjectURI(obj.getURI()); + ops.setProperty(op); + ops.setPropertyURI(op.getURI()); + objectPropertyStatements.add(ops); + } + } + } finally { + if (qexec != null) { + qexec.close(); + } + + tempModel.close(); + ontModel.close(); + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + + return objectPropertyStatements; + } + + /** + * Get related individuals for some property URI. + * + * @param propertyUri The URI. + * + * @return list of related individuals. + */ + public List getRelatedIndividuals(String propertyUri) { + if (propertyUri == null) { + return null; + } + + List relatedIndividuals = new ArrayList<>(); + Dataset dataset = dw.getDataset(); + dataset.getLock().enterCriticalSection(Lock.READ); + try { + String valuesOfProperty = + "SELECT ?object " + + "WHERE{ <" + this.indURI + "> <" + propertyUri + "> ?object } \n"; + ResultSet values = QueryExecutionFactory.create( + QueryFactory.create(valuesOfProperty), dataset).execSelect(); + QuerySolution result = null; + + while (values.hasNext()) { + result = values.next(); + RDFNode value = result.get("object"); + + try { + if (value.canAs(OntResource.class)) { + relatedIndividuals.add(new IndividualDB(value.as(OntResource.class) + .getURI(), dw, mode, getWebappDaoFactory())); + } + } catch (IndividualNotFoundException e) { + // don't add to the list + } + } + } finally { + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + + return relatedIndividuals; + } + + /** + * Get a single related individual for some property URI. + * + * @param propertyUri The URI. + * + * @return list of related individuals. + */ + public Individual getRelatedIndividual(String propertyUri) { + if (propertyUri == null) { + return null; + } + + Dataset dataset = dw.getDataset(); + dataset.getLock().enterCriticalSection(Lock.READ); + try { + String valueOfProperty = + "SELECT ?object " + + "WHERE{ <" + this.indURI + "> <" + propertyUri + "> ?object } \n"; + QueryExecution qe = QueryExecutionFactory.create( + QueryFactory.create(valueOfProperty), dataset); + + try { + ResultSet results = qe.execSelect(); + if (results.hasNext()) { + QuerySolution result = results.next(); + RDFNode value = result.get("object"); + + if (value != null && value.canAs(OntResource.class)) { + try { + return new IndividualDB(value.as(OntResource.class) + .getURI(), dw, mode, getWebappDaoFactory()); + } catch (IndividualNotFoundException e) { + } + } + } + + return null; + } finally { + qe.close(); + } + } finally { + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + } + + /** + * Get VClass for the individual. + * + * @param assertedOnly Set to TRUE to only get asserted, FALSE to get all. + * + * @return The list of VClass. + */ + private List getMyVClasses(boolean assertedOnly) { + List vClassList = new ArrayList<>(); + Model tempModel = null; + + if (getInd().getModel().contains((Resource) null, RDF.type, (RDFNode) null)){ + tempModel = getInd().getModel(); + } else { + tempModel = ModelFactory.createDefaultModel(); + String getTypesQuery = buildMyVClassesQuery(assertedOnly); + + RDFService service = getWebappDaoFactory().getRDFService(); + try { + service.sparqlConstructQuery(getTypesQuery, tempModel); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + + StmtIterator stmtItr = tempModel.listStatements((Resource) null, RDF.type, (RDFNode) null); + LinkedList list = new LinkedList<>(); + + while (stmtItr.hasNext()) { + Statement stmt = stmtItr.nextStatement(); + if (stmt.getObject().isResource() && !stmt.getObject().isAnon()) { + list.add(((Resource) stmt.getObject()).getURI()); + } + } + + if (assertedOnly) { + Iterator itr = null; + VClassDao checkSubClass = getWebappDaoFactory().getVClassDao(); + boolean directTypes = false; + String currentType = null; + ArrayList done = new ArrayList<>(); + + while (!directTypes) { + itr = list.listIterator(); + + do { + if (itr.hasNext()) { + currentType = itr.next(); + } else { + directTypes = true; + break; + } + } while (done.contains(currentType)); + + if (directTypes) { + break; + } else { + itr = list.listIterator(); + } + + while (itr.hasNext()) { + String nextType = itr.next(); + if (checkSubClass.isSubClassOf(currentType, nextType) + && !currentType.equalsIgnoreCase(nextType)) { + itr.remove(); + } + } + + done.add(currentType); + } + } + + for (Iterator it = list.iterator(); it.hasNext();) { + Resource type = ResourceFactory.createResource(it.next().toString()); + if (type.getNameSpace() == null || + (!getWebappDaoFactory().getNonuserNamespaces().contains(type.getNameSpace())) ) { + + VClass vc = getWebappDaoFactory().getVClassDao().getVClassByURI(type.getURI()); + if (vc != null) { + vClassList.add(vc); + } + } + } + + try { + Collections.sort(vClassList); + } catch (Exception e) { + LOG.error("Unable to sort VClass list", e); + } + + return vClassList; + } + + /** + * Build the VClass Sparql query. + * + * If we are restricting to asserted types, either by request or by dataset + * mode, then filter by graph and include a UNION clause to support + * retrieving inferred types from the unnamed base graph, as in Sesame and + * OWLIM. + * + * @param assertedOnly Set to TRUE to only get asserted, FALSE to get all. + * + * @return The query for getting all of the individuals VClass. + */ + private String buildMyVClassesQuery(boolean assertedOnly) { + DatasetMode queryMode = assertedOnly ? DatasetMode.ASSERTIONS_ONLY : mode; + + String filterBlock = WebappDaoFactoryDB.getFilterBlock(new String[] { "?g" }, queryMode); + + if (filterBlock.isEmpty()) { + return + "CONSTRUCT { <" + indURI + "> " + "<" + RDF.type + "> ?types }\n" + + "WHERE { <" + indURI + "> <" + RDF.type + "> ?types } \n"; + } + + String unionBlock = queryMode.equals(DatasetMode.ASSERTIONS_ONLY) + ? "" + : "UNION { <" + indURI +"> <" +RDF.type+ "> ?types }"; + + return + "CONSTRUCT{ <" + indURI + "> " + "<" + RDF.type + "> ?types }\n" + + "WHERE{ { GRAPH ?g" + + " { <" + indURI +"> <" + RDF.type + "> ?types } \n" + + filterBlock + + "} \n" + + unionBlock + + "} \n"; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoDB.java new file mode 100644 index 0000000000..05a74482c2 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoDB.java @@ -0,0 +1,562 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.exception.IndividualNotFoundException; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.ontology.OntClass; +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.UnionClass; +import org.apache.jena.query.Dataset; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.AnonId; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.shared.Lock; +import org.apache.jena.vocabulary.RDFS; +import org.joda.time.DateTime; + +/** + * An extension of {@link IndividualDaoJena} for databases, such as TDB. + */ +public class IndividualDaoDB extends IndividualDaoJena { + + private static final Log LOG = LogFactory.getLog(IndividualDaoDB.class.getName()); + + private DatasetWrapper dw; + private DatasetMode mode; + + /** + * Initialize the individual DAO. + * + * @param dw The dataset wrapper. + * @param mode The dataset mode. + * @param wadf The web application DAO factory. + */ + public IndividualDaoDB(DatasetWrapper dw, DatasetMode mode, WebappDaoFactoryDB wadf) { + super(wadf); + this.dw = dw; + this.mode = mode; + } + + /** + * Get an individual by the URI, creating one if necessary. + * + * @param entityURI The URI of the entity representing an individual. + * + * @return The individual. + */ + public Individual getIndividualByURI(String entityURI) { + if (entityURI == null || entityURI.length() == 0) { + return null; + } + + return makeIndividual(entityURI); + } + + /** + * Get all individuals based on VClass URI. + * + *@param vclassURI The VClass URI. + *@param offset An offset to start from. + *@param quantity A total amount of individuals to get. + * + * @return A list of individuals. + */ + public List getIndividualsByVClassURI(String vclassURI, int offset, int quantity) { + if (vclassURI == null) { + return null; + } + + List ents = new ArrayList<>(); + + Resource theClass = (vclassURI.indexOf(PSEUDO_BNODE_NS) == 0) + ? getOntModel().createResource(new AnonId(vclassURI.split("#")[1])) + : ResourceFactory.createResource(vclassURI); + + if (theClass.isAnon() && theClass.canAs(UnionClass.class)) { + UnionClass u = theClass.as(UnionClass.class); + for (OntClass operand : u.listOperands().toList()) { + VClass vc = new VClassJena(operand, getWebappDaoFactory()); + ents.addAll(getIndividualsByVClass(vc)); + } + } else { + // Check if there is a graph filter. + // If so, we will use it in a slightly strange way. Unfortunately, + // performance is quite bad if we add several graph variables in + // order to account for the fact that an individual's type + // declaration may be in a different graph from its label. + // Thus, we will run two queries: one with a single + // graph variable to get the list of URIs, and a second against + // the union graph to get individuals with their labels. + // We will then toss out any individual in the second + // list that is not also in the first list. + // Annoying, yes, but better than the alternative. + // Note that both queries need to sort identically or + // the results may be very strange. + String[] graphVars = {"?g"}; + String filterStr = WebappDaoFactoryDB.getFilterBlock(graphVars, mode); + + if (!StringUtils.isEmpty(filterStr)) { + List graphFilteredIndividualList = + getGraphFilteredIndividualList(theClass, filterStr); + List unfilteredIndividualList = getIndividualList(theClass); + Iterator unfilteredIt = unfilteredIndividualList.iterator(); + + for (Individual filt : graphFilteredIndividualList) { + Individual unfilt = unfilteredIt.next(); + while (!unfilt.getURI().equals(filt.getURI())) { + unfilt = unfilteredIt.next(); + } + + ents.add(unfilt); + } + } else { + ents = getIndividualList(theClass); + } + } + + Collections.sort(ents); + + if (quantity > 0 && offset > 0) { + List sublist = new ArrayList<>(); + for (int i = offset - 1; i < ((offset - 1) + quantity); i++) { + sublist.add(ents.get(i)); + } + + return sublist; + } + + return ents; + } + + /** + * Get individuals by data property using the full model. + * + * In Jena it can be difficult to get an object with a given dataproperty if + * you do not care about the datatype or lang of the literal. Use this + * method if you would like to ignore the lang and datatype. + * + * Note: this method doesn't require that a property be declared in the + * ontology as a data property -- only that it behaves as one. + * + * @param dataPropertyUri The data property URI. + * @param value The data property value. + * + * @return The list of matching individuals. + */ + @Override + public List getIndividualsByDataProperty(String dataPropertyUri, String value) { + OntModel fullModel = getOntModelSelector().getFullModel(); + + Property prop = null; + if (RDFS.label.getURI().equals(dataPropertyUri)) { + prop = RDFS.label; + } else { + prop = fullModel.getProperty(dataPropertyUri); + } + + if (prop == null) { + LOG.debug("Could not getIndividualsByDataProperty() because " + dataPropertyUri + + "was not found in model."); + return Collections.emptyList(); + } + + if( value == null ){ + LOG.debug("Could not getIndividualsByDataProperty() because value was null"); + return Collections.emptyList(); + } + + Literal litv1 = fullModel.createLiteral(value); + Literal litv2 = fullModel.createTypedLiteral(value); + + //warning: this assumes that any language tags will be EN + Literal litv3 = fullModel.createLiteral(value,"EN"); + + HashMap individualsMap = new HashMap<>(); + + fullModel.enterCriticalSection(Lock.READ); + try { + StmtIterator stmts = fullModel.listStatements((Resource) null, prop, litv1); + while (stmts.hasNext()) { + Statement stmt = stmts.nextStatement(); + + RDFNode sub = stmt.getSubject(); + if (sub == null || sub.isAnon() || sub.isLiteral()) { + continue; + } + + RDFNode obj = stmt.getObject(); + if (obj == null || !obj.isLiteral()) { + continue; + } + + Literal literal = (Literal) obj; + Object v = literal.getValue(); + if (v == null) { + continue; + } + + String subUri = ((Resource) sub).getURI(); + if (!individualsMap.containsKey(subUri)) { + individualsMap.put(subUri,makeIndividual(subUri)); + } + } + + stmts = fullModel.listStatements((Resource) null, prop, litv2); + while (stmts.hasNext()) { + Statement stmt = stmts.nextStatement(); + + RDFNode sub = stmt.getSubject(); + if (sub == null || sub.isAnon() || sub.isLiteral()) { + continue; + } + + RDFNode obj = stmt.getObject(); + if (obj == null || !obj.isLiteral()) { + continue; + } + + Literal literal = (Literal)obj; + Object v = literal.getValue(); + if (v == null) { + continue; + } + + String subUri = ((Resource)sub).getURI(); + if (!individualsMap.containsKey(subUri)) { + individualsMap.put(subUri, makeIndividual(subUri)); + } + } + + stmts = fullModel.listStatements((Resource) null, prop, litv3); + while (stmts.hasNext()) { + Statement stmt = stmts.nextStatement(); + + RDFNode sub = stmt.getSubject(); + if (sub == null || sub.isAnon() || sub.isLiteral()) { + continue; + } + + RDFNode obj = stmt.getObject(); + if (obj == null || !obj.isLiteral()) { + continue; + } + + Literal literal = (Literal) obj; + Object v = literal.getValue(); + if (v == null) { + continue; + } + + String subUri = ((Resource)sub).getURI(); + if (!individualsMap.containsKey(subUri)) { + individualsMap.put(subUri, makeIndividual(subUri)); + } + } + } finally { + fullModel.leaveCriticalSection(); + } + + List rv = new ArrayList<>(individualsMap.size()); + rv.addAll(individualsMap.values()); + return rv; + } + + /** + * Get each URI for all individuals. + * + * @return The list of URIs. + */ + public Collection getAllIndividualUris() { + final List list = new LinkedList<>(); + + // get all labeled resources from any non-tbox and non-metadata graphs, + // as well as the unnamed graph (first pattern below) + String query = "SELECT DISTINCT ?ind WHERE { \n" + + " { ?ind <" + RDFS.label.getURI() + "> ?label } " + + " UNION { " + + " GRAPH ?g { ?ind <" + RDFS.label.getURI() + "> ?label } \n" + + " FILTER (?g != <" + ModelNames.APPLICATION_METADATA + "> " + + " && !regex(str(?g),\"tbox\")) \n " + + " } " + + "}"; + + Query q = QueryFactory.create(query); + Dataset dataset = dw.getDataset(); + dataset.getLock().enterCriticalSection(Lock.READ); + QueryExecution qe = QueryExecutionFactory.create(q, dataset); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + Resource res = rs.next().getResource("ind"); + if (!res.isAnon()) { + list.add(res.getURI()); + } + } + } finally { + qe.close(); + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + + return list; + } + + /** + * Get individual URIs updated since a given unit of time. + * + * @param updatedSince The instant in time, in milliseconds. + * + * @return A list of all individual URIs. + */ + public Iterator getUpdatedSinceIterator(long updatedSince) { + List individualURIs = new ArrayList(); + Date since = new DateTime(updatedSince).toDate(); + String sinceStr = xsdDateTimeFormat.format(since); + + getOntModel().enterCriticalSection(Lock.READ); + try { + String queryStr = "PREFIX vitro: <"+ VitroVocabulary.vitroURI+"> " + + "PREFIX xsd: "+ + "SELECT ?ent " + + "WHERE { " + + " ?ent vitro:modTime ?modTime ." + + " FILTER (xsd:dateTime(?modTime) >= \"" + + sinceStr + "\"^^xsd:dateTime) " + + "}"; + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.create(query,getOntModel()); + try { + ResultSet results = qe.execSelect(); + while (results.hasNext()) { + QuerySolution qs = results.next(); + Resource res = (Resource) qs.get("?ent"); + if (res.getURI() != null) { + individualURIs.add(res.getURI()); + } + } + } finally { + qe.close(); + } + } finally { + getOntModel().leaveCriticalSection(); + } + + return individualURIs.iterator(); + } + + /** + * Get the web application DAO factory for databases such as TDB. + * + * @return The web application DAO factory. + */ + protected WebappDaoFactoryDB getWebappDaoFactory() { + return (WebappDaoFactoryDB) super.getWebappDaoFactory(); + } + + /** + * Get the ontology model. + * + * @return the Ontology model. + */ + protected OntModel getOntModel() { + return getOntModelSelector().getABoxModel(); + } + + /** + * Make an individual. + * + * @param indURI The URI of the individual. + * + * @return The made individual. + */ + protected Individual makeIndividual(String indURI) { + try { + return new IndividualDB(indURI, dw, mode, getWebappDaoFactory()); + } catch (IndividualNotFoundException e) { + LOG.debug("The individual represented by " + indURI + " does not exist"); + } catch (Exception ex) { + LOG.error("An error occurred trying to make an individual ", ex); + + if (StringUtils.isNotEmpty(indURI)) { + LOG.error("IndividualURI equals " + indURI); + } else { + LOG.error("IndividualURI is null or empty"); + } + } + + return null; + } + + /** + * Get a list of individuals associated with the class resource. + * + * @param theClass The class resource. + * + * @return The list of individuals. + */ + private List getIndividualList(Resource theClass) { + final List ents = new ArrayList<>(); + Dataset dataset = dw.getDataset(); + + dataset.getLock().enterCriticalSection(Lock.READ); + try { + String query = + "SELECT DISTINCT ?ind ?label " + + "WHERE " + + "{ \n" + + "{ ?ind a <" + theClass.getURI() + "> } \n" + + "UNION { \n" + + " ?ind a <" + theClass.getURI() + "> . \n" + + " ?ind <" + RDFS.label.getURI() + "> ?label \n" + + "} \n" + + "} ORDER BY ?ind ?label"; + + RDFService rdfService = getWebappDaoFactory().getRDFService(); + try { + rdfService.sparqlSelectQuery(query, new ResultSetConsumer() { + String uri = null; + String label = null; + + protected void processQuerySolution(QuerySolution qs) { + Resource currRes = qs.getResource("ind"); + if (currRes.isAnon()) { + return; + } + + if (uri != null && !uri.equals(currRes.getURI())) { + try { + ents.add(makeIndividual(uri, label)); + } catch (IndividualNotFoundException e) { + // don't add + } + + uri = currRes.getURI(); + label = null; + } else if (uri == null) { + uri = currRes.getURI(); + } + + Literal labelLit = qs.getLiteral("label"); + if (labelLit != null) { + label = labelLit.getLexicalForm(); + } + } + + @Override + protected void endProcessing() { + if (uri != null) { + try { + ents.add(makeIndividual(uri, label)); + } catch (IndividualNotFoundException e) { + // don't add + } + } + } + }); + } catch (RDFServiceException e) { + LOG.debug(e); + throw new RuntimeException(e); + } + } finally { + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + + return ents; + } + + /** + * Get a filtered list of individuals associated with the class resource. + * + * @param theClass The class resource. + * @param filter The filter. + * + * @return The list of individuals. + */ + private List getGraphFilteredIndividualList(Resource theClass, String filter) { + final List filteredIndividualList = new ArrayList<>(); + Dataset dataset = dw.getDataset(); + + dataset.getLock().enterCriticalSection(Lock.READ); + try { + String query = + "SELECT DISTINCT ?ind " + + "WHERE " + + "{ GRAPH ?g { \n" + + "{ ?ind a <" + theClass.getURI() + "> } \n" + + " } \n" + filter + + "} ORDER BY ?ind"; + RDFService rdfService = getWebappDaoFactory().getRDFService(); + try { + rdfService.sparqlSelectQuery(query, new ResultSetConsumer() { + protected void processQuerySolution(QuerySolution qs) { + Resource currRes = qs.getResource("ind"); + if (!currRes.isAnon()) { + try { + filteredIndividualList.add(makeIndividual(currRes.getURI(), null)); + } catch (IndividualNotFoundException e) { + // don't add + } + } + } + }); + } catch (RDFServiceException e) { + LOG.debug(e); + throw new RuntimeException(e); + } + } finally { + dataset.getLock().leaveCriticalSection(); + //w.close(); + } + + return filteredIndividualList; + } + + /** + * Make an individual. + * + * @param indURI The URI of the individual. + * @param label The label of the individual. + * + * @return The made individual. + */ + private Individual makeIndividual(String indURI, String label) + throws IndividualNotFoundException { + + Individual ent = new IndividualDB( + indURI, dw, mode, (WebappDaoFactoryDB) getWebappDaoFactory(), true); + + ent.setName(label); + ent.setRdfsLabel(label); + return ent; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java index a2bdf8e905..53dd2f3abc 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java @@ -52,7 +52,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { //For random number generation, creating it everytime the method is called lead to nextInt being about the same //if calls were made close together in time - private Random random = new Random(System.currentTimeMillis()); + private Random random = new Random(System.currentTimeMillis()); public IndividualDaoJena(WebappDaoFactoryJena wadf) { super(wadf); } @@ -131,49 +131,44 @@ public List getIndividualsByVClassURI(String vclassURI) { } public List getIndividualsByVClassURI(String vclassURI, int offset, int quantity ) { - - if (vclassURI==null) { + if (vclassURI == null) { return null; } - List ents = new ArrayList(); + List ents = new ArrayList<>(); Resource theClass = (vclassURI.indexOf(PSEUDO_BNODE_NS) == 0) ? getOntModel().createResource(new AnonId(vclassURI.split("#")[1])) : ResourceFactory.createResource(vclassURI); - - if (theClass.isAnon() && theClass.canAs(UnionClass.class)) { - UnionClass u = theClass.as(UnionClass.class); - for (OntClass operand : u.listOperands().toList()) { - VClass vc = new VClassJena(operand, getWebappDaoFactory()); - ents.addAll(getIndividualsByVClass(vc)); - } + UnionClass u = theClass.as(UnionClass.class); + for (OntClass operand : u.listOperands().toList()) { + VClass vc = new VClassJena(operand, getWebappDaoFactory()); + ents.addAll(getIndividualsByVClass(vc)); + } } else { - OntModel ontModel = getOntModelSelector().getABoxModel(); - try { - ontModel.enterCriticalSection(Lock.READ); - StmtIterator stmtIt = ontModel.listStatements((Resource) null, RDF.type, theClass); - try { - while (stmtIt.hasNext()) { - Statement stmt = stmtIt.nextStatement(); - OntResource ind = stmt.getSubject().as(OntResource.class); - ents.add(new IndividualJena(ind, getWebappDaoFactory())); - } - } finally { - stmtIt.close(); - } - } finally { - ontModel.leaveCriticalSection(); - } + OntModel ontModel = getOntModelSelector().getABoxModel(); + try { + ontModel.enterCriticalSection(Lock.READ); + StmtIterator stmtIt = ontModel.listStatements((Resource) null, RDF.type, theClass); + try { + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.nextStatement(); + OntResource ind = stmt.getSubject().as(OntResource.class); + ents.add(new IndividualJena(ind, getWebappDaoFactory())); + } + } finally { + stmtIt.close(); + } + } finally { + ontModel.leaveCriticalSection(); + } } - java.util.Collections.sort(ents); return ents; - } public int getCountOfIndividualsInVClass(String vclassURI ) { @@ -711,8 +706,8 @@ public String getUnusedURI(Individual individual) throws InsertException { // This method returns an EditLiteral rather than a Jena Literal, since IndividualDao // should not reference Jena objects. (However, the problem isn't really solved // because EditLiteral currently references the Jena API.) - public EditLiteral getLabelEditLiteral(String individualUri) { - Literal literal = getLabelLiteral(individualUri); + public EditLiteral getLabelEditLiteral(String individualURI) { + Literal literal = getLabelLiteral(individualURI); if (literal == null) { return null; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java deleted file mode 100644 index bfc57e80ea..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java +++ /dev/null @@ -1,550 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.joda.time.DateTime; - -import org.apache.jena.ontology.OntClass; -import org.apache.jena.ontology.OntModel; -import org.apache.jena.ontology.UnionClass; -import org.apache.jena.query.Dataset; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.QuerySolution; -import org.apache.jena.query.ResultSet; -import org.apache.jena.rdf.model.AnonId; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Property; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.ResourceFactory; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.shared.Lock; -import org.apache.jena.vocabulary.RDFS; - -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.IndividualSDB.IndividualNotFoundException; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; - -public class IndividualDaoSDB extends IndividualDaoJena { - - private DatasetWrapperFactory dwf; - private SDBDatasetMode datasetMode; - private WebappDaoFactorySDB wadf; - - public IndividualDaoSDB(DatasetWrapperFactory dwf, - SDBDatasetMode datasetMode, - WebappDaoFactorySDB wadf) { - super(wadf); - this.dwf = dwf; - this.datasetMode = datasetMode; - this.wadf = wadf; - } - - protected DatasetWrapper getDatasetWrapper() { - return dwf.getDatasetWrapper(); - } - - protected Individual makeIndividual(String individualURI) { - try { - return new IndividualSDB(individualURI, - this.dwf, - datasetMode, - wadf); - } catch (IndividualNotFoundException e) { - // If the individual does not exist, return null. - return null; - } catch(Exception ex) { - //Should some other error occur, please log it here - log.error("An error occurred trying to make an individual ", ex); - if(StringUtils.isNotEmpty(individualURI)) { - log.error("IndividualURI equals " + individualURI); - } else { - log.error("IndividualURI is null or empty"); - } - return null; - } - } - - private static final Log log = LogFactory.getLog( - IndividualDaoSDB.class.getName()); - - @Override - protected OntModel getOntModel() { - return getOntModelSelector().getABoxModel(); - } - - private static final boolean SKIP_INITIALIZATION = true; - - @Override - public List getIndividualsByVClassURI(String vclassURI, - int offset, - int quantity ) { - - if (vclassURI==null) { - return null; - } - - List ents = new ArrayList(); - - Resource theClass = (vclassURI.indexOf(PSEUDO_BNODE_NS) == 0) - ? getOntModel().createResource(new AnonId(vclassURI.split("#")[1])) - : ResourceFactory.createResource(vclassURI); - - if (theClass.isAnon() && theClass.canAs(UnionClass.class)) { - UnionClass u = theClass.as(UnionClass.class); - for (OntClass operand : u.listOperands().toList()) { - VClass vc = new VClassJena(operand, getWebappDaoFactory()); - ents.addAll(getIndividualsByVClass(vc)); - } - } else { - - List individualList; - - // Check if there is a graph filter. - // If so, we will use it in a slightly strange way. Unfortunately, - // performance is quite bad if we add several graph variables in - // order to account for the fact that an individual's type - // declaration may be in a different graph from its label. - // Thus, we will run two queries: one with a single - // graph variable to get the list of URIs, and a second against - // the union graph to get individuals with their labels. - // We will then toss out any individual in the second - // list that is not also in the first list. - // Annoying, yes, but better than the alternative. - // Note that both queries need to sort identically or - // the results may be very strange. - String[] graphVars = {"?g"}; - String filterStr = WebappDaoFactorySDB.getFilterBlock( - graphVars, datasetMode); - if (!StringUtils.isEmpty(filterStr)) { - List graphFilteredIndividualList = - getGraphFilteredIndividualList(theClass, filterStr); - List unfilteredIndividualList = getIndividualList( - theClass); - Iterator unfilteredIt = unfilteredIndividualList - .iterator(); - for (Individual filt : graphFilteredIndividualList) { - Individual unfilt = unfilteredIt.next(); - while (!unfilt.getURI().equals(filt.getURI())) { - unfilt = unfilteredIt.next(); - } - ents.add(unfilt); - } - } else { - ents = getIndividualList(theClass); - } - } - - java.util.Collections.sort(ents); - - if (quantity > 0 && offset > 0) { - List sublist = new ArrayList(); - for (int i = offset - 1; i < ((offset - 1) + quantity); i++) { - sublist.add(ents.get(i)); - } - return sublist; - } - - return ents; - - } - - private List getIndividualList(Resource theClass) { - final List ents = new ArrayList(); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - String query = - "SELECT DISTINCT ?ind ?label " + - "WHERE " + - "{ \n" + - "{ ?ind a <" + theClass.getURI() + "> } \n" + - "UNION { \n" + - " ?ind a <" + theClass.getURI() + "> . \n" + - " ?ind <" + RDFS.label.getURI() + "> ?label \n" + - "} \n" + - "} ORDER BY ?ind ?label"; - - RDFService rdfService = wadf.getRDFService(); - try { - rdfService.sparqlSelectQuery( - query, new ResultSetConsumer() { - String uri = null; - String label = null; - - @Override - protected void processQuerySolution(QuerySolution qs) { - Resource currRes = qs.getResource("ind"); - if (currRes.isAnon()) { - return; - } - - if (uri != null && !uri.equals(currRes.getURI())) { - try { - ents.add(makeIndividual(uri, label)); - } catch (IndividualNotFoundException e) { - // don't add - } - uri = currRes.getURI(); - label = null; - } else if (uri == null) { - uri = currRes.getURI(); - } - Literal labelLit = qs.getLiteral("label"); - if (labelLit != null) { - label = labelLit.getLexicalForm(); - } - } - - @Override - protected void endProcessing() { - if (uri != null) { - try { - ents.add(makeIndividual(uri, label)); - } catch (IndividualNotFoundException e) { - // don't add - } - } - } - }); - } catch (RDFServiceException e) { - log.debug(e,e); - throw new RuntimeException(e); - } - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - return ents; - } - - private List getGraphFilteredIndividualList(Resource theClass, - String filterStr) { - final List filteredIndividualList = new ArrayList(); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - String query = - "SELECT DISTINCT ?ind " + - "WHERE " + - "{ GRAPH ?g { \n" + - "{ ?ind a <" + theClass.getURI() + "> } \n" + - " } \n" + filterStr + - "} ORDER BY ?ind"; - RDFService rdfService = wadf.getRDFService(); - try { - rdfService.sparqlSelectQuery( - query, new ResultSetConsumer() { - @Override - protected void processQuerySolution(QuerySolution qs) { - Resource currRes = qs.getResource("ind"); - if (!currRes.isAnon()) { - try { - filteredIndividualList.add( - makeIndividual(currRes.getURI(), null)); - } catch (IndividualNotFoundException e) { - // don't add - } - } - } - }); - } catch (RDFServiceException e) { - log.debug(e,e); - throw new RuntimeException(e); - } - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - return filteredIndividualList; - } - - private Individual makeIndividual(String uri, String label) throws IndividualNotFoundException { - Individual ent = new IndividualSDB(uri, - this.dwf, datasetMode, wadf, - SKIP_INITIALIZATION); - ent.setName(label); - ent.setRdfsLabel(label); - return ent; - } - - @Override - public Individual getIndividualByURI(String entityURI) { - if( entityURI == null || entityURI.length() == 0 ) { - return null; - } else { - return makeIndividual(entityURI); - } - } - - /** - * fills in the Individual objects needed for any ObjectPropertyStatements - * attached to the specified individual. - * @param entity An individual - */ - private void fillIndividualsForObjectPropertyStatements(Individual entity){ - getOntModel().enterCriticalSection(Lock.READ); - try { - for (ObjectPropertyStatement e2e : entity.getObjectPropertyStatements()) { - e2e.setSubject(makeIndividual(e2e.getSubjectURI())); - e2e.setObject(makeIndividual(e2e.getObjectURI())); - } - } finally { - getOntModel().leaveCriticalSection(); - } - } - - /** - * In Jena it can be difficult to get an object with a given dataproperty if - * you do not care about the datatype or lang of the literal. Use this - * method if you would like to ignore the lang and datatype. - * - * Note: this method doesn't require that a property be declared in the - * ontology as a data property -- only that it behaves as one. - */ - @Override - public List getIndividualsByDataProperty(String dataPropertyUri, - String value){ - OntModel fullModel = getOntModelSelector().getFullModel(); - - Property prop = null; - if( RDFS.label.getURI().equals( dataPropertyUri )){ - prop = RDFS.label; - }else{ - prop = fullModel.getProperty(dataPropertyUri); - } - - if( prop == null ) { - log.debug("Could not getIndividualsByDataProperty() " + - "because " + dataPropertyUri + "was not found in model."); - return Collections.emptyList(); - } - - if( value == null ){ - log.debug("Could not getIndividualsByDataProperty() " + - "because value was null"); - return Collections.emptyList(); - } - - Literal litv1 = fullModel.createLiteral(value); - Literal litv2 = fullModel.createTypedLiteral(value); - - //warning: this assumes that any language tags will be EN - Literal litv3 = fullModel.createLiteral(value,"EN"); - - HashMap individualsMap = - new HashMap(); - - fullModel.enterCriticalSection(Lock.READ); - int count = 0; - try{ - StmtIterator stmts - = fullModel.listStatements((Resource)null, prop, litv1); - while(stmts.hasNext()){ - count++; - Statement stmt = stmts.nextStatement(); - - RDFNode sub = stmt.getSubject(); - if( sub == null || sub.isAnon() || sub.isLiteral() ) - continue; - - RDFNode obj = stmt.getObject(); - if( obj == null || !obj.isLiteral() ) - continue; - - Literal literal = (Literal)obj; - Object v = literal.getValue(); - if( v == null ) - continue; - - String subUri = ((Resource)sub).getURI(); - if( ! individualsMap.containsKey(subUri)){ - individualsMap.put(subUri,makeIndividual(subUri)); - } - } - - stmts = fullModel.listStatements((Resource)null, prop, litv2); - while(stmts.hasNext()){ - count++; - Statement stmt = stmts.nextStatement(); - - RDFNode sub = stmt.getSubject(); - if( sub == null || sub.isAnon() || sub.isLiteral() ) - continue; - - RDFNode obj = stmt.getObject(); - if( obj == null || !obj.isLiteral() ) - continue; - - Literal literal = (Literal)obj; - Object v = literal.getValue(); - if( v == null ) - continue; - - String subUri = ((Resource)sub).getURI(); - if( ! individualsMap.containsKey(subUri)){ - individualsMap.put(subUri, makeIndividual(subUri)); - } - } - - stmts = fullModel.listStatements((Resource)null, prop, litv3); - while(stmts.hasNext()){ - count++; - Statement stmt = stmts.nextStatement(); - - RDFNode sub = stmt.getSubject(); - if( sub == null || sub.isAnon() || sub.isLiteral() ) - continue; - - RDFNode obj = stmt.getObject(); - if( obj == null || !obj.isLiteral() ) - continue; - - Literal literal = (Literal)obj; - Object v = literal.getValue(); - if( v == null ) - continue; - - String subUri = ((Resource)sub).getURI(); - if( ! individualsMap.containsKey(subUri)){ - individualsMap.put(subUri, makeIndividual(subUri)); - } - } - } finally { - fullModel.leaveCriticalSection(); - } - - List rv = new ArrayList(individualsMap.size()); - rv.addAll(individualsMap.values()); - return rv; - } - - @Override - public Collection getAllIndividualUris() { - final List list = new LinkedList(); - - // get all labeled resources from any non-tbox and non-metadata graphs, - // as well as the unnamed graph (first pattern below) - String query = "SELECT DISTINCT ?ind WHERE { \n" + - " { ?ind <" + RDFS.label.getURI() + "> ?label } " + - " UNION { " + - " GRAPH ?g { ?ind <" + RDFS.label.getURI() + - "> ?label } \n" + - " FILTER (?g != <" + ModelNames.APPLICATION_METADATA + "> " + - " && !regex(str(?g),\"tbox\")) \n " + - " } " + - "}"; - - Query q = QueryFactory.create(query); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - QueryExecution qe = QueryExecutionFactory.create(q, dataset); - try { - ResultSet rs = qe.execSelect(); - while (rs.hasNext()) { - Resource res = rs.next().getResource("ind"); - if (!res.isAnon()) { - list.add(res.getURI()); - } - } - } finally { - qe.close(); - dataset.getLock().leaveCriticalSection(); - w.close(); - } - - return list; - } - - private Iterator getIndividualIterator( - final List individualURIs) { - if (individualURIs.size() >0){ - log.info("Number of individuals from source: " - + individualURIs.size()); - return new Iterator(){ - Iterator innerIt = individualURIs.iterator(); - public boolean hasNext() { - return innerIt.hasNext(); - } - public Individual next() { - String indURI = innerIt.next(); - Individual ind = makeIndividual(indURI); - if (ind != null) { - return ind; - } else { - return new IndividualImpl(indURI); - } - } - public void remove() { - //not used - } - }; - } - else - return null; - } - - @Override - public Iterator getUpdatedSinceIterator(long updatedSince){ - List individualURIs = new ArrayList(); - Date since = new DateTime(updatedSince).toDate(); - String sinceStr = xsdDateTimeFormat.format(since); - getOntModel().enterCriticalSection(Lock.READ); - try { - String queryStr = "PREFIX vitro: <"+ VitroVocabulary.vitroURI+"> " + - "PREFIX xsd: "+ - "SELECT ?ent " + - "WHERE { " + - " ?ent vitro:modTime ?modTime ." + - " FILTER (xsd:dateTime(?modTime) >= \"" - + sinceStr + "\"^^xsd:dateTime) " + - "}"; - Query query = QueryFactory.create(queryStr); - QueryExecution qe = QueryExecutionFactory.create( - query,getOntModel()); - try { - ResultSet results = qe.execSelect(); - while (results.hasNext()) { - QuerySolution qs = results.next(); - Resource res = (Resource) qs.get("?ent"); - if (res.getURI() != null) { - individualURIs.add(res.getURI()); - } - } - } finally { - qe.close(); - } - } finally { - getOntModel().leaveCriticalSection(); - } - return individualURIs.iterator(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java index c3ec8bb750..0645b81316 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java @@ -2,6 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; +import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.IND_MAIN_IMAGE; +import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.PSEUDO_BNODE_NS; + import java.sql.Timestamp; import java.text.Collator; import java.util.ArrayList; @@ -38,44 +41,37 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; public class IndividualJena extends IndividualImpl implements Individual { - private static final Log log = LogFactory.getLog(IndividualJena.class.getName()); - private OntResource ind = null; - private WebappDaoFactoryJena webappDaoFactory = null; - private Float _searchBoostJena = null; + private static final Log LOG = LogFactory.getLog(IndividualJena.class.getName()); + private boolean retrievedNullRdfsLabel = false; + private OntResource ind = null; + private WebappDaoFactoryJena wadf = null; + public IndividualJena(OntResource ind, WebappDaoFactoryJena wadf) { this.ind = ind; - if (ind.isAnon()) { - this.setNamespace(VitroVocabulary.PSEUDO_BNODE_NS); - this.setLocalName(ind.getId().toString()); - } else { - this.URI = ind.getURI(); - this.namespace = ind.getNameSpace(); - this.localName = ind.getLocalName(); - } - this.webappDaoFactory = wadf; + this.wadf = wadf; + + setupURIParts(this.ind); } public String getName() { if (this.name != null) { return name; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - this.name = webappDaoFactory.getJenaBaseDao().getLabelOrId(ind); - if (this.name == null) { - this.name = "[null]"; - } - return this.name; - } finally { - ind.getOntModel().leaveCriticalSection(); + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + this.name = wadf.getJenaBaseDao().getLabelOrId(ind); + if (this.name == null) { + this.name = "[null]"; } + return this.name; + } finally { + ind.getOntModel().leaveCriticalSection(); } } @@ -86,345 +82,334 @@ public String getLabel() { public String getRdfsLabel() { if (this.rdfsLabel != null) { return rdfsLabel; - } else if( this.rdfsLabel == null && retrievedNullRdfsLabel ){ - return null; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - this.rdfsLabel = webappDaoFactory.getJenaBaseDao().getLabel(ind); - retrievedNullRdfsLabel = this.rdfsLabel == null; - return this.rdfsLabel; - } finally { - ind.getOntModel().leaveCriticalSection(); - } + } + if (this.rdfsLabel == null && retrievedNullRdfsLabel) { + return null; + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + this.rdfsLabel = wadf.getJenaBaseDao().getLabel(ind); + retrievedNullRdfsLabel = this.rdfsLabel == null; + return this.rdfsLabel; + } finally { + ind.getOntModel().leaveCriticalSection(); } } public String getVClassURI() { if (this.vClassURI != null) { return vClassURI; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - ClosableIterator typeIt = ind.listRDFTypes(true); - try { - while (typeIt.hasNext()) { - Resource type = (Resource) typeIt.next(); - if (type.getNameSpace()!=null && (!webappDaoFactory.getJenaBaseDao().NONUSER_NAMESPACES.contains(type.getNameSpace()) || type.getURI().equals(OWL.Thing.getURI())) ) { - this.vClassURI=type.getURI(); - break; - } - } - } finally { - typeIt.close(); + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + ClosableIterator typeIt = ind.listRDFTypes(true); + try { + while (typeIt.hasNext()) { + Resource type = typeIt.next(); + if (type.getNameSpace()!=null && (!wadf.getJenaBaseDao().NONUSER_NAMESPACES + .contains(type.getNameSpace()) || type.getURI() + .equals(OWL.Thing.getURI())) ) { + + this.vClassURI=type.getURI(); + break; + } } - } finally { - ind.getOntModel().leaveCriticalSection(); - } - return this.vClassURI; + } finally { + typeIt.close(); + } + } finally { + ind.getOntModel().leaveCriticalSection(); } + return this.vClassURI; } public VClass getVClass() { if (this.vClass != null) { return this.vClass; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - ClosableIterator typeIt = ind.listRDFTypes(true); - try { - while (typeIt.hasNext()) { - Resource type = (Resource) typeIt.next(); - if (type.getNameSpace()!=null && (!webappDaoFactory.getJenaBaseDao().NONUSER_NAMESPACES.contains(type.getNameSpace()) || type.getURI().equals(OWL.Thing.getURI())) ) { - this.vClassURI=type.getURI(); - this.vClass = webappDaoFactory.getVClassDao().getVClassByURI(this.vClassURI); - break; - } - } - } finally { - typeIt.close(); - } - return this.vClass; - } finally { - ind.getOntModel().leaveCriticalSection(); - } + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + ClosableIterator typeIt = ind.listRDFTypes(true); + try { + while (typeIt.hasNext()) { + Resource type = (Resource) typeIt.next(); + if (type.getNameSpace()!=null && (!wadf.getJenaBaseDao().NONUSER_NAMESPACES + .contains(type.getNameSpace()) || type.getURI() + .equals(OWL.Thing.getURI()))) { + + this.vClassURI=type.getURI(); + this.vClass = wadf.getVClassDao().getVClassByURI(this.vClassURI); + break; + } + } + } finally { + typeIt.close(); + } + return this.vClass; + } finally { + ind.getOntModel().leaveCriticalSection(); } } public Timestamp getModTime() { if (modTime != null) { return modTime; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - Date modDate = webappDaoFactory.getJenaBaseDao().getPropertyDateTimeValue(ind,webappDaoFactory.getJenaBaseDao().MODTIME); - if (modDate != null) { - modTime = new Timestamp(modDate.getTime()); - } - return modTime; - } finally { - ind.getOntModel().leaveCriticalSection(); + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + Date modDate = wadf.getJenaBaseDao().getPropertyDateTimeValue(ind, + wadf.getJenaBaseDao().MODTIME); + if (modDate != null) { + modTime = new Timestamp(modDate.getTime()); } + return modTime; + } finally { + ind.getOntModel().leaveCriticalSection(); } } - public Float getSearchBoost(){ - if( this._searchBoostJena != null ){ - return this._searchBoostJena; - }else{ - ind.getOntModel().enterCriticalSection(Lock.READ); - try{ - try { - searchBoost = - ((Literal)ind.getPropertyValue(webappDaoFactory.getJenaBaseDao().SEARCH_BOOST_ANNOT)).getFloat(); - } catch (Exception e) { - searchBoost = null; - } - return searchBoost; - }finally{ - ind.getOntModel().leaveCriticalSection(); - } + public Float getSearchBoost() { + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + searchBoost = ((Literal) ind + .getPropertyValue(wadf.getJenaBaseDao().SEARCH_BOOST_ANNOT)).getFloat(); + } catch (Exception e) { + LOG.debug(e); + searchBoost = null; + } finally { + ind.getOntModel().leaveCriticalSection(); } + return searchBoost; } - @Override - public String getMainImageUri() { - if (this.mainImageUri != NOT_INITIALIZED) { - return mainImageUri; - } else { - for (ObjectPropertyStatement stmt : getObjectPropertyStatements()) { - if (stmt.getPropertyURI() - .equals(VitroVocabulary.IND_MAIN_IMAGE)) { - mainImageUri = stmt.getObjectURI(); - return mainImageUri; - } - } - return null; - } - } + public String getMainImageUri() { + if (this.mainImageUri != NOT_INITIALIZED) { + return mainImageUri; + } + for (ObjectPropertyStatement stmt : getObjectPropertyStatements()) { + if (stmt.getPropertyURI().equals(IND_MAIN_IMAGE)) { + // arbitrarily return the first value in the list. + mainImageUri = stmt.getObjectURI(); + return mainImageUri; + } + } + return null; + } - @Override - public String getImageUrl() { - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.instanceFromEntityUri(webappDaoFactory, this); - log.trace("figured imageInfo for " + getURI() + ": '" - + this.imageInfo + "'"); - } - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; - log.trace("imageInfo for " + getURI() + " is empty."); - } - return this.imageInfo.getMainImage().getBytestreamAliasUrl(); - } + public String getImageUrl() { + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.instanceFromEntityUri(wadf, this); + LOG.trace("figured imageInfo for " + getURI() + ": '" + this.imageInfo + "'"); + } + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; + LOG.trace("imageInfo for " + getURI() + " is empty."); + } + return this.imageInfo.getMainImage().getBytestreamAliasUrl(); + } - @Override - public String getThumbUrl() { - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.instanceFromEntityUri(webappDaoFactory, this); - log.trace("figured imageInfo for " + getURI() + ": '" - + this.imageInfo + "'"); - } - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; - log.trace("imageInfo for " + getURI() + " is empty."); - } - return this.imageInfo.getThumbnail().getBytestreamAliasUrl(); - } + public String getThumbUrl() { + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.instanceFromEntityUri(wadf, this); + LOG.trace("figured imageInfo for " + getURI() + ": '" + this.imageInfo + "'"); + } + if (this.imageInfo == null) { + this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; + LOG.trace("imageInfo for " + getURI() + " is empty."); + } + return this.imageInfo.getThumbnail().getBytestreamAliasUrl(); + } public List getObjectPropertyStatements() { if (this.objectPropertyStatements != null) { return this.objectPropertyStatements; - } else { - try { - webappDaoFactory.getObjectPropertyStatementDao().fillExistingObjectPropertyStatements(this); - } catch (Exception e) { - log.error(this.getClass().getName()+" could not fill existing ObjectPropertyStatements for "+this.getURI(), e); - } - return this.objectPropertyStatements; } + try { + wadf.getObjectPropertyStatementDao().fillExistingObjectPropertyStatements(this); + } catch (Exception e) { + LOG.error(this.getClass().getName() + + " could not fill existing ObjectPropertyStatements for " + this.getURI(), e); + } + return this.objectPropertyStatements; } @Override public List getObjectPropertyStatements(String propertyURI) { - if (propertyURI == null) { - return null; - } - List objectPropertyStatements = new ArrayList(); - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - StmtIterator sit = ind.listProperties(ind.getModel().getProperty(propertyURI)); - while (sit.hasNext()) { - Statement s = sit.nextStatement(); - if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { - continue; - } - Individual subj = new IndividualJena(s.getSubject().as(OntResource.class), webappDaoFactory); - Individual obj = new IndividualJena(s.getObject().as(OntResource.class), webappDaoFactory); - ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI()); - if (subj != null && obj != null && op != null) { - ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(); - ops.setSubject(subj); - ops.setSubjectURI(subj.getURI()); - ops.setObject(obj); - ops.setObjectURI(obj.getURI()); - ops.setProperty(op); - ops.setPropertyURI(op.getURI()); - objectPropertyStatements.add(ops); - } - } - } finally { - ind.getOntModel().leaveCriticalSection(); - } - return objectPropertyStatements; + if (propertyURI == null) { + return null; + } + List objectPropertyStatements = new ArrayList<>(); + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + StmtIterator sit = ind.listProperties(ind.getModel().getProperty(propertyURI)); + while (sit.hasNext()) { + Statement s = sit.nextStatement(); + if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { + continue; + } + Individual subj = new IndividualJena(s.getSubject().as(OntResource.class), wadf); + Individual obj = new IndividualJena(s.getObject().as(OntResource.class), wadf); + ObjectProperty op = wadf.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI()); + if (subj != null && obj != null && op != null) { + ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(); + ops.setSubject(subj); + ops.setSubjectURI(subj.getURI()); + ops.setObject(obj); + ops.setObjectURI(obj.getURI()); + ops.setProperty(op); + ops.setPropertyURI(op.getURI()); + objectPropertyStatements.add(ops); + } + } + } finally { + ind.getOntModel().leaveCriticalSection(); + } + return objectPropertyStatements; } @Override public List getRelatedIndividuals(String propertyURI) { - if (propertyURI == null) { - return null; - } - List relatedIndividuals = new ArrayList(); - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - NodeIterator values = ind.listPropertyValues(ind.getModel().getProperty(propertyURI)); - while (values.hasNext()) { - RDFNode value = values.nextNode(); - if (value.canAs(OntResource.class)) { - relatedIndividuals.add( - new IndividualJena(value.as(OntResource.class), webappDaoFactory) ); - } - } - } finally { - ind.getOntModel().leaveCriticalSection(); - } - return relatedIndividuals; + if (propertyURI == null) { + return null; + } + List relatedIndividuals = new ArrayList(); + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + NodeIterator values = ind.listPropertyValues(ind.getModel().getProperty(propertyURI)); + while (values.hasNext()) { + RDFNode value = values.nextNode(); + if (value.canAs(OntResource.class)) { + relatedIndividuals.add(new IndividualJena(value.as(OntResource.class), wadf)); + } + } + } finally { + ind.getOntModel().leaveCriticalSection(); + } + return relatedIndividuals; } @Override public Individual getRelatedIndividual(String propertyURI) { - if (propertyURI == null) { - return null; - } - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - RDFNode value = ind.getPropertyValue(ind.getModel().getProperty(propertyURI)); - if (value != null && value.canAs(OntResource.class)) { - return new IndividualJena(value.as(OntResource.class), webappDaoFactory); - } else { - return null; - } - } finally { - ind.getOntModel().leaveCriticalSection(); - } + if (propertyURI == null) { + return null; + } + ind.getOntModel().enterCriticalSection(Lock.READ); + try { + RDFNode value = ind.getPropertyValue(ind.getModel().getProperty(propertyURI)); + if (value != null && value.canAs(OntResource.class)) { + return new IndividualJena(value.as(OntResource.class), wadf); + } + return null; + } finally { + ind.getOntModel().leaveCriticalSection(); + } } public List getObjectPropertyList() { if (this.propertyList != null) { return this.propertyList; - } else { - try { - webappDaoFactory.getObjectPropertyDao().fillObjectPropertiesForIndividual( this ); - } catch (Exception e) { - log.error(this.getClass().getName()+" could not fillEntityProperties for "+this.getURI()); - } - return this.propertyList; } + try { + wadf.getObjectPropertyDao().fillObjectPropertiesForIndividual(this); + } catch (Exception e) { + LOG.error(this.getClass().getName() + " could not fillEntityProperties for " + + this.getURI()); + } + return this.propertyList; } @Override public List getPopulatedObjectPropertyList() { if (populatedObjectPropertyList == null) { - populatedObjectPropertyList = webappDaoFactory.getObjectPropertyDao().getObjectPropertyList(this); + populatedObjectPropertyList = wadf.getObjectPropertyDao().getObjectPropertyList(this); } return populatedObjectPropertyList; } @Override - public Map getObjectPropertyMap() { - if (this.objectPropertyMap != null) { - return objectPropertyMap; - } else { - Map map = new HashMap(); - if (this.propertyList == null) { - getObjectPropertyList(); - } - for (ObjectProperty op : this.propertyList) { - if (op.getURI() != null) { - map.put(op.getURI(), op); - } - } - this.objectPropertyMap = map; - return map; - } + public Map getObjectPropertyMap() { + if (this.objectPropertyMap != null) { + return objectPropertyMap; + } + Map map = new HashMap<>(); + if (this.propertyList == null) { + getObjectPropertyList(); + } + for (ObjectProperty op : this.propertyList) { + if (op.getURI() != null) { + map.put(op.getURI(), op); + } + } + this.objectPropertyMap = map; + return map; } public List getDataPropertyStatements() { if (this.dataPropertyStatements != null) { return this.dataPropertyStatements; - } else { - try { - webappDaoFactory.getDataPropertyStatementDao().fillExistingDataPropertyStatementsForIndividual(this/*,false*/); - } catch (Exception e) { - log.error(this.getClass().getName()+" could not fill existing DataPropertyStatements for "+this.getURI()); - } - return this.dataPropertyStatements; } + try { + wadf.getDataPropertyStatementDao().fillExistingDataPropertyStatementsForIndividual(this/*,false*/); + } catch (Exception e) { + LOG.error(this.getClass().getName() + + " could not fill existing DataPropertyStatements for " + this.getURI()); + } + return this.dataPropertyStatements; } public List getDataPropertyList() { if (this.datatypePropertyList != null) { return this.datatypePropertyList; - } else { - try { - webappDaoFactory.getDataPropertyDao().fillDataPropertiesForIndividual( this ); - } catch (Exception e) { - log.error(this.getClass().getName()+" could not fill data properties for "+this.getURI()); - } - return this.datatypePropertyList; } + try { + wadf.getDataPropertyDao().fillDataPropertiesForIndividual(this); + } catch (Exception e) { + LOG.error(this.getClass().getName() + " could not fill data properties for " + + this.getURI()); + } + return this.datatypePropertyList; } @Override public List getPopulatedDataPropertyList() { if (populatedDataPropertyList == null) { - populatedDataPropertyList = webappDaoFactory.getDataPropertyDao().getDataPropertyList(this); + populatedDataPropertyList = wadf.getDataPropertyDao().getDataPropertyList(this); } return populatedDataPropertyList; } @Override - public Map getDataPropertyMap() { - if (this.dataPropertyMap != null) { - return dataPropertyMap; - } else { - Map map = new HashMap(); - if (this.datatypePropertyList == null) { - getDataPropertyList(); - } - for (DataProperty dp : this.datatypePropertyList) { - if (dp.getURI() != null) { - map.put(dp.getURI(), dp); - } - } - this.dataPropertyMap = map; - return map; - } + public Map getDataPropertyMap() { + if (this.dataPropertyMap != null) { + return dataPropertyMap; + } + Map map = new HashMap<>(); + if (this.datatypePropertyList == null) { + getDataPropertyList(); + } + for (DataProperty dp : this.datatypePropertyList) { + if (dp.getURI() != null) { + map.put(dp.getURI(), dp); + } + } + this.dataPropertyMap = map; + return map; } public List getExternalIds() { // BJL 2007-11-11: need to decide whether we want to use Collections or Lists in our interfaces - we seem to be leaning toward Lists if (this.externalIds != null) { return this.externalIds; - } else { - try { - List dpsList = new ArrayList(); - dpsList.addAll(webappDaoFactory.getIndividualDao().getExternalIds(this.getURI(), null)); - this.externalIds = dpsList; - } catch (Exception e) { - log.error(this.getClass().getName()+" could not fill external IDs for "+this.getURI()); - } - return this.externalIds; } + try { + List dpsList = new ArrayList<>(); + dpsList.addAll(wadf.getIndividualDao().getExternalIds(this.getURI(), null)); + this.externalIds = dpsList; + } catch (Exception e) { + LOG.error(this.getClass().getName() + " could not fill external IDs for " + + this.getURI()); + } + return this.externalIds; } @Override @@ -434,52 +419,51 @@ public List getVClasses() { @Override public List getVClasses(boolean direct) { - if (direct) { - if (directVClasses != null) { - return directVClasses; - } else { - directVClasses = getMyVClasses(true); - return directVClasses; - } - } else { - if (allVClasses != null) { - return allVClasses; - } else { - allVClasses = getMyVClasses(false); - return allVClasses; - } - } + if (direct) { + if (directVClasses != null) { + return directVClasses; + } + directVClasses = getMyVClasses(true); + return directVClasses; + } + if (allVClasses != null) { + return allVClasses; + } + allVClasses = getMyVClasses(false); + return allVClasses; } private List getMyVClasses(boolean direct) { - List vClassList = new ArrayList(); - OntModel ontModel = ind.getOntModel(); - ontModel.enterCriticalSection(Lock.READ); - try { - ClosableIterator typeIt = ind.listRDFTypes(direct); - try { - for (Iterator it = typeIt; it.hasNext();) { - Resource type = (Resource) typeIt.next(); - String typeURI = (!type.isAnon()) ? type.getURI() : VitroVocabulary.PSEUDO_BNODE_NS + type.getId().toString(); - if (type.getNameSpace() == null || (!webappDaoFactory.getNonuserNamespaces().contains(type.getNameSpace())) ) { - VClass vc = webappDaoFactory.getVClassDao().getVClassByURI(typeURI); - if (vc != null) { - vClassList.add(vc); - } - } - - } - } finally { - typeIt.close(); - } - } finally { - ontModel.leaveCriticalSection(); - } - try { - Collections.sort(vClassList); - } catch (Exception e) {} - return vClassList; - } + List vClassList = new ArrayList<>(); + OntModel ontModel = ind.getOntModel(); + ontModel.enterCriticalSection(Lock.READ); + try { + ClosableIterator typeIt = ind.listRDFTypes(direct); + try { + for (Iterator it = typeIt; it.hasNext();) { + Resource type = typeIt.next(); + String typeURI = (!type.isAnon()) + ? type.getURI() + : PSEUDO_BNODE_NS + type.getId().toString(); + if (type.getNameSpace() == null || + (!wadf.getNonuserNamespaces().contains(type.getNameSpace()))) { + VClass vc = wadf.getVClassDao().getVClassByURI(typeURI); + if (vc != null) { + vClassList.add(vc); + } + } + } + } finally { + typeIt.close(); + } + } finally { + ontModel.leaveCriticalSection(); + } + try { + Collections.sort(vClassList); + } catch (Exception e) {} + return vClassList; + } /** * The base method in {@link IndividualImpl} is adequate if the reasoner is @@ -498,7 +482,7 @@ public boolean isVClass(String uri) { return true; } - VClassDao vclassDao = webappDaoFactory.getVClassDao(); + VClassDao vclassDao = wadf.getVClassDao(); for (VClass vClass : getVClasses(true)) { for (String superClassUri: vclassDao.getAllSuperClassURIs(vClass.getURI())) { if (uri.equals(superClassUri)) { @@ -529,9 +513,9 @@ protected void sortEnts2EntsForDisplay(){ private Collator collator = Collator.getInstance(); private void sortObjectPropertyStatementsForDisplay(ObjectProperty prop) { - try { - log.info("Doing special sort for "+prop.getDomainPublic()); - final String sortPropertyURI = prop.getObjectIndividualSortPropertyURI(); + try { + LOG.info("Doing special sort for "+prop.getDomainPublic()); + final String sortPropertyURI = prop.getObjectIndividualSortPropertyURI(); String tmpDir; boolean tmpAsc; @@ -562,7 +546,7 @@ public final int compare(Object o1, Object o2){ val1 = ""; } } else { - log.warn( "IndividualJena.sortObjectPropertiesForDisplay passed object property statement with no range entity."); + LOG.warn( "IndividualJena.sortObjectPropertiesForDisplay passed object property statement with no range entity."); } if( e2 != null ){ @@ -576,7 +560,7 @@ public final int compare(Object o1, Object o2){ val2 = ""; } } else { - log.warn( "IndividualJena.sortObjectPropertyStatementsForDisplay() was passed an object property statement with no range entity."); + LOG.warn( "IndividualJena.sortObjectPropertyStatementsForDisplay() was passed an object property statement with no range entity."); } int rv = 0; @@ -592,7 +576,7 @@ else if( val1 instanceof Date ) { else rv = 0; } catch (NullPointerException e) { - log.error(e, e); + LOG.error(e, e); } if( cAsc ) @@ -604,18 +588,61 @@ else if( val1 instanceof Date ) { try { getObjectPropertyStatements().sort(comp); } catch (Exception e) { - log.error("Exception sorting object property statements for object property "+this.getURI()); + LOG.error("Exception sorting object property statements for object property "+this.getURI()); } - - } catch (Exception e) { - log.error(e, e); + LOG.error(e, e); } } @Override public void resolveAsFauxPropertyStatements(List list) { - webappDaoFactory.getObjectPropertyStatementDao().resolveAsFauxPropertyStatements(list); + wadf.getObjectPropertyStatementDao().resolveAsFauxPropertyStatements(list); } + /** + * Setup the URI parts from the individual ontology. + * + * @param ind The individual ontology resource. + */ + protected void setupURIParts(OntResource ind) { + if (ind != null) { + if (ind.isAnon()) { + this.setNamespace(PSEUDO_BNODE_NS); + this.setLocalName(ind.getId().toString()); + } else { + this.URI = ind.getURI(); + this.namespace = ind.getNameSpace(); + this.localName = ind.getLocalName(); + } + } + } + + /** + * Get web application DAO factory. + * + * @return The web application DAO factory. + */ + protected WebappDaoFactoryJena getWebappDaoFactory() { + return wadf; + } + + /** + * Get the individual ontology resource. + * + * @return The ontology resource. + */ + protected OntResource getInd() { + return ind; + } + + /** + * Set the individual ontology resource. + * + * @param The ontology resource. + */ + protected void setInd(OntResource ind) { + this.ind = ind; + } + } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java deleted file mode 100644 index 8abeaa3d17..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java +++ /dev/null @@ -1,1063 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import static edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY; - -import java.sql.Timestamp; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.joda.time.DateTime; - -import org.apache.jena.ontology.OntModel; -import org.apache.jena.ontology.OntModelSpec; -import org.apache.jena.ontology.OntResource; -import org.apache.jena.query.Dataset; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.QuerySolution; -import org.apache.jena.query.ResultSet; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.ResourceFactory; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.shared.Lock; -import org.apache.jena.vocabulary.RDF; -import org.apache.jena.vocabulary.RDFS; - -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; -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.VClass; -import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; -import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; - -public class IndividualSDB extends IndividualImpl implements Individual { - - private static final Log log = LogFactory.getLog( - IndividualSDB.class.getName()); - private OntResource ind = null; - private WebappDaoFactorySDB webappDaoFactory = null; - private Float _searchBoostJena = null; - private boolean retreivedNullRdfsLabel = false; - private DatasetWrapperFactory dwf = null; - private SDBDatasetMode datasetMode = - SDBDatasetMode.ASSERTIONS_AND_INFERENCES; - private String individualURI = null; - private Model model = null; - private Boolean _hasThumb = null; - - public IndividualSDB(String individualURI, - DatasetWrapperFactory datasetWrapperFactory, - SDBDatasetMode datasetMode, - WebappDaoFactorySDB wadf, - Model initModel) { - this.individualURI = individualURI; - this.webappDaoFactory = wadf; - this.dwf = datasetWrapperFactory; - - try { - initModel.getLock().enterCriticalSection(Lock.READ); - String getStatements = - "CONSTRUCT \n" + - "{ <"+individualURI+"> <" + RDFS.label.getURI() + - "> ?ooo. \n" + - "<"+individualURI+"> a ?type . \n" + - "} \n" + - "WHERE { \n" + - "{ <"+individualURI+"> <" + RDFS.label.getURI() + - "> ?ooo } \n" + - " UNION { <"+individualURI+"> a ?type } \n" + - "} "; - this.model = QueryExecutionFactory.create( - QueryFactory.create(getStatements), initModel) - .execConstruct(); - } finally { - initModel.getLock().leaveCriticalSection(); - } - - OntModel ontModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, model); - this.ind = ontModel.createOntResource(individualURI); - setUpURIParts(ind); - } - - public IndividualSDB(String individualURI, - DatasetWrapperFactory datasetWrapperFactory, - SDBDatasetMode datasetMode, - WebappDaoFactorySDB wadf, - boolean skipInitialization) throws IndividualNotFoundException { - this.individualURI = individualURI; - this.datasetMode = datasetMode; - this.dwf = datasetWrapperFactory; - this.webappDaoFactory = wadf; - - // Check that individualURI is valid. (Prevent SPARQL injection attack.) - // Valid syntax is defined here: https://www.w3.org/TR/rdf-sparql-query/#rIRI_REF - if (!individualURI.matches("[^<>\"{}|^`\\\\\u0000-\u0020]*")) { - throw new IndividualNotFoundException(); - } - - if (skipInitialization) { - OntModel ontModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM); - this.ind = ontModel.createOntResource(individualURI); - } else { - try { - String getStatements = - "CONSTRUCT " + - "{ <"+individualURI+"> <" + RDFS.label.getURI() + - "> ?ooo \n" + - "} WHERE {" + - "{ <"+individualURI+"> <" + RDFS.label.getURI() + - "> ?ooo } \n" + - "}"; - - model = ModelFactory.createDefaultModel(); - webappDaoFactory.getRDFService().sparqlConstructQuery(getStatements, model); - } catch (RDFServiceException e) { - } - - OntModel ontModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, model); - - if (model.isEmpty() && noTriplesFor(individualURI)) { - throw new IndividualNotFoundException(); - } - - this.ind = ontModel.createOntResource(individualURI); - } - setUpURIParts(ind); - } - - private boolean noTriplesFor(String individualURI) { - try { - return !webappDaoFactory.getRDFService().sparqlAskQuery("ASK { <" + individualURI + "> ?p ?o }"); - } catch (RDFServiceException rse) { - } - - return true; - } - - static final boolean SKIP_INITIALIZATION = true; - - public IndividualSDB(String individualURI, - DatasetWrapperFactory datasetWrapperFactory, - SDBDatasetMode datasetMode, - WebappDaoFactorySDB wadf) throws IndividualNotFoundException { - this(individualURI, - datasetWrapperFactory, - datasetMode, - wadf, - !SKIP_INITIALIZATION); - } - - public class IndividualNotFoundException extends Exception {} - - private void setUpURIParts(OntResource ind) { - if (ind != null) { - if (ind.isAnon()) { - this.setNamespace(VitroVocabulary.PSEUDO_BNODE_NS); - this.setLocalName(ind.getId().toString()); - } else { - this.URI = ind.getURI(); - this.namespace = ind.getNameSpace(); - this.localName = ind.getLocalName(); - } - } else if (individualURI != null) { - log.warn("Null individual returned for URI " + individualURI); - } - } - - private DatasetWrapper getDatasetWrapper() { - return this.dwf.getDatasetWrapper(); - } - - public String getName() { - if (this.name != null) { - return name; - } else { - ind.getOntModel().enterCriticalSection(Lock.READ); - - try { - this.name = webappDaoFactory.getJenaBaseDao().getLabelOrId(ind); - if (this.name == null) { - this.name = "[null]"; - } - return this.name; - - } finally { - - ind.getOntModel().leaveCriticalSection(); - } - } - } - - public String getRdfsLabel() { - if (this.rdfsLabel != null) { - return rdfsLabel; - } else if( this.rdfsLabel == null && retreivedNullRdfsLabel ){ - return null; - } else { - - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - this.rdfsLabel = webappDaoFactory.getJenaBaseDao().getLabel(ind); - retreivedNullRdfsLabel = this.rdfsLabel == null; - return this.rdfsLabel; - } finally { - - ind.getOntModel().leaveCriticalSection(); - } - } - } - - public String getVClassURI() { - if (this.vClassURI != null) { - return vClassURI; - } else { - List clist = getVClasses(true); - return (clist.size() > 0) ? clist.get(0).getURI() : null; - } - } - - public VClass getVClass() { - if (this.vClass != null) { - return this.vClass; - } else { - List clist = getVClasses(true); - return (clist.size() > 0) ? clist.get(0) : null ; - } - } - - @Override - public List getMostSpecificTypeURIs() { - final List typeURIs = new ArrayList(); - if (this.getURI() == null) { - return typeURIs; - } else { - String queryStr = "SELECT ?type WHERE { <" + this.getURI() + "> <" + - VitroVocabulary.MOST_SPECIFIC_TYPE + "> ?type }"; - try { - webappDaoFactory.getRDFService().sparqlSelectQuery(queryStr, new ResultSetConsumer() { - @Override - protected void processQuerySolution(QuerySolution qs) { - RDFNode node = qs.get("type"); - if (node.isURIResource()) { - typeURIs.add(node.asResource().getURI()); - } - } - }); - - return typeURIs; - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } - } - - public Timestamp getModTime() { - if (modTime != null) { - return modTime; - } else { - - ind.getOntModel().enterCriticalSection(Lock.READ); - try { - Date modDate = webappDaoFactory.getJenaBaseDao() - .getPropertyDateTimeValue( - ind,webappDaoFactory.getJenaBaseDao().MODTIME); - if (modDate != null) { - modTime = new Timestamp(modDate.getTime()); - } - return modTime; - } finally { - - ind.getOntModel().leaveCriticalSection(); - } - } - } - - public Float getSearchBoost(){ - if( this._searchBoostJena != null ){ - return this._searchBoostJena; - }else{ - String getPropertyValue = - "SELECT ?value \n" + - "WHERE { \n" + - "<" +individualURI+ "> <" +webappDaoFactory.getJenaBaseDao().SEARCH_BOOST_ANNOT+ "> ?value \n" + - "}"; - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - QueryExecution qe = QueryExecutionFactory.create( - QueryFactory.create(getPropertyValue), dataset); - try{ - ResultSet rs = qe.execSelect(); - if(rs.hasNext()){ - QuerySolution qs = rs.nextSolution(); - if(qs.get("value") !=null){ - Literal value = qs.get("value").asLiteral(); - searchBoost = Float.parseFloat(value.getLexicalForm()); - return searchBoost; - } - } else{ - return null; - } - } catch (Exception e){ - log.error(e,e); - return null; - } finally{ - qe.close(); - dataset.getLock().leaveCriticalSection(); - w.close(); - } - } - return null; - } - - @Override - public String getMainImageUri() { - if (this.mainImageUri != NOT_INITIALIZED) { - return mainImageUri; - } else { - List mainImgStmts = - getObjectPropertyStatements(VitroVocabulary.IND_MAIN_IMAGE); - if (mainImgStmts != null && mainImgStmts.size() > 0) { - // arbitrarily return the first value in the list - mainImageUri = mainImgStmts.get(0).getObjectURI(); - return mainImageUri; - } - return null; - } - } - - @Override - public String getImageUrl() { - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.instanceFromEntityUri( - webappDaoFactory, this); - log.trace("figured imageInfo for " + getURI() + ": '" - + this.imageInfo + "'"); - } - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; - log.trace("imageInfo for " + getURI() + " is empty."); - } - return this.imageInfo.getMainImage().getBytestreamAliasUrl(); - } - - @Override - public String getThumbUrl() { - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.instanceFromEntityUri( - webappDaoFactory, this); - log.trace("figured imageInfo for " + getURI() + ": '" - + this.imageInfo + "'"); - } - if (this.imageInfo == null) { - this.imageInfo = ImageInfo.EMPTY_IMAGE_INFO; - log.trace("imageInfo for " + getURI() + " is empty."); - } - return this.imageInfo.getThumbnail().getBytestreamAliasUrl(); - } - - @Override - public boolean hasThumb(){ - if( _hasThumb != null ){ - return _hasThumb; - }else{ - String ask = - "ASK { " + - " <" + individualURI + "> ?mainImage . \n" + - " ?mainImage ?thumbImage . }\n" ; - try{ - _hasThumb = webappDaoFactory.getRDFService().sparqlAskQuery(ask); - }catch(Exception ex){ - _hasThumb = false; - log.error(ex,ex); - } - return _hasThumb; - } - } - - public List getObjectPropertyStatements() { - if (this.objectPropertyStatements != null) { - return this.objectPropertyStatements; - } else { - try { - webappDaoFactory.getObjectPropertyStatementDao() - .fillExistingObjectPropertyStatements(this); - } catch (Exception e) { - log.error("Could not fill existing ObjectPropertyStatements for " - + this.getURI(), e); - } - return this.objectPropertyStatements; - } - } - - @Override - public List getObjectPropertyStatements(String propertyURI) { - if (propertyURI == null) { - return null; - } - List objectPropertyStatements = new ArrayList - (); - Model tempModel = ModelFactory.createDefaultModel(); - OntModel ontModel = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - QueryExecution qexec = null; - try { - String valuesOfProperty = - "CONSTRUCT{ <" + this.individualURI + "> <" + propertyURI + "> ?object }" + - "WHERE{ <" + this.individualURI + "> <" + propertyURI + "> ?object } \n"; - qexec = QueryExecutionFactory.create(QueryFactory.create(valuesOfProperty), dataset); - tempModel = qexec.execConstruct(); - ontModel.add(tempModel.listStatements()); - Resource ontRes = ontModel.getResource(this.individualURI); - StmtIterator sit = ontRes.listProperties(ontRes.getModel().getProperty(propertyURI)); - while (sit.hasNext()) { - Statement s = sit.nextStatement(); - if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { - continue; - } - Individual subj = null; - try { - subj = new IndividualSDB( - s.getSubject().as(OntResource.class).getURI(), - this.dwf, datasetMode, webappDaoFactory); - } catch (IndividualNotFoundException e) { - // leave null subject - } - Individual obj = null; - try { - obj = new IndividualSDB( - s.getObject().as(OntResource.class).getURI(), - this.dwf, datasetMode, webappDaoFactory); - } catch (IndividualNotFoundException e) { - // leave null object - } - ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI()); - // We don't want to filter out statements simply because we - // can't find a type for the property, so we'll just make a - // new ObjectProperty bean if we can't get one from the DAO. - if (op == null) { - op = new ObjectProperty(); - op.setURI(propertyURI); - } - if (subj != null && obj != null) { - ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(); - ops.setSubject(subj); - ops.setSubjectURI(subj.getURI()); - ops.setObject(obj); - ops.setObjectURI(obj.getURI()); - ops.setProperty(op); - ops.setPropertyURI(op.getURI()); - objectPropertyStatements.add(ops); - } - } - } finally { - if(qexec!=null) qexec.close(); - tempModel.close(); - ontModel.close(); - dataset.getLock().leaveCriticalSection(); - w.close(); - } - return objectPropertyStatements; - } - - @Override - public List getRelatedIndividuals(String propertyURI) { - if (propertyURI == null) { - return null; - } - List relatedIndividuals = new ArrayList(); - - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - String valuesOfProperty = - "SELECT ?object " + - "WHERE{ <" + this.individualURI + "> <" + - propertyURI + "> ?object } \n"; - ResultSet values = QueryExecutionFactory.create( - QueryFactory.create(valuesOfProperty), dataset) - .execSelect(); - QuerySolution result = null; - while (values.hasNext()) { - result = values.next(); - RDFNode value = result.get("object"); - try { - if (value.canAs(OntResource.class)) { - relatedIndividuals.add( - new IndividualSDB( - value.as(OntResource.class).getURI(), - this.dwf, - datasetMode, - webappDaoFactory) ); - } - } catch (IndividualNotFoundException e) { - // don't add to the list - } - } - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - return relatedIndividuals; - } - - @Override - public Individual getRelatedIndividual(String propertyURI) { - if (propertyURI == null) { - return null; - } - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - String valueOfProperty = - "SELECT ?object " + - "WHERE{ <" + this.individualURI + "> <" + - propertyURI + "> ?object } \n"; - QueryExecution qe = QueryExecutionFactory.create( - QueryFactory.create(valueOfProperty), dataset); - try { - ResultSet results = qe.execSelect(); - if (results.hasNext()) { - QuerySolution result = results.next(); - RDFNode value = result.get("object"); - if (value != null && value.canAs(OntResource.class)) { - try { - return new IndividualSDB( - value.as(OntResource.class).getURI(), - dwf, datasetMode, webappDaoFactory); - } catch (IndividualNotFoundException e) { - return null; - } - } - } - return null; - } finally { - qe.close(); - } - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - } - - public List getObjectPropertyList() { - if (this.propertyList != null) { - return this.propertyList; - } else { - try { - webappDaoFactory.getObjectPropertyDao() - .fillObjectPropertiesForIndividual( this ); - } catch (Exception e) { - log.error("Could not fillEntityProperties for " + this.getURI(), e); - } - return this.propertyList; - } - } - - @Override - public List getPopulatedObjectPropertyList() { - if (populatedObjectPropertyList == null) { - populatedObjectPropertyList = webappDaoFactory - .getObjectPropertyDao().getObjectPropertyList(this); - } - return populatedObjectPropertyList; - } - - @Override - public Map getObjectPropertyMap() { - if (this.objectPropertyMap != null) { - return objectPropertyMap; - } else { - Map map = new HashMap(); - if (this.propertyList == null) { - getObjectPropertyList(); - } - for (ObjectProperty op : this.propertyList) { - if (op.getURI() != null) { - map.put(op.getURI(), op); - } - } - this.objectPropertyMap = map; - return map; - } - } - - public List getDataPropertyStatements() { - if (this.dataPropertyStatements != null) { - return this.dataPropertyStatements; - } else { - try { - webappDaoFactory.getDataPropertyStatementDao() - .fillExistingDataPropertyStatementsForIndividual(this); - } catch (Exception e) { - log.error("Could not fill existing DataPropertyStatements for " - + this.getURI(), e); - } - return this.dataPropertyStatements; - } - } - - public List getDataPropertyList() { - if (this.datatypePropertyList != null) { - return this.datatypePropertyList; - } else { - try { - webappDaoFactory.getDataPropertyDao() - .fillDataPropertiesForIndividual( this ); - } catch (Exception e) { - log.error("Could not fill data properties for " + this.getURI(), e); - } - return this.datatypePropertyList; - } - } - - @Override - public List getPopulatedDataPropertyList() { - if (populatedDataPropertyList == null) { - populatedDataPropertyList = webappDaoFactory.getDataPropertyDao() - .getDataPropertyList(this); - } - return populatedDataPropertyList; - } - - @Override - public Map getDataPropertyMap() { - if (this.dataPropertyMap != null) { - return dataPropertyMap; - } else { - Map map = new HashMap(); - if (this.datatypePropertyList == null) { - getDataPropertyList(); - } - for (DataProperty dp : this.datatypePropertyList) { - if (dp.getURI() != null) { - map.put(dp.getURI(), dp); - } - } - this.dataPropertyMap = map; - return map; - } - } - - @Override - public List getDataPropertyStatements(String propertyUri) { - List stmts = this.dataPropertyStatements; - if (stmts == null) { - return sparqlForDataPropertyStatements(propertyUri); - } else { - List stmtsForProp = new ArrayList(); - for (DataPropertyStatement stmt : stmts) { - if (stmt.getDatapropURI().equals(propertyUri)) { - stmtsForProp.add(stmt); - } - } - return stmtsForProp; - } - } - - @Override - public String getDataValue(String propertyUri) { - if (propertyUri == null) { - log.error("Cannot retrieve value for null property"); - return null; - } else if (this.getURI() == null) { - log.error("Cannot retrieve value of property " + propertyUri + - " for anonymous individual"); - return null; - } else { - List stmts = sparqlForDataPropertyStatements( - propertyUri); - if (stmts != null && stmts.size() > 0) { - return stmts.get(0).getData(); - } - } - return null; // not found - } - - @Override - public List getDataValues(String propertyUri) { - List values = new ArrayList(); - if (propertyUri == null) { - log.error("Cannot retrieve value for null property"); - return null; - } else if (this.getURI() == null) { - log.error("Cannot retrieve value of property " + propertyUri + - " for anonymous individual"); - return null; - } else { - List stmts = sparqlForDataPropertyStatements( - propertyUri); - if (stmts != null) { - for (DataPropertyStatement stmt : stmts) { - values.add(stmt.getData()); - } - } - return values; - } - } - - private List sparqlForDataPropertyStatements(final String propertyUri) { - final List stmts = new ArrayList(); - final IndividualSDB individualSDB = this; - - String queryStr = "SELECT (str(?value) as ?valueString) WHERE { <" - + this.getURI() + "> <" + propertyUri + "> ?value }"; - try { - webappDaoFactory.getRDFService().sparqlSelectQuery( - queryStr, new ResultSetConsumer() { - @Override - protected void processQuerySolution(QuerySolution qs) { - RDFNode node = qs.get("valueString"); - if (!node.isLiteral()) { - log.debug("Ignoring non-literal value for " + node + - " for property " + propertyUri); - } else { - Literal lit = node.asLiteral(); - DataPropertyStatement stmt = new DataPropertyStatementImpl(); - - stmt.setData(lit.getLexicalForm()); - stmt.setDatatypeURI(lit.getDatatypeURI()); - stmt.setLanguage(lit.getLanguage()); - stmt.setDatapropURI(propertyUri); - stmt.setIndividualURI(individualSDB.getURI()); - stmt.setIndividual(individualSDB); - stmts.add(stmt); - } - } - }); - } catch (RDFServiceException e) { - log.error(e,e); - throw new RuntimeException(e); - } - return stmts; - } - - public List getExternalIds() { - if (this.externalIds != null) { - return this.externalIds; - } else { - try { - List dpsList = - new ArrayList(); - dpsList.addAll(webappDaoFactory.getIndividualDao() - .getExternalIds(this.getURI(), null)); - this.externalIds = dpsList; - } catch (Exception e) { - log.error("Could not fill external IDs for " + this.getURI(), e); - } - return this.externalIds; - } - } - - @Override - public List getVClasses() { - return getVClasses(false); - } - - @Override - public List getVClasses(boolean assertedOnly) { - if (assertedOnly) { - if (directVClasses != null) { - return directVClasses; - } else { - directVClasses = getMyVClasses(true); - return directVClasses; - } - } else { - if (allVClasses != null) { - return allVClasses; - } else { - allVClasses = getMyVClasses(false); - return allVClasses; - } - } - } - - private List getMyVClasses(boolean assertedOnly) { - List vClassList = new ArrayList(); - Model tempModel = null; - if (ind.getModel().contains((Resource) null, RDF.type, (RDFNode) null)){ - tempModel = ind.getModel(); - } else { - tempModel = ModelFactory.createDefaultModel(); - String getTypesQuery = buildMyVClassesQuery(assertedOnly); - - RDFService service = webappDaoFactory.getRDFService(); - try { - service.sparqlConstructQuery(getTypesQuery, tempModel); - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } - StmtIterator stmtItr = tempModel.listStatements( - (Resource) null, RDF.type, (RDFNode) null); - LinkedList list = new LinkedList(); - while(stmtItr.hasNext()){ - Statement stmt = stmtItr.nextStatement(); - if (stmt.getObject().isResource() && !stmt.getObject().isAnon()) { - list.add(((Resource) stmt.getObject()).getURI()); - } - } - Iterator itr = null; - VClassDao checkSubClass = this.webappDaoFactory.getVClassDao(); - boolean directTypes = false; - String currentType = null; - ArrayList done = new ArrayList(); - - /* Loop for comparing starts here */ - if(assertedOnly){ - while(!directTypes){ - itr = list.listIterator(); - - do{ - if(itr.hasNext()){ - currentType = itr.next();} - else{ - directTypes = true; // get next element for comparison - break;} - }while(done.contains(currentType)); - - if(directTypes) - break; - // check to see if it's all over otherwise start comparing - else - itr = list.listIterator(); - - while(itr.hasNext()){ - String nextType = itr.next(); - if(checkSubClass.isSubClassOf(currentType, nextType) - && !currentType.equalsIgnoreCase(nextType)){ - itr.remove(); - } - } - - done.add(currentType); // add the uri to done list. - } - } - - /* Loop for comparing ends here */ - Iterator typeIt = list.iterator(); - - for (Iterator it = typeIt; it.hasNext();) { - Resource type = ResourceFactory - .createResource(it.next().toString()); - String typeURI = (!type.isAnon()) - ? type.getURI() - : VitroVocabulary.PSEUDO_BNODE_NS - + type.getId().toString(); - if (type.getNameSpace() == null || - (!webappDaoFactory.getNonuserNamespaces() - .contains(type.getNameSpace())) ) { - VClass vc = webappDaoFactory.getVClassDao() - .getVClassByURI(type.getURI()); - if (vc != null) { - vClassList.add(vc); - } - } - } - - try { - Collections.sort(vClassList); - } catch (Exception e) { - log.error("Unable to sort VClass list", e); - } - - return vClassList; - } - - /** - * If we are restricting to asserted types, either by request or by dataset - * mode, then filter by graph and include a UNION clause to support - * retrieving inferred types from the unnamed base graph, as in Sesame and - * OWLIM. - */ - private String buildMyVClassesQuery(boolean assertedOnly) { - SDBDatasetMode queryMode = assertedOnly ? ASSERTIONS_ONLY : datasetMode; - - String filterBlock = WebappDaoFactorySDB.getFilterBlock(new String[] { "?g" }, queryMode); - - if (filterBlock.isEmpty()) { - return - "CONSTRUCT { <" + this.individualURI + "> " + "<" + RDF.type + "> ?types }\n" + - "WHERE { <" + this.individualURI +"> <" +RDF.type+ "> ?types } \n"; - } else { - String unionBlock = (queryMode.equals(ASSERTIONS_ONLY)) ? - "" : - "UNION { <" + this.individualURI +"> <" +RDF.type+ "> ?types }"; - return - "CONSTRUCT{ <" + this.individualURI + "> " + "<" + RDF.type + "> ?types }\n" + - "WHERE{ { GRAPH ?g" - + " { <" + this.individualURI +"> <" +RDF.type+ "> ?types } \n" - + filterBlock - + "} \n" - + unionBlock - + "} \n"; - } - } - - /** - * The base method in {@link IndividualImpl} is adequate if the reasoner is - * up to date. - * - * If the base method returns false, check directly to see if - * any of the super classes of the direct classes will satisfy this request. - */ - @Override - public boolean isVClass(String uri) { - if (uri == null || this.getURI() == null) { - return false; - } - String queryString = "ASK { <" + this.getURI() + "> a <" + uri + "> }"; - try { - return webappDaoFactory.getRDFService().sparqlAskQuery(queryString); - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } - - /** - * Overriding the base method so that we can do the sorting by arbitrary property here. An - * IndividualSDB has a reference back to the model; everything else is just a dumb bean (for now). - */ - @Override - protected void sortEnts2EntsForDisplay(){ - if( getObjectPropertyList() == null ) return; - - for (ObjectProperty prop : getObjectPropertyList()) { - /* if (prop.getObjectIndividualSortPropertyURI()==null) { - prop.sortObjectPropertyStatementsForDisplay(prop,prop.getObjectPropertyStatements()); - } else {*/ - prop.sortObjectPropertyStatementsForDisplay(prop, prop.getObjectPropertyStatements()); - /* }*/ - } - } - - private Collator collator = Collator.getInstance(); - - private void sortObjectPropertyStatementsForDisplay(ObjectProperty prop) { - try { - log.info("Doing special sort for "+prop.getDomainPublic()); - final String sortPropertyURI = prop.getObjectIndividualSortPropertyURI(); - String tmpDir; - boolean tmpAsc; - - tmpDir = prop.getDomainEntitySortDirection(); - - //valid values are "desc" and "asc", anything else will default to ascending - tmpAsc = !"desc".equalsIgnoreCase(tmpDir); - - final boolean dir = tmpAsc; - Comparator comp = new Comparator(){ - final boolean cAsc = dir; - - public final int compare(Object o1, Object o2){ - ObjectPropertyStatement e2e1= (ObjectPropertyStatement)o1, e2e2=(ObjectPropertyStatement)o2; - Individual e1 , e2; - e1 = e2e1 != null ? e2e1.getObject():null; - e2 = e2e2 != null ? e2e2.getObject():null; - - Object val1 = null, val2 = null; - if( e1 != null ){ - try { - DataProperty dp = e1.getDataPropertyMap().get(sortPropertyURI); - if (dp.getDataPropertyStatements() != null && dp.getDataPropertyStatements().size()>0) { - val1 = dp.getDataPropertyStatements().get(0).getData(); - } - } - catch (Exception e) { - val1 = ""; - } - } else { - log.warn( "IndividualSDB.sortObjectPropertiesForDisplay passed object property statement with no range entity."); - } - - if( e2 != null ){ - try { - DataProperty dp = e2.getDataPropertyMap().get(sortPropertyURI); - if (dp.getDataPropertyStatements() != null && dp.getDataPropertyStatements().size()>0) { - val2 = dp.getDataPropertyStatements().get(0).getData(); - } - } - catch (Exception e) { - val2 = ""; - } - } else { - log.warn( "IndividualSDB.sortObjectPropertyStatementsForDisplay() was passed an object property statement with no range entity."); - } - - int rv = 0; - try { - if( val1 instanceof String ) - rv = collator.compare( ((String)val1) , ((String)val2) ); - //rv = ((String)val1).compareTo((String)val2); - else if( val1 instanceof Date ) { - DateTime dt1 = new DateTime(val1); - DateTime dt2 = new DateTime(val2); - rv = dt1.compareTo(dt2); - } - else - rv = 0; - } catch (NullPointerException e) { - log.error(e, e); - } - - if( cAsc ) - return rv; - else - return rv * -1; - } - }; - try { - getObjectPropertyStatements().sort(comp); - } catch (Exception e) { - log.error("Exception sorting object property statements for object property "+this.getURI()); - } - - - } catch (Exception e) { - log.error(e, e); - } - } - - @Override - public void resolveAsFauxPropertyStatements(List list) { - webappDaoFactory.getObjectPropertyStatementDao().resolveAsFauxPropertyStatements(list); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 6ba1b1134b..5cfa0d9f43 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -87,7 +87,6 @@ public JenaBaseDao(WebappDaoFactoryJena wadf) { this.NONUSER_NAMESPACES = wadf.getNonuserNamespaces(); this.PREFERRED_LANGUAGES = wadf.getPreferredLanguages(); this.webappDaoFactory = wadf; - } /* ******************** accessors ************************** */ @@ -118,19 +117,18 @@ protected String getPropertyStringValue(OntResource res, Property dataprop) { try { ClosableIterator stateIt = res.getModel().listStatements(res,dataprop,(Literal)null); try { - if (stateIt.hasNext()) + if (stateIt.hasNext()) { return ((Literal)stateIt.next().getObject()).getString(); - else - return null; + } } finally { stateIt.close(); } } catch (Exception e) { - return null; + log.debug(e); } - } else { - return null; } + + return null; } /** @@ -148,21 +146,20 @@ protected void addPropertyStringValue(Resource res, Property dataprop, String va protected Boolean getPropertyBooleanValue(OntResource res, Property dataprop) { if (dataprop != null) { try { - ClosableIterator stateIt = getOntModel().listStatements(res,dataprop,(Literal)null); + StmtIterator stateIt = getOntModel().listStatements(res,dataprop,(Literal)null); try { - if (stateIt.hasNext()) + if (stateIt.hasNext()) { return ((Literal)((Statement)stateIt.next()).getObject()).getBoolean(); - else - return null; + } } finally { stateIt.close(); } } catch (Exception e) { - return null; + log.debug(e); } - } else { - return null; } + + return null; } /** @@ -920,8 +917,8 @@ protected String getLabel(OntResource r){ return label; } - protected Literal getLabelLiteral(String individualUri) { - OntResource resource = webappDaoFactory.getOntModel().createOntResource(individualUri); + protected Literal getLabelLiteral(String individualURI) { + OntResource resource = webappDaoFactory.getOntModel().createOntResource(individualURI); return getLabelLiteral(resource); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 9ae00d59e5..78df14bb2a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -58,10 +58,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp private static final Log log = LogFactory.getLog(ObjectPropertyDaoJena.class.getName()); public ObjectPropertyDaoJena(RDFService rdfService, - DatasetWrapperFactory dwf, + DatasetWrapper dw, Map customListViewConfigFileMap, WebappDaoFactoryJena wadf) { - super(rdfService, dwf, wadf); + super(rdfService, dw, wadf); this.customListViewConfigFileMap = customListViewConfigFileMap; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoDB.java new file mode 100644 index 0000000000..48a51713e2 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoDB.java @@ -0,0 +1,262 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import static edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat.N3; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.NodeIterator; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.vocabulary.RDF; + +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.ObjectPropertyStatementImpl; +import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; +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; + +/** + * An extension of {@link ObjectPropertyStatementDaoJena} for databases, such as TDB. + */ +public class ObjectPropertyStatementDaoDB extends ObjectPropertyStatementDaoJena implements ObjectPropertyStatementDao { + private static final Log LOG = LogFactory.getLog(ObjectPropertyStatementDaoDB.class); + + // Get the types of the base entity. + private static final String SUBJECT_TYPE_QUERY = + "PREFIX rdf: \n" + + "CONSTRUCT { \n" + + " ?uri rdf:type ?type . \n" + + "} WHERE { \n" + + " ?uri rdf:type ?type . \n" + + "} \n"; + + // Get the types of all objects of properties. + private static final String OBJECT_TYPE_QUERY = + "PREFIX rdf: \n" + + "CONSTRUCT { \n" + + " ?uri ?p ?o . \n" + + " ?o rdf:type ?type . \n" + + "} WHERE { \n" + + " ?uri ?p ?o . \n" + + " ?o rdf:type ?type . \n" + + "} \n"; + + // Get the labels of all objects of properties. + private static final String OBJECT_LABEL_QUERY = + "PREFIX rdfs: \n" + + "CONSTRUCT { \n" + + " ?uri ?p ?o . \n" + + " ?o rdfs:label ?label . \n" + + "} WHERE { \n" + + " ?uri ?p ?o . \n" + + " ?o rdfs:label ?label . \n" + + "} \n"; + + private final WebappDaoFactoryDB wadf; + private final DatasetMode mode; + + /** + * Initialize the object property statement DAO. + * + * @param rdfService The rdf service. + * @param dwf The data set wrapper. + * @param mode The data set mode. + * @param wadf The web application DAO factory. + */ + public ObjectPropertyStatementDaoDB(RDFService rdfService, DatasetWrapper dw, DatasetMode mode, + WebappDaoFactoryDB wadf) { + + super(rdfService, dw, wadf); + this.wadf = wadf; + this.mode = mode; + } + + /** + * Fill the existing object property statement for the given individual. + * + * @param entity The individual. + * + * @return The filled individual or null. + */ + public Individual fillExistingObjectPropertyStatements(Individual entity) { + if (entity == null || entity.getURI() == null) { + return entity; + } + + List objectPropertyStatements = new ArrayList<>(); + String subjectUri = entity.getURI(); + + Model m = getInfoForObjectsOfThisEntity(subjectUri); + + for (ObjectPropertyPair pair : getRawObjectPropertyPairs(m, + subjectUri)) { + String predicateUri = pair.getPredicateUri(); + String objectUri = pair.getObjectUri(); + + ObjectProperty prop = findRawProperty(predicateUri); + if (prop == null) { + continue; + } + + Individual object = new IndividualDB(objectUri, dw, mode, wadf, m); + objectPropertyStatements.add(createStatement(entity, prop, object)); + } + entity.setObjectPropertyStatements(objectPropertyStatements); + return entity; + } + + /** + * Get the information for objects of the given entity. + * + * Get the types of this entity. Get the related object and the predicates + * by which they are related. Get the types and labels of those related + * objects. + * + * @param subjectUri The URL representing the entity. + * + * @return The model representing the information for objects. + */ + private Model getInfoForObjectsOfThisEntity(String subjectUri) { + Model m = ModelFactory.createDefaultModel(); + + try { + m.add(RDFServiceUtils.parseModel(rdfService.sparqlConstructQuery( + substituteUri(subjectUri, SUBJECT_TYPE_QUERY), N3), N3)); + m.add(RDFServiceUtils.parseModel(rdfService.sparqlConstructQuery( + substituteUri(subjectUri, OBJECT_TYPE_QUERY), N3), N3)); + m.add(RDFServiceUtils.parseModel(rdfService.sparqlConstructQuery( + substituteUri(subjectUri, OBJECT_LABEL_QUERY), N3), N3)); + } catch (RDFServiceException e) { + LOG.warn("Failed to fill object property statements for '" + subjectUri + "'", e); + } + + return m; + } + + /** + * Substitute the "?uri" text with a given URI string in the query. + * + * @param uri The URI to replace with. + * @param query The query to be updated. + * + * @return The altered query. + */ + private String substituteUri(String uri, String query) { + return query.replace("?uri", "<" + uri + "> "); + } + + /** + * Get types for some model and URI. + * + * @param m The model. + * @param uri The URI. + * + * @return A set of types. + */ + private Set getTypes(Model m, String uri) { + Set typeUris = new HashSet<>(); + + NodeIterator iter = m.listObjectsOfProperty(m.createResource(uri), RDF.type); + for (RDFNode typeNode : iter.toSet()) { + if (typeNode.isURIResource()) { + typeUris.add(typeNode.asResource().getURI()); + } + } + + return typeUris; + } + + /** + * Get raw object property pairs. + * + * @param m The model. + * @param subjectUri The subject URI. + * + * @return An array of object property pairs. + */ + private List getRawObjectPropertyPairs(Model m, String subjectUri) { + List list = new ArrayList<>(); + + StmtIterator iter = m.listStatements(m.createResource(subjectUri), null, (RDFNode) null); + for (Statement stmt : iter.toList()) { + if (wadf.getNonuserNamespaces().contains(stmt.getPredicate().getNameSpace())) { + continue; + } + + if (!stmt.getObject().isURIResource()) { + continue; + } + + list.add(new ObjectPropertyPair(stmt.getPredicate().getURI(), + stmt.getObject().asResource().getURI())); + } + + return list; + } + + /** + * Find the raw property for some predicate URI. + * + * @param predicateUri The predicate URI. + * + * @return The raw object property. + */ + private ObjectProperty findRawProperty(String predicateURI) { + return wadf.getObjectPropertyDao().getObjectPropertyByURI(predicateURI); + } + + /** + * Create a statement from the given triple. + * + * @param entity The individual subject. + * @param prop The individual property. + * @param object The individual object (value). + * + * @return The object property statement. + */ + private ObjectPropertyStatement createStatement(Individual entity, ObjectProperty prop, + Individual object) { + + ObjectPropertyStatementImpl ops = new ObjectPropertyStatementImpl(); + ops.setSubject(entity); + ops.setProperty(prop); + ops.setObject(object); + return ops; + } + + /** + * Helper class for a predicate URI and an object pair URI. + */ + private static class ObjectPropertyPair { + private final String predicateURI; + private final String objectURI; + + public ObjectPropertyPair(String predicateUri, String objectUri) { + this.predicateURI = predicateUri; + this.objectURI = objectUri; + } + + public String getPredicateUri() { + return predicateURI; + } + + public String getObjectUri() { + return objectURI; + } + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index e54ec61a3d..d463e5e9c6 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -55,15 +55,15 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec private static final Log log = LogFactory.getLog(ObjectPropertyStatementDaoJena.class); - protected DatasetWrapperFactory dwf; + protected DatasetWrapper dw; protected RDFService rdfService; public ObjectPropertyStatementDaoJena(RDFService rdfService, - DatasetWrapperFactory dwf, + DatasetWrapper dw, WebappDaoFactoryJena wadf) { super(wadf); + this.dw = dw; this.rdfService = rdfService; - this.dwf = dwf; } @Override @@ -435,13 +435,11 @@ private Model constructModelForSelectQueries(String subjectUri, return constructedModel; } - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); + Dataset dataset = dw.getDataset(); dataset.getLock().enterCriticalSection(Lock.READ); QueryExecution qe = null; try { - qe = QueryExecutionFactory.create( - query, dataset); + qe = QueryExecutionFactory.create(query, dataset); qe.execConstruct(constructedModel); } catch (Exception e) { log.error("Error getting constructed model for subject " @@ -451,7 +449,7 @@ private Model constructModelForSelectQueries(String subjectUri, qe.close(); } dataset.getLock().leaveCriticalSection(); - w.close(); + dw.close(); } } else { rdfService.sparqlConstructQuery(queryString, constructedModel); @@ -507,8 +505,7 @@ public Map getMostSpecificTypesInClassgroupsForIndividual(String Map result = new LinkedHashMap(); Map> types = new LinkedHashMap>(); - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); + Dataset dataset = dw.getDataset(); dataset.getLock().enterCriticalSection(Lock.READ); QueryExecution qexec = null; try { @@ -552,7 +549,7 @@ public Map getMostSpecificTypesInClassgroupsForIndividual(String if (qexec != null) { qexec.close(); } - w.close(); + dw.close(); } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java deleted file mode 100644 index 905900a1a6..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java +++ /dev/null @@ -1,206 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import static edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat.N3; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.vocabulary.RDF; - -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.ObjectPropertyStatementImpl; -import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; -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; - -public class ObjectPropertyStatementDaoSDB extends - ObjectPropertyStatementDaoJena implements ObjectPropertyStatementDao { - private static final Log log = LogFactory - .getLog(ObjectPropertyStatementDaoSDB.class); - - // Get the types of the base entity. - private static final String SUBJECT_TYPE_QUERY = "" - + "PREFIX rdf: \n" - + "CONSTRUCT { \n" // - + " ?uri rdf:type ?type . \n" // - + "} WHERE { \n" // - + " ?uri rdf:type ?type . \n" // - + "} \n"; - - // Get the types of all objects of properties. - private static final String OBJECT_TYPE_QUERY = "" - + "PREFIX rdf: \n" - + "CONSTRUCT { \n" // - + " ?uri ?p ?o . \n" // - + " ?o rdf:type ?type . \n" // - + "} WHERE { \n" // - + " ?uri ?p ?o . \n" // - + " ?o rdf:type ?type . \n" // - + "} \n"; - - // Get the labels of all objects of properties. - private static final String OBJECT_LABEL_QUERY = "" - + "PREFIX rdfs: \n" - + "CONSTRUCT { \n" // - + " ?uri ?p ?o . \n" // - + " ?o rdfs:label ?label . \n" // - + "} WHERE { \n" // - + " ?uri ?p ?o . \n" // - + " ?o rdfs:label ?label . \n" // - + "} \n"; - - private final WebappDaoFactorySDB wadf; - private final SDBDatasetMode datasetMode; - - public ObjectPropertyStatementDaoSDB(RDFService rdfService, - DatasetWrapperFactory dwf, SDBDatasetMode datasetMode, - WebappDaoFactorySDB wadf) { - super(rdfService, dwf, wadf); - this.wadf = wadf; - this.datasetMode = datasetMode; - } - - @Override - public Individual fillExistingObjectPropertyStatements(Individual entity) { - if (entity == null || entity.getURI() == null) - return entity; - else { - List objectPropertyStatements = new ArrayList<>(); - String subjectUri = entity.getURI(); - - Model m = getInfoForObjectsOfThisEntity(subjectUri); - - Set subjectTypes = getTypes(m, subjectUri); - for (ObjectPropertyPair pair : getRawObjectPropertyPairs(m, - subjectUri)) { - String predicateUri = pair.getPredicateUri(); - String objectUri = pair.getObjectUri(); - Set objectTypes = getTypes(m, objectUri); - - ObjectProperty prop = findRawProperty(predicateUri); - if (prop == null) { - continue; - } - - Individual object = new IndividualSDB(objectUri, dwf, - datasetMode, wadf, m); - objectPropertyStatements.add(createStatement(entity, prop, - object)); - } - entity.setObjectPropertyStatements(objectPropertyStatements); - return entity; - } - } - - /** - * Get the types of this entity. Get the related object and the predicates - * by which they are related. Get the types and labels of those related - * objects. - */ - private Model getInfoForObjectsOfThisEntity(String subjectUri) { - Model m = ModelFactory.createDefaultModel(); - try { - m.add(RDFServiceUtils.parseModel( - rdfService.sparqlConstructQuery( - substituteUri(subjectUri, SUBJECT_TYPE_QUERY), N3), - N3)); - m.add(RDFServiceUtils.parseModel( - rdfService.sparqlConstructQuery( - substituteUri(subjectUri, OBJECT_TYPE_QUERY), N3), - N3)); - m.add(RDFServiceUtils.parseModel( - rdfService.sparqlConstructQuery( - substituteUri(subjectUri, OBJECT_LABEL_QUERY), N3), - N3)); - } catch (RDFServiceException e) { - log.warn("Failed to fill object property statements for '" - + subjectUri + "'", e); - } - return m; - } - - private String substituteUri(String uri, String query) { - return query.replace("?uri", "<" + uri + "> "); - } - - private Set getTypes(Model m, String uri) { - Set typeUris = new HashSet<>(); - for (RDFNode typeNode : m.listObjectsOfProperty(m.createResource(uri), - RDF.type).toSet()) { - if (typeNode.isURIResource()) { - typeUris.add(typeNode.asResource().getURI()); - } - } - return typeUris; - } - - private List getRawObjectPropertyPairs(Model m, - String subjectUri) { - List list = new ArrayList<>(); - for (Statement stmt : m.listStatements(m.createResource(subjectUri), - null, (RDFNode) null).toList()) { - if (wadf.getNonuserNamespaces().contains( - stmt.getPredicate().getNameSpace())) { - continue; - } - if (!stmt.getObject().isURIResource()) { - continue; - } - list.add(new ObjectPropertyPair(stmt.getPredicate().getURI(), stmt - .getObject().asResource().getURI())); - } - return list; - } - - private ObjectProperty findRawProperty(String predicateUri) { - return wadf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri); - } - - private ObjectPropertyStatement createStatement(Individual entity, - ObjectProperty prop, Individual object) { - ObjectPropertyStatementImpl ops = new ObjectPropertyStatementImpl(); - ops.setSubject(entity); - ops.setProperty(prop); - ops.setObject(object); - return ops; - } - - // ---------------------------------------------------------------------- - // Helper classes - // ---------------------------------------------------------------------- - - private static class ObjectPropertyPair { - private final String predicateUri; - private final String objectUri; - - public ObjectPropertyPair(String predicateUri, String objectUri) { - this.predicateUri = predicateUri; - this.objectUri = objectUri; - } - - public String getPredicateUri() { - return predicateUri; - } - - public String getObjectUri() { - return objectUri; - } - - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index 8f3b1de99e..453dd7a0ce 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -73,14 +73,14 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } protected RDFService rdfService; - protected DatasetWrapperFactory dwf; + protected DatasetWrapper dw; public PropertyDaoJena(RDFService rdfService, - DatasetWrapperFactory dwf, + DatasetWrapper dw, WebappDaoFactoryJena wadf) { super(wadf); + this.dw = dw; this.rdfService = rdfService; - this.dwf = dwf; } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java index 4d10b9aad1..2d86d6766d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java @@ -33,9 +33,9 @@ public class PropertyInstanceDaoJena extends PropertyDaoJena implements PropertyInstanceDao { public PropertyInstanceDaoJena(RDFService rdfService, - DatasetWrapperFactory dwf, + DatasetWrapper dw, WebappDaoFactoryJena wadf) { - super(rdfService, dwf, wadf); + super(rdfService, dw, wadf); } public void deleteObjectPropertyStatement(String subjectURI, String propertyURI, String objectURI) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java deleted file mode 100644 index 0e2b010ee5..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class SDBGraphConnectionGenerator { - - private final static Log log = LogFactory.getLog( - SDBGraphConnectionGenerator.class); - - private DataSource ds = null; - private Connection connection = null; - - public SDBGraphConnectionGenerator(DataSource dataSource) { - this.ds = dataSource; - } - - public Connection generateConnection() throws SQLException { - if ( this.connection == null ) { - this.connection = ds.getConnection(); - } else if ( this.connection.isClosed() ) { - try { - this.connection.close(); - } catch (SQLException e) { - // The connection will throw an "Already closed" - // SQLException that we need to catch. We need to - // make this extra call to .close() in order to make - // sure that the connection is returned to the pool. - // This depends on the particular behavior of version - // 1.4 of the Apache Commons connection pool library. - // Earlier versions threw the exception right away, - // making this impossible. Future versions may do the - // same. - } - this.connection = ds.getConnection(); - } - return connection; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java deleted file mode 100644 index 23042ccf32..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java +++ /dev/null @@ -1,65 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.graph.Graph; -import org.apache.jena.sdb.SDBFactory; -import org.apache.jena.sdb.Store; -import org.apache.jena.sdb.StoreDesc; - -public class SDBGraphGenerator implements SQLGraphGenerator { - - private static final Log log = LogFactory.getLog(SDBGraphGenerator.class.getName()); - - private SDBGraphConnectionGenerator connGen; - private Connection connection; - private StoreDesc storeDesc; - private String graphID; - - public SDBGraphGenerator(DataSource dataSource, StoreDesc storeDesc, - String graphID) { - this.connGen = new SDBGraphConnectionGenerator(dataSource); - this.storeDesc = storeDesc; - this.graphID = graphID; - } - - public SDBGraphGenerator(SDBGraphConnectionGenerator connectionGenerator, - StoreDesc storeDesc, String graphID) { - this.connGen = connectionGenerator; - this.storeDesc = storeDesc; - this.graphID = graphID; - } - - public boolean isGraphClosed() { - try { - return (connection == null || connection.isClosed()); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public Graph generateGraph() { - try { - this.connection = connGen.generateConnection(); - Store store = SDBFactory.connectStore(connection, storeDesc); - return SDBFactory.connectNamedGraph(store, graphID); - } catch (SQLException e) { - String errMsg = "Unable to generate SDB graph"; - log.error(errMsg, e); - throw new RuntimeException(errMsg, e); - } - } - - public Connection getConnection() { - return connection; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/StaticDatasetFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/StaticDatasetFactory.java deleted file mode 100644 index 4f8ff6747b..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/StaticDatasetFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import org.apache.jena.query.Dataset; - -public class StaticDatasetFactory implements DatasetWrapperFactory { - - private Dataset _dataset; - - public StaticDatasetFactory (Dataset dataset) { - _dataset = dataset; - } - - public DatasetWrapper getDatasetWrapper() { - return new DatasetWrapper(_dataset); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoDB.java new file mode 100644 index 0000000000..87d8cd3ce7 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoDB.java @@ -0,0 +1,187 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import org.apache.jena.query.Dataset; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.ResultSet; +import org.apache.jena.query.Syntax; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.shared.Lock; +import org.apache.jena.vocabulary.RDF; + +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import java.util.Collections; + +/** + * An extension of {@link VClassDaoJena} for databases, such as TDB. + */ +public class VClassDaoDB extends VClassDaoJena { + + private DatasetWrapper dw; + private DatasetMode mode; + + /** + * Initialize VClass DAO. + * + * @param dw The data wrapper. + * @param mode The data set mode. + * @param wadf The web application DAO factory. + * @param isUnderlyingStoreReasoned True if is underlying store reasoned and false otherwise. + */ + public VClassDaoDB(DatasetWrapper dw, DatasetMode mode, WebappDaoFactoryJena wadf, + boolean isUnderlyingStoreReasoned) { + + super(wadf, isUnderlyingStoreReasoned); + this.dw = dw; + this.mode = mode; + } + + /** + * Get the data set wrapper. + * + * @return The data set wrapper. + */ + protected DatasetWrapper getDatasetWrapper() { + return dw; + } + + /** + * Add VClasses to the given group. + * + * @param group the VClass group. + * @param includeUninstantiatedClasses True to include and false otherwise. + * @param getIndividualCount True to get the count and false otherwise. + * + * @deprecated + */ + @Deprecated + public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses, boolean getIndividualCount) { + + if (getIndividualCount) { + group.setIndividualCount( getClassGroupInstanceCount(group)); + } + + getOntModel().enterCriticalSection(Lock.READ); + try { + if ((group != null) && (group.getURI() != null)) { + Resource groupRes = ResourceFactory.createResource(group.getURI()); + Property inClassGroup = ResourceFactory.createProperty(VitroVocabulary.IN_CLASSGROUP); + if (inClassGroup != null) { + StmtIterator annotIt = getOntModel().listStatements((Resource)null,inClassGroup, groupRes); + try { + while (annotIt.hasNext()) { + try { + Statement annot = (Statement) annotIt.next(); + Resource cls = annot.getSubject(); + VClass vcw = getVClassByURI(cls.getURI()); + if (vcw != null) { + boolean classIsInstantiated = false; + if (getIndividualCount) { + int count = 0; + String[] graphVars = { "?g" }; + String countQueryStr = "SELECT COUNT(DISTINCT ?s) WHERE \n" + + "{ GRAPH ?g { ?s a <" + cls.getURI() + "> } \n" + + WebappDaoFactoryDB.getFilterBlock(graphVars, mode) + + "} \n"; + Query countQuery = QueryFactory.create(countQueryStr, Syntax.syntaxARQ); + DatasetWrapper w = getDatasetWrapper(); + Dataset dataset = w.getDataset(); + dataset.getLock().enterCriticalSection(Lock.READ); + try { + QueryExecution qe = QueryExecutionFactory.create(countQuery, dataset); + ResultSet rs = qe.execSelect(); + count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); + } finally { + dataset.getLock().leaveCriticalSection(); + w.close(); + } + vcw.setEntityCount(count); + classIsInstantiated = (count > 0); + } else if (!includeUninstantiatedClasses) { + // Note: to support SDB models, may want to do this with + // SPARQL and LIMIT 1 if SDB can take advantage of it + Model aboxModel = getOntModelSelector().getABoxModel(); + aboxModel.enterCriticalSection(Lock.READ); + try { + StmtIterator countIt = aboxModel.listStatements(null,RDF.type,cls); + try { + if (countIt.hasNext()) { + classIsInstantiated = true; + } + } finally { + countIt.close(); + } + } finally { + aboxModel.leaveCriticalSection(); + } + } + + if (includeUninstantiatedClasses || classIsInstantiated) { + group.add(vcw); + } + } + } catch (ClassCastException cce) { + LOG.error(cce, cce); + } + } + } finally { + annotIt.close(); + } + } + } + Collections.sort(group.getVitroClassList()); + } finally { + getOntModel().leaveCriticalSection(); + } + } + + /** + * Get the VClass group instance count + * + * @param vcg the VClass group. + * + * @return The total number of VClass group instances. + */ + int getClassGroupInstanceCount(VClassGroup vcg){ + int count = 0; + + try { + String queryText = + "SELECT COUNT( DISTINCT ?instance ) WHERE { \n" + + " ?class <" + VitroVocabulary.IN_CLASSGROUP + "> <" + vcg.getURI() + "> .\n" + + " ?instance a ?class . \n" + + "} \n" ; + + Query countQuery = QueryFactory.create(queryText, Syntax.syntaxARQ); + DatasetWrapper dw = getDatasetWrapper(); + Dataset dataset = dw.getDataset(); + + dataset.getLock().enterCriticalSection(Lock.READ); + try { + QueryExecution qe = QueryExecutionFactory.create(countQuery, dataset); + ResultSet rs = qe.execSelect(); + count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); + } finally { + dataset.getLock().leaveCriticalSection(); + dw.close(); + } + } catch (Exception e) { + LOG.error("error in getClassGroupInstanceCount()", e); + } + + return count; + } + +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index 20b207d019..8c69714ced 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -67,7 +67,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { - protected static final Log log = LogFactory.getLog(VClassDaoJena.class); + protected static final Log LOG = LogFactory.getLog(VClassDaoJena.class); private final I18nBundle i18n; private boolean isUnderlyingStoreReasoned = false; @@ -200,7 +200,7 @@ public String getLabelForClass(OntClass cls,boolean withPrefix,boolean forPickLi return getLabelOrId(cls); } } catch (Exception e) { - log.error(e, e); + LOG.error(e, e); return "???"; } finally { cls.getModel().leaveCriticalSection(); @@ -264,7 +264,7 @@ public List getDisjointWithClassURIs(String classURI) { } catch (ProfileException pe) { // Current language profile does not support disjointWith axioms. // We'd prefer to return an empty list instead of throwing an exception. - log.error(pe, pe); + LOG.error(pe, pe); } finally { getOntModel().leaveCriticalSection(); } @@ -480,7 +480,7 @@ public List getAllVclasses() { } } } catch (ClassCastException cce) { - log.error(cce, cce); + LOG.error(cce, cce); } } } finally { @@ -532,7 +532,7 @@ private Iterator smarterListHierarchyRootClasses(OntModel ontModel, St rootClassList.add(ontClass.as(OntClass.class)); } } catch (ClassCastException cce) { - log.error(cce, cce); + LOG.error(cce, cce); } } } finally { @@ -639,7 +639,7 @@ public List getSuperClassURIs(String classURI, boolean direct) { supURIs.add(getClassURIStr(cls)); } } catch (Exception e) { - log.debug(e,e); + LOG.debug(e,e); // we'll try this again using a different method // that doesn't try to convert to OntClass supURIs.clear(); @@ -857,8 +857,6 @@ public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedC vcw.setEntityCount(count); classIsInstantiated = (count > 0); } else if (!includeUninstantiatedClasses) { - // Note: to support SDB models, may want to do this with - // SPARQL and LIMIT 1 if SDB can take advantage of it Model aboxModel = getOntModelSelector().getABoxModel(); aboxModel.enterCriticalSection(Lock.READ); try { @@ -880,7 +878,7 @@ public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedC } } } catch (ClassCastException cce) { - log.error(cce, cce); + LOG.error(cce, cce); } } } finally { @@ -909,7 +907,7 @@ int getClassGroupInstanceCount(VClassGroup vcg){ ResultSet rs =qe.execSelect(); count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); }catch(Exception ex){ - log.error(ex,ex); + LOG.error(ex,ex); } finally { ontModel.leaveCriticalSection(); } @@ -946,7 +944,7 @@ public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException ontCls.removeAll(RDFS.label); } } catch (Exception e) { - log.error("error setting label for class "+cls.getURI()); + LOG.error("error setting label for class "+cls.getURI()); } try { if (cls.getGroupURI() != null && cls.getGroupURI().length()>0) { @@ -954,11 +952,11 @@ public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException if (badURIErrorStr == null) { ontCls.addProperty(IN_CLASSGROUP, getOntModel().getResource(cls.getGroupURI())); } else { - log.error(badURIErrorStr); + LOG.error(badURIErrorStr); } } } catch (Exception e) { - log.error("error linking class "+cls.getURI()+" to class group"); + LOG.error("error linking class "+cls.getURI()+" to class group"); } updatePlainLiteralValue(ontCls, SHORTDEF, cls.getShortDef()); updatePlainLiteralValue(ontCls, EXAMPLE_ANNOT, cls.getExample()); @@ -971,7 +969,7 @@ public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException try { ontCls.addProperty(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getHiddenFromDisplayBelowRoleLevel().getURI())); } catch (Exception e) { - log.error("error adding HiddenFromDisplayBelowRoleLevel annotation to class "+cls.getURI()); + LOG.error("error adding HiddenFromDisplayBelowRoleLevel annotation to class "+cls.getURI()); } } @@ -980,7 +978,7 @@ public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException try { ontCls.addProperty(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getProhibitedFromUpdateBelowRoleLevel().getURI())); } catch (Exception e) { - log.error("error adding ProhibitedFromUpdateBelowRoleLevel annotation to class "+cls.getURI()); + LOG.error("error adding ProhibitedFromUpdateBelowRoleLevel annotation to class "+cls.getURI()); } } @@ -989,7 +987,7 @@ public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException try { ontCls.addProperty(HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getHiddenFromPublishBelowRoleLevel().getURI())); } catch (Exception e) { - log.error("error adding HiddenFromPublishBelowRoleLevel annotation to class "+cls.getURI()); + LOG.error("error adding HiddenFromPublishBelowRoleLevel annotation to class "+cls.getURI()); } } @@ -1043,7 +1041,7 @@ public void updateVClass(VClass cls, OntModel ontModel) { updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel); updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSEARCHVIEWANNOT,cls.getCustomSearchView(),ontModel); } else { - log.error("error: cannot find jena class "+cls.getURI()+" for updating"); + LOG.error("error: cannot find jena class "+cls.getURI()+" for updating"); } } finally { getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); @@ -1063,13 +1061,13 @@ public void deleteClasses2Classes( Classes2Classes c2c, OntModel ontModel ) OntResource subclass = getOntClass(ontModel,c2c.getSubclassURI()); OntResource superclass = getOntClass(ontModel,c2c.getSuperclassURI()); if(subclass == null || superclass == null) { - log.warn("unable to delete " + c2c.getSubclassURI() + + LOG.warn("unable to delete " + c2c.getSubclassURI() + " rdfs:subClassOf " + c2c.getSuperclassURI()); if (subclass == null) { - log.warn(c2c.getSubclassURI() + " not found in the model."); + LOG.warn(c2c.getSubclassURI() + " not found in the model."); } if (superclass == null) { - log.warn(c2c.getSuperclassURI() + " not found in the model."); + LOG.warn(c2c.getSuperclassURI() + " not found in the model."); } return; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java deleted file mode 100644 index cc6e7bea7f..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java +++ /dev/null @@ -1,162 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - - -import org.apache.jena.query.Dataset; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.ResultSet; -import org.apache.jena.query.Syntax; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.Property; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.ResourceFactory; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.shared.Lock; -import org.apache.jena.vocabulary.RDF; - -import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; - -public class VClassDaoSDB extends VClassDaoJena { - - private DatasetWrapperFactory dwf; - private SDBDatasetMode datasetMode; - - public VClassDaoSDB(DatasetWrapperFactory datasetWrapperFactory, - SDBDatasetMode datasetMode, - WebappDaoFactoryJena wadf, boolean isUnderlyingStoreReasoned) { - super(wadf, isUnderlyingStoreReasoned); - this.dwf = datasetWrapperFactory; - this.datasetMode = datasetMode; - } - - protected DatasetWrapper getDatasetWrapper() { - return dwf.getDatasetWrapper(); - } - - @Deprecated - public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses, boolean getIndividualCount) { - - if (getIndividualCount) { - group.setIndividualCount( getClassGroupInstanceCount(group)); - } - - getOntModel().enterCriticalSection(Lock.READ); - try { - if ((group != null) && (group.getURI() != null)) { - Resource groupRes = ResourceFactory.createResource(group.getURI()); - Property inClassGroup = ResourceFactory.createProperty(VitroVocabulary.IN_CLASSGROUP); - if (inClassGroup != null) { - StmtIterator annotIt = getOntModel().listStatements((Resource)null,inClassGroup, groupRes); - try { - while (annotIt.hasNext()) { - try { - Statement annot = (Statement) annotIt.next(); - Resource cls = annot.getSubject(); - VClass vcw = getVClassByURI(cls.getURI()); - if (vcw != null) { - boolean classIsInstantiated = false; - if (getIndividualCount) { - int count = 0; - String[] graphVars = { "?g" }; - String countQueryStr = "SELECT COUNT(DISTINCT ?s) WHERE \n" + - "{ GRAPH ?g { ?s a <" + cls.getURI() + "> } \n" + - WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) + - "} \n"; - Query countQuery = QueryFactory.create(countQueryStr, Syntax.syntaxARQ); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - QueryExecution qe = QueryExecutionFactory.create(countQuery, dataset); - ResultSet rs = qe.execSelect(); - count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - vcw.setEntityCount(count); - classIsInstantiated = (count > 0); - } else if (!includeUninstantiatedClasses) { - // Note: to support SDB models, may want to do this with - // SPARQL and LIMIT 1 if SDB can take advantage of it - Model aboxModel = getOntModelSelector().getABoxModel(); - aboxModel.enterCriticalSection(Lock.READ); - try { - StmtIterator countIt = aboxModel.listStatements(null,RDF.type,cls); - try { - if (countIt.hasNext()) { - classIsInstantiated = true; - } - } finally { - countIt.close(); - } - } finally { - aboxModel.leaveCriticalSection(); - } - } - - if (includeUninstantiatedClasses || classIsInstantiated) { - group.add(vcw); - } - } - } catch (ClassCastException cce) { - log.error(cce, cce); - } - } - } finally { - annotIt.close(); - } - } - } - java.util.Collections.sort(group.getVitroClassList()); - } finally { - getOntModel().leaveCriticalSection(); - } - } - -// protected void addIndividualCountToGroups( List cgList ){ -// for( VClassGroup cg : cgList){ -// cg.setIndividualCount(getClassGroupInstanceCount(cg)); -// } -// } - - @Override - int getClassGroupInstanceCount(VClassGroup vcg){ - int count = 0; - try { - String queryText = - "SELECT COUNT( DISTINCT ?instance ) WHERE { \n" + - " ?class <"+VitroVocabulary.IN_CLASSGROUP+"> <"+vcg.getURI() +"> .\n" + - " ?instance a ?class . \n" + - "} \n" ; - - Query countQuery = QueryFactory.create(queryText, Syntax.syntaxARQ); - DatasetWrapper w = getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - try { - QueryExecution qe = QueryExecutionFactory.create(countQuery, dataset); - ResultSet rs = qe.execSelect(); - count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); - } finally { - dataset.getLock().leaveCriticalSection(); - w.close(); - } - }catch(Exception ex){ - log.error("error in getClassGroupInstanceCount()", ex); - } - - return count; - } - - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryDB.java new file mode 100644 index 0000000000..308919f31b --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryDB.java @@ -0,0 +1,231 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/** + * An extension of {@link WebappDaoFactoryJena} for databases, such as TDB. + */ +public class WebappDaoFactoryDB extends WebappDaoFactoryJena { + + private DatasetMode mode; + + /** + * Initializer for web application DAO factory. + * + * @param base The web application DAO factory. + * @param userURI The URI for the user. + */ + public WebappDaoFactoryDB(WebappDaoFactoryDB base, String userURI) { + super(base.ontModelSelector); + + this.ontModelSelector = base.ontModelSelector; + this.config = base.config; + this.userURI = userURI; + this.dw = base.dw; + this.rdfService = base.rdfService; + this.mode = DatasetMode.ASSERTIONS_AND_INFERENCES; + } + + /** + * Initializer for web application DAO factory. + * + * @param rdfService The RDF service. + * @param ontModelSelector The ontology model selector. + */ + public WebappDaoFactoryDB(RDFService rdfService, OntModelSelector ontModelSelector) { + this(rdfService, ontModelSelector, new WebappDaoFactoryConfig()); + } + + /** + * Initializer for web application DAO factory. + * + * @param rdfService The RDF service. + * @param ontModelSelector The ontology model selector. + * @param config The configuration. + */ + public WebappDaoFactoryDB(RDFService rdfService, OntModelSelector ontModelSelector, + WebappDaoFactoryConfig config) { + + this(rdfService, ontModelSelector, config, null); + } + + /** + * Initializer for web application DAO factory. + * + * @param rdfService The RDF service. + * @param ontModelSelector The ontology model selector. + * @param config The configuration. + * @param mode The data set mode. + */ + public WebappDaoFactoryDB(RDFService rdfService, OntModelSelector ontModelSelector, + WebappDaoFactoryConfig config, DatasetMode mode) { + + super(ontModelSelector, config); + + this.dw = new DatasetWrapper(new RDFServiceDataset(rdfService)); + this.rdfService = rdfService; + + if (mode == null) { + this.mode = DatasetMode.ASSERTIONS_AND_INFERENCES; + } else { + this.mode = mode; + } + } + + /** + * Convert class to a named string. + * + * @return The named string with a hash and notable properties. + */ + public String toString() { + return "WebappDaoFactoryDB[" + Integer.toString(hashCode(), 16) + ", " + mode + "]"; + } + + /** + * Get the individual DAO. + * + * @return The individual DAO. + */ + public IndividualDao getIndividualDao() { + if (entityWebappDao != null) { + return entityWebappDao; + } + + return entityWebappDao = new IndividualDaoDB(dw, mode, this); + } + + /** + * Get the data property statement DAO for databases, such as TDB. + * + * @return The data property statement DAO. + */ + public DataPropertyStatementDaoDB getDataPropertyStatementDao() { + if (!hasDataPropertyStatementDao()) { + setDataPropertyStatementDao(new DataPropertyStatementDaoDB(dw, this)); + } + + return (DataPropertyStatementDaoDB) super.getDataPropertyStatementDao(); + } + + /** + * Set the data property statement DAO for databases, such as TDB. + * + * @param propertyStatement The data property statement DAO. + */ + protected void setDataPropertyStatementDao(DataPropertyStatementDaoDB propertyStatement) { + super.setDataPropertyStatementDao(propertyStatement); + } + + /** + * Get the object property statement DAO for databases, such as TDB. + * + * @return The object property statement DAO. + */ + public ObjectPropertyStatementDaoDB getObjectPropertyStatementDao() { + if (!hasObjectPropertyStatementDao()) { + setObjectPropertyStatementDao( + new ObjectPropertyStatementDaoDB(rdfService, dw, mode, this)); + } + + return (ObjectPropertyStatementDaoDB) super.getObjectPropertyStatementDao(); + } + + /** + * Set the data property statement DAO for databases, such as TDB. + * + * @param propertyStatement The data property statement DAO. + */ + protected void setObjectPropertyStatementDao(ObjectPropertyStatementDaoDB propertyStatement) { + super.setObjectPropertyStatementDao(propertyStatement); + } + + /** + * Get the VClass DAO. + * + * @return The VClass DAO. + */ + public VClassDao getVClassDao() { + if (vClassDao != null) { + return vClassDao; + } + + return vClassDao = new VClassDaoDB(dw, mode, this, config.isUnderlyingStoreReasoned()); + } + + /** + * Get the user aware DAO factory. + * + * @param userURI The URI of the user. + * + * @return The user aware DAO factory. + */ + public WebappDaoFactoryDB getUserAwareDaoFactory(String userURI) { + return new WebappDaoFactoryDB(this, userURI); + } + + /** + * Get the RDF Service. + * + * @return The RDF service. + */ + public RDFService getRDFService() { + return this.rdfService; + } + + public static String getFilterBlock(String[] graphVars, DatasetMode datasetMode) { + StringBuilder filterBlock = new StringBuilder(); + + for (String graphVar : graphVars) { + switch (datasetMode) { + case ASSERTIONS_ONLY: + filterBlock.append("FILTER (") + .append("(!bound(").append(graphVar) + .append(")) || (") + .append(graphVar) + .append(" != <") + .append(ModelNames.ABOX_INFERENCES) + .append("> ") + .append("&& ").append(graphVar).append(" != <") + .append(ModelNames.TBOX_INFERENCES) + .append(">") + .append(") ) \n"); + break; + + case INFERENCES_ONLY: + filterBlock.append("FILTER (") + .append("(!bound(").append(graphVar) + .append(")) || (") + .append(graphVar) + .append(" = <") + .append(ModelNames.ABOX_INFERENCES) + .append("> || ").append(graphVar) + .append(" = <") + .append(ModelNames.TBOX_INFERENCES) + .append(">) )\n"); + break; + default: + break; + } + } + + return filterBlock.toString(); + } + + /** + * Close the DAO and the RDF service. + */ + public void close() { + super.close(); + + if (this.rdfService != null) { + this.rdfService.close(); + } + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index 813cf27ad1..d744f4e24a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -78,7 +78,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { private Map properties = new HashMap(); - protected DatasetWrapperFactory dwf; + protected DatasetWrapper dw; protected RDFService rdfService; @@ -88,7 +88,7 @@ public WebappDaoFactoryJena(WebappDaoFactoryJena base, String userURI) { this.ontModelSelector = base.ontModelSelector; this.config = base.config; this.userURI = userURI; - this.dwf = base.dwf; + this.dw = base.dw; } public WebappDaoFactoryJena(OntModelSelector ontModelSelector, @@ -109,7 +109,7 @@ public WebappDaoFactoryJena(OntModelSelector ontModelSelector, : null; Dataset dataset = makeInMemoryDataset(assertions, inferences); - this.dwf = new StaticDatasetFactory(dataset); + dw = new DatasetWrapper(dataset); this.rdfService = new RDFServiceModel(ontModelSelector.getFullModel()); @@ -331,15 +331,33 @@ public UserAccountsDao getUserAccountsDao() { return userAccountsDao = new UserAccountsDaoJena(this); } - DataPropertyStatementDao dataPropertyStatementDao = null; + private DataPropertyStatementDao dataPropertyStatementDao = null; @Override public DataPropertyStatementDao getDataPropertyStatementDao() { - if( dataPropertyStatementDao == null ) - dataPropertyStatementDao = new DataPropertyStatementDaoJena( - dwf, this); + if (!hasDataPropertyStatementDao()) { + setDataPropertyStatementDao(new DataPropertyStatementDaoJena(dw, this)); + } return dataPropertyStatementDao; } + /** + * Set the data property statement DAO. + * + * @param propertyStatement The data property statement DAO. + */ + protected void setDataPropertyStatementDao(DataPropertyStatementDao propertyStatement) { + this.dataPropertyStatementDao = propertyStatement; + } + + /** + * Check if the data property statement DAO is defined. + * + * @return True if defined, false if null. + */ + protected boolean hasDataPropertyStatementDao() { + return dataPropertyStatementDao != null; + } + DatatypeDao datatypeDao = null; @Override public DatatypeDao getDatatypeDao() { @@ -352,7 +370,7 @@ public DatatypeDao getDatatypeDao() { @Override public DataPropertyDao getDataPropertyDao() { if( dataPropertyDao == null ) - dataPropertyDao = new DataPropertyDaoJena(rdfService, dwf, this); + dataPropertyDao = new DataPropertyDaoJena(rdfService, dw, this); return dataPropertyDao; } @@ -365,13 +383,31 @@ public IndividualDao getEntityDao() { ObjectPropertyStatementDao objectPropertyStatementDao = null; @Override - public ObjectPropertyStatementDao getObjectPropertyStatementDao() { - if( objectPropertyStatementDao == null ) - objectPropertyStatementDao = new ObjectPropertyStatementDaoJena( - rdfService, dwf, this); + public ObjectPropertyStatementDao getObjectPropertyStatementDao() { + if (!hasObjectPropertyStatementDao()) { + setObjectPropertyStatementDao(new ObjectPropertyStatementDaoJena(rdfService, dw, this)); + } return objectPropertyStatementDao; } + /** + * Set the object property statement DAO. + * + * @param propertyStatement The object property statement DAO. + */ + protected void setObjectPropertyStatementDao(ObjectPropertyStatementDao propertyStatement) { + this.objectPropertyStatementDao = propertyStatement; + } + + /** + * Check if the object property statement DAO is defined. + * + * @return True if defined, false if null. + */ + protected boolean hasObjectPropertyStatementDao() { + return objectPropertyStatementDao != null; + } + private OntologyDao ontologyDao = null; @Override public OntologyDao getOntologyDao() { @@ -385,7 +421,7 @@ public OntologyDao getOntologyDao() { public ObjectPropertyDao getObjectPropertyDao() { if( objectPropertyDao == null ) objectPropertyDao = new ObjectPropertyDaoJena( - rdfService, dwf, config.customListViewConfigFileMap, this); + rdfService, dw, config.customListViewConfigFileMap, this); return objectPropertyDao; } @@ -402,7 +438,7 @@ public FauxPropertyDao getFauxPropertyDao() { @Override public PropertyInstanceDao getPropertyInstanceDao() { if( propertyInstanceDao == null ) - propertyInstanceDao = new PropertyInstanceDaoJena(rdfService, dwf, this); + propertyInstanceDao = new PropertyInstanceDaoJena(rdfService, dw, this); return propertyInstanceDao; } @@ -484,7 +520,7 @@ public WebappDaoFactoryJena (WebappDaoFactoryJena base) { } this.config = base.config; this.userURI = base.userURI; - this.dwf = base.dwf; + this.dw = base.dw; } /** diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java deleted file mode 100644 index 7a140f2c3d..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java +++ /dev/null @@ -1,186 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import java.sql.Connection; -import java.sql.SQLException; - -import org.apache.commons.dbcp2.BasicDataSource; - -import org.apache.jena.query.Dataset; -import org.apache.jena.sdb.SDBFactory; -import org.apache.jena.sdb.Store; -import org.apache.jena.sdb.StoreDesc; -import org.apache.jena.sdb.sql.SDBConnection; - -import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; -import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; - -public class WebappDaoFactorySDB extends WebappDaoFactoryJena { - - private SDBDatasetMode datasetMode = SDBDatasetMode.ASSERTIONS_AND_INFERENCES; - - public WebappDaoFactorySDB(RDFService rdfService, - OntModelSelector ontModelSelector) { - this(rdfService, ontModelSelector, new WebappDaoFactoryConfig()); - } - - public WebappDaoFactorySDB(RDFService rdfService, - OntModelSelector ontModelSelector, - WebappDaoFactoryConfig config) { - this(rdfService, ontModelSelector, config, null); - } - - public WebappDaoFactorySDB(RDFService rdfService, - OntModelSelector ontModelSelector, - WebappDaoFactoryConfig config, - SDBDatasetMode datasetMode) { - super(ontModelSelector, config); - this.dwf = new StaticDatasetFactory(new RDFServiceDataset(rdfService)); - this.rdfService = rdfService; - if (datasetMode != null) { - this.datasetMode = datasetMode; - } - } - - @Override - public String toString() { - return "WebappDaoFactorySDB[" + Integer.toString(hashCode(), 16) + ", " - + datasetMode + "]"; - } - - public WebappDaoFactorySDB(WebappDaoFactorySDB base, String userURI) { - super(base.ontModelSelector); - this.ontModelSelector = base.ontModelSelector; - this.config = base.config; - this.userURI = userURI; - this.dwf = base.dwf; - this.rdfService = base.rdfService; - } - - @Override - public IndividualDao getIndividualDao() { - if (entityWebappDao != null) - return entityWebappDao; - else - return entityWebappDao = new IndividualDaoSDB( - dwf, datasetMode, this); - } - - @Override - public DataPropertyStatementDao getDataPropertyStatementDao() { - if (dataPropertyStatementDao != null) - return dataPropertyStatementDao; - else - return dataPropertyStatementDao = new DataPropertyStatementDaoSDB( - dwf, datasetMode, this); - } - - @Override - public ObjectPropertyStatementDao getObjectPropertyStatementDao() { - if (objectPropertyStatementDao != null) - return objectPropertyStatementDao; - else - return objectPropertyStatementDao = - new ObjectPropertyStatementDaoSDB(rdfService, dwf, datasetMode, this); - } - - @Override - public VClassDao getVClassDao() { - if (vClassDao != null) - return vClassDao; - else - return vClassDao = new VClassDaoSDB(dwf, datasetMode, this, config.isUnderlyingStoreReasoned()); - } - - @Override - public WebappDaoFactory getUserAwareDaoFactory(String userURI) { - return new WebappDaoFactorySDB(this, userURI); - } - - public RDFService getRDFService() { - return this.rdfService; - } - - public enum SDBDatasetMode { - ASSERTIONS_ONLY, INFERENCES_ONLY, ASSERTIONS_AND_INFERENCES - } - - public static String getFilterBlock(String[] graphVars, - SDBDatasetMode datasetMode) { - StringBuilder filterBlock = new StringBuilder(); - for (String graphVar : graphVars) { - switch (datasetMode) { - case ASSERTIONS_ONLY: - filterBlock.append("FILTER (") - .append("(!bound(").append(graphVar) - .append(")) || (") - .append(graphVar) - .append(" != <") - .append(ModelNames.ABOX_INFERENCES) - .append("> ") - .append("&& ").append(graphVar).append(" != <") - .append(ModelNames.TBOX_INFERENCES) - .append(">") - .append(") ) \n"); - break; - case INFERENCES_ONLY: - filterBlock.append("FILTER (") - .append("(!bound(").append(graphVar) - .append(")) || (") - .append(graphVar) - .append(" = <") - .append(ModelNames.ABOX_INFERENCES) - .append("> || ").append(graphVar) - .append(" = <") - .append(ModelNames.TBOX_INFERENCES) - .append(">) )\n"); - break; - default: - break; - } - } - return filterBlock.toString(); - } - - @Override - public void close() { - super.close(); - if (this.rdfService != null) { - this.rdfService.close(); - } - } - - private class ReconnectingDatasetFactory implements DatasetWrapperFactory { - - private BasicDataSource _bds; - private StoreDesc _storeDesc; - - public ReconnectingDatasetFactory(BasicDataSource bds, - StoreDesc storeDesc) { - _bds = bds; - _storeDesc = storeDesc; - } - - public DatasetWrapper getDatasetWrapper() { - try { - Connection sqlConn = _bds.getConnection(); - SDBConnection conn = new SDBConnection(sqlConn) ; - Store store = SDBFactory.connectStore(conn, _storeDesc); - Dataset dataset = SDBFactory.connectDataset(store); - return new DatasetWrapper(dataset, conn); - } catch (SQLException sqe) { - throw new RuntimeException( - "Unable to connect to database", sqe); - } - } - - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/exception/IndividualNotFoundException.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/exception/IndividualNotFoundException.java new file mode 100644 index 0000000000..4928b57e9a --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/exception/IndividualNotFoundException.java @@ -0,0 +1,10 @@ +package edu.cornell.mannlib.vitro.webapp.dao.jena.exception; + +/** + * A generic not found exception for an Individual. + */ +public class IndividualNotFoundException extends Exception { + + private static final long serialVersionUID = 1L; + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java index 320c6c236a..273e046526 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/ContextModelAccessImpl.java @@ -36,10 +36,10 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetMode; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryDB; import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService; @@ -247,15 +247,17 @@ private Map populateWadfMap() { Map map = new EnumMap<>( ReasoningOption.class); - map.put(ASSERTIONS_ONLY, new WebappDaoFactorySDB(rdfService, - getOntModelSelector(ASSERTIONS_ONLY), config, - SDBDatasetMode.ASSERTIONS_ONLY)); - map.put(INFERENCES_ONLY, new WebappDaoFactorySDB(rdfService, - getOntModelSelector(INFERENCES_ONLY), config, - SDBDatasetMode.INFERENCES_ONLY)); - map.put(ASSERTIONS_AND_INFERENCES, new WebappDaoFactorySDB(rdfService, - getOntModelSelector(ASSERTIONS_AND_INFERENCES), config, - SDBDatasetMode.ASSERTIONS_AND_INFERENCES)); + + map.put(ASSERTIONS_ONLY, new WebappDaoFactoryDB(rdfService, + getOntModelSelector(ASSERTIONS_ONLY), config, + DatasetMode.ASSERTIONS_ONLY)); + map.put(INFERENCES_ONLY, new WebappDaoFactoryDB(rdfService, + getOntModelSelector(INFERENCES_ONLY), config, + DatasetMode.INFERENCES_ONLY)); + map.put(ASSERTIONS_AND_INFERENCES, new WebappDaoFactoryDB(rdfService, + getOntModelSelector(ASSERTIONS_AND_INFERENCES), config, + DatasetMode.ASSERTIONS_AND_INFERENCES)); + log.debug("WebappdaoFactoryMap: " + map); return Collections.unmodifiableMap(map); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java index 63d70691cc..e12b0682ed 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/modelaccess/impl/RequestModelAccessImpl.java @@ -30,11 +30,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; +import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetMode; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryDB; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.filters.ModelSwitcher; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.DatasetOption; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption; @@ -317,25 +318,25 @@ private WebappDaoFactory createWebappDaoFactory(WebappDaoFactoryKey key) { } RDFService rdfService = getRDFService(key.rdfServiceKey()); - OntModelSelector ontModelSelector = getOntModelSelector(key - .ontModelSelectorKey()); + OntModelSelector ontModelSelector = getOntModelSelector(key.ontModelSelectorKey()); WebappDaoFactoryConfig config = source.getWebappDaoFactoryConfig(); - switch (key.getReasoningOption()) { - case ASSERTIONS_ONLY: - return new WebappDaoFactorySDB(rdfService, ontModelSelector, - config, SDBDatasetMode.ASSERTIONS_ONLY); - case INFERENCES_ONLY: - return new WebappDaoFactorySDB(rdfService, ontModelSelector, - config, SDBDatasetMode.INFERENCES_ONLY); - default: // ASSERTIONS_AND_INFERENCES - // TODO Do model switching and replace the WebappDaoFactory with - // a different version if requested by parameters - WebappDaoFactory unswitched = new WebappDaoFactorySDB(rdfService, - ontModelSelector, config); - return new ModelSwitcher().checkForModelSwitching(new VitroRequest( - req), unswitched); - } + switch (key.getReasoningOption()) { + case ASSERTIONS_ONLY: + return new WebappDaoFactoryDB(rdfService, ontModelSelector, config, + DatasetMode.ASSERTIONS_ONLY); + case INFERENCES_ONLY: + return new WebappDaoFactoryDB(rdfService, ontModelSelector, config, + DatasetMode.INFERENCES_ONLY); + default: + // ASSERTIONS_AND_INFERENCES + // TODO Do model switching and replace the WebappDaoFactory with + // a different version if requested by parameters + WebappDaoFactory unswitched = + new WebappDaoFactoryDB(rdfService, ontModelSelector, config); + + return new ModelSwitcher().checkForModelSwitching(new VitroRequest(req), unswitched); + } } private WebappDaoFactory addPolicyAwareness(WebappDaoFactory unaware) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java index 09a98a6479..61f8b51a14 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java @@ -38,7 +38,6 @@ import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.Statement; import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.sdb.SDB; import org.apache.jena.shared.Lock; import org.apache.jena.sparql.core.Quad; @@ -574,30 +573,26 @@ public void serializeGraph(String graphURI, OutputStream outputStream) } private void serialize(OutputStream outputStream, String query) throws RDFServiceException { - DatasetWrapper dw = getDatasetWrapper(); - try { - Dataset d = dw.getDataset(); - Query q = createQuery(query); - QueryExecution qe = createQueryExecution(query, q, d); - // These properties only help for SDB, but shouldn't hurt for TDB. - qe.getContext().set(SDB.jdbcFetchSize, Integer.MIN_VALUE); - qe.getContext().set(SDB.jdbcStream, true); - qe.getContext().set(SDB.streamGraphAPI, true); - try { - ResultSet resultSet = qe.execSelect(); - if (resultSet.getResultVars().contains("g")) { - Iterator quads = new ResultSetQuadsIterator(resultSet); - RDFDataMgr.writeQuads(outputStream, quads); - } else { - Iterator triples = new ResultSetTriplesIterator(resultSet); - RDFDataMgr.writeTriples(outputStream, triples); - } - } finally { - qe.close(); - } - } finally { - dw.close(); - } + DatasetWrapper dw = getDatasetWrapper(); + try { + Dataset d = dw.getDataset(); + Query q = createQuery(query); + QueryExecution qe = createQueryExecution(query, q, d); + try { + ResultSet resultSet = qe.execSelect(); + if (resultSet.getResultVars().contains("g")) { + Iterator quads = new ResultSetQuadsIterator(resultSet); + RDFDataMgr.writeQuads(outputStream, quads); + } else { + Iterator triples = new ResultSetTriplesIterator(resultSet); + RDFDataMgr.writeTriples(outputStream, triples); + } + } finally { + qe.close(); + } + } finally { + dw.close(); + } } /** diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/model/RDFServiceModel.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/model/RDFServiceModel.java index 4b910b568c..a750ec93de 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/model/RDFServiceModel.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/model/RDFServiceModel.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model; import java.io.ByteArrayInputStream; -import java.util.Iterator; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; @@ -58,8 +57,7 @@ protected DatasetWrapper getDatasetWrapper() { d.addNamedModel(this.modelName, model); } } - DatasetWrapper datasetWrapper = new DatasetWrapper(d); - return datasetWrapper; + return new DatasetWrapper(d); } @Override @@ -73,8 +71,6 @@ public boolean changeSetUpdate(ChangeSet changeSet) return false; } - //Dataset dataset = getDatasetWrapper().getDataset(); - try { for (Object o : changeSet.getPreChangeEvents()) { this.notifyListenersOfEvent(o); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceFactorySDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceFactorySDB.java deleted file mode 100644 index f69a615b4b..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceFactorySDB.java +++ /dev/null @@ -1,80 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.rdf.model.ModelChangedListener; -import org.apache.jena.sdb.StoreDesc; - -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; - -public class RDFServiceFactorySDB implements RDFServiceFactory { - - private final static Log log = LogFactory.getLog(RDFServiceFactorySDB.class); - - private DataSource ds; - private StoreDesc storeDesc; - private RDFService longTermRDFService; - - public RDFServiceFactorySDB(DataSource dataSource, StoreDesc storeDesc) { - this.ds = dataSource; - this.storeDesc = storeDesc; - this.longTermRDFService = new RDFServiceSDB(dataSource, storeDesc); - } - - @Override - public RDFService getRDFService() { - return this.longTermRDFService; - } - - @Override - public RDFService getShortTermRDFService() { - try { - RDFService rdfService = new RDFServiceSDB(ds.getConnection(), storeDesc); - for (ChangeListener cl : ((RDFServiceSDB) longTermRDFService) - .getRegisteredListeners() ) { - rdfService.registerListener(cl); - } - for (ModelChangedListener cl : ((RDFServiceSDB) longTermRDFService) - .getRegisteredJenaModelChangedListeners() ) { - rdfService.registerJenaModelChangedListener(cl); - } - return rdfService; - } catch (Exception e) { - log.error(e,e); - throw new RuntimeException(e); - } - } - - @Override - public void registerListener(ChangeListener changeListener) - throws RDFServiceException { - this.longTermRDFService.registerListener(changeListener); - } - - @Override - public void unregisterListener(ChangeListener changeListener) - throws RDFServiceException { - this.longTermRDFService.unregisterListener(changeListener); - } - - @Override - public void registerJenaModelChangedListener(ModelChangedListener changeListener) - throws RDFServiceException { - this.longTermRDFService.registerJenaModelChangedListener(changeListener); - } - - @Override - public void unregisterJenaModelChangedListener(ModelChangedListener changeListener) - throws RDFServiceException { - this.longTermRDFService.unregisterJenaModelChangedListener(changeListener); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java deleted file mode 100644 index d66efc94c6..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java +++ /dev/null @@ -1,343 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import javax.sql.DataSource; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.datatypes.RDFDatatype; -import org.apache.jena.datatypes.TypeMapper; -import org.apache.jena.datatypes.xsd.XSDDatatype; -import org.apache.jena.graph.Node; -import org.apache.jena.graph.NodeFactory; -import org.apache.jena.graph.Triple; -import org.apache.jena.query.Dataset; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.sdb.SDBFactory; -import org.apache.jena.sdb.Store; -import org.apache.jena.sdb.StoreDesc; -import org.apache.jena.sdb.layout2.NodeLayout2; -import org.apache.jena.sdb.layout2.ValueType; -import org.apache.jena.sdb.sql.SDBConnection; - -import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; -import edu.cornell.mannlib.vitro.webapp.dao.jena.StaticDatasetFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.RDFServiceJena; -import org.apache.jena.sdb.store.DatabaseType; -import org.apache.jena.sdb.store.LayoutType; - -public class RDFServiceSDB extends RDFServiceJena implements RDFService { - - private final static Log log = LogFactory.getLog(RDFServiceSDB.class); - - private DataSource ds; - private StoreDesc storeDesc; - private Connection conn; - private StaticDatasetFactory staticDatasetFactory; - - public RDFServiceSDB(DataSource dataSource, StoreDesc storeDesc) { - this.ds = dataSource; - this.storeDesc = storeDesc; - } - - public RDFServiceSDB(Connection conn, StoreDesc storeDesc) { - this.conn = conn; - this.storeDesc = storeDesc; - this.staticDatasetFactory = new StaticDatasetFactory(getDataset( - new SDBConnection(conn))); - } - - @Override - protected DatasetWrapper getDatasetWrapper() { - try { - if (staticDatasetFactory != null) { - return staticDatasetFactory.getDatasetWrapper(); - } - SDBConnection sdbConn = new SDBConnection(ds.getConnection()); - return new DatasetWrapper(getDataset(sdbConn), sdbConn); - } catch (SQLException sqle) { - log.error(sqle, sqle); - throw new RuntimeException(sqle); - } - } - - @Override - public boolean changeSetUpdate(ChangeSet changeSet) - throws RDFServiceException { - - if (changeSet.getPreconditionQuery() != null - && !isPreconditionSatisfied( - changeSet.getPreconditionQuery(), - changeSet.getPreconditionQueryType())) { - return false; - } - - SDBConnection sdbConn = getSDBConnection(); - Dataset dataset = getDataset(sdbConn); - try { - insureThatInputStreamsAreResettable(changeSet); - } catch (IOException e) { - throw new RuntimeException(e); - } - - try { - beginTransaction(sdbConn); - notifyListenersOfPreChangeEvents(changeSet); - applyChangeSetToModel(changeSet, dataset); - commitTransaction(sdbConn); - notifyListenersOfChanges(changeSet); - notifyListenersOfPostChangeEvents(changeSet); - return true; - } catch (Exception e) { - log.error(e, e); - abortTransaction(sdbConn); - throw new RDFServiceException(e); - } finally { - rebuildGraphURICache = true; - close(sdbConn); - } - } - - private SDBConnection getSDBConnection() throws RDFServiceException { - try { - Connection c = (conn != null) ? conn : ds.getConnection(); - return new SDBConnection(c); - } catch (SQLException sqle) { - log.error(sqle, sqle); - throw new RDFServiceException(sqle); - } - } - - private void close(SDBConnection sdbConn) { - if (!sdbConn.getSqlConnection().equals(conn)) { - sdbConn.close(); - } - } - - private Dataset getDataset(SDBConnection sdbConn) { - Store store = SDBFactory.connectStore(sdbConn, storeDesc); - store.getLoader().setUseThreading(false); - return SDBFactory.connectDataset(store); - } - - private void beginTransaction(SDBConnection sdbConn) { - if (sdbConn.getTransactionHandler().transactionsSupported()) { - sdbConn.getTransactionHandler().begin(); - } - } - - private void commitTransaction(SDBConnection sdbConn) { - if (sdbConn.getTransactionHandler().transactionsSupported()) { - sdbConn.getTransactionHandler().commit(); - } - } - - private void abortTransaction(SDBConnection sdbConn) { - if (sdbConn.getTransactionHandler().transactionsSupported()) { - sdbConn.getTransactionHandler().abort(); - } - } - - @Override - protected QueryExecution createQueryExecution(String queryString, Query q, Dataset d) { - return QueryExecutionFactory.create(q, d); - - // This used to execute against the default model if the query included an OPTIONAL - // However, in recent Jena this turns out to be much slower than executing against the dataset directly - } - - @Override - public long countTriples(RDFNode subject, RDFNode predicate, RDFNode object) throws RDFServiceException { - if (LayoutType.LayoutTripleNodesHash.equals(storeDesc.getLayout())) { - if (DatabaseType.MySQL.equals(storeDesc.getDbType()) || - DatabaseType.PostgreSQL.equals(storeDesc.getDbType())) { - SDBConnection sdbConn = getSDBConnection(); - try { - String whereClause = makeWhereClause(subject, predicate, object); - Statement stmt = sdbConn.getSqlConnection().createStatement(); - ResultSet rs = stmt.executeQuery("SELECT count(DISTINCT s,p,o) AS tcount FROM Quads" + (StringUtils.isEmpty(whereClause) ? "" : " WHERE " + whereClause)); - try { - if (rs.next()) { - return rs.getLong("tcount"); - } - } finally { - rs.close(); - } - } catch (SQLException sqle) { - throw new RDFServiceException("Unable to retrieve triples", sqle); - } finally { - close(sdbConn); - } - } - } else { - return super.countTriples(subject, predicate, object); - } - - return super.countTriples(subject, predicate, object); - } - - @Override - public Model getTriples(RDFNode subject, RDFNode predicate, RDFNode object, long limit, long offset) throws RDFServiceException { - if (LayoutType.LayoutTripleNodesHash.equals(storeDesc.getLayout())) { - if (DatabaseType.MySQL.equals(storeDesc.getDbType()) || - DatabaseType.PostgreSQL.equals(storeDesc.getDbType())) { - Model triples = ModelFactory.createDefaultModel(); - - SDBConnection sdbConn = getSDBConnection(); - try { - String whereClause = makeWhereClause(subject, predicate, object); - Statement stmt = sdbConn.getSqlConnection().createStatement(); - ResultSet rs = stmt.executeQuery("SELECT \n" + - "N1.lex AS s_lex,\n" + - "N1.lang AS s_lang,\n" + - "N1.datatype AS s_datatype,\n" + - "N1.type AS s_type,\n" + - "N2.lex AS p_lex,\n" + - "N2.lang AS p_lang,\n" + - "N2.datatype AS p_datatype,\n" + - "N2.type AS p_type,\n" + - "N3.lex AS o_lex,\n" + - "N3.lang AS o_lang,\n" + - "N3.datatype AS o_datatype,\n" + - "N3.type AS o_type\n" + - "FROM\n" + - "(SELECT DISTINCT s,p,o FROM Quads" + - (StringUtils.isEmpty(whereClause) ? "" : " WHERE " + whereClause) + - " ORDER BY s,p,o " + - (limit > 0 ? "LIMIT " + limit : "") + - (offset > 0 ? " OFFSET " + offset : "") + ") Q\n" + - "LEFT OUTER JOIN\n" + - "\tNodes AS N1\n" + - "ON ( Q.s = N1.hash )\n" + - "LEFT OUTER JOIN\n" + - "\tNodes AS N2\n" + - "ON ( Q.p = N2.hash )\n" + - "LEFT OUTER JOIN\n" + - "\tNodes AS N3\n" + - "ON ( Q.o = N3.hash )"); - - try { - while (rs.next()) { - Node subjectNode = makeNode( - rs.getString("s_lex"), - rs.getString("s_datatype"), - rs.getString("s_lang"), - ValueType.lookup(rs.getInt("s_type"))); - - Node predicateNode = makeNode( - rs.getString("p_lex"), - rs.getString("p_datatype"), - rs.getString("p_lang"), - ValueType.lookup(rs.getInt("p_type"))); - - Node objectNode = makeNode( - rs.getString("o_lex"), - rs.getString("o_datatype"), - rs.getString("o_lang"), - ValueType.lookup(rs.getInt("o_type"))); - - triples.add( - triples.asStatement(Triple.create(subjectNode, predicateNode, objectNode)) - ); - } - } finally { - rs.close(); - } - } catch (SQLException sqle) { - throw new RDFServiceException("Unable to retrieve triples", sqle); - } finally { - close(sdbConn); - } - - return triples; - } - } - - return super.getTriples(subject, predicate, object, limit, offset); - } - - @Override - public boolean preferPreciseOptionals() { - return true; - } - - @Override - public void close() { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - log.error(e,e); - } - } - } - - // Copied from Jena SQLBridge2 - private static Node makeNode(String lex, String datatype, String lang, ValueType vType) { - switch(vType) { - case BNODE: - return NodeFactory.createBlankNode(lex); - case URI: - return NodeFactory.createURI(lex); - case STRING: - return NodeFactory.createLiteral(lex, lang); - case XSDSTRING: - return NodeFactory.createLiteral(lex, XSDDatatype.XSDstring); - case INTEGER: - return NodeFactory.createLiteral(lex, XSDDatatype.XSDinteger); - case DOUBLE: - return NodeFactory.createLiteral(lex, XSDDatatype.XSDdouble); - case DATETIME: - return NodeFactory.createLiteral(lex, XSDDatatype.XSDdateTime); - case OTHER: - RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(datatype); - return NodeFactory.createLiteral(lex, dt); - default: - log.warn("Unrecognized: (" + lex + ", " + lang + ", " + vType + ")"); - return NodeFactory.createLiteral("UNRECOGNIZED"); - } - } - - private String makeWhereClause(RDFNode subject, RDFNode predicate, RDFNode object) { - StringBuilder whereClause = new StringBuilder(); - if (subject != null) { - if (whereClause.length() > 0) { - whereClause.append(" AND "); - } - whereClause.append("s=").append(NodeLayout2.hash(subject.asNode())); - } - - if (predicate != null) { - if (whereClause.length() > 0) { - whereClause.append(" AND "); - } - whereClause.append("p=").append(NodeLayout2.hash(predicate.asNode())); - } - - if (object != null) { - if (whereClause.length() > 0) { - whereClause.append(" AND "); - } - whereClause.append("o=").append(NodeLayout2.hash(object.asNode())); - } - - return whereClause.length() > 0 ? whereClause.toString() : null; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index 5b669b7321..e9a3f20ab9 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -139,7 +139,7 @@ public SimpleReasoner(OntModel tboxModel, OntModel aboxModel, Model inferenceMod this.inferenceModel = inferenceModel; this.fullModel = VitroModelFactory.createUnion(aboxModel, VitroModelFactory.createOntologyModel(inferenceModel)); - Dataset ds = DatasetFactory.createMem(); + Dataset ds = DatasetFactory.createMem(); ds.addNamedModel(ModelNames.ABOX_ASSERTIONS, aboxModel); ds.addNamedModel(ModelNames.ABOX_INFERENCES, inferenceModel); ds.addNamedModel(ModelNames.TBOX_ASSERTIONS, tboxModel); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index 80656403b9..da12f226c4 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -147,7 +147,7 @@ private Set getFilegraphPaths(ServletContext ctx, String... strings) { /* * Reads the graphs stored as files in sub-directories of - * 1. updates the SDB store to reflect the current contents of the graph. + * 1. updates the data store to reflect the current contents of the graph. * 2. adds the graph as an in-memory submodel of the base in-memory graph * * Note: no connection needs to be maintained between the in-memory copy of the @@ -160,7 +160,7 @@ private boolean readGraphs(Set pathSet, RDFService rdfService, String type boolean modelChanged = false; // For each file graph in the target directory update or add that graph to - // the Jena SDB, and attach the graph as a submodel of the base model + // the Jena data store, and attach the graph as a submodel of the base model for ( Path p : pathSet ) { count++; // note this will count the empty files too @@ -251,7 +251,7 @@ public boolean updateGraphInDB(RDFService rdfService, Model fileModel, String ty * graphs (of the given type) in the file * system. * @param type (input) - abox or tbox. - * @param kbStore (output) - the SDB store for the application + * @param kbStore (output) - the data store for the application */ public void cleanupDB(Dataset dataset, Set uriSet, String type) { @@ -288,7 +288,7 @@ private Set pathsToURIs(Set paths, String type) { } /* - * Takes a path for a file graph and returns the corresponding SDB URI + * Takes a path for a file graph and returns the corresponding URI * for the graph. The correspondence is by defined convention. */ private String pathToURI(Path path, String type) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/ContentTripleSourceSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/ContentTripleSourceSDB.java deleted file mode 100644 index 659b73b0a8..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/ContentTripleSourceSDB.java +++ /dev/null @@ -1,288 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb; - -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.BasicCombinedTripleSource.CONTENT_UNIONS; - -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Enumeration; - -import javax.servlet.ServletContext; -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.query.Dataset; -import org.apache.jena.rdf.model.ModelMaker; -import org.apache.jena.sdb.SDB; -import org.apache.jena.sdb.SDBFactory; -import org.apache.jena.sdb.Store; -import org.apache.jena.sdb.StoreDesc; -import org.apache.jena.sdb.sql.SDBConnection; -import org.apache.jena.sdb.store.DatabaseType; -import org.apache.jena.sdb.store.LayoutType; -import org.apache.jena.sdb.util.StoreUtils; -import org.apache.commons.dbcp2.BasicDataSource; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.MemoryMappingModelMaker; -import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.ModelMakerWithPersistentEmptyModels; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.MaskingOntModelCache; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.ModelMakerOntModelCache; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntModelsCache; -import edu.cornell.mannlib.vitro.webapp.modules.Application; -import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; -import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceFactorySDB; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; -import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; - -/** - * Create the connection to the SDB triple-store. - * - * Do some smoke-tests on the parameters, create the connection pool, and create - * the RDFServiceFactory. - */ -public class ContentTripleSourceSDB extends ContentTripleSource { - private static final Log log = LogFactory - .getLog(ContentTripleSourceSDB.class); - - static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url"; - static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username"; - static final String PROPERTY_DB_PASSWORD = "VitroConnection.DataSource.password"; - static final String PROPERTY_DB_DRIVER_CLASS_NAME = "VitroConnection.DataSource.driver"; - static final String PROPERTY_DB_TYPE = "VitroConnection.DataSource.dbtype"; - static final String PROPERTY_DB_MAX_ACTIVE = "VitroConnection.DataSource.pool.maxActive"; - static final String PROPERTY_DB_MAX_IDLE = "VitroConnection.DataSource.pool.maxIdle"; - static final String PROPERTY_DB_MAX_IDLE_TIME = "VitroConnection.DataSource.pool.maxIdleTime"; - static final String PROPERTY_DB_MAX_IDLE_TIME_EXCESS = "VitroConnection.DataSource.pool.maxIdleTimeExcess"; - static final String PROPERTY_DB_VALIDATION_QUERY = "VitroConnection.DataSource.validationQuery"; - static final String PROPERTY_DB_SDB_LAYOUT = "VitroConnection.DataSource.sdb.layout"; - - static final String DEFAULT_TYPE = "MySQL"; - static final String DEFAULT_DRIVER_CLASS = "com.mysql.jdbc.Driver"; - static final String DEFAULT_LAYOUT = "layout2/hash"; - static final String DEFAULT_VALIDATION_QUERY = "SELECT 1"; - - static final int DEFAULT_MAXACTIVE = 40; // ms - static final int MINIMUM_MAXACTIVE = 20; // ms - static final int DEFAULT_MAXIDLE = 10; // ms - - static final int DEFAULT_MAX_IDLE_TIME = 1800; // seconds - static final int DEFAULT_MAX_IDLE_TIME_EXCESS = 300; // seconds - - static final boolean DEFAULT_TESTONBORROW = true; - static final boolean DEFAULT_TESTONRETURN = true; - - private ServletContext ctx; - private BasicDataSource ds; - private RDFServiceFactory rdfServiceFactory; - private RDFService rdfService; - private Dataset dataset; - private ModelMaker modelMaker; - - @Override - public void startup(Application application, ComponentStartupStatus ss) { - try { - this.ctx = application.getServletContext(); - - configureSDBContext(); - - new SDBConnectionSmokeTests(ctx, ss).checkDatabaseConnection(); - - this.ds = new SDBDataSource(ctx).getDataSource(); - this.rdfServiceFactory = createRdfServiceFactory(); - this.rdfService = rdfServiceFactory.getRDFService(); - this.dataset = new RDFServiceDataset(this.rdfService); - this.modelMaker = createModelMaker(); - ss.info("Initialized the content data structures for SDB"); - } catch (SQLException e) { - throw new RuntimeException( - "Failed to set up the content data structures for SDB", e); - } - } - - private void configureSDBContext() { - SDB.getContext().set(SDB.unionDefaultGraph, true); - } - - private RDFServiceFactory createRdfServiceFactory() throws SQLException { - StoreDesc storeDesc = makeStoreDesc(); - Store store = connectStore(ds, storeDesc); - - if (!isSetUp(store)) { - JenaDataSourceSetupBase.thisIsFirstStartup(); - setupSDB(store); - } - - return new LoggingRDFServiceFactory(new RDFServiceFactorySDB(ds, - storeDesc)); - } - - /** - * Tests whether an SDB store has been formatted and populated for use. - */ - private boolean isSetUp(Store store) throws SQLException { - if (!(StoreUtils.isFormatted(store))) { - return false; - } - - // even if the store exists, it may be empty - try { - return (SDBFactory.connectNamedModel(store, - ModelNames.TBOX_ASSERTIONS)).size() > 0; - } catch (Exception e) { - return false; - } - } - - private StoreDesc makeStoreDesc() { - ConfigurationProperties props = ConfigurationProperties.getBean(ctx); - String layoutStr = props.getProperty(PROPERTY_DB_SDB_LAYOUT, - DEFAULT_LAYOUT); - String dbtypeStr = props.getProperty(PROPERTY_DB_TYPE, DEFAULT_TYPE); - return new StoreDesc(LayoutType.fetch(layoutStr), - DatabaseType.fetch(dbtypeStr)); - } - - private Store connectStore(DataSource bds, StoreDesc storeDesc) - throws SQLException { - SDBConnection conn = new SDBConnection(bds.getConnection()); - return SDBFactory.connectStore(conn, storeDesc); - } - - private void setupSDB(Store store) { - log.info("Initializing SDB store"); - store.getTableFormatter().create(); - store.getTableFormatter().truncate(); - } - - private ModelMaker createModelMaker() { - return addContentDecorators(new ModelMakerWithPersistentEmptyModels( - new MemoryMappingModelMaker(new RDFServiceModelMaker( - this.rdfService), SMALL_CONTENT_MODELS))); - } - - @Override - public RDFServiceFactory getRDFServiceFactory() { - return this.rdfServiceFactory; - } - - @Override - public RDFService getRDFService() { - return this.rdfService; - } - - @Override - public Dataset getDataset() { - return this.dataset; - } - - @Override - public ModelMaker getModelMaker() { - return this.modelMaker; - } - - /** - * Use models from the short-term RDFService, since there is less contention - * for the database connections that way. The exceptions are the - * memory-mapped models. By keeping them, we also keep their sub-models. - * - * Set up the Union models again also, so they will reference the short-term - * models. - */ - @Override - public OntModelCache getShortTermOntModels(RDFService shortTermRdfService, - OntModelCache longTermOntModelCache) { - ModelMakerOntModelCache shortCache = new ModelMakerOntModelCache( - addContentDecorators(new ModelMakerWithPersistentEmptyModels( - new RDFServiceModelMaker(shortTermRdfService)))); - - MaskingOntModelCache combinedCache = new MaskingOntModelCache( - shortCache, longTermOntModelCache, - Arrays.asList(MEMORY_MAPPED_CONTENT_MODELS)); - - return new UnionModelsOntModelsCache(combinedCache, CONTENT_UNIONS); - } - - @Override - public String toString() { - return "ContentTripleSourceSDB[" + ToString.hashHex(this) + "]"; - } - - @Override - public void shutdown(Application application) { - if (this.modelMaker != null) { - this.modelMaker.close(); - } - if (this.dataset != null) { - this.dataset.close(); - } - if (this.rdfService != null) { - this.rdfService.close(); - } - if (ds != null) { - String driverClassName = ds.getDriverClassName(); - try { - ds.close(); - } catch (SQLException e) { - }finally { - attemptToDeregisterJdbcDriver(driverClassName); - cleanupAbandonedConnectionThread(driverClassName); - } - } - } - - private void attemptToDeregisterJdbcDriver(String driverClassName) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - - for (Enumeration drivers = DriverManager.getDrivers(); drivers - .hasMoreElements();) { - Driver driver = drivers.nextElement(); - if (driver.getClass().getClassLoader() == cl) { - // This driver was registered by the webapp's ClassLoader, so - // deregister it: - try { - DriverManager.deregisterDriver(driver); - } catch (SQLException ex) { - log.error("Error deregistering JDBC driver {" + driver - + "}", ex); - } - } else { - // driver was not registered by the webapp's ClassLoader and may - // be in use elsewhere - } - } - } - - /** - * The MySQL driver leaves a thread running after it is deregistered. - * Versions after 5.1.23 provide AbandonedConnectionCleanupThread.shutdown() - * to stop this thread. - * - * Using reflection to invoke this method means that we don't have a - * hard-coded dependency to MySQL. - */ - private void cleanupAbandonedConnectionThread(String driverClassName) { - if (!driverClassName.contains("mysql")) { - return; - } - try { - Class.forName("com.mysql.jdbc.AbandonedConnectionCleanupThread") - .getMethod("shutdown").invoke(null); - } catch (Exception e) { - log.info("Failed to shutdown MySQL connection cleanup thread: " + e); - } - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBConnectionSmokeTests.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBConnectionSmokeTests.java deleted file mode 100644 index d3b35576df..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBConnectionSmokeTests.java +++ /dev/null @@ -1,187 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb; - -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_DRIVER_CLASS; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_DRIVER_CLASS_NAME; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_PASSWORD; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_TYPE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_URL; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_USERNAME; - -import java.io.UnsupportedEncodingException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - -import javax.servlet.ServletContext; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; - -/** - * Smoke tests for the database connection that SDB will use. - * - * Confirm that the URL, Username and Password have been specified for the - * Database connection. - * - * Confirm that we can load the database driver. - * - * Confirm that we can connect to the database using those properties. - * - * Try to confirm that the database connection is configured to use UTF-8 - * encoding. Don't know how well this works. - */ -public class SDBConnectionSmokeTests { - private final ConfigurationProperties props; - private final ComponentStartupStatus ss; - - public SDBConnectionSmokeTests(ServletContext ctx, ComponentStartupStatus ss) { - this.props = ConfigurationProperties.getBean(ctx); - this.ss = ss; - } - - public void checkDatabaseConnection() { - String url = props.getProperty(PROPERTY_DB_URL); - if (url == null || url.isEmpty()) { - ss.fatal("runtime.properties does not contain a value for '" - + PROPERTY_DB_URL + "'"); - return; - } - - // Get the full URL, with options. - url = SDBDataSource.getJdbcUrl(props); - - String username = props.getProperty(PROPERTY_DB_USERNAME); - if (username == null || username.isEmpty()) { - ss.fatal("runtime.properties does not contain a value for '" - + PROPERTY_DB_USERNAME + "'"); - return; - } - String password = props.getProperty(PROPERTY_DB_PASSWORD); - if (password == null || password.isEmpty()) { - ss.fatal("runtime.properties does not contain a value for '" - + PROPERTY_DB_PASSWORD + "'"); - return; - } - - String driverClassName = props - .getProperty(PROPERTY_DB_DRIVER_CLASS_NAME); - if (driverClassName == null) { - try { - Class.forName(DEFAULT_DRIVER_CLASS).newInstance(); - } catch (Exception e) { - ss.fatal("The default Database Driver failed to load. " - + "The driver class is '" + DEFAULT_DRIVER_CLASS + "'", - e); - return; - } - } else { - try { - Class.forName(driverClassName).newInstance(); - } catch (Exception e) { - ss.fatal("The Database Driver failed to load. " - + "The driver class was set by " - + PROPERTY_DB_DRIVER_CLASS_NAME + " to be '" - + driverClassName + "'", e); - return; - } - } - - Properties connectionProps = new Properties(); - connectionProps.put("user", username); - connectionProps.put("password", password); - - try (Connection conn = DriverManager - .getConnection(url, connectionProps)) { - // We have an SQL connection - see if we have any XSD Strings in the database - String skip = props.getProperty("skip.Jena3StringTest", "false"); - if (!Boolean.parseBoolean(skip)) { - try { - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT COUNT(1) AS total FROM Nodes WHERE datatype='http://www.w3.org/2001/XMLSchema#string'"); - if (rs != null && rs.next()) { - long total = rs.getLong("total"); - if (total > 0) { - ss.fatal("XSD Strings exist in Nodes table. Requires upgrade for Jena 3"); - } - } - } catch (SQLException e) { - // Ignore SQL Exception here, as it likely represents a triple store that's not initialised yet. - } - } - } catch (SQLException e) { - ss.fatal("Can't connect to the database: " + PROPERTY_DB_URL + "='" - + url + "', " + PROPERTY_DB_USERNAME + "='" + username - + "'", e); - return; - } - - String dbType = props.getProperty(PROPERTY_DB_TYPE, "MySQL"); - checkForPropertHandlingOfUnicodeCharacters(url, connectionProps, dbType); - } - - private void checkForPropertHandlingOfUnicodeCharacters(String url, - Properties connectionProps, String dbType) { - String testString = "ABC\u00CE\u0123"; - - try (Connection conn = DriverManager - .getConnection(url, connectionProps); - Statement stmt = conn.createStatement()) { - - // Create the temporary table. - stmt.executeUpdate("CREATE TEMPORARY TABLE smoke_test (contents varchar(100))"); - - // Write the test string, encoding in UTF-8 on the way in. - try (PreparedStatement pstmt = conn - .prepareStatement("INSERT INTO smoke_test values ( ? )")) { - pstmt.setBytes(1, testString.getBytes("UTF-8")); - pstmt.executeUpdate(); - } catch (UnsupportedEncodingException e1) { - e1.printStackTrace(); - } - - // Read it back as a String. Does the database decode it properly? - ResultSet rs = stmt.executeQuery("SELECT * FROM smoke_test"); - if (!rs.next()) { - throw new SQLException( - "Query of temporary table returned 0 rows."); - } - String storedValue = rs.getString(1); - if (!testString.equals(storedValue)) { - String message = "The database does not store Unicode " - + "characters correctly. The test inserted \"" - + showUnicode(testString) - + "\", but the query returned \"" - + showUnicode(storedValue) - + "\". Is the character encoding correctly " - + "set on the database?"; - if ("MySQL".equals(dbType)) { - // For MySQL, we know that this is a configuration problem. - ss.fatal(message); - } else { - // For other databases, it might not be. - ss.warning(message); - } - } - } catch (SQLException e) { - ss.fatal("Failed to check handling of Unicode characters", e); - } - } - - /** - * Display the hex codes for a String. - */ - private String showUnicode(String testString) { - StringBuilder u = new StringBuilder(); - for (char c : testString.toCharArray()) { - u.append(String.format("\\u%04x", c & 0x0000FFFF)); - } - return u.toString(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBDataSource.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBDataSource.java deleted file mode 100644 index 9f80da08d7..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/triplesource/impl/sdb/SDBDataSource.java +++ /dev/null @@ -1,178 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb; - -import javax.servlet.ServletContext; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.commons.dbcp2.BasicDataSource; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; - -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_DRIVER_CLASS; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_MAXACTIVE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_MAXIDLE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_MAX_IDLE_TIME; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_MAX_IDLE_TIME_EXCESS; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_TESTONBORROW; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_TESTONRETURN; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_TYPE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.DEFAULT_VALIDATION_QUERY; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.MINIMUM_MAXACTIVE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_DRIVER_CLASS_NAME; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_MAX_ACTIVE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_MAX_IDLE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_MAX_IDLE_TIME; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_MAX_IDLE_TIME_EXCESS; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_PASSWORD; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_TYPE; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_URL; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_USERNAME; -import static edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB.PROPERTY_DB_VALIDATION_QUERY; - -/** - * Create a DataSource on the SDB database. - */ -public class SDBDataSource { - private static final Log log = LogFactory.getLog(SDBDataSource.class); - - private final ConfigurationProperties configProps; - - - public SDBDataSource(ServletContext ctx) { - this.configProps = ConfigurationProperties.getBean(ctx); - } - - public BasicDataSource getDataSource() { - BasicDataSource cpds = new BasicDataSource(); - cpds.setDriverClassName(getDbDriverClassName()); - cpds.setUrl(getJdbcUrl(configProps)); - cpds.setUsername(configProps.getProperty(PROPERTY_DB_USERNAME)); - cpds.setPassword(configProps.getProperty(PROPERTY_DB_PASSWORD)); - cpds.setMaxTotal(getMaxActive()); - cpds.setMaxIdle(getMaxIdle()); - cpds.setMinEvictableIdleTimeMillis(getMaxIdleTime()); - cpds.setTestOnBorrow(DEFAULT_TESTONBORROW); - cpds.setTestOnReturn(DEFAULT_TESTONRETURN); - cpds.setValidationQuery(getValidationQuery()); - return cpds; -// try { -// cpds.setMaxIdleTimeExcessConnections(getMaxIdleTimeExcess()); -// cpds.setAcquireIncrement(5); -// cpds.setNumHelperThreads(6); -// } catch (PropertyVetoException pve) { -// throw new RuntimeException(pve); -// } - } - - private String getDbDriverClassName() { - return configProps.getProperty(PROPERTY_DB_DRIVER_CLASS_NAME, - DEFAULT_DRIVER_CLASS); - } - - private String getValidationQuery() { - return configProps.getProperty(PROPERTY_DB_VALIDATION_QUERY, - DEFAULT_VALIDATION_QUERY); - } - - private int getMaxActive() { - String maxActiveStr = configProps.getProperty(PROPERTY_DB_MAX_ACTIVE); - if (StringUtils.isEmpty(maxActiveStr)) { - return DEFAULT_MAXACTIVE; - } - - int maxActive = DEFAULT_MAXACTIVE; - try { - maxActive = Integer.parseInt(maxActiveStr); - } catch (NumberFormatException nfe) { - log.error("Unable to parse connection pool maxActive setting " - + maxActiveStr + " as an integer"); - return DEFAULT_MAXACTIVE; - } - - if (maxActive >= MINIMUM_MAXACTIVE) { - return maxActive; - } - - log.warn("Specified value for " + PROPERTY_DB_MAX_ACTIVE - + " is too low. Using minimum value of " + MINIMUM_MAXACTIVE); - return MINIMUM_MAXACTIVE; - } - - private int getMaxIdle() { - int maxIdleInt = Math.max(getMaxActive() / 4, DEFAULT_MAXIDLE); - return getPropertyAsInt(PROPERTY_DB_MAX_IDLE, maxIdleInt); - } - - private int getMaxIdleTime() { - return getPropertyAsInt(PROPERTY_DB_MAX_IDLE_TIME, DEFAULT_MAX_IDLE_TIME); - } - - private int getMaxIdleTimeExcess() { - return getPropertyAsInt(PROPERTY_DB_MAX_IDLE_TIME_EXCESS, DEFAULT_MAX_IDLE_TIME_EXCESS); - } - - private int getPropertyAsInt(String prop, int defaultValue) { - String propStr = configProps.getProperty(prop); - - if (StringUtils.isEmpty(propStr)) { - return defaultValue; - } - - try { - return Integer.parseInt(propStr); - } catch (NumberFormatException nfe) { - log.error("Unable to parse connection pool maxIdle setting " - + propStr + " as an integer"); - return defaultValue; - } - } - - /** - * Get the JDBC URL, perhaps with special MySQL options. - * - * This must be static and package-accessible so SDBConnectionSmokeTests can - * use the same options. - */ - static String getJdbcUrl(ConfigurationProperties props) { - String url = props.getProperty(PROPERTY_DB_URL); - - // Ensure that MySQL handles unicode properly, else all kinds of - // horrible nastiness ensues. Also, set some other handy options. - if (DEFAULT_TYPE.equals(getDbType(props))) { - if (!url.contains("?")) { - url += "?useUnicode=yes&characterEncoding=utf8&nullNamePatternMatchesAll=true&cachePrepStmts=true&useServerPrepStmts=true&serverTimezone=UTC"; - } else { - String urlLwr = url.toLowerCase(); - if (!urlLwr.contains("useunicode")) { - url += "&useUnicode=yes"; - } - if (!urlLwr.contains("characterencoding")) { - url += "&characterEncoding=utf8"; - } - if (!urlLwr.contains("nullnamepatternmatchesall")) { - url += "&nullNamePatternMatchesAll=true"; - } - if (!urlLwr.contains("cacheprepstmts")) { - url += "&cachePrepStmts=true"; - } - if (!urlLwr.contains("useserverprepstmts")) { - url += "&useServerPrepStmts=true"; - } - if (!urlLwr.contains("servertimezone")) { - url += "&serverTimezone=UTC"; - } - } - } - return url; - } - - private static String getDbType(ConfigurationProperties props) { - return props.getProperty(PROPERTY_DB_TYPE, DEFAULT_TYPE); - } - - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java index e4ed16e93d..124d1bdf0c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java @@ -4,8 +4,6 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceSDB; import org.apache.commons.lang3.StringUtils; public final class ListConfigUtils { diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 6e3fa542ec..653ac45a1c 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -189,11 +189,6 @@ jena-core 3.16.0 - - org.apache.jena - jena-sdb - 3.16.0 - org.apache.jena jena-tdb diff --git a/home/src/main/resources/config/example.applicationSetup.n3 b/home/src/main/resources/config/example.applicationSetup.n3 index 0df7bdb6e4..d880a3590d 100644 --- a/home/src/main/resources/config/example.applicationSetup.n3 +++ b/home/src/main/resources/config/example.applicationSetup.n3 @@ -85,14 +85,10 @@ # The TDB-based implementation is the default option. It reads its parameters # from the runtime.properties file, for backward compatibility. # -# Other implementations are based on an SDB instance, a "standard" SPARQL -# endpoint, or a Virtuoso endpoint, with parameters as shown. +# Other implementations are based on a "standard" SPARQL endpoint or a +# Virtuoso endpoint, with parameters as shown. # -#:sdbContentTripleSource -# a vitroWebapp:triplesource.impl.sdb.ContentTripleSourceSDB , -# vitroWebapp:modules.tripleSource.ContentTripleSource . - :tdbContentTripleSource a vitroWebapp:triplesource.impl.tdb.ContentTripleSourceTDB , vitroWebapp:modules.tripleSource.ContentTripleSource ; diff --git a/home/src/main/resources/config/example.runtime.properties b/home/src/main/resources/config/example.runtime.properties index 989cf19e3f..229b33ab8f 100644 --- a/home/src/main/resources/config/example.runtime.properties +++ b/home/src/main/resources/config/example.runtime.properties @@ -48,8 +48,8 @@ email.smtpHost = email.replyTo = # -# NOTE: VitroConnection.DataSource.* properties are only used in conjuction with -# an SDB triple store. +# NOTE: VitroConnection.DataSource.* properties are only used by OpenSocial for +# SQL database interaction. # # The basic parameters for a database connection. Change the end of the # URL to reflect your database name (if it is not "vitrodb"). Change the username diff --git a/home/src/main/resources/rdf/i18n/de_DE/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/de_DE/interface-i18n/firsttime/vitro_UiLabel.ttl index 0a8c972a8a..d8e22c81b1 100644 --- a/home/src/main/resources/rdf/i18n/de_DE/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/de_DE/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1402,14 +1402,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Starte SDB-Setup"@de-DE ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/en_CA/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/en_CA/interface-i18n/firsttime/vitro_UiLabel.ttl index af03833315..21f62d7496 100644 --- a/home/src/main/resources/rdf/i18n/en_CA/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/en_CA/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1405,14 +1405,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Run SDB Setup"@en-CA ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/en_US/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/en_US/interface-i18n/firsttime/vitro_UiLabel.ttl index 372588e1a9..2000871432 100644 --- a/home/src/main/resources/rdf/i18n/en_US/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/en_US/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1405,14 +1405,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Run SDB Setup"@en-US ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/es/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/es/interface-i18n/firsttime/vitro_UiLabel.ttl index df34897a47..0767119791 100644 --- a/home/src/main/resources/rdf/i18n/es/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/es/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1401,14 +1401,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Ejecutar la instalación SDB"@es ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/fr_CA/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/fr_CA/interface-i18n/firsttime/vitro_UiLabel.ttl index 233a2ee326..8cc78a4f83 100644 --- a/home/src/main/resources/rdf/i18n/fr_CA/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/fr_CA/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1401,14 +1401,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Exécuter la configuration SDB"@fr-CA ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/pt_BR/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/pt_BR/interface-i18n/firsttime/vitro_UiLabel.ttl index 0cab595f9f..c4a3156a39 100644 --- a/home/src/main/resources/rdf/i18n/pt_BR/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/pt_BR/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1401,14 +1401,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Executar Configuração do SDB"@pt-BR ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/ru_RU/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/ru_RU/interface-i18n/firsttime/vitro_UiLabel.ttl index 75fc2e81de..64af510a71 100644 --- a/home/src/main/resources/rdf/i18n/ru_RU/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/ru_RU/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1401,14 +1401,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Запустить установку SDB"@ru-RU ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/home/src/main/resources/rdf/i18n/sr_Latn_RS/interface-i18n/firsttime/vitro_UiLabel.ttl b/home/src/main/resources/rdf/i18n/sr_Latn_RS/interface-i18n/firsttime/vitro_UiLabel.ttl index 506fb9669c..69fff58ec8 100644 --- a/home/src/main/resources/rdf/i18n/sr_Latn_RS/interface-i18n/firsttime/vitro_UiLabel.ttl +++ b/home/src/main/resources/rdf/i18n/sr_Latn_RS/interface-i18n/firsttime/vitro_UiLabel.ttl @@ -1401,14 +1401,6 @@ prop-data:fake_external_auth.Vitro prop:hasKey "fake_external_auth" ; prop:hasPackage "Vitro-languages" . -prop-data:run_sdb_setup.Vitro - rdf:type owl:NamedIndividual ; - rdf:type prop:PropertyKey ; - rdfs:label "Pokrenite SDB setup"@sr-Latn-RS ; - prop:hasApp "Vitro" ; - prop:hasKey "run_sdb_setup" ; - prop:hasPackage "Vitro-languages" . - prop-data:property_management.Vitro rdf:type owl:NamedIndividual ; rdf:type prop:PropertyKey ; diff --git a/installer/webapp/src/main/webResources/WEB-INF/classes/log4j.properties b/installer/webapp/src/main/webResources/WEB-INF/classes/log4j.properties index acfd46f59e..7e84c3df9f 100644 --- a/installer/webapp/src/main/webResources/WEB-INF/classes/log4j.properties +++ b/installer/webapp/src/main/webResources/WEB-INF/classes/log4j.properties @@ -42,8 +42,6 @@ log4j.logger.org.semanticweb.owlapi.rdf.rdfxml.parser=WARN log4j.logger.org.springframework=WARN # suppress odd warnings from libraries -log4j.logger.org.apache.jena.sdb.layout2.LoaderTuplesNodes=FATAL -log4j.logger.org.apache.jena.sdb.sql.SDBConnection=ERROR log4j.logger.org.openjena.riot=FATAL log4j.logger.org.apache.jena.riot=FATAL log4j.logger.org.directwebremoting=FATAL diff --git a/webapp/src/main/webapp/templates/freemarker/body/sdbSetup.ftl b/webapp/src/main/webapp/templates/freemarker/body/sdbSetup.ftl deleted file mode 100644 index 01f351850b..0000000000 --- a/webapp/src/main/webapp/templates/freemarker/body/sdbSetup.ftl +++ /dev/null @@ -1,12 +0,0 @@ -<#-- $This file is distributed under the terms of the license in LICENSE$ --> - -<#if link??> -
-

${sdbstatus}

- - -
- -<#if message??> -

${message}

-