diff --git a/doc/rdfservice/doc/allclasses-frame.html b/doc/rdfservice/doc/allclasses-frame.html new file mode 100644 index 000000000..87e9cc064 --- /dev/null +++ b/doc/rdfservice/doc/allclasses-frame.html @@ -0,0 +1,47 @@ + + + + + + +All Classes + + + + + + + + + + + +All Classes +
+ + + + + +
ChangeListener +
+ChangeSet +
+ModelChange +
+ModelChange.Operation +
+RDFService +
+RDFService.ModelSerializationFormat +
+RDFService.ResultFormat +
+RDFService.SPARQLQueryType +
+RDFServiceException +
+
+ + + diff --git a/doc/rdfservice/doc/allclasses-noframe.html b/doc/rdfservice/doc/allclasses-noframe.html new file mode 100644 index 000000000..0455a39a9 --- /dev/null +++ b/doc/rdfservice/doc/allclasses-noframe.html @@ -0,0 +1,47 @@ + + + + + + +All Classes + + + + + + + + + + + +All Classes +
+ + + + + +
ChangeListener +
+ChangeSet +
+ModelChange +
+ModelChange.Operation +
+RDFService +
+RDFService.ModelSerializationFormat +
+RDFService.ResultFormat +
+RDFService.SPARQLQueryType +
+RDFServiceException +
+
+ + + diff --git a/doc/rdfservice/doc/constant-values.html b/doc/rdfservice/doc/constant-values.html new file mode 100644 index 000000000..ce9caf148 --- /dev/null +++ b/doc/rdfservice/doc/constant-values.html @@ -0,0 +1,144 @@ + + + + + + +Constant Field Values + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/deprecated-list.html b/doc/rdfservice/doc/deprecated-list.html new file mode 100644 index 000000000..13f5c7ee7 --- /dev/null +++ b/doc/rdfservice/doc/deprecated-list.html @@ -0,0 +1,144 @@ + + + + + + +Deprecated List + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.html new file mode 100644 index 000000000..166db2c8a --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.html @@ -0,0 +1,254 @@ + + + + + + +ChangeListener + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Interface ChangeListener

+
+
+
public interface ChangeListener
+ + +

+


+ +

+ + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidaddedStatement(java.lang.String serializedTriple, + java.lang.String graphURI) + +
+          Override this to listen to all statements added to the RDF store.
+ voidnotifyEvent(java.lang.String graphURI, + java.lang.Object event) + +
+          Override this to listen to events pertaining to the given graphURI.
+ voidremovedStatement(java.lang.String serializedTriple, + java.lang.String graphURI) + +
+          Override this to listen to all statements removed from the RDF store.
+  +

+ + + + + + + + +
+Method Detail
+ +

+addedStatement

+
+void addedStatement(java.lang.String serializedTriple,
+                    java.lang.String graphURI)
+
+
Override this to listen to all statements added to the RDF store. +

+

+
Parameters:
serializedTriple - - the added statement in n3 format
graphURI - - the graph to which the statement was added
+
+
+
+ +

+removedStatement

+
+void removedStatement(java.lang.String serializedTriple,
+                      java.lang.String graphURI)
+
+
Override this to listen to all statements removed from the RDF store. +

+

+
Parameters:
serializedTriple - - the removed statement in n3 format
graphURI - - the graph from which the statement was removed
+
+
+
+ +

+notifyEvent

+
+void notifyEvent(java.lang.String graphURI,
+                 java.lang.Object event)
+
+
Override this to listen to events pertaining to the given graphURI. +

+

+
Parameters:
graphURI - - the graph to which the event pertains
event - - the event that occurred.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.html new file mode 100644 index 000000000..e6253f016 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.html @@ -0,0 +1,391 @@ + + + + + + +ChangeSet + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Interface ChangeSet

+
+
+
public interface ChangeSet
+ + +

+


+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidaddAddition(java.io.InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + java.lang.String graphURI) + +
+          Adds one model change representing an addition to the list of model changes
+ voidaddRemoval(java.io.InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + java.lang.String graphURI) + +
+          Adds one model change representing a deletion to the list of model changes
+ java.util.List<ModelChange>getModelChanges() + +
+          Getter for the list of model changes
+ java.lang.StringgetPreconditionQuery() + +
+          Getter for the precondition query
+ RDFService.SPARQLQueryTypegetPreconditionQueryType() + +
+          Getter for the precondition query type
+ ModelChangemanufactureModelChange() + +
+          Creates an instance of the ModelChange class
+ ModelChangemanufactureModelChange(java.io.InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + ModelChange.Operation operation, + java.lang.String graphURI) + +
+          Creates an instance of the ModelChange class
+ voidsetPreconditionQuery(java.lang.String preconditionQuery) + +
+          Setter for the precondition query
+ voidsetPreconditionQueryType(RDFService.SPARQLQueryType queryType) + +
+          Setter for the precondition query type
+  +

+ + + + + + + + +
+Method Detail
+ +

+getPreconditionQuery

+
+java.lang.String getPreconditionQuery()
+
+
Getter for the precondition query +

+

+ +
Returns:
String - a SPARQL query
+
+
+
+ +

+setPreconditionQuery

+
+void setPreconditionQuery(java.lang.String preconditionQuery)
+
+
Setter for the precondition query +

+

+
Parameters:
preconditionQuery - - a SPARQL query
+
+
+
+ +

+getPreconditionQueryType

+
+RDFService.SPARQLQueryType getPreconditionQueryType()
+
+
Getter for the precondition query type +

+

+ +
Returns:
RDFService.SPARQLQueryType - the precondition query type
+
+
+
+ +

+setPreconditionQueryType

+
+void setPreconditionQueryType(RDFService.SPARQLQueryType queryType)
+
+
Setter for the precondition query type +

+

+
Parameters:
queryType - - the precondition query type
+
+
+
+ +

+getModelChanges

+
+java.util.List<ModelChange> getModelChanges()
+
+
Getter for the list of model changes +

+

+ +
Returns:
List - list of model changes
+
+
+
+ +

+addAddition

+
+void addAddition(java.io.InputStream model,
+                 RDFService.ModelSerializationFormat serializationFormat,
+                 java.lang.String graphURI)
+
+
Adds one model change representing an addition to the list of model changes +

+

+
Parameters:
model - - a serialized RDF model (collection of triples)
serializationFormat - - format of the serialized RDF model
graphURI - - URI of the graph to which the RDF model should be added
+
+
+
+ +

+addRemoval

+
+void addRemoval(java.io.InputStream model,
+                RDFService.ModelSerializationFormat serializationFormat,
+                java.lang.String graphURI)
+
+
Adds one model change representing a deletion to the list of model changes +

+

+
Parameters:
model - - a serialized RDF model (collection of triples)
serializationFormat - - format of the serialized RDF model
graphURI - - URI of the graph from which the RDF model should be removed
+
+
+
+ +

+manufactureModelChange

+
+ModelChange manufactureModelChange()
+
+
Creates an instance of the ModelChange class +

+

+
+
+
+
+ +

+manufactureModelChange

+
+ModelChange manufactureModelChange(java.io.InputStream serializedModel,
+                                   RDFService.ModelSerializationFormat serializationFormat,
+                                   ModelChange.Operation operation,
+                                   java.lang.String graphURI)
+
+
Creates an instance of the ModelChange class +

+

+
Parameters:
serializedModel - - a serialized RDF model (collection of triples)
serializationFormat - - format of the serialized RDF model
operation - - the type of operation to be performed with the serialized RDF model
graphURI - - URI of the graph on which to apply the model change operation
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.Operation.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.Operation.html new file mode 100644 index 000000000..5e2790179 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.Operation.html @@ -0,0 +1,323 @@ + + + + + + +ModelChange.Operation + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Enum ModelChange.Operation

+
+java.lang.Object
+  extended by java.lang.Enum<ModelChange.Operation>
+      extended by edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation
+
+
+
All Implemented Interfaces:
java.io.Serializable, java.lang.Comparable<ModelChange.Operation>
+
+
+
Enclosing interface:
ModelChange
+
+
+
+
public static enum ModelChange.Operation
extends java.lang.Enum<ModelChange.Operation>
+ + +

+


+ +

+ + + + + + + + + + + + + +
+Enum Constant Summary
ADD + +
+           
REMOVE + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static ModelChange.OperationvalueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static ModelChange.Operation[]values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+ + + + + + + +
Methods inherited from class java.lang.Enum
compareTo, equals, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Enum Constant Detail
+ +

+ADD

+
+public static final ModelChange.Operation ADD
+
+
+
+
+
+ +

+REMOVE

+
+public static final ModelChange.Operation REMOVE
+
+
+
+
+ + + + + + + + +
+Method Detail
+ +

+values

+
+public static ModelChange.Operation[] values()
+
+
Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
+for (ModelChange.Operation c : ModelChange.Operation.values())
+    System.out.println(c);
+
+

+

+ +
Returns:
an array containing the constants of this enum type, in +the order they are declared
+
+
+
+ +

+valueOf

+
+public static ModelChange.Operation valueOf(java.lang.String name)
+
+
Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.) +

+

+
Parameters:
name - the name of the enum constant to be returned. +
Returns:
the enum constant with the specified name +
Throws: +
java.lang.IllegalArgumentException - if this enum type has no constant +with the specified name +
java.lang.NullPointerException - if the argument is null
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.html new file mode 100644 index 000000000..ca99aff4b --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.html @@ -0,0 +1,374 @@ + + + + + + +ModelChange + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Interface ModelChange

+
+
+
public interface ModelChange
+ + +

+


+ +

+ + + + + + + + + + + +
+Nested Class Summary
+static classModelChange.Operation + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ java.lang.StringgetGraphURI() + +
+          Getter for the URI of the graph to which to apply the change
+ ModelChange.OperationgetOperation() + +
+          Getter for the operation type
+ RDFService.ModelSerializationFormatgetSerializationFormat() + +
+          Getter for the serialization format of the model
+ java.io.InputStreamgetSerializedModel() + +
+          Getter for the serialized model
+ voidsetGraphURI(java.lang.String graphURI) + +
+          Setter for the URI of the graph to which to apply the change
+ voidsetOperation(ModelChange.Operation operation) + +
+          Setter for the operation type
+ voidsetSerializationFormat(RDFService.ModelSerializationFormat serializationFormat) + +
+          Setter for the serialization format of the model
+ voidsetSerializedModel(java.io.InputStream serializedModel) + +
+          Setter for the serialized model
+  +

+ + + + + + + + +
+Method Detail
+ +

+getSerializedModel

+
+java.io.InputStream getSerializedModel()
+
+
Getter for the serialized model +

+

+ +
Returns:
InputStream - a serialized model (collection of RDF triples) representing a change to make
+
+
+
+ +

+setSerializedModel

+
+void setSerializedModel(java.io.InputStream serializedModel)
+
+
Setter for the serialized model +

+

+
Parameters:
serializedModel - - a serialized model (collection of RDF triples) representing a change to make
+
+
+
+ +

+getSerializationFormat

+
+RDFService.ModelSerializationFormat getSerializationFormat()
+
+
Getter for the serialization format of the model +

+

+ +
Returns:
RDFService.ModelSerializationFormat - the serialization format of the model
+
+
+
+ +

+setSerializationFormat

+
+void setSerializationFormat(RDFService.ModelSerializationFormat serializationFormat)
+
+
Setter for the serialization format of the model +

+

+
Parameters:
serializationFormat - - the serialization format of the model
+
+
+
+ +

+getOperation

+
+ModelChange.Operation getOperation()
+
+
Getter for the operation type +

+

+ +
Returns:
ModelChange.Operation - the operation to be performed
+
+
+
+ +

+setOperation

+
+void setOperation(ModelChange.Operation operation)
+
+
Setter for the operation type +

+

+
Parameters:
operation - - the operation to be performed
+
+
+
+ +

+getGraphURI

+
+java.lang.String getGraphURI()
+
+
Getter for the URI of the graph to which to apply the change +

+

+ +
Returns:
String - the URI of the graph to which to apply the change
+
+
+
+ +

+setGraphURI

+
+void setGraphURI(java.lang.String graphURI)
+
+
Setter for the URI of the graph to which to apply the change +

+

+
Parameters:
graphURI - - the URI of the graph to which to apply the change
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ModelSerializationFormat.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ModelSerializationFormat.html new file mode 100644 index 000000000..d0038052b --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ModelSerializationFormat.html @@ -0,0 +1,323 @@ + + + + + + +RDFService.ModelSerializationFormat + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Enum RDFService.ModelSerializationFormat

+
+java.lang.Object
+  extended by java.lang.Enum<RDFService.ModelSerializationFormat>
+      extended by edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat
+
+
+
All Implemented Interfaces:
java.io.Serializable, java.lang.Comparable<RDFService.ModelSerializationFormat>
+
+
+
Enclosing interface:
RDFService
+
+
+
+
public static enum RDFService.ModelSerializationFormat
extends java.lang.Enum<RDFService.ModelSerializationFormat>
+ + +

+


+ +

+ + + + + + + + + + + + + +
+Enum Constant Summary
N3 + +
+           
RDFXML + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static RDFService.ModelSerializationFormatvalueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.ModelSerializationFormat[]values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+ + + + + + + +
Methods inherited from class java.lang.Enum
compareTo, equals, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Enum Constant Detail
+ +

+RDFXML

+
+public static final RDFService.ModelSerializationFormat RDFXML
+
+
+
+
+
+ +

+N3

+
+public static final RDFService.ModelSerializationFormat N3
+
+
+
+
+ + + + + + + + +
+Method Detail
+ +

+values

+
+public static RDFService.ModelSerializationFormat[] values()
+
+
Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
+for (RDFService.ModelSerializationFormat c : RDFService.ModelSerializationFormat.values())
+    System.out.println(c);
+
+

+

+ +
Returns:
an array containing the constants of this enum type, in +the order they are declared
+
+
+
+ +

+valueOf

+
+public static RDFService.ModelSerializationFormat valueOf(java.lang.String name)
+
+
Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.) +

+

+
Parameters:
name - the name of the enum constant to be returned. +
Returns:
the enum constant with the specified name +
Throws: +
java.lang.IllegalArgumentException - if this enum type has no constant +with the specified name +
java.lang.NullPointerException - if the argument is null
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ResultFormat.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ResultFormat.html new file mode 100644 index 000000000..ade5fc894 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.ResultFormat.html @@ -0,0 +1,355 @@ + + + + + + +RDFService.ResultFormat + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Enum RDFService.ResultFormat

+
+java.lang.Object
+  extended by java.lang.Enum<RDFService.ResultFormat>
+      extended by edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat
+
+
+
All Implemented Interfaces:
java.io.Serializable, java.lang.Comparable<RDFService.ResultFormat>
+
+
+
Enclosing interface:
RDFService
+
+
+
+
public static enum RDFService.ResultFormat
extends java.lang.Enum<RDFService.ResultFormat>
+ + +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Enum Constant Summary
CSV + +
+           
JSON + +
+           
TEXT + +
+           
XML + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static RDFService.ResultFormatvalueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.ResultFormat[]values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+ + + + + + + +
Methods inherited from class java.lang.Enum
compareTo, equals, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Enum Constant Detail
+ +

+JSON

+
+public static final RDFService.ResultFormat JSON
+
+
+
+
+
+ +

+CSV

+
+public static final RDFService.ResultFormat CSV
+
+
+
+
+
+ +

+XML

+
+public static final RDFService.ResultFormat XML
+
+
+
+
+
+ +

+TEXT

+
+public static final RDFService.ResultFormat TEXT
+
+
+
+
+ + + + + + + + +
+Method Detail
+ +

+values

+
+public static RDFService.ResultFormat[] values()
+
+
Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
+for (RDFService.ResultFormat c : RDFService.ResultFormat.values())
+    System.out.println(c);
+
+

+

+ +
Returns:
an array containing the constants of this enum type, in +the order they are declared
+
+
+
+ +

+valueOf

+
+public static RDFService.ResultFormat valueOf(java.lang.String name)
+
+
Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.) +

+

+
Parameters:
name - the name of the enum constant to be returned. +
Returns:
the enum constant with the specified name +
Throws: +
java.lang.IllegalArgumentException - if this enum type has no constant +with the specified name +
java.lang.NullPointerException - if the argument is null
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.SPARQLQueryType.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.SPARQLQueryType.html new file mode 100644 index 000000000..a9b5b5f16 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.SPARQLQueryType.html @@ -0,0 +1,355 @@ + + + + + + +RDFService.SPARQLQueryType + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Enum RDFService.SPARQLQueryType

+
+java.lang.Object
+  extended by java.lang.Enum<RDFService.SPARQLQueryType>
+      extended by edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.SPARQLQueryType
+
+
+
All Implemented Interfaces:
java.io.Serializable, java.lang.Comparable<RDFService.SPARQLQueryType>
+
+
+
Enclosing interface:
RDFService
+
+
+
+
public static enum RDFService.SPARQLQueryType
extends java.lang.Enum<RDFService.SPARQLQueryType>
+ + +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Enum Constant Summary
ASK + +
+           
CONSTRUCT + +
+           
DESCRIBE + +
+           
SELECT + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static RDFService.SPARQLQueryTypevalueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.SPARQLQueryType[]values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+ + + + + + + +
Methods inherited from class java.lang.Enum
compareTo, equals, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Enum Constant Detail
+ +

+SELECT

+
+public static final RDFService.SPARQLQueryType SELECT
+
+
+
+
+
+ +

+CONSTRUCT

+
+public static final RDFService.SPARQLQueryType CONSTRUCT
+
+
+
+
+
+ +

+DESCRIBE

+
+public static final RDFService.SPARQLQueryType DESCRIBE
+
+
+
+
+
+ +

+ASK

+
+public static final RDFService.SPARQLQueryType ASK
+
+
+
+
+ + + + + + + + +
+Method Detail
+ +

+values

+
+public static RDFService.SPARQLQueryType[] values()
+
+
Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
+for (RDFService.SPARQLQueryType c : RDFService.SPARQLQueryType.values())
+    System.out.println(c);
+
+

+

+ +
Returns:
an array containing the constants of this enum type, in +the order they are declared
+
+
+
+ +

+valueOf

+
+public static RDFService.SPARQLQueryType valueOf(java.lang.String name)
+
+
Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.) +

+

+
Parameters:
name - the name of the enum constant to be returned. +
Returns:
the enum constant with the specified name +
Throws: +
java.lang.IllegalArgumentException - if this enum type has no constant +with the specified name +
java.lang.NullPointerException - if the argument is null
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.html new file mode 100644 index 000000000..578c6f18c --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.html @@ -0,0 +1,568 @@ + + + + + + +RDFService + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Interface RDFService

+
+
+
public interface RDFService
+ + +

+


+ +

+ + + + + + + + + + + + + + + + + + + +
+Nested Class Summary
+static classRDFService.ModelSerializationFormat + +
+           
+static classRDFService.ResultFormat + +
+           
+static classRDFService.SPARQLQueryType + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanchangeSetUpdate(ChangeSet changeSet) + +
+          Perform a series of additions to and or removals from specified graphs + in the RDF store.
+ java.lang.StringgetDefaultWriteGraphURI() + +
+          Get the URI of the default write graph
+ voidgetGraphMetadata() + +
+          TBD - we need to define this method
+ java.util.List<java.lang.String>getGraphURIs() + +
+          Get a list of all the graph URIs in the RDF store.
+ ChangeSetmanufactureChangeSet() + +
+          Create a ChangeSet object
+ voidnewIndividual(java.lang.String individualURI, + java.lang.String individualTypeURI) + +
+          If the given individual already exists in the default graph, throws an + RDFServiceException, otherwise adds one type assertion to the default + graph.
+ voidnewIndividual(java.lang.String individualURI, + java.lang.String individualTypeURI, + java.lang.String graphURI) + +
+          If the given individual already exists in the given graph, throws an + RDFServiceException, otherwise adds one type assertion to the given + graph.
+ voidregisterListener(ChangeListener changeListener) + +
+          Register a listener to listen to changes in any graph in + the RDF store.
+ booleansparqlAskQuery(java.lang.String query) + +
+          Performs a SPARQL ASK query against the knowledge base.
+ java.io.InputStreamsparqlConstructQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL construct query against the knowledge base.
+ java.io.InputStreamsparqlDescribeQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL describe query against the knowledge base.
+ java.io.InputStreamsparqlSelectQuery(java.lang.String query, + RDFService.ResultFormat resultFormat) + +
+          Performs a SPARQL select query against the knowledge base.
+ voidunregisterListener(ChangeListener changeListener) + +
+          Unregister a listener from listening to changes in + the RDF store in any graph.
+  +

+ + + + + + + + +
+Method Detail
+ +

+changeSetUpdate

+
+boolean changeSetUpdate(ChangeSet changeSet)
+                        throws RDFServiceException
+
+
Perform a series of additions to and or removals from specified graphs + in the RDF store. preConditionSparql will be executed against the + union of all the graphs in the knowledge base before any updates are made. + If the precondition query returns a non-empty result, no updates + will be made. +

+

+
Parameters:
changeSet - - a set of changes to be performed on the RDF store. +
Returns:
boolean - indicates whether the precondition was satisfied +
Throws: +
RDFServiceException
+
+
+
+ +

+newIndividual

+
+void newIndividual(java.lang.String individualURI,
+                   java.lang.String individualTypeURI)
+                   throws RDFServiceException
+
+
If the given individual already exists in the default graph, throws an + RDFServiceException, otherwise adds one type assertion to the default + graph. +

+

+
Parameters:
individualURI - - URI of the individual to be added
individualTypeURI - - URI of the type for the individual +
Throws: +
RDFServiceException
+
+
+
+ +

+newIndividual

+
+void newIndividual(java.lang.String individualURI,
+                   java.lang.String individualTypeURI,
+                   java.lang.String graphURI)
+                   throws RDFServiceException
+
+
If the given individual already exists in the given graph, throws an + RDFServiceException, otherwise adds one type assertion to the given + graph. +

+

+
Parameters:
individualURI - - URI of the individual to be added
individualTypeURI - - URI of the type for the individual
graphURI - - URI of the graph to which to add the individual +
Throws: +
RDFServiceException
+
+
+
+ +

+sparqlConstructQuery

+
+java.io.InputStream sparqlConstructQuery(java.lang.String query,
+                                         RDFService.ModelSerializationFormat resultFormat)
+                                         throws RDFServiceException
+
+
Performs a SPARQL construct query against the knowledge base. The query may have + an embedded graph identifier. +

+

+
Parameters:
query - - the SPARQL query to be executed against the RDF store
resultFormat - - type of serialization for RDF result of the SPARQL query +
Returns:
InputStream - the result of the query +
Throws: +
RDFServiceException
+
+
+
+ +

+sparqlDescribeQuery

+
+java.io.InputStream sparqlDescribeQuery(java.lang.String query,
+                                        RDFService.ModelSerializationFormat resultFormat)
+                                        throws RDFServiceException
+
+
Performs a SPARQL describe query against the knowledge base. The query may have + an embedded graph identifier. +

+

+
Parameters:
query - - the SPARQL query to be executed against the RDF store
resultFormat - - type of serialization for RDF result of the SPARQL query +
Returns:
InputStream - the result of the query +
Throws: +
RDFServiceException
+
+
+
+ +

+sparqlSelectQuery

+
+java.io.InputStream sparqlSelectQuery(java.lang.String query,
+                                      RDFService.ResultFormat resultFormat)
+                                      throws RDFServiceException
+
+
Performs a SPARQL select query against the knowledge base. The query may have + an embedded graph identifier. +

+

+
Parameters:
query - - the SPARQL query to be executed against the RDF store
resultFormat - - format for the result of the Select query +
Returns:
InputStream - the result of the query +
Throws: +
RDFServiceException
+
+
+
+ +

+sparqlAskQuery

+
+boolean sparqlAskQuery(java.lang.String query)
+                       throws RDFServiceException
+
+
Performs a SPARQL ASK query against the knowledge base. The query may have + an embedded graph identifier. +

+

+
Parameters:
query - - the SPARQL query to be executed against the RDF store +
Returns:
boolean - the result of the SPARQL query +
Throws: +
RDFServiceException
+
+
+
+ +

+getGraphURIs

+
+java.util.List<java.lang.String> getGraphURIs()
+                                              throws RDFServiceException
+
+
Get a list of all the graph URIs in the RDF store. +

+

+ +
Returns:
List - list of all the graph URIs in the RDF store +
Throws: +
RDFServiceException
+
+
+
+ +

+getGraphMetadata

+
+void getGraphMetadata()
+                      throws RDFServiceException
+
+
TBD - we need to define this method +

+

+ +
Throws: +
RDFServiceException
+
+
+
+ +

+getDefaultWriteGraphURI

+
+java.lang.String getDefaultWriteGraphURI()
+                                         throws RDFServiceException
+
+
Get the URI of the default write graph +

+

+ +
Returns:
String URI of default write graph +
Throws: +
RDFServiceException
+
+
+
+ +

+registerListener

+
+void registerListener(ChangeListener changeListener)
+                      throws RDFServiceException
+
+
Register a listener to listen to changes in any graph in + the RDF store. +

+

+
Parameters:
changeListener - - the change listener +
Throws: +
RDFServiceException
+
+
+
+ +

+unregisterListener

+
+void unregisterListener(ChangeListener changeListener)
+                        throws RDFServiceException
+
+
Unregister a listener from listening to changes in + the RDF store in any graph. +

+

+
Parameters:
changeListener - - the change listener +
Throws: +
RDFServiceException
+
+
+
+ +

+manufactureChangeSet

+
+ChangeSet manufactureChangeSet()
+
+
Create a ChangeSet object +

+

+ +
Returns:
ChangeSet an empty ChangeSet object
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.html new file mode 100644 index 000000000..faceaf9d8 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.html @@ -0,0 +1,252 @@ + + + + + + +RDFServiceException + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +edu.cornell.mannlib.vitro.webapp.rdfservice +
+Class RDFServiceException

+
+java.lang.Object
+  extended by java.lang.Throwable
+      extended by java.lang.Exception
+          extended by edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException
+
+
+
All Implemented Interfaces:
java.io.Serializable
+
+
+
+
public class RDFServiceException
extends java.lang.Exception
+ + +

+

+
See Also:
Serialized Form
+
+ +

+ + + + + + + + + + + + + + +
+Constructor Summary
RDFServiceException() + +
+           
RDFServiceException(java.lang.String message) + +
+           
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+RDFServiceException

+
+public RDFServiceException()
+
+
+
+ +

+RDFServiceException

+
+public RDFServiceException(java.lang.String message)
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeListener.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeListener.html new file mode 100644 index 000000000..131314010 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeListener.html @@ -0,0 +1,175 @@ + + + + + + +Uses of Interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener

+
+ + + + + +
+Uses of ChangeListener in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type ChangeListener
+ voidRDFService.registerListener(ChangeListener changeListener) + +
+          Register a listener to listen to changes in any graph in + the RDF store.
+ voidRDFService.unregisterListener(ChangeListener changeListener) + +
+          Unregister a listener from listening to changes in + the RDF store in any graph.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeSet.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeSet.html new file mode 100644 index 000000000..75dd4d46b --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ChangeSet.html @@ -0,0 +1,182 @@ + + + + + + +Uses of Interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet

+
+ + + + + +
+Uses of ChangeSet in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return ChangeSet
+ ChangeSetRDFService.manufactureChangeSet() + +
+          Create a ChangeSet object
+  +

+ + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type ChangeSet
+ booleanRDFService.changeSetUpdate(ChangeSet changeSet) + +
+          Perform a series of additions to and or removals from specified graphs + in the RDF store.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.Operation.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.Operation.html new file mode 100644 index 000000000..909bb7595 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.Operation.html @@ -0,0 +1,209 @@ + + + + + + +Uses of Class edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation

+
+ + + + + +
+Uses of ModelChange.Operation in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return ModelChange.Operation
+ ModelChange.OperationModelChange.getOperation() + +
+          Getter for the operation type
+static ModelChange.OperationModelChange.Operation.valueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static ModelChange.Operation[]ModelChange.Operation.values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+  +

+ + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type ModelChange.Operation
+ ModelChangeChangeSet.manufactureModelChange(java.io.InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + ModelChange.Operation operation, + java.lang.String graphURI) + +
+          Creates an instance of the ModelChange class
+ voidModelChange.setOperation(ModelChange.Operation operation) + +
+          Setter for the operation type
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.html new file mode 100644 index 000000000..186b30efc --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/ModelChange.html @@ -0,0 +1,192 @@ + + + + + + +Uses of Interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange

+
+ + + + + +
+Uses of ModelChange in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return ModelChange
+ ModelChangeChangeSet.manufactureModelChange() + +
+          Creates an instance of the ModelChange class
+ ModelChangeChangeSet.manufactureModelChange(java.io.InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + ModelChange.Operation operation, + java.lang.String graphURI) + +
+          Creates an instance of the ModelChange class
+  +

+ + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return types with arguments of type ModelChange
+ java.util.List<ModelChange>ChangeSet.getModelChanges() + +
+          Getter for the list of model changes
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ModelSerializationFormat.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ModelSerializationFormat.html new file mode 100644 index 000000000..8659180bc --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ModelSerializationFormat.html @@ -0,0 +1,247 @@ + + + + + + +Uses of Class edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat

+
+ + + + + +
+Uses of RDFService.ModelSerializationFormat in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return RDFService.ModelSerializationFormat
+ RDFService.ModelSerializationFormatModelChange.getSerializationFormat() + +
+          Getter for the serialization format of the model
+static RDFService.ModelSerializationFormatRDFService.ModelSerializationFormat.valueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.ModelSerializationFormat[]RDFService.ModelSerializationFormat.values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type RDFService.ModelSerializationFormat
+ voidChangeSet.addAddition(java.io.InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + java.lang.String graphURI) + +
+          Adds one model change representing an addition to the list of model changes
+ voidChangeSet.addRemoval(java.io.InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + java.lang.String graphURI) + +
+          Adds one model change representing a deletion to the list of model changes
+ ModelChangeChangeSet.manufactureModelChange(java.io.InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + ModelChange.Operation operation, + java.lang.String graphURI) + +
+          Creates an instance of the ModelChange class
+ voidModelChange.setSerializationFormat(RDFService.ModelSerializationFormat serializationFormat) + +
+          Setter for the serialization format of the model
+ java.io.InputStreamRDFService.sparqlConstructQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL construct query against the knowledge base.
+ java.io.InputStreamRDFService.sparqlDescribeQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL describe query against the knowledge base.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ResultFormat.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ResultFormat.html new file mode 100644 index 000000000..bba06f3da --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.ResultFormat.html @@ -0,0 +1,191 @@ + + + + + + +Uses of Class edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat

+
+ + + + + +
+Uses of RDFService.ResultFormat in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return RDFService.ResultFormat
+static RDFService.ResultFormatRDFService.ResultFormat.valueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.ResultFormat[]RDFService.ResultFormat.values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+  +

+ + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type RDFService.ResultFormat
+ java.io.InputStreamRDFService.sparqlSelectQuery(java.lang.String query, + RDFService.ResultFormat resultFormat) + +
+          Performs a SPARQL select query against the knowledge base.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.SPARQLQueryType.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.SPARQLQueryType.html new file mode 100644 index 000000000..274bf20f0 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.SPARQLQueryType.html @@ -0,0 +1,198 @@ + + + + + + +Uses of Class edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.SPARQLQueryType + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.SPARQLQueryType

+
+ + + + + +
+Uses of RDFService.SPARQLQueryType in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that return RDFService.SPARQLQueryType
+ RDFService.SPARQLQueryTypeChangeSet.getPreconditionQueryType() + +
+          Getter for the precondition query type
+static RDFService.SPARQLQueryTypeRDFService.SPARQLQueryType.valueOf(java.lang.String name) + +
+          Returns the enum constant of this type with the specified name.
+static RDFService.SPARQLQueryType[]RDFService.SPARQLQueryType.values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+  +

+ + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice with parameters of type RDFService.SPARQLQueryType
+ voidChangeSet.setPreconditionQueryType(RDFService.SPARQLQueryType queryType) + +
+          Setter for the precondition query type
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.html new file mode 100644 index 000000000..68e7f2658 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFService.html @@ -0,0 +1,142 @@ + + + + + + +Uses of Interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService

+
+No usage of edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFServiceException.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFServiceException.html new file mode 100644 index 000000000..c4599885d --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/class-use/RDFServiceException.html @@ -0,0 +1,266 @@ + + + + + + +Uses of Class edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException

+
+ + + + + +
+Uses of RDFServiceException in edu.cornell.mannlib.vitro.webapp.rdfservice
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in edu.cornell.mannlib.vitro.webapp.rdfservice that throw RDFServiceException
+ booleanRDFService.changeSetUpdate(ChangeSet changeSet) + +
+          Perform a series of additions to and or removals from specified graphs + in the RDF store.
+ java.lang.StringRDFService.getDefaultWriteGraphURI() + +
+          Get the URI of the default write graph
+ voidRDFService.getGraphMetadata() + +
+          TBD - we need to define this method
+ java.util.List<java.lang.String>RDFService.getGraphURIs() + +
+          Get a list of all the graph URIs in the RDF store.
+ voidRDFService.newIndividual(java.lang.String individualURI, + java.lang.String individualTypeURI) + +
+          If the given individual already exists in the default graph, throws an + RDFServiceException, otherwise adds one type assertion to the default + graph.
+ voidRDFService.newIndividual(java.lang.String individualURI, + java.lang.String individualTypeURI, + java.lang.String graphURI) + +
+          If the given individual already exists in the given graph, throws an + RDFServiceException, otherwise adds one type assertion to the given + graph.
+ voidRDFService.registerListener(ChangeListener changeListener) + +
+          Register a listener to listen to changes in any graph in + the RDF store.
+ booleanRDFService.sparqlAskQuery(java.lang.String query) + +
+          Performs a SPARQL ASK query against the knowledge base.
+ java.io.InputStreamRDFService.sparqlConstructQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL construct query against the knowledge base.
+ java.io.InputStreamRDFService.sparqlDescribeQuery(java.lang.String query, + RDFService.ModelSerializationFormat resultFormat) + +
+          Performs a SPARQL describe query against the knowledge base.
+ java.io.InputStreamRDFService.sparqlSelectQuery(java.lang.String query, + RDFService.ResultFormat resultFormat) + +
+          Performs a SPARQL select query against the knowledge base.
+ voidRDFService.unregisterListener(ChangeListener changeListener) + +
+          Unregister a listener from listening to changes in + the RDF store in any graph.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-frame.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-frame.html new file mode 100644 index 000000000..88d3920d9 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-frame.html @@ -0,0 +1,66 @@ + + + + + + +edu.cornell.mannlib.vitro.webapp.rdfservice + + + + + + + + + + + +edu.cornell.mannlib.vitro.webapp.rdfservice + + + + +
+Interfaces  + +
+ChangeListener +
+ChangeSet +
+ModelChange +
+RDFService
+ + + + + + +
+Enums  + +
+ModelChange.Operation +
+RDFService.ModelSerializationFormat +
+RDFService.ResultFormat +
+RDFService.SPARQLQueryType
+ + + + + + +
+Exceptions  + +
+RDFServiceException
+ + + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-summary.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-summary.html new file mode 100644 index 000000000..da2059877 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-summary.html @@ -0,0 +1,207 @@ + + + + + + +edu.cornell.mannlib.vitro.webapp.rdfservice + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package edu.cornell.mannlib.vitro.webapp.rdfservice +

+ + + + + + + + + + + + + + + + + + + + + +
+Interface Summary
ChangeListener 
ChangeSet 
ModelChange 
RDFService 
+  + +

+ + + + + + + + + + + + + + + + + + + + + +
+Enum Summary
ModelChange.Operation 
RDFService.ModelSerializationFormat 
RDFService.ResultFormat 
RDFService.SPARQLQueryType 
+  + +

+ + + + + + + + + +
+Exception Summary
RDFServiceException 
+  + +

+

+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-tree.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-tree.html new file mode 100644 index 000000000..2c7e2fd7b --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-tree.html @@ -0,0 +1,168 @@ + + + + + + +edu.cornell.mannlib.vitro.webapp.rdfservice Class Hierarchy + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package edu.cornell.mannlib.vitro.webapp.rdfservice +

+
+

+Class Hierarchy +

+ +

+Interface Hierarchy +

+ +

+Enum Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-use.html b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-use.html new file mode 100644 index 000000000..89bd67032 --- /dev/null +++ b/doc/rdfservice/doc/edu/cornell/mannlib/vitro/webapp/rdfservice/package-use.html @@ -0,0 +1,197 @@ + + + + + + +Uses of Package edu.cornell.mannlib.vitro.webapp.rdfservice + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
edu.cornell.mannlib.vitro.webapp.rdfservice

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Classes in edu.cornell.mannlib.vitro.webapp.rdfservice used by edu.cornell.mannlib.vitro.webapp.rdfservice
ChangeListener + +
+           
ChangeSet + +
+           
ModelChange + +
+           
ModelChange.Operation + +
+           
RDFService.ModelSerializationFormat + +
+           
RDFService.ResultFormat + +
+           
RDFService.SPARQLQueryType + +
+           
RDFServiceException + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/help-doc.html b/doc/rdfservice/doc/help-doc.html new file mode 100644 index 000000000..d773383c3 --- /dev/null +++ b/doc/rdfservice/doc/help-doc.html @@ -0,0 +1,215 @@ + + + + + + +API Help + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+ +

+Annotation Type

+
+ +

+Each annotation type has its own separate page with the following sections:

+
+ +

+Enum

+
+ +

+Each enum has its own separate page with the following sections:

+
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object. +
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+

+Constant Field Values

+The Constant Field Values page lists the static final fields and their values. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/index-files/index-1.html b/doc/rdfservice/doc/index-files/index-1.html new file mode 100644 index 000000000..f71528d71 --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-1.html @@ -0,0 +1,149 @@ + + + + + + +A-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+A

+
+
addAddition(InputStream, RDFService.ModelSerializationFormat, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Adds one model change representing an addition to the list of model changes +
addedStatement(String, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener +
Override this to listen to all statements added to the RDF store. +
addRemoval(InputStream, RDFService.ModelSerializationFormat, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Adds one model change representing a deletion to the list of model changes +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-10.html b/doc/rdfservice/doc/index-files/index-10.html new file mode 100644 index 000000000..9dc7029d6 --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-10.html @@ -0,0 +1,168 @@ + + + + + + +V-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+V

+
+
valueOf(String) - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation +
Returns the enum constant of this type with the specified name. +
valueOf(String) - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat +
Returns the enum constant of this type with the specified name. +
valueOf(String) - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat +
Returns the enum constant of this type with the specified name. +
valueOf(String) - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.SPARQLQueryType +
Returns the enum constant of this type with the specified name. +
values() - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation +
Returns an array containing the constants of this enum type, in +the order they are declared. +
values() - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat +
Returns an array containing the constants of this enum type, in +the order they are declared. +
values() - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat +
Returns an array containing the constants of this enum type, in +the order they are declared. +
values() - +Static method in enum edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.SPARQLQueryType +
Returns an array containing the constants of this enum type, in +the order they are declared. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-2.html b/doc/rdfservice/doc/index-files/index-2.html new file mode 100644 index 000000000..5c8b8423f --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-2.html @@ -0,0 +1,144 @@ + + + + + + +C-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+C

+
+
ChangeListener - Interface in edu.cornell.mannlib.vitro.webapp.rdfservice
 
ChangeSet - Interface in edu.cornell.mannlib.vitro.webapp.rdfservice
 
changeSetUpdate(ChangeSet) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Perform a series of additions to and or removals from specified graphs + in the RDF store. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-3.html b/doc/rdfservice/doc/index-files/index-3.html new file mode 100644 index 000000000..43c9bbdee --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-3.html @@ -0,0 +1,140 @@ + + + + + + +E-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+E

+
+
edu.cornell.mannlib.vitro.webapp.rdfservice - package edu.cornell.mannlib.vitro.webapp.rdfservice
 
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-4.html b/doc/rdfservice/doc/index-files/index-4.html new file mode 100644 index 000000000..0be8982d0 --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-4.html @@ -0,0 +1,170 @@ + + + + + + +G-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+G

+
+
getDefaultWriteGraphURI() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Get the URI of the default write graph +
getGraphMetadata() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
TBD - we need to define this method +
getGraphURI() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Getter for the URI of the graph to which to apply the change +
getGraphURIs() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Get a list of all the graph URIs in the RDF store. +
getModelChanges() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Getter for the list of model changes +
getOperation() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Getter for the operation type +
getPreconditionQuery() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Getter for the precondition query +
getPreconditionQueryType() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Getter for the precondition query type +
getSerializationFormat() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Getter for the serialization format of the model +
getSerializedModel() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Getter for the serialized model +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-5.html b/doc/rdfservice/doc/index-files/index-5.html new file mode 100644 index 000000000..93543c14e --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-5.html @@ -0,0 +1,149 @@ + + + + + + +M-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+M

+
+
manufactureChangeSet() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Create a ChangeSet object +
manufactureModelChange() - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Creates an instance of the ModelChange class +
manufactureModelChange(InputStream, RDFService.ModelSerializationFormat, ModelChange.Operation, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Creates an instance of the ModelChange class +
ModelChange - Interface in edu.cornell.mannlib.vitro.webapp.rdfservice
 
ModelChange.Operation - Enum in edu.cornell.mannlib.vitro.webapp.rdfservice
 
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-6.html b/doc/rdfservice/doc/index-files/index-6.html new file mode 100644 index 000000000..dad3eed7b --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-6.html @@ -0,0 +1,153 @@ + + + + + + +N-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+N

+
+
newIndividual(String, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
If the given individual already exists in the default graph, throws an + RDFServiceException, otherwise adds one type assertion to the default + graph. +
newIndividual(String, String, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
If the given individual already exists in the given graph, throws an + RDFServiceException, otherwise adds one type assertion to the given + graph. +
notifyEvent(String, Object) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener +
Override this to listen to events pertaining to the given graphURI. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-7.html b/doc/rdfservice/doc/index-files/index-7.html new file mode 100644 index 000000000..e832fa11c --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-7.html @@ -0,0 +1,153 @@ + + + + + + +R-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+R

+
+
RDFService - Interface in edu.cornell.mannlib.vitro.webapp.rdfservice
 
RDFService.ModelSerializationFormat - Enum in edu.cornell.mannlib.vitro.webapp.rdfservice
 
RDFService.ResultFormat - Enum in edu.cornell.mannlib.vitro.webapp.rdfservice
 
RDFService.SPARQLQueryType - Enum in edu.cornell.mannlib.vitro.webapp.rdfservice
 
RDFServiceException - Exception in edu.cornell.mannlib.vitro.webapp.rdfservice
 
RDFServiceException() - +Constructor for exception edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException +
  +
RDFServiceException(String) - +Constructor for exception edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException +
  +
registerListener(ChangeListener) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Register a listener to listen to changes in any graph in + the RDF store. +
removedStatement(String, String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener +
Override this to listen to all statements removed from the RDF store. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-8.html b/doc/rdfservice/doc/index-files/index-8.html new file mode 100644 index 000000000..47704fddb --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-8.html @@ -0,0 +1,170 @@ + + + + + + +S-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+S

+
+
setGraphURI(String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Setter for the URI of the graph to which to apply the change +
setOperation(ModelChange.Operation) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Setter for the operation type +
setPreconditionQuery(String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Setter for the precondition query +
setPreconditionQueryType(RDFService.SPARQLQueryType) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet +
Setter for the precondition query type +
setSerializationFormat(RDFService.ModelSerializationFormat) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Setter for the serialization format of the model +
setSerializedModel(InputStream) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange +
Setter for the serialized model +
sparqlAskQuery(String) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Performs a SPARQL ASK query against the knowledge base. +
sparqlConstructQuery(String, RDFService.ModelSerializationFormat) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Performs a SPARQL construct query against the knowledge base. +
sparqlDescribeQuery(String, RDFService.ModelSerializationFormat) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Performs a SPARQL describe query against the knowledge base. +
sparqlSelectQuery(String, RDFService.ResultFormat) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Performs a SPARQL select query against the knowledge base. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index-files/index-9.html b/doc/rdfservice/doc/index-files/index-9.html new file mode 100644 index 000000000..c00edc195 --- /dev/null +++ b/doc/rdfservice/doc/index-files/index-9.html @@ -0,0 +1,144 @@ + + + + + + +U-Index + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+

+U

+
+
unregisterListener(ChangeListener) - +Method in interface edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService +
Unregister a listener from listening to changes in + the RDF store in any graph. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C E G M N R S U V
+ + + diff --git a/doc/rdfservice/doc/index.html b/doc/rdfservice/doc/index.html new file mode 100644 index 000000000..fb8a9ddc2 --- /dev/null +++ b/doc/rdfservice/doc/index.html @@ -0,0 +1,36 @@ + + + + + + +Generated Documentation (Untitled) + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="edu/cornell/mannlib/vitro/webapp/rdfservice/package-summary.html">Non-frame version.</A> + + + diff --git a/doc/rdfservice/doc/overview-tree.html b/doc/rdfservice/doc/overview-tree.html new file mode 100644 index 000000000..3ae2b215c --- /dev/null +++ b/doc/rdfservice/doc/overview-tree.html @@ -0,0 +1,170 @@ + + + + + + +Class Hierarchy + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
edu.cornell.mannlib.vitro.webapp.rdfservice
+
+

+Class Hierarchy +

+ +

+Interface Hierarchy +

+ +

+Enum Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/package-list b/doc/rdfservice/doc/package-list new file mode 100644 index 000000000..eca5affca --- /dev/null +++ b/doc/rdfservice/doc/package-list @@ -0,0 +1 @@ +edu.cornell.mannlib.vitro.webapp.rdfservice diff --git a/doc/rdfservice/doc/resources/inherit.gif b/doc/rdfservice/doc/resources/inherit.gif new file mode 100644 index 000000000..c814867a1 Binary files /dev/null and b/doc/rdfservice/doc/resources/inherit.gif differ diff --git a/doc/rdfservice/doc/serialized-form.html b/doc/rdfservice/doc/serialized-form.html new file mode 100644 index 000000000..b647d910b --- /dev/null +++ b/doc/rdfservice/doc/serialized-form.html @@ -0,0 +1,161 @@ + + + + + + +Serialized Form + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Serialized Form

+
+
+ + + + + +
+Package edu.cornell.mannlib.vitro.webapp.rdfservice
+ +

+ + + + + +
+Class edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException extends java.lang.Exception implements Serializable
+ +

+ +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ + + diff --git a/doc/rdfservice/doc/stylesheet.css b/doc/rdfservice/doc/stylesheet.css new file mode 100644 index 000000000..6ea9e5161 --- /dev/null +++ b/doc/rdfservice/doc/stylesheet.css @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF; color:#000000 } + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */ +.TableRowColor { background: #FFFFFF; color:#000000 } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} + diff --git a/webapp/lib/aduna-commons-collections-2.3.jar b/webapp/lib/aduna-commons-collections-2.3.jar deleted file mode 100644 index 665f995d9..000000000 Binary files a/webapp/lib/aduna-commons-collections-2.3.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-concurrent-2.2.jar b/webapp/lib/aduna-commons-concurrent-2.2.jar deleted file mode 100644 index f2d73fdf7..000000000 Binary files a/webapp/lib/aduna-commons-concurrent-2.2.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-io-2.4.jar b/webapp/lib/aduna-commons-io-2.4.jar deleted file mode 100644 index 6642ac658..000000000 Binary files a/webapp/lib/aduna-commons-io-2.4.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-iteration-2.3.jar b/webapp/lib/aduna-commons-iteration-2.3.jar deleted file mode 100644 index 366d2cbe6..000000000 Binary files a/webapp/lib/aduna-commons-iteration-2.3.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-lang-2.2.jar b/webapp/lib/aduna-commons-lang-2.2.jar deleted file mode 100644 index 842faee4b..000000000 Binary files a/webapp/lib/aduna-commons-lang-2.2.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-net-2.2.jar b/webapp/lib/aduna-commons-net-2.2.jar deleted file mode 100644 index 88273c0c9..000000000 Binary files a/webapp/lib/aduna-commons-net-2.2.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-text-2.2.jar b/webapp/lib/aduna-commons-text-2.2.jar deleted file mode 100644 index 76b817335..000000000 Binary files a/webapp/lib/aduna-commons-text-2.2.jar and /dev/null differ diff --git a/webapp/lib/aduna-commons-xml-2.2.jar b/webapp/lib/aduna-commons-xml-2.2.jar deleted file mode 100644 index 76ece0936..000000000 Binary files a/webapp/lib/aduna-commons-xml-2.2.jar and /dev/null differ diff --git a/webapp/lib/aopalliance-1.0.jar b/webapp/lib/aopalliance-1.0.jar new file mode 100644 index 000000000..578b1a0c3 Binary files /dev/null and b/webapp/lib/aopalliance-1.0.jar differ diff --git a/webapp/lib/asm-3.1.jar b/webapp/lib/asm-3.1.jar new file mode 100644 index 000000000..8217cae0a Binary files /dev/null and b/webapp/lib/asm-3.1.jar differ diff --git a/webapp/lib/cglib-2.2.jar b/webapp/lib/cglib-2.2.jar new file mode 100644 index 000000000..084ef6e54 Binary files /dev/null and b/webapp/lib/cglib-2.2.jar differ diff --git a/webapp/lib/commons-cli-1.2.jar b/webapp/lib/commons-cli-1.2.jar new file mode 100644 index 000000000..ce4b9fffe Binary files /dev/null and b/webapp/lib/commons-cli-1.2.jar differ diff --git a/webapp/lib/commons-codec-1.4.jar b/webapp/lib/commons-codec-1.4.jar new file mode 100644 index 000000000..458d432da Binary files /dev/null and b/webapp/lib/commons-codec-1.4.jar differ diff --git a/webapp/lib/commons-dbcp-1.3.jar b/webapp/lib/commons-dbcp-1.3.jar new file mode 100644 index 000000000..d29339738 Binary files /dev/null and b/webapp/lib/commons-dbcp-1.3.jar differ diff --git a/webapp/lib/commons-pool-1.5.4.jar b/webapp/lib/commons-pool-1.5.4.jar new file mode 100644 index 000000000..43edf9963 Binary files /dev/null and b/webapp/lib/commons-pool-1.5.4.jar differ diff --git a/webapp/lib/spring-aop-2.5.6.jar b/webapp/lib/spring-aop-2.5.6.jar new file mode 100644 index 000000000..a11cc3aa5 Binary files /dev/null and b/webapp/lib/spring-aop-2.5.6.jar differ diff --git a/webapp/lib/spring-beans-2.5.6.jar b/webapp/lib/spring-beans-2.5.6.jar new file mode 100644 index 000000000..3f306b673 Binary files /dev/null and b/webapp/lib/spring-beans-2.5.6.jar differ diff --git a/webapp/lib/spring-context-2.5.6.jar b/webapp/lib/spring-context-2.5.6.jar new file mode 100644 index 000000000..29fabcc1d Binary files /dev/null and b/webapp/lib/spring-context-2.5.6.jar differ diff --git a/webapp/lib/spring-context-support-2.5.6.jar b/webapp/lib/spring-context-support-2.5.6.jar new file mode 100644 index 000000000..2927c6ebf Binary files /dev/null and b/webapp/lib/spring-context-support-2.5.6.jar differ diff --git a/webapp/lib/spring-core-2.5.6.jar b/webapp/lib/spring-core-2.5.6.jar new file mode 100644 index 000000000..aafa33609 Binary files /dev/null and b/webapp/lib/spring-core-2.5.6.jar differ diff --git a/webapp/lib/spring-web-2.5.6.jar b/webapp/lib/spring-web-2.5.6.jar new file mode 100644 index 000000000..432e8f036 Binary files /dev/null and b/webapp/lib/spring-web-2.5.6.jar differ diff --git a/webapp/lib/spring-webmvc-2.5.6.jar b/webapp/lib/spring-webmvc-2.5.6.jar new file mode 100644 index 000000000..613f5953d Binary files /dev/null and b/webapp/lib/spring-webmvc-2.5.6.jar differ diff --git a/webapp/lib/standard-1.1.2.jar b/webapp/lib/standard-1.1.2.jar new file mode 100644 index 000000000..bc528acb9 Binary files /dev/null and b/webapp/lib/standard-1.1.2.jar differ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index e1d18a8a7..33d9a57ef 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -19,7 +19,10 @@ import com.hp.hpl.jena.query.Dataset; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; public class VitroRequest extends HttpServletRequestWrapper { @@ -40,6 +43,16 @@ public class VitroRequest extends HttpServletRequestWrapper { this._req = _req; } + public RDFService getRDFService() { + Object o = getAttribute("rdfService"); + if (o instanceof RDFService) { + return (RDFService) o; + } else { + RDFService rdfService = RDFServiceUtils.getRDFService(this); + setAttribute("rdfService", rdfService); + return rdfService; + } + } public void setWebappDaoFactory( WebappDaoFactory wdf){ setAttribute("webappDaoFactory",wdf); @@ -78,6 +91,10 @@ public class VitroRequest extends HttpServletRequestWrapper { setAttribute("jenaOntModel", ontModel); } + public void setOntModelSelector(OntModelSelector oms) { + setAttribute("ontModelSelector", oms); + } + /** gets assertions + inferences WebappDaoFactory with no filtering **/ public WebappDaoFactory getFullWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory"); @@ -97,12 +114,26 @@ public class VitroRequest extends HttpServletRequestWrapper { public WebappDaoFactory getAssertionsWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory"); if (webappDaoFactoryAttr instanceof WebappDaoFactory) { + log.debug("Returning assertionsWebappDaoFactory from session"); return (WebappDaoFactory) webappDaoFactoryAttr; } else { - return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory"); + webappDaoFactoryAttr = getAttribute("assertionsWebappDaoFactory"); + if (webappDaoFactoryAttr instanceof WebappDaoFactory) { + log.debug("returning assertionsWebappDaoFactory from request attribute"); + return (WebappDaoFactory) webappDaoFactoryAttr; + } else { + log.debug("Returning assertionsWebappDaoFactory from context"); + return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory"); + } + } } + /** gets assertions-only WebappDaoFactory with no filtering */ + public void setAssertionsWebappDaoFactory(WebappDaoFactory wadf) { + setAttribute("assertionsWebappDaoFactory", wadf); + } + /** gets inferences-only WebappDaoFactory with no filtering */ public WebappDaoFactory getDeductionsWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory"); @@ -137,6 +168,16 @@ public class VitroRequest extends HttpServletRequestWrapper { return jenaOntModel; } + public OntModelSelector getOntModelSelector() { + Object o = this.getAttribute("ontModelSelector"); + if (o instanceof OntModelSelector) { + return (OntModelSelector) o; + } else { + return null; + } + } + + public OntModel getAssertionsOntModel() { OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME ); if ( jenaOntModel == null ) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java index 292524c72..886828b4b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java @@ -57,7 +57,7 @@ public class Classes2ClassesOperationController extends BaseEditController { return; } - VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao(); + VClassDao vcDao = request.getAssertionsWebappDaoFactory().getVClassDao(); String modeStr = request.getParameter("opMode"); modeStr = (modeStr == null) ? "" : modeStr; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java index 3e2e6bce1..029774720 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java @@ -46,8 +46,9 @@ public class EntityEditController extends BaseEditController { String entURI = request.getParameter("uri"); VitroRequest vreq = (new VitroRequest(request)); - ApplicationBean application = vreq.getAppBean(); - + ApplicationBean application = vreq.getAppBean(); + + //Individual ent = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI); Individual ent = vreq.getAssertionsWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI); if (ent == null) { try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java index 4cc312433..5decb70d3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java @@ -78,7 +78,11 @@ public class EntityRetryController extends BaseEditController { action = epo.getAction(); } - WebappDaoFactory wadf = (vreq.getAssertionsWebappDaoFactory()!=null) ? vreq.getAssertionsWebappDaoFactory() : vreq.getFullWebappDaoFactory(); + WebappDaoFactory wadf = vreq.getAssertionsWebappDaoFactory(); + if (wadf == null) { + log.info("Using vreq.getFullWebappDaoFactory()"); + vreq.getFullWebappDaoFactory(); + } LoginStatusBean loginBean = LoginStatusBean.getBean(request); WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java index 3af9fbb1e..c822a5fc1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RestrictionOperationController.java @@ -15,9 +15,12 @@ import com.hp.hpl.jena.datatypes.RDFDatatype; import com.hp.hpl.jena.datatypes.TypeMapper; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.ontology.Restriction; import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.shared.Lock; @@ -57,129 +60,12 @@ public class RestrictionOperationController extends BaseEditController { if (epo == null) { response.sendRedirect(defaultLandingPage); return; - } - - // TODO: I need to de-spaghettify this and remap this controller, now that I know what I'm doing + } - if ( (request.getParameter("_cancel") == null ) ) { - - ontModel.enterCriticalSection(Lock.WRITE); - try { - - ontModel.getBaseModel().notifyEvent(new EditEvent(request.getFullWebappDaoFactory().getUserURI(),true)); - - if ( request.getParameter("_action") != null && request.getParameter("_action").equals("delete") ) { - - String restId = request.getParameter("restrictionId"); - - if (restId != null) { - - OntClass restrictedClass = ontModel.getOntClass( request.getParameter( "classUri" ) ); - - OntClass rest = null; - - for ( Iterator i = restrictedClass.listEquivalentClasses(); i.hasNext(); ) { - OntClass equivClass = (OntClass) i.next(); - if (equivClass.isAnon() && equivClass.getId().toString().equals(restId)) { - rest = equivClass; - } - } - - if ( rest == null ) { - for ( Iterator i = restrictedClass.listSuperClasses(); i.hasNext(); ) { - OntClass superClass = (OntClass) i.next(); - if (superClass.isAnon() && superClass.getId().toString().equals(restId)) { - rest = superClass; - } - } - } - - if ( rest != null ) { - rest.remove(); - } - - } - - } else { - - OntProperty onProperty = ontModel.getOntProperty( (String) request.getParameter("onProperty") ); - - String conditionTypeStr = request.getParameter("conditionType"); - - String restrictionTypeStr = (String) epo.getAttribute("restrictionType"); - Restriction rest = null; - - OntClass ontClass = ontModel.getOntClass( (String) epo.getAttribute("VClassURI") ); - - String roleFillerURIStr = request.getParameter("ValueClass"); - Resource roleFiller = null; - if (roleFillerURIStr != null) { - roleFiller = ontModel.getResource(roleFillerURIStr); - } - - int cardinality = -1; - String cardinalityStr = request.getParameter("cardinality"); - if (cardinalityStr != null) { - cardinality = Integer.decode(cardinalityStr); - } - - if (restrictionTypeStr.equals("allValuesFrom")) { - rest = ontModel.createAllValuesFromRestriction(null,onProperty,roleFiller); - } else if (restrictionTypeStr.equals("someValuesFrom")) { - rest = ontModel.createSomeValuesFromRestriction(null,onProperty,roleFiller); - } else if (restrictionTypeStr.equals("hasValue")) { - String valueURI = request.getParameter("ValueIndividual"); - if (valueURI != null) { - Resource valueRes = ontModel.getResource(valueURI); - if (valueRes != null) { - rest = ontModel.createHasValueRestriction(null, onProperty, valueRes); - } - } else { - String valueLexicalForm = request.getParameter("ValueLexicalForm"); - if (valueLexicalForm != null) { - String valueDatatype = request.getParameter("ValueDatatype"); - Literal value = null; - if (valueDatatype != null && valueDatatype.length() > 0) { - RDFDatatype dtype = null; - try { - dtype = TypeMapper.getInstance().getSafeTypeByName(valueDatatype); - } catch (Exception e) { - log.warn ("Unable to get safe type " + valueDatatype + " using TypeMapper"); - } - if (dtype != null) { - value = ontModel.createTypedLiteral(valueLexicalForm, dtype); - } else { - value = ontModel.createLiteral(valueLexicalForm); - } - } else { - value = ontModel.createLiteral(valueLexicalForm); - } - rest = ontModel.createHasValueRestriction(null, onProperty, value); - } - } - } else if (restrictionTypeStr.equals("minCardinality")) { - rest = ontModel.createMinCardinalityRestriction(null,onProperty,cardinality); - } else if (restrictionTypeStr.equals("maxCardinality")) { - rest = ontModel.createMaxCardinalityRestriction(null,onProperty,cardinality); - } else if (restrictionTypeStr.equals("cardinality")) { - rest = ontModel.createCardinalityRestriction(null,onProperty,cardinality); - } - - if (conditionTypeStr.equals("necessary")) { - ontClass.addSuperClass(rest); - } else if (conditionTypeStr.equals("necessaryAndSufficient")) { - ontClass.addEquivalentClass(rest); - } - - } - - } finally { - ontModel.getBaseModel().notifyEvent(new EditEvent(request.getFullWebappDaoFactory().getUserURI(),false)); - ontModel.leaveCriticalSection(); - } - + if ( (request.getParameter("_cancel") == null ) ) { + processRestriction(request, epo, ontModel); } - + //if no page forwarder was set, just go back to referring page: String referer = epo.getReferer(); if (referer == null) { @@ -198,7 +84,144 @@ public class RestrictionOperationController extends BaseEditController { throw new RuntimeException(f); } } - } + + private void processRestriction(VitroRequest request, EditProcessObject epo, OntModel ontModel) { + ontModel.enterCriticalSection(Lock.WRITE); + try { + + ontModel.getBaseModel().notifyEvent(new EditEvent(request.getFullWebappDaoFactory().getUserURI(),true)); + + if ("delete".equals(request.getParameter("_action"))) { + processDelete(request, ontModel); + } else { + processCreate(request, epo, ontModel); + } + + } finally { + ontModel.getBaseModel().notifyEvent(new EditEvent(request.getFullWebappDaoFactory().getUserURI(),false)); + ontModel.leaveCriticalSection(); + } + + } + private void processDelete(VitroRequest request, OntModel ontModel) { + + String restId = request.getParameter("restrictionId"); + + if (restId != null) { + + OntClass restrictedClass = ontModel.getOntClass( request.getParameter( "classUri" ) ); + + OntClass rest = null; + + for ( Iterator i = restrictedClass.listEquivalentClasses(); i.hasNext(); ) { + OntClass equivClass = (OntClass) i.next(); + if (equivClass.isAnon() && equivClass.getId().toString().equals(restId)) { + rest = equivClass; + } + } + + if ( rest == null ) { + for ( Iterator i = restrictedClass.listSuperClasses(); i.hasNext(); ) { + OntClass superClass = (OntClass) i.next(); + if (superClass.isAnon() && superClass.getId().toString().equals(restId)) { + rest = superClass; + } + } + } + + /** + * removing by graph subtraction so that statements with blank nodes + * stick together and are processed appropriately by the bulk update + * handler + */ + if ( rest != null ) { + Model temp = ModelFactory.createDefaultModel(); + temp.add(rest.listProperties()); + ontModel.getBaseModel().remove(temp); + } + + } + } + + private void processCreate(VitroRequest request, EditProcessObject epo, OntModel origModel) { + + Model temp = ModelFactory.createDefaultModel(); + Model dynamicUnion = ModelFactory.createUnion(temp, origModel); + OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, dynamicUnion); + + OntProperty onProperty = ontModel.getOntProperty( (String) request.getParameter("onProperty") ); + + String conditionTypeStr = request.getParameter("conditionType"); + + String restrictionTypeStr = (String) epo.getAttribute("restrictionType"); + Restriction rest = null; + + OntClass ontClass = ontModel.getOntClass( (String) epo.getAttribute("VClassURI") ); + + String roleFillerURIStr = request.getParameter("ValueClass"); + Resource roleFiller = null; + if (roleFillerURIStr != null) { + roleFiller = ontModel.getResource(roleFillerURIStr); + } + + int cardinality = -1; + String cardinalityStr = request.getParameter("cardinality"); + if (cardinalityStr != null) { + cardinality = Integer.decode(cardinalityStr); + } + + if (restrictionTypeStr.equals("allValuesFrom")) { + rest = ontModel.createAllValuesFromRestriction(null,onProperty,roleFiller); + } else if (restrictionTypeStr.equals("someValuesFrom")) { + rest = ontModel.createSomeValuesFromRestriction(null,onProperty,roleFiller); + } else if (restrictionTypeStr.equals("hasValue")) { + String valueURI = request.getParameter("ValueIndividual"); + if (valueURI != null) { + Resource valueRes = ontModel.getResource(valueURI); + if (valueRes != null) { + rest = ontModel.createHasValueRestriction(null, onProperty, valueRes); + } + } else { + String valueLexicalForm = request.getParameter("ValueLexicalForm"); + if (valueLexicalForm != null) { + String valueDatatype = request.getParameter("ValueDatatype"); + Literal value = null; + if (valueDatatype != null && valueDatatype.length() > 0) { + RDFDatatype dtype = null; + try { + dtype = TypeMapper.getInstance().getSafeTypeByName(valueDatatype); + } catch (Exception e) { + log.warn ("Unable to get safe type " + valueDatatype + " using TypeMapper"); + } + if (dtype != null) { + value = ontModel.createTypedLiteral(valueLexicalForm, dtype); + } else { + value = ontModel.createLiteral(valueLexicalForm); + } + } else { + value = ontModel.createLiteral(valueLexicalForm); + } + rest = ontModel.createHasValueRestriction(null, onProperty, value); + } + } + } else if (restrictionTypeStr.equals("minCardinality")) { + rest = ontModel.createMinCardinalityRestriction(null,onProperty,cardinality); + } else if (restrictionTypeStr.equals("maxCardinality")) { + rest = ontModel.createMaxCardinalityRestriction(null,onProperty,cardinality); + } else if (restrictionTypeStr.equals("cardinality")) { + rest = ontModel.createCardinalityRestriction(null,onProperty,cardinality); + } + + if (conditionTypeStr.equals("necessary")) { + ontClass.addSuperClass(rest); + } else if (conditionTypeStr.equals("necessaryAndSufficient")) { + ontClass.addEquivalentClass(rest); + } + + origModel.add(temp); + + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java index 933039834..991b9b34d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java @@ -211,7 +211,7 @@ class IndividualResponseBuilder { private IndividualTemplateModel getIndividualTemplateModel( Individual individual) { - individual.sortForDisplay(); + //individual.sortForDisplay(); return new IndividualTemplateModel(individual, vreq); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java index 7d2fb6434..149d64af5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java @@ -69,11 +69,12 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSetup; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult; @@ -206,13 +207,13 @@ public class JenaIngestController extends BaseEditController { } private void processRDBModelsRequest(VitroRequest vreq, ModelMaker maker, String modelType) { - VitroJenaModelMaker vjmm = (VitroJenaModelMaker) getServletContext().getAttribute("vitroJenaModelMaker"); + ModelMaker vjmm = (ModelMaker) getServletContext().getAttribute("vitroJenaModelMaker"); vreq.getSession().setAttribute("vitroJenaModelMaker", vjmm); showModelList(vreq, vjmm, "rdb"); } private void processSDBModelsRequest(VitroRequest vreq, ModelMaker maker, String modelType) { - VitroJenaSDBModelMaker vsmm = (VitroJenaSDBModelMaker) getServletContext().getAttribute("vitroJenaSDBModelMaker"); + ModelMaker vsmm = (ModelMaker) getServletContext().getAttribute("vitroJenaSDBModelMaker"); vreq.getSession().setAttribute("vitroJenaModelMaker", vsmm); showModelList(vreq, vsmm, "sdb"); } @@ -714,7 +715,7 @@ public class JenaIngestController extends BaseEditController { ? ((VitroJenaSpecialModelMaker) maker).getInnerModelMaker() : maker; if (modelType == null) { - if (maker instanceof VitroJenaSDBModelMaker) { + if (maker instanceof RDFServiceModelMaker) { modelType = "sdb"; } else { modelType = "rdb"; @@ -942,7 +943,7 @@ public class JenaIngestController extends BaseEditController { log.debug("Connecting to DB at "+jdbcUrl); StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ; ServletContext ctx = vreq.getSession().getServletContext(); - BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource( + BasicDataSource bds = WebappDaoSetup.makeBasicDataSource( driver, jdbcUrl, username, password, ctx); try { VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java index 1e5f08ee2..108639c0b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.jena; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Map; @@ -37,6 +38,10 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; +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.servlet.setup.JenaDataSourceSetupBase; public class RDFUploadController extends JenaIngestController { @@ -119,12 +124,17 @@ public class RDFUploadController extends JenaIngestController { && fileStreams.get("rdfStream").size() > 0 ) { FileItem rdfStream = fileStreams.get("rdfStream").get(0); try { - uploadModel.enterCriticalSection(Lock.WRITE); - try { - uploadModel.read( - rdfStream.getInputStream(), null, languageStr); - } finally { - uploadModel.leaveCriticalSection(); + if (directRead) { + addUsingRDFService(rdfStream.getInputStream(), languageStr, + request.getRDFService()); + } else { + uploadModel.enterCriticalSection(Lock.WRITE); + try { + uploadModel.read( + rdfStream.getInputStream(), null, languageStr); + } finally { + uploadModel.leaveCriticalSection(); + } } uploadDesc = verb + " RDF from file " + rdfStream.getName(); } catch (IOException e) { @@ -198,6 +208,24 @@ public class RDFUploadController extends JenaIngestController { } } + private void addUsingRDFService(InputStream in, String languageStr, + RDFService rdfService) { + ChangeSet changeSet = rdfService.manufactureChangeSet(); + RDFService.ModelSerializationFormat format = + ("RDF/XML".equals(languageStr) + || "RDF/XML-ABBREV".equals(languageStr)) + ? RDFService.ModelSerializationFormat.RDFXML + : RDFService.ModelSerializationFormat.N3; + changeSet.addAddition(in, format, + JenaDataSourceSetupBase.JENA_DB_MODEL); + try { + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + log.error(rdfse); + throw new RuntimeException(rdfse); + } + } + public void loadRDF(FileUploadServletRequest req, VitroRequest request, HttpServletResponse response) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ABoxJenaChangeListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ABoxJenaChangeListener.java new file mode 100644 index 000000000..0d374f030 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ABoxJenaChangeListener.java @@ -0,0 +1,44 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.HashSet; + +import com.hp.hpl.jena.rdf.model.ModelChangedListener; + +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; + +public class ABoxJenaChangeListener extends JenaChangeListener { + + private HashSet ignoredGraphs = new HashSet(); + + public ABoxJenaChangeListener(ModelChangedListener listener) { + super(listener); + ignoredGraphs.add(JenaDataSourceSetupBase.JENA_INF_MODEL); + ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); + ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL); + } + + @Override + public void addedStatement(String serializedTriple, String graphURI) { + if (isABoxGraph(graphURI)) { + super.addedStatement(serializedTriple, graphURI); + } + } + + @Override + public void removedStatement(String serializedTriple, String graphURI) { + if (isABoxGraph(graphURI)) { + super.removedStatement(serializedTriple, graphURI); + } + } + + private boolean isABoxGraph(String graphURI) { + return (graphURI == null || + JenaDataSourceSetupBase.JENA_DB_MODEL.equals(graphURI) + || (!ignoredGraphs.contains(graphURI) + && !graphURI.contains("filegraph") + && !graphURI.contains("tbox"))); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java index fbbb291f7..8a1ce1189 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java @@ -674,7 +674,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements static { List namespaceFilters = new ArrayList(); for (String namespace : EXCLUDED_NAMESPACES) { - namespaceFilters.add("( afn:namespace(?property) != \"" + namespace + "\" )"); + namespaceFilters.add("( !regex(str(?property), \"^" + namespace + "\" ))"); } PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && "); } @@ -686,11 +686,11 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements " ?property a owl:DatatypeProperty . \n" + " FILTER ( \n" + " isLiteral(?object) && \n" + - " ( afn:namespace(?property) != \"" + VitroVocabulary.PUBLIC + "\" ) && \n" + - " ( afn:namespace(?property) != \"" + VitroVocabulary.OWL + "\" ) && \n" + + " ( !regex(str(?property), \"^" + VitroVocabulary.PUBLIC + "\" )) && \n" + + " ( !regex(str(?property), \"^" + VitroVocabulary.OWL + "\" )) && \n" + // NIHVIVO-2790 vitro:moniker has been deprecated, but display existing values for editorial management (deletion is encouraged). // This property will be hidden from public display by default. - " ( ?property = <" + VitroVocabulary.MONIKER + "> || afn:namespace(?property) != \"" + VitroVocabulary.vitroURI + "\" ) \n" + + " ( ?property = <" + VitroVocabulary.MONIKER + "> || !regex(str(?property), \"^" + VitroVocabulary.vitroURI + "\" )) \n" + " ) \n" + "}"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java new file mode 100644 index 000000000..cd45a9795 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DifferenceGraph.java @@ -0,0 +1,138 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.Set; + +import com.hp.hpl.jena.graph.BulkUpdateHandler; +import com.hp.hpl.jena.graph.Capabilities; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEventManager; +import com.hp.hpl.jena.graph.GraphStatisticsHandler; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Reifier; +import com.hp.hpl.jena.graph.TransactionHandler; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.query.QueryHandler; +import com.hp.hpl.jena.shared.AddDeniedException; +import com.hp.hpl.jena.shared.DeleteDeniedException; +import com.hp.hpl.jena.shared.PrefixMapping; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class DifferenceGraph implements Graph { + + private Graph g; + private Graph subtract; + + public DifferenceGraph(Graph g, Graph subtract) { + this.g = g; + this.subtract = subtract; + } + + @Override + public void close() { + // not clear what the best behavior here is + } + + @Override + public boolean contains(Triple arg0) { + return g.contains(arg0) && !subtract.contains(arg0); + } + + @Override + public boolean contains(Node arg0, Node arg1, Node arg2) { + return g.contains(arg0, arg1, arg2) && !subtract.contains(arg0, arg1, arg2); + } + + @Override + public void delete(Triple arg0) throws DeleteDeniedException { + g.delete(arg0); + } + + @Override + public boolean dependsOn(Graph arg0) { + return g.dependsOn(arg0); + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + Set tripSet = g.find(arg0).toSet(); + tripSet.removeAll(subtract.find(arg0).toSet()); + return WrappedIterator.create(tripSet.iterator()); + } + + @Override + public ExtendedIterator find(Node arg0, Node arg1, Node arg2) { + Set tripSet = g.find(arg0, arg1, arg2).toSet(); + tripSet.removeAll(subtract.find(arg0, arg1, arg2).toSet()); + return WrappedIterator.create(tripSet.iterator()); + } + + @Override + public BulkUpdateHandler getBulkUpdateHandler() { + return g.getBulkUpdateHandler(); + } + + @Override + public Capabilities getCapabilities() { + return g.getCapabilities(); + } + + @Override + public GraphEventManager getEventManager() { + return g.getEventManager(); + } + + @Override + public PrefixMapping getPrefixMapping() { + return g.getPrefixMapping(); + } + + @Override + public Reifier getReifier() { + return g.getReifier(); + } + + @Override + public GraphStatisticsHandler getStatisticsHandler() { + return g.getStatisticsHandler(); + } + + @Override + public TransactionHandler getTransactionHandler() { + return g.getTransactionHandler(); + } + + @Override + public boolean isClosed() { + return g.isClosed(); + } + + @Override + public boolean isEmpty() { + return g.isEmpty(); + } + + @Override + public boolean isIsomorphicWith(Graph arg0) { + return g.isIsomorphicWith(arg0); + } + + @Override + public QueryHandler queryHandler() { + return g.queryHandler(); + } + + @Override + public int size() { + return g.size() - subtract.size(); + } + + @Override + public void add(Triple arg0) throws AddDeniedException { + g.add(arg0); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java new file mode 100644 index 000000000..064dce350 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java @@ -0,0 +1,119 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; + +import org.apache.commons.collections.iterators.EmptyIterator; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Reifier; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.shared.ReificationStyle; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class EmptyReifier implements Reifier { + + private Graph g; + + public EmptyReifier(Graph g) { + this.g = g; + } + + @Override + public Triple getTriple(Node arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ExtendedIterator allNodes() { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + + @Override + public ExtendedIterator allNodes(Triple arg0) { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + + @Override + public void close() { + // TODO Auto-generated method stub + + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + return g.find(arg0); + } + + @Override + public ExtendedIterator findEither(TripleMatch arg0, boolean arg1) { + return WrappedIterator.create(EmptyIterator.INSTANCE); + } + + @Override + public ExtendedIterator findExposed(TripleMatch arg0) { + return WrappedIterator.create(EmptyIterator.INSTANCE); + } + + @Override + public Graph getParentGraph() { + return g; + } + + @Override + public ReificationStyle getStyle() { + return ReificationStyle.Minimal; + } + + @Override + public boolean handledAdd(Triple arg0) { + g.add(arg0); + return true; + } + + @Override + public boolean handledRemove(Triple arg0) { + g.delete(arg0); + return true; + } + + @Override + public boolean hasTriple(Node arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasTriple(Triple arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Node reifyAs(Node arg0, Triple arg1) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void remove(Triple arg0) { + g.delete(arg0); + } + + @Override + public void remove(Node arg0, Triple arg1) { + g.delete(arg1); + } + + @Override + public int size() { + return g.size(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java index abb572095..c51db6f96 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java @@ -109,7 +109,8 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { public void removeVClass(String individualURI, String vclassURI) { OntModel ontModel = getOntModelSelector().getABoxModel(); ontModel.enterCriticalSection(Lock.WRITE); - ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI)); + Object event = new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI); + ontModel.getBaseModel().notifyEvent(event); try { Resource indRes = ontModel.getResource(individualURI); getOntModel().remove(indRes, RDF.type, ontModel.getResource(vclassURI)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java index 47661e3e4..ffe1b086c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java @@ -134,6 +134,12 @@ public class IndividualSDB extends IndividualImpl implements Individual { QueryFactory.create(getStatements), dataset) .execConstruct(); } finally { + if (dataset == null) { + throw new RuntimeException("dataset is null"); + } else if (dataset.getLock() == null) { + throw new RuntimeException("dataset lock is null"); + } + dataset.getLock().leaveCriticalSection(); w.close(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java new file mode 100644 index 000000000..aaa1af321 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java @@ -0,0 +1,72 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelChangedListener; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; + +/** + * A ChangeListener that forwards events to a Jena ModelChangedListener + * @author bjl23 + * + */ +public class JenaChangeListener implements ChangeListener { + + private static final Log log = LogFactory.getLog(JenaChangeListener.class); + + private ModelChangedListener listener; + private Model m = ModelFactory.createDefaultModel(); + + public JenaChangeListener(ModelChangedListener listener) { + this.listener = listener; + } + + @Override + public void addedStatement(String serializedTriple, String graphURI) { + listener.addedStatement(parseTriple(serializedTriple)); + } + + @Override + public void removedStatement(String serializedTriple, String graphURI) { + listener.removedStatement(parseTriple(serializedTriple)); + } + + @Override + public void notifyEvent(String graphURI, Object event) { + log.debug("event: " + event.getClass()); + listener.notifyEvent(m, event); + } + + // TODO avoid overhead of Model + private Statement parseTriple(String serializedTriple) { + try { + Model m = ModelFactory.createDefaultModel(); + m.read(new ByteArrayInputStream( + serializedTriple.getBytes("UTF-8")), null, "N3"); + StmtIterator sit = m.listStatements(); + if (!sit.hasNext()) { + throw new RuntimeException("no triple parsed from change event"); + } else { + Statement s = sit.nextStatement(); + if (sit.hasNext()) { + log.warn("More than one triple parsed from change event"); + } + return s; + } + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException(uee); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java index 89afe54ed..57d835a4c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java @@ -4,12 +4,19 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import javax.servlet.ServletContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.ModelChangedListener; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; public class ModelContext { + + private static final Log log = LogFactory.getLog(ModelContext.class); private static final String ONT_MODEL_SELECTOR = "ontModelSelector"; private static final String UNION_ONT_MODEL_SELECTOR = "unionOntModelSelector"; @@ -96,15 +103,13 @@ public class ModelContext { * Changes to application model */ public static void registerListenerForChanges(ServletContext ctx, ModelChangedListener ml){ - ModelContext.getJenaOntModel(ctx).register(ml); - ModelContext.getBaseOntModel(ctx).register(ml); - ModelContext.getInferenceOntModel(ctx).register(ml); - ModelContext.getUnionOntModelSelector(ctx).getABoxModel().register(ml); - ModelContext.getBaseOntModelSelector(ctx).getABoxModel().register(ml); - ModelContext.getBaseOntModelSelector(ctx).getApplicationMetadataModel().register(ml); - ModelContext.getInferenceOntModelSelector(ctx).getABoxModel().register(ml); - - ModelContext.getBaseOntModelSelector(ctx).getTBoxModel().register(ml); + + try { + RDFServiceUtils.getRDFServiceFactory(ctx).registerListener( + new JenaChangeListener(ml)); + } catch (RDFServiceException e) { + log.error(e,e); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 49de9b8ed..1c71bcc48 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -785,12 +785,12 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp static { List namespaceFilters = new ArrayList(); for (String namespace : EXCLUDED_NAMESPACES) { - namespaceFilters.add("( afn:namespace(?property) != \"" + namespace + "\" )"); + namespaceFilters.add("( !regex(str(?property), \"^" + namespace + "\" ))"); } // A hack to include the vitro:primaryLink and vitro:additionalLink properties in the list namespaceFilters.add("( ?property = vitro:primaryLink ||" + "?property = vitro:additionalLink ||" + - "afn:namespace(?property) != \"http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" )"); + "!regex(str(?property), \"^http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" ))"); PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && "); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index 85462ebe2..7775fbac1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -42,16 +42,20 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements ObjectPropertyStatementDao { private static final Log log = LogFactory.getLog(ObjectPropertyStatementDaoJena.class); private DatasetWrapperFactory dwf; + private RDFService rdfService; - public ObjectPropertyStatementDaoJena(DatasetWrapperFactory dwf, + public ObjectPropertyStatementDaoJena(RDFService rdfService, + DatasetWrapperFactory dwf, WebappDaoFactoryJena wadf) { super(wadf); + this.rdfService = rdfService; this.dwf = dwf; } @@ -335,7 +339,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec } } - + private Model constructModelForSelectQueries(String subjectUri, String propertyUri, Set constructQueries) { @@ -351,39 +355,28 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec log.debug("CONSTRUCT query string for object property " + propertyUri + ": " + queryString); - Query query = null; + queryString = queryString.replace("?subject", "<" + subjectUri + ">"); + queryString = queryString.replace("?property", "<" + propertyUri + ">"); + + // we no longer need this query object, but we might want to do this + // query parse step to improve debugging, depending on the error returned + // through the RDF API +// try { +// QueryFactory.create(queryString, Syntax.syntaxARQ); +// } catch(Throwable th){ +// log.error("Could not create CONSTRUCT SPARQL query for query " + +// "string. " + th.getMessage()); +// log.error(queryString); +// return constructedModel; +// } + try { - query = QueryFactory.create(queryString, Syntax.syntaxARQ); - } catch(Throwable th){ - log.error("Could not create CONSTRUCT SPARQL query for query " + - "string. " + th.getMessage()); - log.error(queryString); - return constructedModel; - } - - QuerySolutionMap initialBindings = new QuerySolutionMap(); - initialBindings.add( - "subject", ResourceFactory.createResource(subjectUri)); - initialBindings.add( - "property", ResourceFactory.createResource(propertyUri)); - - DatasetWrapper w = dwf.getDatasetWrapper(); - Dataset dataset = w.getDataset(); - dataset.getLock().enterCriticalSection(Lock.READ); - QueryExecution qe = null; - try { - qe = QueryExecutionFactory.create( - query, dataset, initialBindings); - qe.execConstruct(constructedModel); + constructedModel.read( + rdfService.sparqlConstructQuery( + queryString, RDFService.ModelSerializationFormat.N3), null, "N3"); } catch (Exception e) { log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri); - } finally { - if (qe != null) { - qe.close(); - } - dataset.getLock().leaveCriticalSection(); - w.close(); - } + } } return constructedModel; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java index d43c4e48b..15011a0be 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java @@ -23,16 +23,15 @@ import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.util.iterator.ClosableIterator; -import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; -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.rdfservice.RDFService; public class ObjectPropertyStatementDaoSDB extends ObjectPropertyStatementDaoJena implements ObjectPropertyStatementDao { @@ -43,10 +42,11 @@ public class ObjectPropertyStatementDaoSDB extends private SDBDatasetMode datasetMode; public ObjectPropertyStatementDaoSDB( + RDFService rdfService, DatasetWrapperFactory dwf, SDBDatasetMode datasetMode, WebappDaoFactoryJena wadf) { - super (dwf, wadf); + super (rdfService, dwf, wadf); this.dwf = dwf; this.datasetMode = datasetMode; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index fba1936e1..d91d2dd0a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -35,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.sparql.resultset.ResultSetMem; +import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDFS; @@ -596,6 +596,31 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } } + private List listSuperClasses(OntClass ontClass) { + return relatedClasses(ontClass, RDFS.subClassOf); + } + + private List listEquivalentClasses(OntClass ontClass) { + return relatedClasses(ontClass, OWL.equivalentClass); + } + + private List relatedClasses(OntClass ontClass, + com.hp.hpl.jena.rdf.model.Property property) { + List classes = new ArrayList(); + StmtIterator closeIt = ontClass.listProperties(property); + try { + while (closeIt.hasNext()) { + Statement stmt = closeIt.nextStatement(); + if (stmt.getObject().canAs(OntClass.class)) { + classes.add(stmt.getObject().as(OntClass.class)); + } + } + } finally { + closeIt.close(); + } + return classes; + } + public List getAllPropInstByVClasses(List vclasses) { List propInsts = new ArrayList(); @@ -628,11 +653,11 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { OntClass ontClass = getOntClass(ontModel,VClassURI); if (ontClass != null) { List relatedClasses = new ArrayList(); - relatedClasses.addAll(ontClass.listEquivalentClasses().toList()); - relatedClasses.addAll(ontClass.listSuperClasses().toList()); + relatedClasses.addAll(listEquivalentClasses(ontClass)); + relatedClasses.addAll(listSuperClasses(ontClass)); for (OntClass relatedClass : relatedClasses) { // find properties in restrictions - if (relatedClass.isRestriction()) { + if (relatedClass.isRestriction() && relatedClass.canAs(Restriction.class)) { // TODO: check if restriction is something like // maxCardinality 0 or allValuesFrom owl:Nothing, // in which case the property is NOT applicable! diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java new file mode 100644 index 000000000..61cd2b58c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java @@ -0,0 +1,70 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.sparql.core.DatasetGraph; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +public class RDFServiceDataset implements Dataset { + + private RDFServiceDatasetGraph g; + + public RDFServiceDataset(RDFServiceDatasetGraph g) { + this.g = g; + } + + public RDFServiceDataset(RDFService rdfService) { + this.g = new RDFServiceDatasetGraph(rdfService); + } + + @Override + public DatasetGraph asDatasetGraph() { + return g; + } + + @Override + public void close() { + g.close(); + } + + @Override + public boolean containsNamedModel(String arg0) { + return g.containsGraph(Node.createURI(arg0)); + } + + @Override + public Model getDefaultModel() { + return RDFServiceGraph.createRDFServiceModel(g.getDefaultGraph()); + } + + @Override + public Lock getLock() { + return g.getLock(); + } + + @Override + public Model getNamedModel(String arg0) { + return RDFServiceGraph.createRDFServiceModel(g.getGraph(Node.createURI(arg0))); + } + + @Override + public Iterator listNames() { + ArrayList nameList = new ArrayList(); + Iterator nodeIt = g.listGraphNodes(); + while (nodeIt.hasNext()) { + Node n = nodeIt.next(); + nameList.add(n.getURI()); + } + return nameList.iterator(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java new file mode 100644 index 000000000..ca0dfa80f --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java @@ -0,0 +1,223 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.shared.LockMRSW; +import com.hp.hpl.jena.sparql.core.DatasetGraph; +import com.hp.hpl.jena.sparql.core.Quad; +import com.hp.hpl.jena.sparql.resultset.JSONInput; +import com.hp.hpl.jena.sparql.resultset.ResultSetMem; +import com.hp.hpl.jena.sparql.util.Context; +import com.hp.hpl.jena.util.iterator.SingletonIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; + +public class RDFServiceDatasetGraph implements DatasetGraph { + + private RDFService rdfService; + private Lock lock = new LockMRSW(); + + public RDFServiceDatasetGraph(RDFService rdfService) { + this.rdfService = rdfService; + } + + private Graph getGraphFor(Quad q) { + return getGraphFor(q.getGraph()); + } + + private Graph getGraphFor(Node g) { + return (g == Node.ANY) + ? new RDFServiceGraph(rdfService) + : new RDFServiceGraph(rdfService, g.getURI()); + } + + @Override + public void add(Quad arg0) { + getGraphFor(arg0).add(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public void addGraph(Node arg0, Graph arg1) { + // TODO Auto-generated method stub + } + + @Override + public void close() { + // TODO Auto-generated method stub + } + + @Override + public boolean contains(Quad arg0) { + return getGraphFor(arg0).contains(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public boolean contains(Node arg0, Node arg1, Node arg2, Node arg3) { + return getGraphFor(arg0).contains(arg1, arg2, arg3); + } + + @Override + public boolean containsGraph(Node arg0) { + // TODO Auto-generated method stub + return true; + } + + @Override + public void delete(Quad arg0) { + getGraphFor(arg0).delete(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public void deleteAny(Node arg0, Node arg1, Node arg2, Node arg3) { + // TODO check this + getGraphFor(arg0).delete(new Triple(arg1, arg2, arg3)); + } + + @Override + public Iterator find() { + return find(Node.ANY, Node.ANY, Node.ANY, Node.ANY); + } + + @Override + public Iterator find(Quad arg0) { + return find(arg0.getSubject(), arg0.getPredicate(), arg0.getObject(), arg0.getGraph()); + } + + @Override + public Iterator find(Node graph, Node subject, Node predicate, Node object) { + if (!isVar(subject) && !isVar(predicate) && !isVar(object) &&!isVar(graph)) { + if (contains(subject, predicate, object, graph)) { + return new SingletonIterator(new Triple(subject, predicate, object)); + } else { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + } + StringBuffer findQuery = new StringBuffer("SELECT * WHERE { \n"); + String graphURI = !isVar(graph) ? graph.getURI() : null; + findQuery.append(" GRAPH "); + if (graphURI != null) { + findQuery.append(" <" + graphURI + ">"); + } else { + findQuery.append("?g"); + } + findQuery.append(" { "); + findQuery.append(SparqlGraph.sparqlNode(subject, "?s")) + .append(" ") + .append(SparqlGraph.sparqlNode(predicate, "?p")) + .append(" ") + .append(SparqlGraph.sparqlNode(object, "?o")); + findQuery.append(" } "); + findQuery.append("\n}"); + + //log.info(findQuery.toString()); + + ResultSet rs = null; + + try { + rs = JSONInput.fromJSON(rdfService.sparqlSelectQuery( + findQuery.toString(), RDFService.ResultFormat.JSON)); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + + List quadlist = new ArrayList(); + while (rs.hasNext()) { + QuerySolution soln = rs.nextSolution(); + Quad q = new Quad(isVar(graph) ? soln.get("?g").asNode() : graph, + isVar(subject) ? soln.get("?s").asNode() : subject, + isVar(predicate) ? soln.get("?p").asNode() : predicate, + isVar(object) ? soln.get("?o").asNode() : object); + //log.info(t); + quadlist.add(q); + } + //log.info(triplist.size() + " results"); + return WrappedIterator.create(quadlist.iterator()); } + + @Override + public Iterator findNG(Node arg0, Node arg1, Node arg2, Node arg3) { + // TODO check this + return find(arg0, arg1, arg2, arg3); + } + + @Override + public Context getContext() { + // TODO Auto-generated method stub + return null; + } + + @Override + public RDFServiceGraph getDefaultGraph() { + return new RDFServiceGraph(rdfService); + } + + @Override + public RDFServiceGraph getGraph(Node arg0) { + return new RDFServiceGraph(rdfService, arg0.getURI()); + } + + @Override + public Lock getLock() { + return lock; + } + + @Override + public boolean isEmpty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Iterator listGraphNodes() { + List graphNodeList = new ArrayList(); + try { + for (String graphURI : rdfService.getGraphURIs()) { + graphNodeList.add(Node.createURI(graphURI)); + } + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + return graphNodeList.iterator(); + } + + @Override + public void removeGraph(Node arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setDefaultGraph(Graph arg0) { + // TODO Auto-generated method stub + + } + + @Override + public long size() { + // TODO Auto-generated method stub + return 0; + } + + private boolean isVar(Node node) { + return (node == null || node.isVariable() || node == Node.ANY); + } + + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java new file mode 100644 index 000000000..766b1bbf4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java @@ -0,0 +1,460 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.BulkUpdateHandler; +import com.hp.hpl.jena.graph.Capabilities; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEventManager; +import com.hp.hpl.jena.graph.GraphStatisticsHandler; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Reifier; +import com.hp.hpl.jena.graph.TransactionHandler; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.impl.GraphWithPerform; +import com.hp.hpl.jena.graph.impl.SimpleEventManager; +import com.hp.hpl.jena.graph.query.QueryHandler; +import com.hp.hpl.jena.graph.query.SimpleQueryHandler; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.listeners.StatementListener; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.shared.AddDeniedException; +import com.hp.hpl.jena.shared.DeleteDeniedException; +import com.hp.hpl.jena.shared.PrefixMapping; +import com.hp.hpl.jena.shared.impl.PrefixMappingImpl; +import com.hp.hpl.jena.sparql.resultset.JSONInput; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.SingletonIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +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.RDFServiceUtils; + +public class RDFServiceGraph implements GraphWithPerform { + + private RDFService rdfService; + private String graphURI; + private static final Log log = LogFactory.getLog(SparqlGraph.class); + + private BulkUpdateHandler bulkUpdateHandler; + private PrefixMapping prefixMapping = new PrefixMappingImpl(); + private GraphEventManager eventManager; + private Reifier reifier = new EmptyReifier(this); + private QueryHandler queryHandler; + + /** + * Returns a SparqlGraph for the union of named graphs in a remote repository + * @param endpointURI + */ + public RDFServiceGraph(RDFService rdfService) { + this(rdfService, null); + } + + /** + * Returns a SparqlGraph for a particular named graph in a remote repository + * @param endpointURI + * @param graphURI + */ + public RDFServiceGraph(RDFService rdfService, String graphURI) { + this.rdfService = rdfService; + this.graphURI = graphURI; + } + + public RDFService getRDFService() { + return this.rdfService; + } + + public String getGraphURI() { + return graphURI; + } + + @Override + public void add(Triple arg0) throws AddDeniedException { + performAdd(arg0); + } + + private String serialize(Triple t) { + StringBuffer sb = new StringBuffer(); + sb.append(sparqlNodeUpdate(t.getSubject(), "")).append(" ") + .append(sparqlNodeUpdate(t.getPredicate(), "")).append(" ") + .append(sparqlNodeUpdate(t.getObject(), "")).append(" ."); + return sb.toString(); + } + + @Override + public void performAdd(Triple t) { + + ChangeSet changeSet = rdfService.manufactureChangeSet(); + try { + changeSet.addAddition(RDFServiceUtils.toInputStream(serialize(t)), + RDFService.ModelSerializationFormat.N3, graphURI); + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + + } + + @Override + public void performDelete(Triple t) { + ChangeSet changeSet = rdfService.manufactureChangeSet(); + try { + changeSet.addRemoval(RDFServiceUtils.toInputStream(serialize(t)), + RDFService.ModelSerializationFormat.N3, graphURI); + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + public void removeAll() { + // only to be used with a single graph + if (graphURI == null) { + return; + } + String constructStr = "CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <" + graphURI + "> { ?s ?p ?o } }"; + try { + InputStream model = rdfService.sparqlConstructQuery( + constructStr, RDFService.ModelSerializationFormat.N3); + ChangeSet changeSet = rdfService.manufactureChangeSet(); + changeSet.addRemoval(model, RDFService.ModelSerializationFormat.N3, graphURI); + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + @Override + public void close() { + // can't close a remote endpoint + } + + @Override + public boolean contains(Triple arg0) { + return contains(arg0.getSubject(), arg0.getPredicate(), arg0.getObject()); + } + + @Override + public boolean contains(Node subject, Node predicate, Node object) { + if (subject.isBlank() || predicate.isBlank() || object.isBlank()) { + return false; + } + StringBuffer containsQuery = new StringBuffer("ASK { \n"); + if (graphURI != null) { + containsQuery.append(" GRAPH <" + graphURI + "> { "); + } + containsQuery.append(sparqlNode(subject, "?s")) + .append(" ") + .append(sparqlNode(predicate, "?p")) + .append(" ") + .append(sparqlNode(object, "?o")); + if (graphURI != null) { + containsQuery.append(" } \n"); + } + containsQuery.append("\n}"); + boolean result = execAsk(containsQuery.toString()); + return result; + } + + @Override + public void delete(Triple arg0) throws DeleteDeniedException { + performDelete(arg0); + } + + @Override + public boolean dependsOn(Graph arg0) { + return false; // who knows? + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + //log.info("find(TripleMatch) " + arg0); + Triple t = arg0.asTriple(); + return find(t.getSubject(), t.getPredicate(), t.getObject()); + } + + public static String sparqlNode(Node node, String varName) { + if (node == null || node.isVariable()) { + return varName; + } else if (node.isBlank()) { + return ""; // or throw exception? + } else if (node.isURI()) { + StringBuffer uriBuff = new StringBuffer(); + return uriBuff.append("<").append(node.getURI()).append(">").toString(); + } else if (node.isLiteral()) { + StringBuffer literalBuff = new StringBuffer(); + literalBuff.append("\""); + pyString(literalBuff, node.getLiteralLexicalForm()); + literalBuff.append("\""); + if (node.getLiteralDatatypeURI() != null) { + literalBuff.append("^^<").append(node.getLiteralDatatypeURI()).append(">"); + } else if (node.getLiteralLanguage() != null && node.getLiteralLanguage() != "") { + literalBuff.append("@").append(node.getLiteralLanguage()); + } + return literalBuff.toString(); + } else { + return varName; + } + } + + public static String sparqlNodeUpdate(Node node, String varName) { + if (node.isBlank()) { + return "_:" + node.getBlankNodeLabel().replaceAll("\\W", ""); + } else { + return sparqlNode(node, varName); + } + } + + public static String sparqlNodeDelete(Node node, String varName) { + if (node.isBlank()) { + return "?" + node.getBlankNodeLabel().replaceAll("\\W", ""); + } else { + return sparqlNode(node, varName); + } + } + + @Override + public ExtendedIterator find(Node subject, Node predicate, Node object) { + if (!isVar(subject) && !isVar(predicate) && !isVar(object)) { + if (contains(subject, predicate, object)) { + return new SingletonIterator(new Triple(subject, predicate, object)); + } else { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + } + StringBuffer findQuery = new StringBuffer("SELECT * WHERE { \n"); + if (graphURI != null) { + findQuery.append(" GRAPH <" + graphURI + "> { "); + } + findQuery.append(sparqlNode(subject, "?s")) + .append(" ") + .append(sparqlNode(predicate, "?p")) + .append(" ") + .append(sparqlNode(object, "?o")); + if (graphURI != null) { + findQuery.append(" } "); + } + findQuery.append("\n}"); + + String queryString = findQuery.toString(); + + ResultSet rs = execSelect(queryString); + + List triplist = new ArrayList(); + while (rs.hasNext()) { + QuerySolution soln = rs.nextSolution(); + Triple t = new Triple(isVar(subject) ? soln.get("?s").asNode() : subject, + isVar(predicate) ? soln.get("?p").asNode() : predicate, + isVar(object) ? soln.get("?o").asNode() : object); + //log.info(t); + triplist.add(t); + } + //log.info(triplist.size() + " results"); + return WrappedIterator.create(triplist.iterator()); + } + + private boolean isVar(Node node) { + return (node == null || node.isVariable() || node == Node.ANY); + } + + @Override + public BulkUpdateHandler getBulkUpdateHandler() { + if (this.bulkUpdateHandler == null) { + this.bulkUpdateHandler = new RDFServiceGraphBulkUpdater(this); + } + return this.bulkUpdateHandler; + } + + @Override + public Capabilities getCapabilities() { + return capabilities; + } + + @Override + public GraphEventManager getEventManager() { + if (eventManager == null) { + eventManager = new SimpleEventManager(this); + } + return eventManager; + } + + @Override + public PrefixMapping getPrefixMapping() { + return prefixMapping; + } + + @Override + public Reifier getReifier() { + return reifier; + } + + @Override + public GraphStatisticsHandler getStatisticsHandler() { + return null; + } + + @Override + public TransactionHandler getTransactionHandler() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isClosed() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isEmpty() { + return (size() == 0); + } + + @Override + public boolean isIsomorphicWith(Graph arg0) { + throw new UnsupportedOperationException("isIsomorphicWith() not supported " + + "by SPARQL graphs"); + } + + @Override + public QueryHandler queryHandler() { + if (queryHandler == null) { + queryHandler = new SimpleQueryHandler(this); + } + return queryHandler; + } + + @Override + public int size() { + int size = find(null, null, null).toList().size(); + return size; + } + + private final static Capabilities capabilities = new Capabilities() { + + public boolean addAllowed() { + return false; + } + + public boolean addAllowed(boolean everyTriple) { + return false; + } + + public boolean canBeEmpty() { + return true; + } + + public boolean deleteAllowed() { + return false; + } + + public boolean deleteAllowed(boolean everyTriple) { + return false; + } + + public boolean findContractSafe() { + return true; + } + + public boolean handlesLiteralTyping() { + return true; + } + + public boolean iteratorRemoveAllowed() { + return false; + } + + public boolean sizeAccurate() { + return true; + } + }; + + private boolean execAsk(String queryStr) { + try { + return rdfService.sparqlAskQuery(queryStr); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + private ResultSet execSelect(String queryStr) { + try { + return JSONInput.fromJSON(rdfService.sparqlSelectQuery( + queryStr, RDFService.ResultFormat.JSON)); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + /* + * + * see http://www.python.org/doc/2.5.2/ref/strings.html + * or see jena's n3 grammar jena/src/com/hp/hpl/jena/n3/n3.g + */ + protected static void pyString(StringBuffer sbuff, String s) + { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + // Escape escapes and quotes + if (c == '\\' || c == '"' ) + { + sbuff.append('\\') ; + sbuff.append(c) ; + continue ; + } + + // Whitespace + if (c == '\n'){ sbuff.append("\\n");continue; } + if (c == '\t'){ sbuff.append("\\t");continue; } + if (c == '\r'){ sbuff.append("\\r");continue; } + if (c == '\f'){ sbuff.append("\\f");continue; } + if (c == '\b'){ sbuff.append("\\b");continue; } + if( c == 7 ) { sbuff.append("\\a");continue; } + + // Output as is (subject to UTF-8 encoding on output that is) + sbuff.append(c) ; + +// // Unicode escapes +// // c < 32, c >= 127, not whitespace or other specials +// String hexstr = Integer.toHexString(c).toUpperCase(); +// int pad = 4 - hexstr.length(); +// sbuff.append("\\u"); +// for (; pad > 0; pad--) +// sbuff.append("0"); +// sbuff.append(hexstr); + } + } + + public static Model createRDFServiceModel(final RDFServiceGraph g) { + Model m = ModelFactory.createModelForGraph(g); + m.register(new StatementListener() { + @Override + public void notifyEvent(Model m, Object event) { + ChangeSet changeSet = g.getRDFService().manufactureChangeSet(); + changeSet.addPreChangeEvent(event); + try { + g.getRDFService().changeSetUpdate(changeSet); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + + }); + return m; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java new file mode 100644 index 000000000..9b6300fe4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java @@ -0,0 +1,185 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEvents; +import com.hp.hpl.jena.graph.GraphUtil; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.impl.SimpleBulkUpdateHandler; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sparql.util.graph.GraphFactory; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; + +public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler { + + private static final Log log = LogFactory.getLog(RDFServiceGraphBulkUpdater.class); + private RDFServiceGraph graph; + + public RDFServiceGraphBulkUpdater(RDFServiceGraph graph) { + super(graph); + this.graph = graph; + } + + @Override + public void add(Triple[] arg0) { + Graph g = GraphFactory.createPlainGraph(); + for (int i = 0 ; i < arg0.length ; i++) { + g.add(arg0[i]); + } + add(g); + } + + @Override + public void add(List arg0) { + Graph g = GraphFactory.createPlainGraph(); + for (Triple t : arg0) { + g.add(t); + } + add(g); + } + + @Override + public void add(Iterator arg0) { + Graph g = GraphFactory.createPlainGraph(); + while (arg0.hasNext()) { + Triple t = arg0.next(); + g.add(t); + } + add(g); + } + + @Override + public void add(Graph arg0) { + add(arg0, false); + } + + @Override + public void add(Graph g, boolean arg1) { + Model[] model = separateStatementsWithBlankNodes(g); + addModel(model[1] /* nonBlankNodeModel */); + // replace following call with different method + addModel(model[0] /*blankNodeModel*/); + } + + /** + * Returns a pair of models. The first contains any statement containing at + * least one blank node. The second contains all remaining statements. + * @param g + * @return + */ + + private Model[] separateStatementsWithBlankNodes(Graph g) { + Model gm = ModelFactory.createModelForGraph(g); + Model blankNodeModel = ModelFactory.createDefaultModel(); + Model nonBlankNodeModel = ModelFactory.createDefaultModel(); + StmtIterator sit = gm.listStatements(); + while (sit.hasNext()) { + Statement stmt = sit.nextStatement(); + if (!stmt.getSubject().isAnon() && !stmt.getObject().isAnon()) { + nonBlankNodeModel.add(stmt); + } else { + blankNodeModel.add(stmt); + } + } + Model[] result = new Model[2]; + result[0] = blankNodeModel; + result[1] = nonBlankNodeModel; + return result; + } + + + @Override + public void delete(Graph g, boolean withReifications) { + delete(g); + } + + @Override + public void delete(Graph g) { + deleteModel(ModelFactory.createModelForGraph(g)); + } + + public void addModel(Model model) { + ChangeSet changeSet = graph.getRDFService().manufactureChangeSet(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + model.write(out, "N-TRIPLE"); + changeSet.addAddition(new ByteArrayInputStream( + out.toByteArray()), RDFService.ModelSerializationFormat.N3, + graph.getGraphURI()); + try { + graph.getRDFService().changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + public void deleteModel(Model model) { + ChangeSet changeSet = graph.getRDFService().manufactureChangeSet(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + model.write(out, "N-TRIPLE"); + changeSet.addRemoval(new ByteArrayInputStream( + out.toByteArray()), RDFService.ModelSerializationFormat.N3, + graph.getGraphURI()); + try { + graph.getRDFService().changeSetUpdate(changeSet); + } catch (RDFServiceException rdfse) { + throw new RuntimeException(rdfse); + } + } + + @Override + public void removeAll() { + removeAll(graph); + notifyRemoveAll(); + } + + protected void notifyRemoveAll() { + manager.notifyEvent(graph, GraphEvents.removeAll); + } + + @Override + public void remove(Node s, Node p, Node o) { + removeAll(graph, s, p, o); + manager.notifyEvent(graph, GraphEvents.remove(s, p, o)); + } + + public static void removeAll(Graph g, Node s, Node p, Node o) + { + ExtendedIterator it = g.find( s, p, o ); + try { + while (it.hasNext()) { + Triple t = it.next(); + g.delete(t); + it.remove(); + } + } + finally { + it.close(); + } + } + + public static void removeAll( Graph g ) + { + g.getBulkUpdateHandler().delete(g); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java new file mode 100644 index 000000000..812ae899e --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java @@ -0,0 +1,244 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.GraphMaker; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelMaker; +import com.hp.hpl.jena.rdf.model.ModelReader; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sdb.SDBFactory; +import com.hp.hpl.jena.sdb.Store; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; +import com.hp.hpl.jena.vocabulary.RDFS; + +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 RDFServiceModelMaker implements ModelMaker { + + private final static Log log = LogFactory.getLog(VitroJenaSDBModelMaker.class); + + private RDFServiceFactory rdfServiceFactory; + + public static final String METADATA_MODEL_URI = + "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/metadata"; + + public static final String HAS_NAMED_MODEL_URI = + "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/hasNamedModel"; + + private Resource sdbResource; // a resource representing the SDB database + + public RDFServiceModelMaker(RDFServiceFactory rdfServiceFactory) { + this.rdfServiceFactory = rdfServiceFactory; + } + + protected RDFService getRDFService() { + return rdfServiceFactory.getRDFService(); + } + + Model getMetadataModel() { + return getModel(METADATA_MODEL_URI); + } + + public void close() { + // n.a. + } + + public Model createModel(String modelName) { + Model model = getModel(modelName); + Model metadataModel = getMetadataModel(); + try { + metadataModel.add( + sdbResource,metadataModel.getProperty( + HAS_NAMED_MODEL_URI), modelName); + } finally { + metadataModel.close(); + } + return model; + } + + public Model createModel(String arg0, boolean arg1) { + // TODO Figure out if we can offer a "create if not found" option using SDB + return createModel(arg0); + } + + public GraphMaker getGraphMaker() { + throw new UnsupportedOperationException( + "GraphMaker not supported by " + this.getClass().getName()); + } + + public boolean hasModel(String arg0) { + Model metadataModel = getMetadataModel(); + try { + StmtIterator stmtIt = metadataModel.listStatements( + sdbResource, metadataModel.getProperty( + HAS_NAMED_MODEL_URI), arg0); + try { + return stmtIt.hasNext(); + } finally { + if (stmtIt != null) { + stmtIt.close(); + } + } + } finally { + metadataModel.close(); + } + } + + public ExtendedIterator listModels() { + Model metadataModel = getMetadataModel(); + try { + return listModelNames(metadataModel); + } finally { + metadataModel.close(); + } + } + + private ExtendedIterator listModelNames(Model metadataModel) { + + Set modelNameSet = new HashSet(); + + Iterator metadataNameIt = metadataModel.listObjectsOfProperty( + metadataModel.getProperty(HAS_NAMED_MODEL_URI)); + while (metadataNameIt.hasNext()) { + RDFNode rdfNode = metadataNameIt.next(); + if (rdfNode.isLiteral()) { + modelNameSet.add(((Literal) rdfNode).getLexicalForm()); + } + } + + RDFService service = getRDFService(); + try { + modelNameSet.addAll(service.getGraphURIs()); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } finally { + service.close(); + } + + List modelNameList = new ArrayList(); + modelNameList.addAll(modelNameSet); + Collections.sort(modelNameList, Collator.getInstance()); + + return WrappedIterator.create(modelNameList.iterator()); + } + + public Model openModel(String arg0, boolean arg1) { + RDFService service = getRDFService(); + try { + Dataset dataset = new RDFServiceDataset(service); + return dataset.getNamedModel(arg0); + } finally { + service.close(); + } + } + + public void removeModel(String arg0) { + Model m = getModel(arg0); + m.removeAll(null,null,null); + Model metadataModel = getMetadataModel(); + try { + metadataModel.remove(sdbResource, metadataModel.getProperty( + HAS_NAMED_MODEL_URI),metadataModel.createLiteral(arg0)); + } finally { + metadataModel.close(); + } + } + + public Model addDescription(Model arg0, Resource arg1) { + throw new UnsupportedOperationException( + "addDescription not supported by " + this.getClass().getName()); + } + + public Model createModelOver(String arg0) { + throw new UnsupportedOperationException( + "createModelOver not supported by " + this.getClass().getName()); + } + + public Model getDescription() { + throw new UnsupportedOperationException( + "createModelOver not supported by " + this.getClass().getName()); + } + + public Model getDescription(Resource arg0) { + throw new UnsupportedOperationException( + "getDescription not supported by "+this.getClass().getName()); + } + + public Model openModel() { + RDFService service = getRDFService(); + try { + Dataset dataset = new RDFServiceDataset(service); + return dataset.getDefaultModel(); + } finally { + service.close(); + } + } + + public Model createDefaultModel() { + return openModel(); + } + + public Model createFreshModel() { + throw new UnsupportedOperationException( + "createFreshModel not supported by " + this.getClass().getName()); + } + + /** + * @deprecated + */ + public Model createModel() { + return openModel(); + } + + /** + * @deprecated + */ + public Model getModel() { + return openModel(); + } + + public Model openModel(String arg0) { + return openModel(); + } + + public Model openModelIfPresent(String arg0) { + return (this.hasModel(arg0)) + ? openModel(arg0, false) + : null; + } + + public Model getModel(String modelName) { + return openModel(modelName, true); + } + + public Model getModel(String arg0, ModelReader arg1) { + throw new UnsupportedOperationException( + "getModel(String, ModelReader) not supported by " + + this.getClass().getName()); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java index 73c356a38..7564dc891 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java @@ -14,14 +14,14 @@ import com.hp.hpl.jena.shared.Lock; */ public class SimpleOntModelSelector implements OntModelSelector { - private OntModel fullModel; - private OntModel aboxModel; - private OntModel applicationMetadataModel; - private OntModel tboxModel; - private OntModel userAccountsModel; + protected OntModel fullModel; + protected OntModel aboxModel; + protected OntModel applicationMetadataModel; + protected OntModel tboxModel; + protected OntModel userAccountsModel; - private OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; - private OntModel displayModel; + protected OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; + protected OntModel displayModel; /** * Construct an OntModelSelector with a bunch of empty models diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java new file mode 100644 index 000000000..b9d65d2c1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java @@ -0,0 +1,15 @@ +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import com.hp.hpl.jena.ontology.OntModel; + +public class SingleContentOntModelSelector extends SimpleOntModelSelector { + + public SingleContentOntModelSelector(OntModel contentModel, + OntModel displayModel, + OntModel userAccountsModel) { + super(contentModel); + super.displayModel = displayModel; + super.userAccountsModel = userAccountsModel; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDataset.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDataset.java new file mode 100644 index 000000000..16ce9b326 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDataset.java @@ -0,0 +1,64 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.sparql.core.DatasetGraph; + +public class SparqlDataset implements Dataset { + + private SparqlDatasetGraph g; + + public SparqlDataset(SparqlDatasetGraph g) { + this.g = g; + } + + @Override + public DatasetGraph asDatasetGraph() { + return g; + } + + @Override + public void close() { + g.close(); + } + + @Override + public boolean containsNamedModel(String arg0) { + return g.containsGraph(Node.createURI(arg0)); + } + + @Override + public Model getDefaultModel() { + return ModelFactory.createModelForGraph(g.getDefaultGraph()); + } + + @Override + public Lock getLock() { + return g.getLock(); + } + + @Override + public Model getNamedModel(String arg0) { + return ModelFactory.createModelForGraph(g.getGraph(Node.createURI(arg0))); + } + + @Override + public Iterator listNames() { + ArrayList nameList = new ArrayList(); + Iterator nodeIt = g.listGraphNodes(); + while (nodeIt.hasNext()) { + Node n = nodeIt.next(); + nameList.add(n.getURI()); + } + return nameList.iterator(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDatasetGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDatasetGraph.java new file mode 100644 index 000000000..7cd6f8822 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlDatasetGraph.java @@ -0,0 +1,266 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.openrdf.model.Resource; +import org.openrdf.repository.Repository; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.RepositoryResult; +import org.openrdf.repository.http.HTTPRepository; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.shared.LockMRSW; +import com.hp.hpl.jena.sparql.core.DatasetGraph; +import com.hp.hpl.jena.sparql.core.Quad; +import com.hp.hpl.jena.sparql.resultset.ResultSetMem; +import com.hp.hpl.jena.sparql.util.Context; +import com.hp.hpl.jena.util.iterator.SingletonIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class SparqlDatasetGraph implements DatasetGraph { + + private String endpointURI; + private Repository repository; + private Lock lock = new LockMRSW(); + + public SparqlDatasetGraph(String endpointURI) { + this.endpointURI = endpointURI; + this.repository = new HTTPRepository(endpointURI); + } + + private Graph getGraphFor(Quad q) { + return getGraphFor(q.getGraph()); + } + + private Graph getGraphFor(Node g) { + return (g == Node.ANY) + ? new SparqlGraph(endpointURI) + : new SparqlGraph(endpointURI, g.getURI()); + } + + @Override + public void add(Quad arg0) { + getGraphFor(arg0).add(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public void addGraph(Node arg0, Graph arg1) { + // TODO Auto-generated method stub + } + + @Override + public void close() { + // TODO Auto-generated method stub + } + + @Override + public boolean contains(Quad arg0) { + return getGraphFor(arg0).contains(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public boolean contains(Node arg0, Node arg1, Node arg2, Node arg3) { + return getGraphFor(arg0).contains(arg1, arg2, arg3); + } + + @Override + public boolean containsGraph(Node arg0) { + // TODO Auto-generated method stub + return true; + } + + @Override + public void delete(Quad arg0) { + getGraphFor(arg0).delete(new Triple(arg0.getSubject(), arg0.getPredicate(), arg0.getObject())); + } + + @Override + public void deleteAny(Node arg0, Node arg1, Node arg2, Node arg3) { + // TODO check this + getGraphFor(arg0).delete(new Triple(arg1, arg2, arg3)); + } + + @Override + public Iterator find() { + return find(Node.ANY, Node.ANY, Node.ANY, Node.ANY); + } + + @Override + public Iterator find(Quad arg0) { + return find(arg0.getSubject(), arg0.getPredicate(), arg0.getObject(), arg0.getGraph()); + } + + @Override + public Iterator find(Node graph, Node subject, Node predicate, Node object) { + if (!isVar(subject) && !isVar(predicate) && !isVar(object) &&!isVar(graph)) { + if (contains(subject, predicate, object, graph)) { + return new SingletonIterator(new Triple(subject, predicate, object)); + } else { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + } + StringBuffer findQuery = new StringBuffer("SELECT * WHERE { \n"); + String graphURI = !isVar(graph) ? graph.getURI() : null; + findQuery.append(" GRAPH "); + if (graphURI != null) { + findQuery.append(" <" + graphURI + ">"); + } else { + findQuery.append("?g"); + } + findQuery.append(" { "); + findQuery.append(SparqlGraph.sparqlNode(subject, "?s")) + .append(" ") + .append(SparqlGraph.sparqlNode(predicate, "?p")) + .append(" ") + .append(SparqlGraph.sparqlNode(object, "?o")); + findQuery.append(" } "); + findQuery.append("\n}"); + + //log.info(findQuery.toString()); + ResultSet rs = execSelect(findQuery.toString()); + //rs = execSelect(findQuery.toString()); + //rs = execSelect(findQuery.toString()); + + List quadlist = new ArrayList(); + while (rs.hasNext()) { + QuerySolution soln = rs.nextSolution(); + Quad q = new Quad(isVar(graph) ? soln.get("?g").asNode() : graph, + isVar(subject) ? soln.get("?s").asNode() : subject, + isVar(predicate) ? soln.get("?p").asNode() : predicate, + isVar(object) ? soln.get("?o").asNode() : object); + //log.info(t); + quadlist.add(q); + } + //log.info(triplist.size() + " results"); + return WrappedIterator.create(quadlist.iterator()); } + + @Override + public Iterator findNG(Node arg0, Node arg1, Node arg2, Node arg3) { + // TODO check this + return find(arg0, arg1, arg2, arg3); + } + + @Override + public Context getContext() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Graph getDefaultGraph() { + return new SparqlGraph(endpointURI); + } + + @Override + public Graph getGraph(Node arg0) { + return new SparqlGraph(endpointURI, arg0.getURI()); + } + + @Override + public Lock getLock() { + return lock; + } + + @Override + public boolean isEmpty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Iterator listGraphNodes() { + List graphNodeList = new ArrayList(); + try { + RepositoryConnection conn = getConnection(); + try { + RepositoryResult conResult = conn.getContextIDs(); + while (conResult.hasNext()) { + Resource con = conResult.next(); + graphNodeList.add(Node.createURI(con.stringValue())); + } + } finally { + conn.close(); + } + } catch (RepositoryException re) { + throw new RuntimeException(re); + } + return graphNodeList.iterator(); + } + + private RepositoryConnection getConnection() { + try { + return this.repository.getConnection(); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + @Override + public void removeGraph(Node arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void setDefaultGraph(Graph arg0) { + // TODO Auto-generated method stub + + } + + @Override + public long size() { + // TODO Auto-generated method stub + return 0; + } + + private boolean isVar(Node node) { + return (node == null || node.isVariable() || node == Node.ANY); + } + + private ResultSet execSelect(String queryStr) { + +// long startTime1 = System.currentTimeMillis(); +// try { +// +// RepositoryConnection conn = getConnection(); +// try { +// GraphQuery q = conn.prepareGraphQuery(QueryLanguage.SPARQL, queryStr); +// q.evaluate(); +// } catch (MalformedQueryException e) { +// throw new RuntimeException(e); +// } finally { +// conn.close(); +// } +// } catch (Exception re) { +// //log.info(re,re); +// } + +// log.info((System.currentTimeMillis() - startTime1) + " to execute via sesame"); + + long startTime = System.currentTimeMillis(); + Query askQuery = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, askQuery); + try { + return new ResultSetMem(qe.execSelect()); + } finally { + //log.info((System.currentTimeMillis() - startTime) + " to execute via Jena"); + qe.close(); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java new file mode 100644 index 000000000..d3988bc66 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java @@ -0,0 +1,508 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.Update; +import org.openrdf.query.UpdateExecutionException; +import org.openrdf.repository.Repository; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.http.HTTPRepository; + +import com.hp.hpl.jena.graph.BulkUpdateHandler; +import com.hp.hpl.jena.graph.Capabilities; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEventManager; +import com.hp.hpl.jena.graph.GraphStatisticsHandler; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Reifier; +import com.hp.hpl.jena.graph.TransactionHandler; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.impl.GraphWithPerform; +import com.hp.hpl.jena.graph.impl.SimpleEventManager; +import com.hp.hpl.jena.graph.query.QueryHandler; +import com.hp.hpl.jena.graph.query.SimpleQueryHandler; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.shared.AddDeniedException; +import com.hp.hpl.jena.shared.DeleteDeniedException; +import com.hp.hpl.jena.shared.PrefixMapping; +import com.hp.hpl.jena.shared.impl.PrefixMappingImpl; +import com.hp.hpl.jena.sparql.resultset.ResultSetMem; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.SingletonIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class SparqlGraph implements GraphWithPerform { + + private String endpointURI; + private String graphURI; + private static final Log log = LogFactory.getLog(SparqlGraph.class); + + private BulkUpdateHandler bulkUpdateHandler; + private PrefixMapping prefixMapping = new PrefixMappingImpl(); + private GraphEventManager eventManager; + private Reifier reifier = new EmptyReifier(this); + private GraphStatisticsHandler graphStatisticsHandler; + private TransactionHandler transactionHandler; + private QueryHandler queryHandler; + + private Repository repository; + + /** + * Returns a SparqlGraph for the union of named graphs in a remote repository + * @param endpointURI + */ + public SparqlGraph(String endpointURI) { + this(endpointURI, null); + } + + /** + * Returns a SparqlGraph for a particular named graph in a remote repository + * @param endpointURI + * @param graphURI + */ + public SparqlGraph(String endpointURI, String graphURI) { + this.endpointURI = endpointURI; + this.graphURI = graphURI; + this.repository = new HTTPRepository(endpointURI); + } + + public String getEndpointURI() { + return endpointURI; + } + + public String getGraphURI() { + return graphURI; + } + + public RepositoryConnection getConnection() { + try { + return this.repository.getConnection(); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + @Override + public void add(Triple arg0) throws AddDeniedException { + performAdd(arg0); + } + + public void executeUpdate(String updateString) { + try { + RepositoryConnection conn = getConnection(); + try { + Update u = conn.prepareUpdate(QueryLanguage.SPARQL, updateString); + u.execute(); + } catch (MalformedQueryException e) { + throw new RuntimeException(e); + } catch (UpdateExecutionException e) { + log.error(e,e); + log.error("Update command: \n" + updateString); + throw new RuntimeException(e); + } finally { + conn.close(); + } + } catch (RepositoryException re) { + throw new RuntimeException(re); + } + } + + @Override + public void performAdd(Triple t) { + + //log.info("adding " + t); + + String updateString = "INSERT DATA { " + ((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ) + + sparqlNodeUpdate(t.getSubject(), "") + " " + + sparqlNodeUpdate(t.getPredicate(), "") + " " + + sparqlNodeUpdate(t.getObject(), "") + " } " + + ((graphURI != null) ? " } " : ""); + + + if (graphURI != null) { + log.info("=====> update to graph " + graphURI); + } + log.info(updateString); + + executeUpdate(updateString); + + } + + @Override + public void performDelete(Triple t) { + + String updateString = "DELETE DATA { " + ((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ) + + sparqlNodeUpdate(t.getSubject(), "") + " " + + sparqlNodeUpdate(t.getPredicate(), "") + " " + + sparqlNodeUpdate(t.getObject(), "") + " } " + + ((graphURI != null) ? " } " : ""); + + //log.info(updateString); + + executeUpdate(updateString); + } + + public void removeAll() { + // now we flush out any remaining blank nodes + String updateString = "DELETE { ?s ?p ?o } WHERE { \n" + + ((getGraphURI() != null) ? ("GRAPH <" + getGraphURI() + "> { \n") : ("")) + + " ?s ?p ?o \n" + + ((getGraphURI() != null) ? "} \n" : "") + + "}"; + executeUpdate(updateString); + } + + @Override + public void close() { + // can't close a remote endpoint + } + + @Override + public boolean contains(Triple arg0) { + return contains(arg0.getSubject(), arg0.getPredicate(), arg0.getObject()); + } + + @Override + public boolean contains(Node subject, Node predicate, Node object) { + if (subject.isBlank() || predicate.isBlank() || object.isBlank()) { + return false; + } + StringBuffer containsQuery = new StringBuffer("ASK { \n"); + if (graphURI != null) { + containsQuery.append(" GRAPH <" + graphURI + "> { "); + } + containsQuery.append(sparqlNode(subject, "?s")) + .append(" ") + .append(sparqlNode(predicate, "?p")) + .append(" ") + .append(sparqlNode(object, "?o")); + if (graphURI != null) { + containsQuery.append(" } \n"); + } + containsQuery.append("\n}"); + boolean result = execAsk(containsQuery.toString()); + return result; + } + + @Override + public void delete(Triple arg0) throws DeleteDeniedException { + performDelete(arg0); + } + + @Override + public boolean dependsOn(Graph arg0) { + return false; // who knows? + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + //log.info("find(TripleMatch) " + arg0); + Triple t = arg0.asTriple(); + return find(t.getSubject(), t.getPredicate(), t.getObject()); + } + + public static String sparqlNode(Node node, String varName) { + if (node == null || node.isVariable()) { + return varName; + } else if (node.isBlank()) { + return ""; // or throw exception? + } else if (node.isURI()) { + StringBuffer uriBuff = new StringBuffer(); + return uriBuff.append("<").append(node.getURI()).append(">").toString(); + } else if (node.isLiteral()) { + StringBuffer literalBuff = new StringBuffer(); + literalBuff.append("\""); + pyString(literalBuff, node.getLiteralLexicalForm()); + literalBuff.append("\""); + if (node.getLiteralDatatypeURI() != null) { + literalBuff.append("^^<").append(node.getLiteralDatatypeURI()).append(">"); + } else if (node.getLiteralLanguage() != null && node.getLiteralLanguage() != "") { + literalBuff.append("@").append(node.getLiteralLanguage()); + } + return literalBuff.toString(); + } else { + return varName; + } + } + + public static String sparqlNodeUpdate(Node node, String varName) { + if (node.isBlank()) { + return "_:" + node.getBlankNodeLabel().replaceAll("\\W", ""); + } else { + return sparqlNode(node, varName); + } + } + + public static String sparqlNodeDelete(Node node, String varName) { + if (node.isBlank()) { + return "?" + node.getBlankNodeLabel().replaceAll("\\W", ""); + } else { + return sparqlNode(node, varName); + } + } + + @Override + public ExtendedIterator find(Node subject, Node predicate, Node object) { + if (!isVar(subject) && !isVar(predicate) && !isVar(object)) { + if (contains(subject, predicate, object)) { + return new SingletonIterator(new Triple(subject, predicate, object)); + } else { + return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + } + } + StringBuffer findQuery = new StringBuffer("SELECT * WHERE { \n"); + if (graphURI != null) { + findQuery.append(" GRAPH <" + graphURI + "> { "); + } + findQuery.append(sparqlNode(subject, "?s")) + .append(" ") + .append(sparqlNode(predicate, "?p")) + .append(" ") + .append(sparqlNode(object, "?o")); + if (graphURI != null) { + findQuery.append(" } "); + } + findQuery.append("\n}"); + + String queryString = findQuery.toString(); + //log.info(queryString); + +// //TODO remove me +// if (queryString.contains("individual/AI") && queryString.contains("label")) { +// throw new RuntimeException("break!"); +// } + + ResultSet rs = execSelect(queryString); + //rs = execSelect(findQuery.toString()); + //rs = execSelect(findQuery.toString()); + + List triplist = new ArrayList(); + while (rs.hasNext()) { + QuerySolution soln = rs.nextSolution(); + Triple t = new Triple(isVar(subject) ? soln.get("?s").asNode() : subject, + isVar(predicate) ? soln.get("?p").asNode() : predicate, + isVar(object) ? soln.get("?o").asNode() : object); + //log.info(t); + triplist.add(t); + } + //log.info(triplist.size() + " results"); + return WrappedIterator.create(triplist.iterator()); + } + + private boolean isVar(Node node) { + return (node == null || node.isVariable() || node == Node.ANY); + } + + @Override + public BulkUpdateHandler getBulkUpdateHandler() { + if (this.bulkUpdateHandler == null) { + this.bulkUpdateHandler = new SparqlGraphBulkUpdater(this); + } + return this.bulkUpdateHandler; + } + + @Override + public Capabilities getCapabilities() { + return capabilities; + } + + @Override + public GraphEventManager getEventManager() { + if (eventManager == null) { + eventManager = new SimpleEventManager(this); + } + return eventManager; + } + + @Override + public PrefixMapping getPrefixMapping() { + return prefixMapping; + } + + @Override + public Reifier getReifier() { + //if (reifier == null) { + // reifier = new SimpleReifier(this, ReificationStyle.Standard); + //} + return reifier; + } + + @Override + public GraphStatisticsHandler getStatisticsHandler() { + return null; + } + + @Override + public TransactionHandler getTransactionHandler() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isClosed() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isEmpty() { + return (size() == 0); + } + + @Override + public boolean isIsomorphicWith(Graph arg0) { + log.info("Hey dummy!"); + throw new UnsupportedOperationException("isIsomorphicWith() not supported " + + "by SPARQL graphs"); + } + + @Override + public QueryHandler queryHandler() { + if (queryHandler == null) { + queryHandler = new SimpleQueryHandler(this); + } + return queryHandler; + } + + @Override + public int size() { + int size = find(null, null, null).toList().size(); + return size; + } + + private final static Capabilities capabilities = new Capabilities() { + + public boolean addAllowed() { + return false; + } + + public boolean addAllowed(boolean everyTriple) { + return false; + } + + public boolean canBeEmpty() { + return true; + } + + public boolean deleteAllowed() { + return false; + } + + public boolean deleteAllowed(boolean everyTriple) { + return false; + } + + public boolean findContractSafe() { + return true; + } + + public boolean handlesLiteralTyping() { + return true; + } + + public boolean iteratorRemoveAllowed() { + return false; + } + + public boolean sizeAccurate() { + return true; + } + }; + + private boolean execAsk(String queryStr) { + Query askQuery = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, askQuery); + try { + return qe.execAsk(); + } finally { + qe.close(); + } + } + + private ResultSet execSelect(String queryStr) { + +// long startTime1 = System.currentTimeMillis(); +// try { +// +// RepositoryConnection conn = getConnection(); +// try { +// GraphQuery q = conn.prepareGraphQuery(QueryLanguage.SPARQL, queryStr); +// q.evaluate(); +// } catch (MalformedQueryException e) { +// throw new RuntimeException(e); +// } finally { +// conn.close(); +// } +// } catch (Exception re) { +// //log.info(re,re); +// } + +// log.info((System.currentTimeMillis() - startTime1) + " to execute via sesame"); + + long startTime = System.currentTimeMillis(); + Query askQuery = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, askQuery); + try { + return new ResultSetMem(qe.execSelect()); + } finally { + //log.info((System.currentTimeMillis() - startTime) + " to execute via Jena"); + qe.close(); + } + } + + /* + * + * see http://www.python.org/doc/2.5.2/ref/strings.html + * or see jena's n3 grammar jena/src/com/hp/hpl/jena/n3/n3.g + */ + protected static void pyString(StringBuffer sbuff, String s) + { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + // Escape escapes and quotes + if (c == '\\' || c == '"' ) + { + sbuff.append('\\') ; + sbuff.append(c) ; + continue ; + } + + // Whitespace + if (c == '\n'){ sbuff.append("\\n");continue; } + if (c == '\t'){ sbuff.append("\\t");continue; } + if (c == '\r'){ sbuff.append("\\r");continue; } + if (c == '\f'){ sbuff.append("\\f");continue; } + if (c == '\b'){ sbuff.append("\\b");continue; } + if( c == 7 ) { sbuff.append("\\a");continue; } + + // Output as is (subject to UTF-8 encoding on output that is) + sbuff.append(c) ; + +// // Unicode escapes +// // c < 32, c >= 127, not whitespace or other specials +// String hexstr = Integer.toHexString(c).toUpperCase(); +// int pad = 4 - hexstr.length(); +// sbuff.append("\\u"); +// for (; pad > 0; pad--) +// sbuff.append("0"); +// sbuff.append(hexstr); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphBulkUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphBulkUpdater.java new file mode 100644 index 000000000..4c2e4c39a --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphBulkUpdater.java @@ -0,0 +1,242 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.io.StringWriter; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEvents; +import com.hp.hpl.jena.graph.GraphUtil; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.impl.SimpleBulkUpdateHandler; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sparql.util.graph.GraphFactory; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; + +public class SparqlGraphBulkUpdater extends SimpleBulkUpdateHandler { + + private static final Log log = LogFactory.getLog(SparqlGraphBulkUpdater.class); + private SparqlGraph graph; + + public SparqlGraphBulkUpdater(SparqlGraph graph) { + super(graph); + this.graph = graph; + } + + @Override + public void add(Triple[] arg0) { + Graph g = GraphFactory.createPlainGraph(); + for (int i = 0 ; i < arg0.length ; i++) { + g.add(arg0[i]); + } + add(g); + } + + @Override + public void add(List arg0) { + Graph g = GraphFactory.createPlainGraph(); + for (Triple t : arg0) { + g.add(t); + } + add(g); + } + + @Override + public void add(Iterator arg0) { + Graph g = GraphFactory.createPlainGraph(); + while (arg0.hasNext()) { + Triple t = arg0.next(); + g.add(t); + } + add(g); + } + + @Override + public void add(Graph arg0) { + add(arg0, false); + } + + @Override + public void add(Graph g, boolean arg1) { + log.info("adding graph"); + Model[] model = separateStatementsWithBlankNodes(g); + addModel(model[1] /* nonBlankNodeModel */); + // replace following call with different method + addModel(model[0] /*blankNodeModel*/); + } + + /** + * Returns a pair of models. The first contains any statement containing at + * least one blank node. The second contains all remaining statements. + * @param g + * @return + */ + + private Model[] separateStatementsWithBlankNodes(Graph g) { + Model gm = ModelFactory.createModelForGraph(g); + Model blankNodeModel = ModelFactory.createDefaultModel(); + Model nonBlankNodeModel = ModelFactory.createDefaultModel(); + StmtIterator sit = gm.listStatements(); + while (sit.hasNext()) { + Statement stmt = sit.nextStatement(); + if (!stmt.getSubject().isAnon() && !stmt.getObject().isAnon()) { + nonBlankNodeModel.add(stmt); + } else { + blankNodeModel.add(stmt); + } + } + Model[] result = new Model[2]; + result[0] = blankNodeModel; + result[1] = nonBlankNodeModel; + return result; + } + + + @Override + public void delete(Graph g, boolean withReifications) { + delete(g); + } + + @Override + public void delete(Graph g) { + Model[] model = separateStatementsWithBlankNodes(g); + deleteModel(model[1] /*statements without blank nodes*/); + // replace blank nodes in remaining statements with variables + + StringBuffer patternBuff = new StringBuffer(); + Iterator tripIt = g.find(null, null, null); + while(tripIt.hasNext()) { + Triple t = tripIt.next(); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); + patternBuff.append(" "); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); + patternBuff.append(" "); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getObject(), null)); + patternBuff.append(" .\n"); + } + + StringBuffer queryBuff = new StringBuffer(); + String graphURI = graph.getGraphURI(); + queryBuff.append("DELETE { " + ((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ) + " \n"); + queryBuff.append(patternBuff); + if (graphURI != null) { + queryBuff.append(" } \n"); + } + queryBuff.append("} WHERE { \n"); + if (graphURI != null) { + queryBuff.append(" GRAPH <" + graphURI + "> { \n"); + } + queryBuff.append(patternBuff); + if (graphURI != null) { + queryBuff.append(" } \n"); + } + queryBuff.append("} \n"); + + log.debug(queryBuff.toString()); + + graph.executeUpdate(queryBuff.toString()); + + } + + public void addModel(Model model) { + verbModel(model, "INSERT"); + } + + public void deleteModel(Model model) { + verbModel(model, "DELETE"); + } + + private void verbModel(Model model, String verb) { + Model m = ModelFactory.createDefaultModel(); + int testLimit = 1000; + StmtIterator stmtIt = model.listStatements(); + int count = 0; + try { + while (stmtIt.hasNext()) { + count++; + m.add(stmtIt.nextStatement()); + if (count % testLimit == 0 || !stmtIt.hasNext()) { + StringWriter sw = new StringWriter(); + m.write(sw, "N-TRIPLE"); + StringBuffer updateStringBuff = new StringBuffer(); + String graphURI = graph.getGraphURI(); + updateStringBuff.append(verb + " DATA { " + ((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" )); + updateStringBuff.append(sw); + updateStringBuff.append(((graphURI != null) ? " } " : "") + " }"); + + String updateString = updateStringBuff.toString(); + + //log.info(updateString); + + graph.executeUpdate(updateString); + + m.removeAll(); + } + } + } finally { + stmtIt.close(); + } + } + + + @Override + public void removeAll() { + removeAll(graph); + notifyRemoveAll(); + } + + protected void notifyRemoveAll() { + manager.notifyEvent(graph, GraphEvents.removeAll); + } + + @Override + public void remove(Node s, Node p, Node o) { + removeAll(graph, s, p, o); + manager.notifyEvent(graph, GraphEvents.remove(s, p, o)); + } + + public static void removeAll(Graph g, Node s, Node p, Node o) + { + ExtendedIterator it = g.find( s, p, o ); + try { + while (it.hasNext()) { + Triple t = it.next(); + g.delete(t); + it.remove(); + } + } + finally { + it.close(); + } + } + + public static void removeAll( Graph g ) + { + ExtendedIterator it = GraphUtil.findAll(g); + try { + while (it.hasNext()) { + Triple t = it.next(); + g.delete(t); + it.remove(); + } + } finally { + it.close(); + } + + // get rid of remaining blank nodes using a SPARQL DELETE + if (g instanceof SparqlGraph) { + ((SparqlGraph) g).removeAll(); + } + + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java new file mode 100644 index 000000000..1e6aeb9de --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java @@ -0,0 +1,149 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.impl.GraphWithPerform; +import com.hp.hpl.jena.shared.AddDeniedException; +import com.hp.hpl.jena.sparql.util.NodeFactory; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class SparqlGraphMultilingual extends SparqlGraph implements GraphWithPerform { + + private static final Log log = LogFactory.getLog(SparqlGraphMultilingual.class); + + protected List langs; + + + public SparqlGraphMultilingual(String endpointURI, List languages) { + super(endpointURI); + this.langs = languages; + } + + @Override + public void add(Triple arg0) throws AddDeniedException { + performAdd(arg0); + } + + @Override + public void performAdd(Triple t) { + if (true) { + super.performAdd(t); + return; + } + if (langs == null || langs.size() == 0) { + log.info("No language configured - adding original triple " + t); + super.performAdd(t); + } else if (t.getObject().isLiteral() + && t.getObject().getLiteral().getDatatypeURI() == null) { + log.info("adding language tag"); + super.performAdd(Triple.create(t.getSubject(), + t.getPredicate(), NodeFactory.createLiteralNode( + t.getObject().getLiteralLexicalForm(), langs.get(0), null))); + } else { + log.info("adding original triple " + t); + super.performAdd(t); + } + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + //log.info("find(TripleMatch) " + arg0); + Triple t = arg0.asTriple(); + return find(t.getSubject(), t.getPredicate(), t.getObject()); + } + + @Override + public ExtendedIterator find(Node subject, Node predicate, Node object) { + + long startTime = System.currentTimeMillis(); + + ExtendedIterator rawResults = super.find(subject, predicate, object); + long rawTime = System.currentTimeMillis() - startTime; + + List tripList = new ArrayList(); + while (rawResults.hasNext()) { + tripList.add(rawResults.next()); + } + if (tripList.size() == 0) { + return WrappedIterator.create(tripList.iterator()); + } + if (subject.isConcrete() && predicate.isConcrete() && !object.isConcrete()) { + Collections.sort(tripList, new TripleSortByLang()); + LinkedList tripl = new LinkedList(); + if (!tripList.get(0).getObject().isLiteral()) { + tripl.addAll(tripList); + } else if (StringUtils.isEmpty(tripList.get(0).getObject().getLiteralLanguage())) { + tripl.addAll(tripList); // is this right? + } else { + String lang = tripList.get(0).getObject().getLiteralLanguage(); + for (Triple t : tripList) { + if (lang.equals(t.getObject().getLiteralLanguage())) { + tripl.add(t); + } else { + break; + } + } + } + long filterTime = System.currentTimeMillis() - rawTime - startTime; + if (filterTime > 1) { + log.info("raw time " + rawTime + " ; filter time " + filterTime); + } + return WrappedIterator.create(tripl.iterator()); + } else { + if (rawTime > 9) { + log.info("raw time " + rawTime); + log.info("^ " + subject + " : " + predicate + " : " + object); + } + return WrappedIterator.create(tripList.iterator()); + } + } + + private class TripleSortByLang implements Comparator { + + public int compare(Triple t1, Triple t2) { + if (t1 == null || t2 == null) { + return 0; + } else if (!t1.getObject().isLiteral() || !t2.getObject().isLiteral()) { + return 0; + } + + String t1lang = t1.getObject().getLiteral().language(); + String t2lang = t2.getObject().getLiteral().language(); + + if ( t1lang == null && t2lang == null) { + return 0; + } else if (t1lang == null) { + return 1; + } else if (t2lang == null) { + return -1; + } else { + int t1langPref = langs.indexOf(t1.getObject().getLiteral().language()); + if (t1langPref == -1) { + t1langPref = Integer.MAX_VALUE; + } + int t2langPref = langs.indexOf(t2.getObject().getLiteral().language()); + if (t2langPref == -1) { + t2langPref = Integer.MAX_VALUE; + } + return t1langPref - t2langPref; + } + } + + } + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index e33d777c1..93e5b28c3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -38,6 +38,7 @@ import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; @@ -620,9 +621,13 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { supURIs.add(getClassURIStr(cls)); } } catch (Exception e) { - //TODO make this attempt respect the direct argument - // we'll try this again using a different method that doesn't try to convert to OntClass - List supList = this.listDirectObjectPropertyValues(getOntModel().getResource(classURI), RDFS.subClassOf); + log.debug(e,e); + // we'll try this again using a different method + // that doesn't try to convert to OntClass + supURIs.clear(); + List supList = (direct) + ? listDirectObjectPropertyValues(subClass, RDFS.subClassOf) + : listObjectPropertyValues(subClass, RDFS.subClassOf); for (Resource res : supList) { supURIs.add(getClassURIStr(res)); } @@ -630,6 +635,18 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { return supURIs; } + private List listObjectPropertyValues(Resource res, Property prop) { + List values = new ArrayList(); + StmtIterator stmtIt = res.listProperties(prop); + while (stmtIt.hasNext()) { + Statement s = stmtIt.nextStatement(); + if (s.getObject().isResource()) { + values.add(s.getObject().asResource()); + } + } + return values; + } + public VClass getTopConcept() { VClass top = new VClass(); if (getOntModel().getProfile().NAMESPACE().equals(RDFS.getURI())) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index 055d1501b..f519824a1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -48,6 +48,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; public class WebappDaoFactoryJena implements WebappDaoFactory { @@ -73,6 +74,8 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { protected DatasetWrapperFactory dwf; + protected RDFService rdfService; + /* **************** constructors **************** */ public WebappDaoFactoryJena(WebappDaoFactoryJena base, String userURI) { @@ -343,8 +346,10 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { ObjectPropertyStatementDao objectPropertyStatementDao = null; public ObjectPropertyStatementDao getObjectPropertyStatementDao() { if( objectPropertyStatementDao == null ) + // TODO supply a valid RDFService as the first argument if we keep this + // implementation objectPropertyStatementDao = new ObjectPropertyStatementDaoJena( - dwf, this); + null, dwf, this); return objectPropertyStatementDao; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java index d79bb4af1..d33051beb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.sql.Connection; import java.sql.SQLException; -import java.util.HashSet; import org.apache.commons.dbcp.BasicDataSource; @@ -20,62 +19,37 @@ 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.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup; public class WebappDaoFactorySDB extends WebappDaoFactoryJena { - - public static final String UNION_GRAPH = "urn:x-arq:UnionGraph"; + private SDBDatasetMode datasetMode = SDBDatasetMode.ASSERTIONS_AND_INFERENCES; - /** - * For use when any database connection associated with the Dataset - * is managed externally - */ - public WebappDaoFactorySDB(OntModelSelector ontModelSelector, - Dataset dataset) { - super(ontModelSelector); - this.dwf = new StaticDatasetFactory(dataset); + public WebappDaoFactorySDB(RDFService rdfService, + OntModelSelector ontModelSelector) { + this(rdfService, ontModelSelector, new WebappDaoFactoryConfig()); } - /** - * For use when any database connection associated with the Dataset - * is managed externally - */ - public WebappDaoFactorySDB(OntModelSelector ontModelSelector, - Dataset dataset, - WebappDaoFactoryConfig config) { - super(ontModelSelector, config); - this.dwf = new StaticDatasetFactory(dataset); - } - - /** - * For use when any Dataset access should get a temporary DB connection - * from a pool - */ - public WebappDaoFactorySDB(OntModelSelector ontModelSelector, - BasicDataSource bds, - StoreDesc storeDesc, - WebappDaoFactoryConfig config) { - super(ontModelSelector, config); - this.dwf = new ReconnectingDatasetFactory(bds, storeDesc); + public WebappDaoFactorySDB(RDFService rdfService, + OntModelSelector ontModelSelector, + WebappDaoFactoryConfig config) { + this(rdfService, ontModelSelector, config, null); } - /** - * For use when any Dataset access should get a temporary DB connection - * from a pool, and access to the inference graph needs to be specified. - */ - public WebappDaoFactorySDB(OntModelSelector ontModelSelector, - BasicDataSource bds, - StoreDesc storeDesc, - WebappDaoFactoryConfig config, - SDBDatasetMode datasetMode) { + public WebappDaoFactorySDB(RDFService rdfService, + OntModelSelector ontModelSelector, + WebappDaoFactoryConfig config, + SDBDatasetMode datasetMode) { super(ontModelSelector, config); - this.dwf = new ReconnectingDatasetFactory(bds, storeDesc); - this.datasetMode = datasetMode; + this.dwf = new StaticDatasetFactory(new RDFServiceDataset(rdfService)); + this.rdfService = rdfService; + if (datasetMode != null) { + this.datasetMode = datasetMode; + } } - - + public WebappDaoFactorySDB(WebappDaoFactorySDB base, String userURI) { super(base.ontModelSelector); this.ontModelSelector = base.ontModelSelector; @@ -108,7 +82,7 @@ public class WebappDaoFactorySDB extends WebappDaoFactoryJena { return objectPropertyStatementDao; else return objectPropertyStatementDao = - new ObjectPropertyStatementDaoSDB(dwf, datasetMode, this); + new ObjectPropertyStatementDaoSDB(rdfService, dwf, datasetMode, this); } @Override @@ -170,6 +144,12 @@ public class WebappDaoFactorySDB extends WebappDaoFactoryJena { return filterBlock.toString(); } + @Override + public void close() { + super.close(); + this.rdfService.close(); + } + private class ReconnectingDatasetFactory implements DatasetWrapperFactory { private BasicDataSource _bds; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java index 6ac3b4f68..2a2e1fda1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java @@ -163,7 +163,9 @@ public class PelletListener implements ModelChangedListener { this.deletedDataProperties = ModelFactory.createDefaultModel(); this.mainModel.enterCriticalSection(Lock.READ); try { - addedStatements(mainModel); + for (ObjectPropertyStatementPattern pat : this.inferenceDrivingPatternAllowSet) { + addedStatements(mainModel.listStatements((Resource) null, pat.getPredicate(), (RDFNode) null)); + } if (!skipReasoningUponInitialization) { this.foreground = foreground; notifyEvent(null,new EditEvent(null,false)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java index 7b11268df..632802ac3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java @@ -509,7 +509,7 @@ public class EditConfigurationVTwo { } public void addUrisOnForm(String ... strs){ - this.urisOnform.addAll(new ArrayList(Arrays.asList( strs ))); + this.urisOnform.addAll(Arrays.asList( strs )); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java index 5129d2b80..47c0d19d2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java @@ -5,6 +5,9 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -12,6 +15,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; public class StandardModelSelector implements ModelSelector { + private static final Log log = LogFactory.getLog(StandardModelSelector.class); + public OntModel getModel(HttpServletRequest request, ServletContext context) { VitroRequest vreq = new VitroRequest( request ); @@ -23,11 +28,17 @@ public class StandardModelSelector implements ModelSelector { sessionOntModel = oms.getABoxModel(); } } - if(sessionOntModel != null && sessionOntModel instanceof OntModel ) + if(sessionOntModel != null && sessionOntModel instanceof OntModel ) { + log.debug("using OntModelSelector from session"); return (OntModel)sessionOntModel; - else + } else if (vreq.getOntModelSelector() != null) { + log.debug("using OntModelSelector from request"); + return vreq.getOntModelSelector().getABoxModel(); + } else { + log.debug("using OntModelSelector from context"); return ((OntModelSelector) context - .getAttribute("unionOntModelSelector")).getABoxModel(); + .getAttribute("unionOntModelSelector")).getABoxModel(); + } } public static final ModelSelector selector = new StandardModelSelector(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java index 7319f148a..80adcecd0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java @@ -66,7 +66,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = vreq.getJenaOntModel(); // (OntModel)vreq.getAttribute("jenaOntModel"); if( editConfig.getSubjectUri() == null) editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index e879b70e1..109be552a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -51,6 +51,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; /** @@ -172,10 +173,11 @@ public class VitroRequestPrep implements Filter { vreq.setDataset(dataset); } + ServletContext ctx = vreq.getSession().getServletContext(); vreq.setUnfilteredWebappDaoFactory(new WebappDaoFactorySDB( + RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(), ModelContext.getUnionOntModelSelector( - vreq.getSession().getServletContext()), - vreq.getDataset())); + ctx))); req.setAttribute("VitroRequestPrep.setup", new Integer(1)); chain.doFilter(req, response); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java index 30351715d..eafe98550 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java @@ -3,8 +3,10 @@ package edu.cornell.mannlib.vitro.webapp.filters; import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -21,19 +23,29 @@ import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.sdb.SDBFactory; -import com.hp.hpl.jena.sdb.Store; import com.hp.hpl.jena.sdb.StoreDesc; -import com.hp.hpl.jena.sdb.sql.SDBConnection; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlDatasetGraph; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraphMultilingual; 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.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; public class WebappDaoFactorySDBPrep implements Filter { @@ -79,67 +91,52 @@ public class WebappDaoFactorySDBPrep implements Filter { } } - BasicDataSource bds = JenaDataSourceSetupBase.getApplicationDataSource(_ctx); - StoreDesc storeDesc = (StoreDesc) _ctx.getAttribute("storeDesc"); - OntModelSelector oms = (OntModelSelector) _ctx.getAttribute("unionOntModelSelector"); + OntModelSelector oms = ModelContext.getUnionOntModelSelector(_ctx); + OntModelSelector baseOms = ModelContext.getBaseOntModelSelector(_ctx); String defaultNamespace = (String) _ctx.getAttribute("defaultNamespace"); - Connection sqlConn = null; - SDBConnection conn = null; - Store store = null; - Dataset dataset = null; WebappDaoFactory wadf = null; + VitroRequest vreq = new VitroRequest((HttpServletRequest) request); - try { - if (bds == null || storeDesc == null || oms == null) { - throw new RuntimeException("SDB store not property set up"); - } - - try { - sqlConn = bds.getConnection(); - conn = new SDBConnection(sqlConn) ; - } catch (SQLException sqe) { - throw new RuntimeException("Unable to connect to database", sqe); - } - if (conn != null) { - store = SDBFactory.connectStore(conn, storeDesc); - dataset = SDBFactory.connectDataset(store); - VitroRequest vreq = new VitroRequest((HttpServletRequest) request); - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(defaultNamespace); - wadf = new WebappDaoFactorySDB(oms, dataset, config); - vreq.setWebappDaoFactory(wadf); - vreq.setFullWebappDaoFactory(wadf); - vreq.setDataset(dataset); - vreq.setJenaOntModel(ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, dataset.getNamedModel( - WebappDaoFactorySDB.UNION_GRAPH))); - } - } catch (Throwable t) { - log.error("Unable to filter request to set up SDB connection", t); - } + List langs = new ArrayList(); + + log.debug("Accept-Language: " + vreq.getHeader("Accept-Language")); + Enumeration locs = vreq.getLocales(); + while (locs.hasMoreElements()) { + Locale locale = locs.nextElement(); + langs.add(locale.toString().replace("_", "-")); + } + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(defaultNamespace); + config.setPreferredLanguages(langs); + RDFServiceFactory factory = RDFServiceUtils.getRDFServiceFactory(_ctx); + RDFService rdfService = factory.getRDFService(); + Dataset dataset = new RDFServiceDataset(rdfService); + wadf = new WebappDaoFactorySDB(rdfService, oms, config); + WebappDaoFactory assertions = new WebappDaoFactorySDB( + rdfService, baseOms, config, SDBDatasetMode.ASSERTIONS_ONLY); + vreq.setWebappDaoFactory(wadf); + vreq.setAssertionsWebappDaoFactory(assertions); + vreq.setFullWebappDaoFactory(wadf); + vreq.setDataset(dataset); + vreq.setOntModelSelector(oms); + + vreq.setJenaOntModel(ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, dataset.getDefaultModel())); + request.setAttribute("WebappDaoFactorySDBPrep.setup", 1); try { filterChain.doFilter(request, response); return; } finally { - if (conn != null) { - conn.close(); - } - if (dataset != null) { - dataset.close(); - } - if (store != null) { - store.close(); - } if (wadf != null) { wadf.close(); } } } - + @Override public void init(FilterConfig filterConfig) throws ServletException { try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java new file mode 100644 index 000000000..2812c9434 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java @@ -0,0 +1,211 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filters; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.DataSource; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.DatasetFactory; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.sdb.SDBFactory; +import com.hp.hpl.jena.sdb.Store; +import com.hp.hpl.jena.sdb.StoreDesc; +import com.hp.hpl.jena.sdb.sql.SDBConnection; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SingleContentOntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlDatasetGraph; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraphMultilingual; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; + +public class WebappDaoFactorySparqlPrep implements Filter { + + private final static Log log = LogFactory.getLog(WebappDaoFactorySparqlPrep.class); + + ServletContext _ctx; + + /** + * The filter will be applied to all incoming urls, + this is a list of URI patterns to skip. These are + matched against the requestURI sans query parameters, + * e.g. + * "/vitro/index.jsp" + * "/vitro/themes/enhanced/css/edit.css" + * + * These patterns are from VitroRequestPrep.java + */ + Pattern[] skipPatterns = { + Pattern.compile(".*\\.(gif|GIF|jpg|jpeg)$"), + Pattern.compile(".*\\.css$"), + Pattern.compile(".*\\.js$"), + Pattern.compile("/.*/themes/.*/site_icons/.*"), + Pattern.compile("/.*/images/.*") + }; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain filterChain) throws IOException, ServletException { + + if ( request.getAttribute("WebappDaoFactorySDBPrep.setup") != null ) { + // don't run multiple times + filterChain.doFilter(request, response); + return; + } + + for( Pattern skipPattern : skipPatterns){ + Matcher match =skipPattern.matcher( ((HttpServletRequest)request).getRequestURI() ); + if( match.matches() ){ + log.debug("request matched a skipPattern, skipping VitroRequestPrep"); + filterChain.doFilter(request, response); + return; + } + } + + BasicDataSource bds = JenaDataSourceSetupBase.getApplicationDataSource(_ctx); + StoreDesc storeDesc = (StoreDesc) _ctx.getAttribute("storeDesc"); + OntModelSelector oms = (OntModelSelector) _ctx.getAttribute("unionOntModelSelector"); + String defaultNamespace = (String) _ctx.getAttribute("defaultNamespace"); + Connection sqlConn = null; + SDBConnection conn = null; + Store store = null; + Dataset dataset = null; + WebappDaoFactory wadf = null; + + try { + if (bds == null || storeDesc == null || oms == null) { + throw new RuntimeException("SDB store not property set up"); + } + + try { + sqlConn = bds.getConnection(); + conn = new SDBConnection(sqlConn) ; + } catch (SQLException sqe) { + throw new RuntimeException("Unable to connect to database", sqe); + } + if (conn != null) { + store = SDBFactory.connectStore(conn, storeDesc); + dataset = SDBFactory.connectDataset(store); + VitroRequest vreq = new VitroRequest((HttpServletRequest) request); + + log.info("---------"); + + Enumeration headStrs = vreq.getHeaderNames(); + while (headStrs.hasMoreElements()) { + String head = headStrs.nextElement(); + log.info(head + " : " + vreq.getHeader(head)); + } + + List langs = new ArrayList(); + + log.info("Accept-Language: " + vreq.getHeader("Accept-Language")); + Enumeration locs = vreq.getLocales(); + while (locs.hasMoreElements()) { + Locale locale = locs.nextElement(); + langs.add(locale.toString().replace("_", "-")); + log.info(locale.toString() + " / " + locale.getLanguage() + " + " + locale.getCountry() + " : " + locale.getDisplayCountry() + " | " + locale.getLanguage() + " : " + locale.getDisplayLanguage()); + } + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(defaultNamespace); + config.setPreferredLanguages(langs); + + //okay let's make a graph-backed model + String endpointURI = ConfigurationProperties.getBean( + request).getProperty("VitroConnection.DataSource.endpointURI"); + + Graph g = new SparqlGraphMultilingual(endpointURI, langs); + //Graph g = new SparqlGraph(endpointURI); + + Model m = ModelFactory.createModelForGraph(g); + OntModel om = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m); + oms = new SingleContentOntModelSelector(om, oms.getDisplayModel(), oms.getUserAccountsModel()); + + dataset = DatasetFactory.create(new SparqlDatasetGraph(endpointURI)); + + //DataSource datasource = DatasetFactory.create(); + //datasource.addNamedModel("fake:fake", m); + //dataset = datasource; + + vreq.setAssertionsWebappDaoFactory(wadf); + + wadf = new WebappDaoFactoryJena(oms, config); + //wadf = new WebappDaoFactorySDB(oms, dataset, config); + vreq.setWebappDaoFactory(wadf); + vreq.setFullWebappDaoFactory(wadf); + vreq.setUnfilteredWebappDaoFactory(wadf); + vreq.setWebappDaoFactory(wadf); + vreq.setDataset(dataset); + vreq.setJenaOntModel(om); + vreq.setOntModelSelector(oms); + } + } catch (Throwable t) { + log.error("Unable to filter request to set up SDB connection", t); + } + + request.setAttribute("WebappDaoFactorySDBPrep.setup", 1); + + try { + filterChain.doFilter(request, response); + return; + } finally { + if (conn != null) { + conn.close(); + } + if (dataset != null) { + dataset.close(); + } + if (store != null) { + store.close(); + } + if (wadf != null) { + wadf.close(); + } + } + + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + try { + _ctx = filterConfig.getServletContext(); + } catch (Throwable t) { + log.error("Unable to initialize WebappDaoFactorySDBPrep", t); + } + } + + @Override + public void destroy() { + // no destroy actions + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.java new file mode 100644 index 000000000..dad8128d9 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeListener.java @@ -0,0 +1,37 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +/* + * + * A listener that filters all its listening down to the single-statement level. Users of + * this class override addedStatement(statement) and removedStatement(statement). + * + */ + +public interface ChangeListener { + + /** + * Override this to listen to all statements added to the RDF store. + * + * @param serializedTriple - the added statement in n3 format + * @param graphURI - the graph to which the statement was added + */ + public void addedStatement(String serializedTriple, String graphURI); + + /** + * Override this to listen to all statements removed from the RDF store. + * + * @param serializedTriple - the removed statement in n3 format + * @param graphURI - the graph from which the statement was removed + */ + public void removedStatement(String serializedTriple, String graphURI); + + /** + * Override this to listen to events pertaining to the given graphURI. + * + * @param graphURI - the graph to which the event pertains + * @param event - the event that occurred. + */ + public void notifyEvent(String graphURI, Object event); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.java new file mode 100644 index 000000000..f2ff916b6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ChangeSet.java @@ -0,0 +1,119 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +import java.io.InputStream; +import java.util.List; + +/* + * Input parameter to changeSetUpdate() method in RDFService. + * Represents a precondition query and an ordered list of model changes. + */ + +public interface ChangeSet { + + /** + * Getter for the precondition query + * + * @return String - a SPARQL query + */ + public String getPreconditionQuery(); + + /** + * Setter for the precondition query + * + * @param preconditionQuery - a SPARQL query + */ + public void setPreconditionQuery(String preconditionQuery); + + /** + * Getter for the precondition query type + * + * @return RDFService.SPARQLQueryType - the precondition query type + */ + public RDFService.SPARQLQueryType getPreconditionQueryType(); + + /** + * Setter for the precondition query type + * + * @param queryType - the precondition query type + */ + public void setPreconditionQueryType(RDFService.SPARQLQueryType queryType); + + /** + * Getter for the list of model changes + * + * @return List - list of model changes + */ + public List getModelChanges(); + + /** + * Adds one model change representing an addition to the list of model changes + * + * @param model - a serialized RDF model (collection of triples) + * @param serializationFormat - format of the serialized RDF model + * @param graphURI - URI of the graph to which the RDF model should be added + */ + public void addAddition(InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + String graphURI); + + /** + * Adds one model change representing a deletion to the list of model changes + * + * @param model - a serialized RDF model (collection of triples) + * @param serializationFormat - format of the serialized RDF model + * @param graphURI - URI of the graph from which the RDF model should be removed + */ + public void addRemoval(InputStream model, + RDFService.ModelSerializationFormat serializationFormat, + String graphURI); + + /** + * Creates an instance of the ModelChange class + */ + public ModelChange manufactureModelChange(); + + /** + * Creates an instance of the ModelChange class + * + * @param serializedModel - a serialized RDF model (collection of triples) + * @param serializationFormat - format of the serialized RDF model + * @param operation - the type of operation to be performed with the serialized RDF model + * @param graphURI - URI of the graph on which to apply the model change operation + */ + public ModelChange manufactureModelChange(InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + ModelChange.Operation operation, + String graphURI); + + /** + * Add an event that will be be passed to any change listeners in advance of + * the change set additions and retractions being performed. The event + * will only be fired if the precondition (if any) is met. + * @param event + */ + public void addPreChangeEvent(Object event); + + /** + * Add an event that will be be passed to any change listeners after all of + * the change set additions and retractions are performed. + * @param event + */ + public void addPostChangeEvent(Object event); + + /** + * Return a list of events to pass to any change listeners in + * advance of the change set additions and retractions being performed. + * @return + */ + public List getPreChangeEvents(); + + /** + * Return a list of events to pass to any change listeners after + * the change set additions and retractions are performed. + * @return + */ + public List getPostChangeEvents(); + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.java new file mode 100644 index 000000000..919f1201c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/ModelChange.java @@ -0,0 +1,73 @@ +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +import java.io.InputStream; + +/* + * A ModelChange is one component of a ChangeSet. + * Represents a model (collection of RDF triples), the URI + * of a graph, and an indication of whether to add or + * remove the model from the graph. + */ + +public interface ModelChange { + + public enum Operation { + ADD, REMOVE + } + + /** + * Getter for the serialized model + * + * @return InputStream - a serialized model (collection of RDF triples) representing a change to make + */ + public InputStream getSerializedModel(); + + /** + * Setter for the serialized model + * + * @param serializedModel - a serialized model (collection of RDF triples) representing a change to make + */ + public void setSerializedModel(InputStream serializedModel); + + /** + * Getter for the serialization format of the model + * + * @return RDFService.ModelSerializationFormat - the serialization format of the model + */ + public RDFService.ModelSerializationFormat getSerializationFormat(); + + /** + * Setter for the serialization format of the model + * + * @param serializationFormat - the serialization format of the model + */ + public void setSerializationFormat(RDFService.ModelSerializationFormat serializationFormat); + + /** + * Getter for the operation type + * + * @return ModelChange.Operation - the operation to be performed + */ + public ModelChange.Operation getOperation(); + + /** + * Setter for the operation type + * + * @param operation - the operation to be performed + */ + public void setOperation(ModelChange.Operation operation); + + /** + * Getter for the URI of the graph to which to apply the change + * + * @return String - the URI of the graph to which to apply the change + */ + public String getGraphURI(); + + /** + * Setter for the URI of the graph to which to apply the change + * + * @param graphURI - the URI of the graph to which to apply the change + */ + public void setGraphURI(String graphURI); +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java new file mode 100644 index 000000000..689db1ec1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java @@ -0,0 +1,155 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +import java.io.InputStream; +import java.util.List; + +/* + * Interface for API to write, read, and update Vitro's RDF store, with support + * to allow listening, logging and auditing. + */ + +public interface RDFService { + + public enum SPARQLQueryType { + SELECT, CONSTRUCT, DESCRIBE, ASK + } + + public enum ModelSerializationFormat { + RDFXML, N3 + } + + public enum ResultFormat { + JSON, CSV, XML, TEXT + } + + /** + * Perform a series of additions to and or removals from specified graphs + * in the RDF store. preConditionSparql will be executed against the + * union of all the graphs in the knowledge base before any updates are made. + * If the precondition query returns a non-empty result, no updates + * will be made. + * + * @param changeSet - a set of changes to be performed on the RDF store. + * + * @return boolean - indicates whether the precondition was satisfied + */ + public boolean changeSetUpdate(ChangeSet changeSet) throws RDFServiceException; + + /** + * If the given individual already exists in the default graph, throws an + * RDFServiceException, otherwise adds one type assertion to the default + * graph. + * + * @param individualURI - URI of the individual to be added + * @param individualTypeURI - URI of the type for the individual + */ + public void newIndividual(String individualURI, String individualTypeURI) throws RDFServiceException; + + /** + * If the given individual already exists in the given graph, throws an + * RDFServiceException, otherwise adds one type assertion to the given + * graph. + * + * @param individualURI - URI of the individual to be added + * @param individualTypeURI - URI of the type for the individual + * @param graphURI - URI of the graph to which to add the individual + */ + public void newIndividual(String individualURI, String individualTypeURI, String graphURI) throws RDFServiceException; + + /** + * Performs a SPARQL construct query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param query - the SPARQL query to be executed against the RDF store + * @param resultFormat - type of serialization for RDF result of the SPARQL query + * + * @return InputStream - the result of the query + * + */ + public InputStream sparqlConstructQuery(String query, RDFService.ModelSerializationFormat resultFormat) throws RDFServiceException; + + /** + * Performs a SPARQL describe query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param query - the SPARQL query to be executed against the RDF store + * @param resultFormat - type of serialization for RDF result of the SPARQL query + * + * @return InputStream - the result of the query + * + */ + public InputStream sparqlDescribeQuery(String query, RDFService.ModelSerializationFormat resultFormat) throws RDFServiceException; + + /** + * Performs a SPARQL select query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param query - the SPARQL query to be executed against the RDF store + * @param resultFormat - format for the result of the Select query + * + * @return InputStream - the result of the query + * + */ + public InputStream sparqlSelectQuery(String query, RDFService.ResultFormat resultFormat) throws RDFServiceException; + + /** + * Performs a SPARQL ASK query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param query - the SPARQL query to be executed against the RDF store + * + * @return boolean - the result of the SPARQL query + */ + + public boolean sparqlAskQuery(String query) throws RDFServiceException; + + /** + * Get a list of all the graph URIs in the RDF store. + * + * @return List - list of all the graph URIs in the RDF store + */ + public List getGraphURIs() throws RDFServiceException; + + /** + * TBD - we need to define this method + */ + public void getGraphMetadata() throws RDFServiceException; + + /** + * Get the URI of the default write graph + * + * @return String URI of default write graph + */ + public String getDefaultWriteGraphURI() throws RDFServiceException; + + /** + * Register a listener to listen to changes in any graph in + * the RDF store. + * + * @param changeListener - the change listener + */ + public void registerListener(ChangeListener changeListener) throws RDFServiceException; + + /** + * Unregister a listener from listening to changes in + * the RDF store in any graph. + * + * @param changeListener - the change listener + */ + public void unregisterListener(ChangeListener changeListener) throws RDFServiceException; + + /** + * Create a ChangeSet object + * + * @return ChangeSet an empty ChangeSet object + */ + public ChangeSet manufactureChangeSet(); + + /** + * Free any resources held by this RDFService object + */ + public void close(); + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.java new file mode 100644 index 000000000..ee0a59f5e --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceException.java @@ -0,0 +1,21 @@ +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +public class RDFServiceException extends Exception { + + public RDFServiceException() { + super(); + } + + public RDFServiceException(Throwable cause) { + super(cause); + } + + public RDFServiceException(String message) { + super(message); + } + + public RDFServiceException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceFactory.java new file mode 100644 index 000000000..770b60a48 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFServiceFactory.java @@ -0,0 +1,29 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; + +public interface RDFServiceFactory { + + public RDFService getRDFService(); + + /** + * Register a listener to listen to changes in any graph in + * the RDF store. Any RDFService objects returned by this factory should notify + * this listener of changes. + * + * @param changeListener - the change listener + */ + public void registerListener(ChangeListener changeListener) throws RDFServiceException; + + /** + * Unregister a listener from listening to changes in + * the RDF store. Any RDFService objects returned by this factory should notify + * this listener of changes. + * + * @param changeListener - the change listener + */ + public void unregisterListener(ChangeListener changeListener) throws RDFServiceException; + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ChangeSetImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ChangeSetImpl.java new file mode 100644 index 000000000..0f79ede1a --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ChangeSetImpl.java @@ -0,0 +1,148 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange.Operation; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/* + * Input parameter to changeSetUpdate() method in RDFService. + * Represents a precondition query and an ordered list of model changes. + */ +public class ChangeSetImpl implements ChangeSet { + + public ChangeSetImpl() { + modelChanges = new ArrayList(); + } + + private String preconditionQuery; + private RDFService.SPARQLQueryType queryType; + private ArrayList modelChanges = new ArrayList(); + private ArrayList preChangeEvents = new ArrayList(); + private ArrayList postChangeEvents = new ArrayList(); + + /** + * Getter for the precondition query + * + * @return String - a SPARQL query + */ + @Override + public String getPreconditionQuery() { + return preconditionQuery; + } + + /** + * Setter for the precondition query + * + * @param String - a SPARQL query + */ + @Override + public void setPreconditionQuery(String preconditionQuery) { + this.preconditionQuery = preconditionQuery; + } + + /** + * Getter for the precondition query type + * + * @return RDFService.SPARQLQueryType - the precondition query type + */ + @Override + public RDFService.SPARQLQueryType getPreconditionQueryType() { + return queryType; + } + + /** + * Setter for the precondition query type + * + * @param RDFService.SPARQLQueryType - the precondition query type + */ + @Override + public void setPreconditionQueryType(RDFService.SPARQLQueryType queryType) { + this.queryType = queryType; + } + + /** + * Getter for the list of model changes + * + * @return List - list of model changes + */ + @Override + public List getModelChanges() { + return modelChanges; + } + + /** + * Adds one model change representing an addition to the list of model changes + * + * @param InputStream - a serialized RDF model (collection of triples) + * @param RDFService.ModelSerializationFormat - format of the serialized RDF model + * @param String - URI of the graph to which the RDF model should be added + */ + @Override + public void addAddition(InputStream model, RDFService.ModelSerializationFormat format, String graphURI) { + modelChanges.add(manufactureModelChange(model,format, ModelChange.Operation.ADD, graphURI)); + } + + /** + * Adds one model change representing a deletion to the list of model changes + * + * @param InputStream - a serialized RDF model (collection of triples) + * @param RDFService.ModelSerializationFormat - format of the serialized RDF model + * @param String - URI of the graph from which the RDF model should be removed + */ + @Override + public void addRemoval(InputStream model, RDFService.ModelSerializationFormat format, String graphURI) { + modelChanges.add(manufactureModelChange(model, format, ModelChange.Operation.REMOVE, graphURI)); + } + + /** + * Creates an instance of the ModelChange class + */ + @Override + public ModelChange manufactureModelChange() { + return new ModelChangeImpl(); + } + + /** + * Creates an instance of the ModelChange class + * + * @param InputStream - a serialized RDF model (collection of triples) + * @param RDFService.ModelSerializationFormat - format of the serialized RDF model + * @param ModelChange.Operation - the type of operation to be performed with the serialized RDF model + * @param String - URI of the graph on which to apply the model change operation + */ + @Override + public ModelChange manufactureModelChange(InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + Operation operation, + String graphURI) { + return new ModelChangeImpl(serializedModel, serializationFormat, operation, graphURI); + } + + @Override + public void addPreChangeEvent(Object o) { + this.preChangeEvents.add(o); + } + + @Override + public void addPostChangeEvent(Object o) { + this.postChangeEvents.add(o); + } + + @Override + public List getPreChangeEvents() { + return this.preChangeEvents; + } + + @Override + public List getPostChangeEvents() { + return this.postChangeEvents; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ModelChangeImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ModelChangeImpl.java new file mode 100644 index 000000000..64706dbe4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/ModelChangeImpl.java @@ -0,0 +1,113 @@ +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; + +import java.io.InputStream; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +/* + * A ModelChange is one component of a ChangeSet. + * Represents a model (collection of RDF triples), the URI + * of a graph, and an indication of whether to add or + * remove the model from the graph. + */ +public class ModelChangeImpl implements ModelChange { + + private InputStream serializedModel; + private RDFService.ModelSerializationFormat serializationFormat; + private Operation operation; + private String graphURI; + + public ModelChangeImpl() {} + + public ModelChangeImpl(InputStream serializedModel, + RDFService.ModelSerializationFormat serializationFormat, + Operation operation, + String graphURI) { + + this.serializedModel = serializedModel; + this.serializationFormat = serializationFormat; + this.operation = operation; + this.graphURI = graphURI; + } + + /** + * Getter for the serialized model + * + * @return InputStream - a model (collection of RDF triples), serialized + */ + @Override + public InputStream getSerializedModel() { + return serializedModel; + } + + /** + * Setter for the serialized model + * + * @param InputStream - a model (collection of RDF triples), serialized + */ + @Override + public void setSerializedModel(InputStream serializedModel) { + this.serializedModel = serializedModel; + } + + /** + * Getter for the serialization format of the model + * + * @return RDFService.ModelSerializationFormat - the serialization format of the model + */ + @Override + public RDFService.ModelSerializationFormat getSerializationFormat() { + return serializationFormat; + } + + /** + * Setter for the serialization format of the model + * + * @param RDFService.ModelSerializationFormat - the serialization format of the model + */ + @Override + public void setSerializationFormat(RDFService.ModelSerializationFormat serializationFormat) { + this.serializationFormat = serializationFormat; + } + + /** + * Getter for the operation type + * + * @return ModelChange.Operation - the operation type + */ + @Override + public Operation getOperation() { + return operation; + } + + /** + * Setter for the operation type + * + * @param ModelChange.Operation - the operation type + */ + @Override + public void setOperation(Operation operation) { + this.operation = operation; + } + + /** + * Getter for the URI of the graph to which to apply the change + * + * @return String - the graph URI + */ + @Override + public String getGraphURI() { + return graphURI; + } + + /** + * Setter for the URI of the graph to which to apply the change + * + * @param String - the graph URI + */ + @Override + public void setGraphURI(String graphURI) { + this.graphURI = graphURI; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java new file mode 100644 index 000000000..f9f801f5a --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java @@ -0,0 +1,38 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; + +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; + +/** + * An RDFServiceFactory that always returns the same RDFService object + * @author bjl23 + * + */ +public class RDFServiceFactorySingle implements RDFServiceFactory { + + private RDFService rdfService; + + public RDFServiceFactorySingle(RDFService rdfService) { + this.rdfService = rdfService; + } + + @Override + public RDFService getRDFService() { + return this.rdfService; + } + + @Override + public void registerListener(ChangeListener listener) throws RDFServiceException { + this.rdfService.registerListener(listener); + } + + @Override + public void unregisterListener(ChangeListener listener) throws RDFServiceException { + this.rdfService.unregisterListener(listener); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java new file mode 100644 index 000000000..e1b4885f0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceImpl.java @@ -0,0 +1,266 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; + +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.sparql.resultset.XMLInput; +import com.hp.hpl.jena.vocabulary.RDF; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; + +/* + * API to write, read, and update Vitro's RDF store, with support + * to allow listening, logging and auditing. + */ + +public abstract class RDFServiceImpl implements RDFService { + + private static final Log log = LogFactory.getLog(RDFServiceImpl.class); + protected String defaultWriteGraphURI; + protected ArrayList registeredListeners = new ArrayList(); + + /** + * If the given individual already exists in the default graph, throws an + * RDFServiceException, otherwise adds one type assertion to the default + * graph. + * + * @param String individualURI - URI of the individual to be added + * @param String individualTypeURI - URI of the type for the individual + */ + @Override + public void newIndividual(String individualURI, + String individualTypeURI) throws RDFServiceException { + + newIndividual(individualURI, individualTypeURI, defaultWriteGraphURI); + } + + /** + * If the given individual already exists in the given graph, throws an + * RDFServiceException, otherwise adds one type assertion to the given + * graph. + * + * @param String individualURI - URI of the individual to be added + * @param String individualTypeURI - URI of the type for the individual + * @param String graphURI - URI of the graph to which to add the individual + */ + @Override + public void newIndividual(String individualURI, + String individualTypeURI, + String graphURI) throws RDFServiceException { + + StringBuffer containsQuery = new StringBuffer("ASK { \n"); + if (graphURI != null) { + containsQuery.append(" GRAPH <" + graphURI + "> { "); + } + containsQuery.append("<"); + containsQuery.append(individualURI); + containsQuery.append("> "); + containsQuery.append("?p ?o"); + if (graphURI != null) { + containsQuery.append(" } \n"); + } + containsQuery.append("\n}"); + + if (sparqlAskQuery(containsQuery.toString())) { + throw new RDFServiceException("individual already exists"); + } else { + Triple triple = new Triple(Node.createURI(individualURI), RDF.type.asNode(), Node.createURI(individualTypeURI)); + //addTriple(triple, graphURI); + ChangeSet cs = this.manufactureChangeSet(); + cs.addAddition(new ByteArrayInputStream( + sparqlTriple(triple).getBytes()), ModelSerializationFormat.N3, graphURI); + changeSetUpdate(cs); + } + } + + /** + * Get the URI of the default write graph + * + * @return String URI of default write graph + */ + @Override + public String getDefaultWriteGraphURI() throws RDFServiceException { + return defaultWriteGraphURI; + } + + /** + * Register a listener to listen to changes in any graph in + * the RDF store. + * + */ + @Override + public synchronized void registerListener(ChangeListener changeListener) throws RDFServiceException { + + if (!registeredListeners.contains(changeListener)) { + registeredListeners.add(changeListener); + } + } + + /** + * Unregister a listener from listening to changes in any graph + * in the RDF store. + * + */ + @Override + public synchronized void unregisterListener(ChangeListener changeListener) throws RDFServiceException { + registeredListeners.remove(changeListener); + } + + /** + * Create a ChangeSet object + * + * @return a ChangeSet object + */ + @Override + public ChangeSet manufactureChangeSet() { + return new ChangeSetImpl(); + } + + public synchronized void notifyListeners(Triple triple, ModelChange.Operation operation, String graphURI) { + + Iterator iter = registeredListeners.iterator(); + + while (iter.hasNext()) { + ChangeListener listener = iter.next(); + if (operation == ModelChange.Operation.ADD) { + listener.addedStatement(sparqlTriple(triple), graphURI); + } else { + listener.removedStatement(sparqlTriple(triple).toString(), graphURI); + } + } + } + + public synchronized void notifyListenersOfEvent(Object event) { + + Iterator iter = registeredListeners.iterator(); + + while (iter.hasNext()) { + ChangeListener listener = iter.next(); + // TODO what is the graphURI parameter for? + listener.notifyEvent(null, event); + } + } + + protected boolean isPreconditionSatisfied(String query, + RDFService.SPARQLQueryType queryType) + throws RDFServiceException { + Model model = ModelFactory.createDefaultModel(); + switch (queryType) { + case DESCRIBE: + model.read(sparqlDescribeQuery(query,RDFService.ModelSerializationFormat.N3), null); + return !model.isEmpty(); + case CONSTRUCT: + model.read(sparqlConstructQuery(query,RDFService.ModelSerializationFormat.N3), null); + return !model.isEmpty(); + case SELECT: + return sparqlSelectQueryHasResults(query); + case ASK: + return sparqlAskQuery(query); + default: + throw new RDFServiceException("unrecognized SPARQL query type"); + } + } + + protected static String getSerializationFormatString(RDFService.ModelSerializationFormat format) { + switch (format) { + case RDFXML: + return "RDF/XML"; + case N3: + return "N3"; + default: + log.error("unexpected format in getFormatString"); + return null; + } + } + + protected boolean sparqlSelectQueryHasResults(String queryStr) throws RDFServiceException { + ResultSet rs = XMLInput.fromXML(sparqlSelectQuery(queryStr, ResultFormat.XML)); + return rs.hasNext(); + } + + protected static String sparqlTriple(Triple triple) { + StringBuffer serializedTriple = new StringBuffer(); + serializedTriple.append(sparqlNodeUpdate(triple.getSubject(), "")); + serializedTriple.append(" "); + serializedTriple.append(sparqlNodeUpdate(triple.getPredicate(), "")); + serializedTriple.append(" "); + serializedTriple.append(sparqlNodeUpdate(triple.getObject(), "")); + serializedTriple.append(" ."); + return serializedTriple.toString(); + + } + + protected static String sparqlNodeUpdate(Node node, String varName) { + if (node.isBlank()) { + return "_:" + node.getBlankNodeLabel().replaceAll("\\W", ""); + } else { + return sparqlNode(node, varName); + } + } + + protected static String sparqlNode(Node node, String varName) { + if (node == null || node.isVariable()) { + return varName; + } else if (node.isBlank()) { + return ""; // or throw exception? + } else if (node.isURI()) { + StringBuffer uriBuff = new StringBuffer(); + return uriBuff.append("<").append(node.getURI()).append(">").toString(); + } else if (node.isLiteral()) { + StringBuffer literalBuff = new StringBuffer(); + literalBuff.append("\""); + pyString(literalBuff, node.getLiteralLexicalForm()); + literalBuff.append("\""); + if (node.getLiteralDatatypeURI() != null) { + literalBuff.append("^^<").append(node.getLiteralDatatypeURI()).append(">"); + } else if (node.getLiteralLanguage() != null && node.getLiteralLanguage() != "") { + literalBuff.append("@").append(node.getLiteralLanguage()); + } + return literalBuff.toString(); + } else { + return varName; + } + } + + // see http://www.python.org/doc/2.5.2/ref/strings.html + // or see jena's n3 grammar jena/src/com/hp/hpl/jena/n3/n3.g + protected static void pyString(StringBuffer sbuff, String s) { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + // Escape escapes and quotes + if (c == '\\' || c == '"' ) + { + sbuff.append('\\') ; + sbuff.append(c) ; + continue ; + } + + // Whitespace + if (c == '\n'){ sbuff.append("\\n");continue; } + if (c == '\t'){ sbuff.append("\\t");continue; } + if (c == '\r'){ sbuff.append("\\r");continue; } + if (c == '\f'){ sbuff.append("\\f");continue; } + if (c == '\b'){ sbuff.append("\\b");continue; } + if( c == 7 ) { sbuff.append("\\a");continue; } + + // Output as is (subject to UTF-8 encoding on output that is) + sbuff.append(c) ; + } + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java new file mode 100644 index 000000000..10b6313f7 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceUtils.java @@ -0,0 +1,43 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import javax.servlet.ServletContext; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; + +public class RDFServiceUtils { + + private static final String RDFSERVICEFACTORY_ATTR = + RDFServiceUtils.class.getName() + ".RDFServiceFactory"; + + public static RDFServiceFactory getRDFServiceFactory(ServletContext context) { + Object o = context.getAttribute(RDFSERVICEFACTORY_ATTR); + return (o instanceof RDFServiceFactory) ? (RDFServiceFactory) o : null; + } + + public static void setRDFServiceFactory(ServletContext context, + RDFServiceFactory factory) { + context.setAttribute(RDFSERVICEFACTORY_ATTR, factory); + } + + public static InputStream toInputStream(String serializedRDF) { + try { + return new ByteArrayInputStream(serializedRDF.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static RDFService getRDFService(VitroRequest vreq) { + return getRDFServiceFactory( + vreq.getSession().getServletContext()).getRDFService(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/ListeningGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/ListeningGraph.java new file mode 100644 index 000000000..2db8d1e64 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/ListeningGraph.java @@ -0,0 +1,217 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.BulkUpdateHandler; +import com.hp.hpl.jena.graph.Capabilities; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.GraphEventManager; +import com.hp.hpl.jena.graph.GraphStatisticsHandler; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Reifier; +import com.hp.hpl.jena.graph.TransactionHandler; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.impl.GraphWithPerform; +import com.hp.hpl.jena.graph.impl.SimpleBulkUpdateHandler; +import com.hp.hpl.jena.graph.impl.SimpleEventManager; +import com.hp.hpl.jena.graph.query.QueryHandler; +import com.hp.hpl.jena.graph.query.SimpleQueryHandler; +import com.hp.hpl.jena.shared.AddDeniedException; +import com.hp.hpl.jena.shared.DeleteDeniedException; +import com.hp.hpl.jena.shared.PrefixMapping; +import com.hp.hpl.jena.shared.impl.PrefixMappingImpl; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.EmptyReifier; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; + +public class ListeningGraph implements GraphWithPerform { + + private static final Log log = LogFactory.getLog(ListeningGraph.class); + + private RDFServiceSDB rdfServiceSDB; + private String graphURI; + + private BulkUpdateHandler bulkUpdateHandler; + private GraphEventManager eventManager; + private PrefixMapping prefixMapping = new PrefixMappingImpl(); + private Reifier reifier = new EmptyReifier(this); + private QueryHandler queryHandler; + + public ListeningGraph(String graphURI, RDFServiceSDB rdfServiceSDB) { + this.graphURI = graphURI; + this.rdfServiceSDB = rdfServiceSDB; + } + + @Override + public void add(Triple triple) throws AddDeniedException { + performAdd(triple); + } + + @Override + public void performAdd(Triple triple) throws AddDeniedException { + this.rdfServiceSDB.notifyListeners(triple, ModelChange.Operation.ADD, graphURI); + } + + @Override + public void delete(Triple triple) throws DeleteDeniedException { + performDelete(triple); + } + + @Override + public void performDelete(Triple triple) throws DeleteDeniedException { + this.rdfServiceSDB.notifyListeners(triple, ModelChange.Operation.REMOVE, graphURI); + } + + @Override + public void close() { + } + + @Override + public boolean contains(Triple arg0) { + return contains(arg0.getSubject(), arg0.getPredicate(), arg0.getObject()); + } + + @Override + public boolean contains(Node subject, Node predicate, Node object) { + return false; + } + + @Override + public boolean dependsOn(Graph arg0) { + return false; // who knows? + } + + @Override + public ExtendedIterator find(TripleMatch arg0) { + Triple t = arg0.asTriple(); + return find(t.getSubject(), t.getPredicate(), t.getObject()); + } + + @Override + public ExtendedIterator find(Node subject, Node predicate, Node object) { + List triplist = new ArrayList(); + return WrappedIterator.create(triplist.iterator()); + } + + @Override + public BulkUpdateHandler getBulkUpdateHandler() { + if (this.bulkUpdateHandler == null) { + this.bulkUpdateHandler = new SimpleBulkUpdateHandler(this); + } + return this.bulkUpdateHandler; + } + + @Override + public Capabilities getCapabilities() { + return capabilities; + } + + @Override + public GraphEventManager getEventManager() { + if (eventManager == null) { + eventManager = new SimpleEventManager(this); + } + return eventManager; + } + + @Override + public PrefixMapping getPrefixMapping() { + return prefixMapping; + } + + @Override + public Reifier getReifier() { + return reifier; + } + + @Override + public GraphStatisticsHandler getStatisticsHandler() { + return null; + } + + @Override + public TransactionHandler getTransactionHandler() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isClosed() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isEmpty() { + return (size() == 0); + } + + @Override + public boolean isIsomorphicWith(Graph arg0) { + throw new UnsupportedOperationException("isIsomorphicWith() not supported " + + "by SPARQL graphs"); + } + + @Override + public QueryHandler queryHandler() { + if (queryHandler == null) { + queryHandler = new SimpleQueryHandler(this); + } + return queryHandler; + } + + @Override + public int size() { + int size = find(null, null, null).toList().size(); + return size; + } + + private final static Capabilities capabilities = new Capabilities() { + + public boolean addAllowed() { + return false; + } + + public boolean addAllowed(boolean everyTriple) { + return false; + } + + public boolean canBeEmpty() { + return true; + } + + public boolean deleteAllowed() { + return false; + } + + public boolean deleteAllowed(boolean everyTriple) { + return false; + } + + public boolean findContractSafe() { + return true; + } + + public boolean handlesLiteralTyping() { + return true; + } + + public boolean iteratorRemoveAllowed() { + return false; + } + + public boolean sizeAccurate() { + return true; + } + }; + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceFactorySDB.java new file mode 100644 index 000000000..c48fdcea1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceFactorySDB.java @@ -0,0 +1,25 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb; + +import org.apache.commons.dbcp.BasicDataSource; + +import com.hp.hpl.jena.sdb.StoreDesc; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; + +public class RDFServiceFactorySDB { + + private BasicDataSource bds; + private StoreDesc storeDesc; + + public RDFServiceFactorySDB(BasicDataSource dataSource, StoreDesc storeDesc) { + this.bds = dataSource; + this.storeDesc = storeDesc; + } + + public RDFService getRDFService() { + return new RDFServiceSDB(bds, storeDesc); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceSDB.java new file mode 100644 index 000000000..c6042e809 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sdb/RDFServiceSDB.java @@ -0,0 +1,446 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.DataSource; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.DatasetFactory; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.ResultSetFormatter; +import com.hp.hpl.jena.rdf.listeners.StatementListener; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.sdb.SDBFactory; +import com.hp.hpl.jena.sdb.Store; +import com.hp.hpl.jena.sdb.StoreDesc; +import com.hp.hpl.jena.sdb.sql.SDBConnection; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.vocabulary.OWL; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; + +public class RDFServiceSDB extends RDFServiceImpl implements RDFService { + + private final static Log log = LogFactory.getLog(RDFServiceSDB.class); + + private BasicDataSource bds; + private StoreDesc storeDesc; + + public RDFServiceSDB(BasicDataSource dataSource, StoreDesc storeDesc) { + this.bds = dataSource; + this.storeDesc = storeDesc; + } + + protected DatasetWrapper getDatasetWrapper() { + try { + SDBConnection conn = new SDBConnection(bds.getConnection()); + return new DatasetWrapper(getDataset(conn), conn); + } catch (SQLException sqle) { + log.error(sqle, sqle); + throw new RuntimeException(sqle); + } + } + + protected Dataset getDataset(SDBConnection conn) { + Store store = SDBFactory.connectStore(conn, storeDesc); + store.getLoader().setUseThreading(false); + return SDBFactory.connectDataset(store); + } + + @Override + public boolean changeSetUpdate(ChangeSet changeSet) + throws RDFServiceException { + + if (changeSet.getPreconditionQuery() != null + && !isPreconditionSatisfied( + changeSet.getPreconditionQuery(), + changeSet.getPreconditionQueryType())) { + return false; + } + + SDBConnection conn = null; + try { + conn = new SDBConnection(bds.getConnection()); + } catch (SQLException sqle) { + log.error(sqle, sqle); + throw new RDFServiceException(sqle); + } + + Dataset dataset = getDataset(conn); + boolean transaction = conn.getTransactionHandler().transactionsSupported(); + + try { + + if (transaction) { + conn.getTransactionHandler().begin(); + } + + for (Object o : changeSet.getPreChangeEvents()) { + this.notifyListenersOfEvent(o); + } + + Iterator csIt = changeSet.getModelChanges().iterator(); + while (csIt.hasNext()) { + ModelChange modelChange = csIt.next(); + modelChange.getSerializedModel().mark(Integer.MAX_VALUE); + dataset.getLock().enterCriticalSection(Lock.WRITE); + try { + Model model = dataset.getNamedModel(modelChange.getGraphURI()); + operateOnModel(model, modelChange, dataset); + } finally { + dataset.getLock().leaveCriticalSection(); + } + } + + if (transaction) { + conn.getTransactionHandler().commit(); + } + + // notify listeners of triple changes + csIt = changeSet.getModelChanges().iterator(); + while (csIt.hasNext()) { + ModelChange modelChange = csIt.next(); + modelChange.getSerializedModel().reset(); + Model model = ModelFactory.createModelForGraph( + new ListeningGraph(modelChange.getGraphURI(), this)); + operateOnModel(model, modelChange, null); + } + + for (Object o : changeSet.getPostChangeEvents()) { + this.notifyListenersOfEvent(o); + } + + } catch (Exception e) { + log.error(e, e); + if (transaction) { + conn.getTransactionHandler().abort(); + } + throw new RDFServiceException(e); + } finally { + conn.close(); + } + + return true; + } + + private void operateOnModel(Model model, ModelChange modelChange, Dataset dataset) { + model.enterCriticalSection(Lock.WRITE); + try { + if (modelChange.getOperation() == ModelChange.Operation.ADD) { + model.read(modelChange.getSerializedModel(), null, + getSerializationFormatString(modelChange.getSerializationFormat())); + } else if (modelChange.getOperation() == ModelChange.Operation.REMOVE) { + model.remove(parseModel(modelChange)); + if (dataset != null) { + removeBlankNodesWithSparqlUpdate(dataset, model, modelChange.getGraphURI()); + } + } else { + log.error("unrecognized operation type"); + } + } finally { + model.leaveCriticalSection(); + } + } + + private void removeBlankNodesWithSparqlUpdate(Dataset dataset, Model model, String graphURI) { + + Model blankNodeModel = ModelFactory.createDefaultModel(); + StmtIterator stmtIt = model.listStatements(); + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.nextStatement(); + if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) { + blankNodeModel.add(stmt); + } + } + + String rootFinder = "SELECT ?s WHERE { ?s ?p ?o OPTIONAL { ?ss ?pp ?s } FILTER (!bound(?ss)) }"; + Query rootFinderQuery = QueryFactory.create(rootFinder); + QueryExecution qe = QueryExecutionFactory.create(rootFinderQuery, blankNodeModel); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + Resource s = qs.getResource("s"); + String treeFinder = makeDescribe(s); + Query treeFinderQuery = QueryFactory.create(treeFinder); + QueryExecution qee = QueryExecutionFactory.create(treeFinderQuery, blankNodeModel); + try { + Model tree = qee.execDescribe(); + StmtIterator sit = tree.listStatements(s, null, (RDFNode) null); + while (sit.hasNext()) { + Statement stmt = sit.nextStatement(); + RDFNode n = stmt.getObject(); + Model m2 = ModelFactory.createDefaultModel(); + if (n.isResource()) { + Resource s2 = (Resource) n; + // now run yet another describe query + String smallerTree = makeDescribe(s2); + Query smallerTreeQuery = QueryFactory.create(smallerTree); + QueryExecution qe3 = QueryExecutionFactory.create( + smallerTreeQuery, tree); + try { + qe3.execDescribe(m2); + } finally { + qe3.close(); + } + } + m2.add(stmt); + DataSource ds = DatasetFactory.create(); + ds.addNamedModel(graphURI, dataset.getNamedModel(graphURI)); + removeUsingSparqlUpdate(ds, m2, graphURI); + } + } finally { + qee.close(); + } + } + } finally { + qe.close(); + } + } + + private String makeDescribe(Resource s) { + StringBuffer query = new StringBuffer("DESCRIBE <") ; + if (s.isAnon()) { + query.append("_:" + s.getId().toString()); + } else { + query.append(s.getURI()); + } + query.append(">"); + return query.toString(); + } + + private void removeUsingSparqlUpdate(Dataset dataset, Model model, String graphURI) { + + StringBuffer patternBuff = new StringBuffer(); + StmtIterator stmtIt = model.listStatements(); + + if (!stmtIt.hasNext()) { + stmtIt.close(); + return; + } + + while(stmtIt.hasNext()) { + Triple t = stmtIt.next().asTriple(); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); + patternBuff.append(" "); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); + patternBuff.append(" "); + patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getObject(), null)); + patternBuff.append(" .\n"); + } + + StringBuffer queryBuff = new StringBuffer(); + queryBuff.append("CONSTRUCT { \n"); + queryBuff.append(patternBuff); + queryBuff.append("} WHERE { \n"); + if (graphURI != null) { + queryBuff.append(" GRAPH <" + graphURI + "> { \n"); + } + queryBuff.append(patternBuff); + if (graphURI != null) { + queryBuff.append(" } \n"); + } + queryBuff.append("} \n"); + + //log.debug(queryBuff.toString()); + + Query construct = QueryFactory.create(queryBuff.toString()); + // make a plain dataset to force the query to be run in a way that + // won't overwhelm MySQL with too many joins + DataSource ds = DatasetFactory.create(); + ds.addNamedModel(graphURI, (graphURI != null) + ? dataset.getNamedModel(graphURI) : dataset.getDefaultModel()); + QueryExecution qe = QueryExecutionFactory.create(construct, ds); + try { + Model m = qe.execConstruct(); + if (graphURI != null) { + dataset.getNamedModel(graphURI).remove(m); + } else { + dataset.getDefaultModel().remove(m); + } + } finally { + qe.close(); + } + } + + private Model parseModel(ModelChange modelChange) { + Model model = ModelFactory.createDefaultModel(); + model.read(modelChange.getSerializedModel(), null, + getSerializationFormatString(modelChange.getSerializationFormat())); + return model; + } + + @Override + public void newIndividual(String individualURI, String individualTypeURI, + String graphURI) throws RDFServiceException { + // TODO Auto-generated method stub + + } + + private InputStream getRDFResultStream(String query, boolean construct, + ModelSerializationFormat resultFormat) throws RDFServiceException { + DatasetWrapper dw = getDatasetWrapper(); + try { + Dataset d = dw.getDataset(); + Query q = QueryFactory.create(query); + QueryExecution qe = QueryExecutionFactory.create(q, d); + ByteArrayOutputStream serializedModel = new ByteArrayOutputStream(); + try { + // TODO pipe this + Model m = construct ? qe.execConstruct() : qe.execDescribe(); + m.write(serializedModel, getSerializationFormatString(resultFormat)); + InputStream result = new ByteArrayInputStream(serializedModel.toByteArray()); + return result; + } finally { + qe.close(); + } + } finally { + dw.close(); + } + } + + private static final boolean CONSTRUCT = true; + + private static final boolean DESCRIBE = false; + + @Override + public InputStream sparqlConstructQuery(String query, + ModelSerializationFormat resultFormat) throws RDFServiceException { + return getRDFResultStream(query, CONSTRUCT, resultFormat); + } + + @Override + public InputStream sparqlDescribeQuery(String query, + ModelSerializationFormat resultFormat) throws RDFServiceException { + return getRDFResultStream(query, DESCRIBE, resultFormat); + } + + @Override + public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat) + throws RDFServiceException { + DatasetWrapper dw = getDatasetWrapper(); + try { + Dataset d = dw.getDataset(); + Query q = QueryFactory.create(query); + QueryExecution qe = QueryExecutionFactory.create(q, d); + try { + ResultSet resultSet = qe.execSelect(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + switch (resultFormat) { + case CSV: + ResultSetFormatter.outputAsCSV(outputStream,resultSet); + break; + case TEXT: + ResultSetFormatter.out(outputStream,resultSet); + break; + case JSON: + ResultSetFormatter.outputAsJSON(outputStream, resultSet); + break; + case XML: + ResultSetFormatter.outputAsXML(outputStream, resultSet); + break; + default: + throw new RDFServiceException("unrecognized result format"); + } + InputStream result = new ByteArrayInputStream(outputStream.toByteArray()); + return result; + } finally { + qe.close(); + } + } finally { + dw.close(); + } + } + + @Override + public boolean sparqlAskQuery(String query) throws RDFServiceException { + DatasetWrapper dw = getDatasetWrapper(); + try { + Dataset d = dw.getDataset(); + Query q = QueryFactory.create(query); + QueryExecution qe = QueryExecutionFactory.create(q, d); + try { + return qe.execAsk(); + } finally { + qe.close(); + } + } finally { + dw.close(); + } + } + + @Override + public List getGraphURIs() throws RDFServiceException { + DatasetWrapper dw = getDatasetWrapper(); + try { + Dataset d = dw.getDataset(); + List graphURIs = new ArrayList(); + Iterator nameIt = d.listNames(); + while (nameIt.hasNext()) { + graphURIs.add(nameIt.next()); + } + return graphURIs; + } finally { + dw.close(); + } + } + + @Override + public void getGraphMetadata() throws RDFServiceException { + // TODO Auto-generated method stub + } + + @Override + public void close() { + // nothing + } + + private class ModelListener extends StatementListener { + + private String graphURI; + private RDFServiceImpl s; + + public ModelListener(String graphURI, RDFServiceImpl s) { + this.graphURI = graphURI; + this.s = s; + } + + public void addedStatement(Statement stmt) { + s.notifyListeners(stmt.asTriple(), ModelChange.Operation.ADD, graphURI); + } + + public void removedStatement(Statement stmt) { + s.notifyListeners(stmt.asTriple(), ModelChange.Operation.REMOVE, graphURI); + } + + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java new file mode 100644 index 000000000..8f229443c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java @@ -0,0 +1,469 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openrdf.model.Resource; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.Update; +import org.openrdf.query.UpdateExecutionException; +import org.openrdf.repository.Repository; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.RepositoryResult; +import org.openrdf.repository.http.HTTPRepository; + +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.ResultSetFormatter; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; + +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.ChangeSetImpl; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; + +/* + * API to write, read, and update Vitro's RDF store, with support + * to allow listening, logging and auditing. + */ + +public class RDFServiceSparql extends RDFServiceImpl implements RDFService { + + private static final Log log = LogFactory.getLog(RDFServiceImpl.class); + private String endpointURI; + private Repository repository; + + /** + * Returns an RDFService for a remote repository + * @param String - URI of the SPARQL endpoint for the knowledge base + * @param String - URI of the default write graph within the knowledge base. + * this is the graph that will be written to when a graph + * is not explicitly specified. + * + * The default read graph is the union of all graphs in the + * knowledge base + */ + public RDFServiceSparql(String endpointURI, String defaultWriteGraphURI) { + this.endpointURI = endpointURI; + this.repository = new HTTPRepository(endpointURI); + } + + /** + * Returns an RDFService for a remote repository + * @param String - URI of the SPARQL endpoint for the knowledge base + * + * The default read graph is the union of all graphs in the + * knowledge base + */ + public RDFServiceSparql(String endpointURI) { + this(endpointURI, null); + } + + public void close() { + try { + this.repository.shutDown(); + } catch (RepositoryException re) { + log.error(re, re); + } + } + + /** + * Perform a series of additions to and or removals from specified graphs + * in the RDF store. preConditionSparql will be executed against the + * union of all the graphs in the knowledge base before any updates are made. + * If the precondition query returns a non-empty result no updates + * will be made. + * + * @param ChangeSet - a set of changes to be performed on the RDF store. + * + * @return boolean - indicates whether the precondition was satisfied + */ + @Override + public boolean changeSetUpdate(ChangeSet changeSet) throws RDFServiceException { + + if (changeSet.getPreconditionQuery() != null + && !isPreconditionSatisfied( + changeSet.getPreconditionQuery(), + changeSet.getPreconditionQueryType())) { + return false; + } + + Iterator csIt = changeSet.getModelChanges().iterator(); + + while (csIt.hasNext()) { + + ModelChange modelChange = csIt.next(); + + if (modelChange.getOperation() == ModelChange.Operation.ADD) { + performAdd(modelChange); + } else if (modelChange.getOperation() == ModelChange.Operation.REMOVE) { + performRemove(modelChange); + } else { + log.error("unrecognized operation type"); + } + } + + return true; + } + + /** + * Performs a SPARQL construct query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param String query - the SPARQL query to be executed against the RDF store + * @param RDFService.ModelSerializationFormat resultFormat - type of serialization for RDF result of the SPARQL query + * @param OutputStream outputStream - the result of the query + * + */ + @Override + public InputStream sparqlConstructQuery(String queryStr, + RDFServiceImpl.ModelSerializationFormat resultFormat) throws RDFServiceException { + + Model model = ModelFactory.createDefaultModel(); + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, query); + + try { + qe.execConstruct(model); + } finally { + qe.close(); + } + + ByteArrayOutputStream serializedModel = new ByteArrayOutputStream(); + model.write(serializedModel,getSerializationFormatString(resultFormat)); + InputStream result = new ByteArrayInputStream(serializedModel.toByteArray()); + return result; + } + + /** + * Performs a SPARQL describe query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param String query - the SPARQL query to be executed against the RDF store + * @param RDFService.ModelSerializationFormat resultFormat - type of serialization for RDF result of the SPARQL query + * + * @return InputStream - the result of the query + * + */ + @Override + public InputStream sparqlDescribeQuery(String queryStr, + RDFServiceImpl.ModelSerializationFormat resultFormat) throws RDFServiceException { + + Model model = ModelFactory.createDefaultModel(); + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, query); + + try { + qe.execDescribe(model); + } finally { + qe.close(); + } + + ByteArrayOutputStream serializedModel = new ByteArrayOutputStream(); + model.write(serializedModel,getSerializationFormatString(resultFormat)); + InputStream result = new ByteArrayInputStream(serializedModel.toByteArray()); + return result; + } + + /** + * Performs a SPARQL select query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param String query - the SPARQL query to be executed against the RDF store + * @param RDFService.ResultFormat resultFormat - format for the result of the Select query + * + * @return InputStream - the result of the query + * + */ + @Override + public InputStream sparqlSelectQuery(String queryStr, RDFService.ResultFormat resultFormat) throws RDFServiceException { + + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, query); + + try { + ResultSet resultSet = qe.execSelect(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + switch (resultFormat) { + case CSV: + ResultSetFormatter.outputAsCSV(outputStream,resultSet); + break; + case TEXT: + ResultSetFormatter.out(outputStream,resultSet); + break; + case JSON: + ResultSetFormatter.outputAsJSON(outputStream, resultSet); + break; + case XML: + ResultSetFormatter.outputAsXML(outputStream, resultSet); + break; + default: + throw new RDFServiceException("unrecognized result format"); + } + + InputStream result = new ByteArrayInputStream(outputStream.toByteArray()); + return result; + } finally { + qe.close(); + } + } + + /** + * Performs a SPARQL ASK query against the knowledge base. The query may have + * an embedded graph identifier. + * + * @param String query - the SPARQL query to be executed against the RDF store + * + * @return boolean - the result of the SPARQL query + */ + @Override + public boolean sparqlAskQuery(String queryStr) throws RDFServiceException { + + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, query); + + try { + return qe.execAsk(); + } finally { + qe.close(); + } + } + + /** + * Get a list of all the graph URIs in the RDF store. + * + * @return List - list of all the graph URIs in the RDF store + */ + //TODO - need to verify that the sesame getContextIDs method is implemented + // in such a way that it works with all triple stores that support the + // graph update API + @Override + public List getGraphURIs() throws RDFServiceException { + + List graphNodeList = new ArrayList(); + + try { + RepositoryConnection conn = getConnection(); + try { + RepositoryResult conResult = conn.getContextIDs(); + while (conResult.hasNext()) { + Resource res = conResult.next(); + graphNodeList.add(res.stringValue()); + } + } finally { + conn.close(); + } + } catch (RepositoryException re) { + throw new RuntimeException(re); + } + + return graphNodeList; + } + + /** + * TODO - what is the definition of this method? + * @return + */ + @Override + public void getGraphMetadata() throws RDFServiceException { + + } + + /** + * Get the URI of the default write graph + * + * @return String URI of default write graph + */ + @Override + public String getDefaultWriteGraphURI() throws RDFServiceException { + return defaultWriteGraphURI; + } + + /** + * Register a listener to listen to changes in any graph in + * the RDF store. + * + */ + @Override + public synchronized void registerListener(ChangeListener changeListener) throws RDFServiceException { + + if (!registeredListeners.contains(changeListener)) { + registeredListeners.add(changeListener); + } + } + + /** + * Unregister a listener from listening to changes in any graph + * in the RDF store. + * + */ + @Override + public synchronized void unregisterListener(ChangeListener changeListener) throws RDFServiceException { + registeredListeners.remove(changeListener); + } + + /** + * Create a ChangeSet object + * + * @return a ChangeSet object + */ + @Override + public ChangeSet manufactureChangeSet() { + return new ChangeSetImpl(); + } + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Non-override methods below + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + protected String getEndpointURI() { + return endpointURI; + } + + protected RepositoryConnection getConnection() { + try { + return this.repository.getConnection(); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + protected void executeUpdate(String updateString) { + try { + RepositoryConnection conn = getConnection(); + try { + Update u = conn.prepareUpdate(QueryLanguage.SPARQL, updateString); + u.execute(); + } catch (MalformedQueryException e) { + throw new RuntimeException(e); + } catch (UpdateExecutionException e) { + log.error(e,e); + log.error("Update command: \n" + updateString); + throw new RuntimeException(e); + } finally { + conn.close(); + } + } catch (RepositoryException re) { + throw new RuntimeException(re); + } + } + + protected void addTriple(Triple t, String graphURI) { + + StringBuffer updateString = new StringBuffer(); + updateString.append("INSERT DATA { "); + updateString.append((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ); + updateString.append(sparqlNodeUpdate(t.getSubject(), "")); + updateString.append(" "); + updateString.append(sparqlNodeUpdate(t.getPredicate(), "")); + updateString.append(" "); + updateString.append(sparqlNodeUpdate(t.getObject(), "")); + updateString.append(" }"); + updateString.append((graphURI != null) ? " } " : ""); + + executeUpdate(updateString.toString()); + notifyListeners(t, ModelChange.Operation.ADD, graphURI); + } + + protected void removeTriple(Triple t, String graphURI) { + + StringBuffer updateString = new StringBuffer(); + updateString.append("DELETE DATA { "); + updateString.append((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ); + updateString.append(sparqlNodeUpdate(t.getSubject(), "")); + updateString.append(" "); + updateString.append(sparqlNodeUpdate(t.getPredicate(), "")); + updateString.append(" "); + updateString.append(sparqlNodeUpdate(t.getObject(), "")); + updateString.append(" }"); + updateString.append((graphURI != null) ? " } " : ""); + + executeUpdate(updateString.toString()); + notifyListeners(t, ModelChange.Operation.REMOVE, graphURI); + } + + @Override + protected boolean isPreconditionSatisfied(String query, + RDFService.SPARQLQueryType queryType) + throws RDFServiceException { + Model model = ModelFactory.createDefaultModel(); + + switch (queryType) { + case DESCRIBE: + model.read(sparqlDescribeQuery(query,RDFService.ModelSerializationFormat.N3), null); + return !model.isEmpty(); + case CONSTRUCT: + model.read(sparqlConstructQuery(query,RDFService.ModelSerializationFormat.N3), null); + return !model.isEmpty(); + case SELECT: + return sparqlSelectQueryHasResults(query); + case ASK: + return sparqlAskQuery(query); + default: + throw new RDFServiceException("unrecognized SPARQL query type"); + } + } + + @Override + protected boolean sparqlSelectQueryHasResults(String queryStr) throws RDFServiceException { + + Query query = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.sparqlService(endpointURI, query); + + try { + ResultSet resultSet = qe.execSelect(); + return resultSet.hasNext(); + } finally { + qe.close(); + } + } + + protected void performAdd(ModelChange modelChange) throws RDFServiceException { + + Model model = ModelFactory.createDefaultModel(); + model.read(modelChange.getSerializedModel(),getSerializationFormatString(modelChange.getSerializationFormat())); + + StmtIterator stmtIt = model.listStatements(); + + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.next(); + Triple triple = new Triple(stmt.getSubject().asNode(), stmt.getPredicate().asNode(), stmt.getObject().asNode()); + addTriple(triple, modelChange.getGraphURI()); + } + } + + protected void performRemove(ModelChange modelChange) throws RDFServiceException { + + Model model = ModelFactory.createDefaultModel(); + model.read(modelChange.getSerializedModel(),getSerializationFormatString(modelChange.getSerializationFormat())); + + StmtIterator stmtIt = model.listStatements(); + + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.next(); + Triple triple = new Triple(stmt.getSubject().asNode(), stmt.getPredicate().asNode(), stmt.getObject().asNode()); + removeTriple(triple, modelChange.getGraphURI()); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index 21979b68b..5df4d7271 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -39,8 +39,13 @@ import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ABoxJenaChangeListener; import edu.cornell.mannlib.vitro.webapp.dao.jena.CumulativeDeltaModeler; +import edu.cornell.mannlib.vitro.webapp.dao.jena.DifferenceGraph; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; /** * Allows for real-time incremental materialization or retraction of RDFS- @@ -53,6 +58,7 @@ public class SimpleReasoner extends StatementListener { private static final Log log = LogFactory.getLog(SimpleReasoner.class); + private RDFService rdfService; private OntModel tboxModel; // asserted and inferred TBox axioms private OntModel aboxModel; // ABox assertions private Model inferenceModel; // ABox inferences @@ -79,10 +85,13 @@ public class SimpleReasoner extends StatementListener { * @param inferenceRebuildModel - output. This the model temporarily used when the whole ABox inference model is rebuilt * @param inferenceScratchpadModel - output. This the model temporarily used when the whole ABox inference model is rebuilt */ - public SimpleReasoner(OntModel tboxModel, OntModel aboxModel, Model inferenceModel, + public SimpleReasoner(OntModel tboxModel, RDFService rdfService, Model inferenceModel, Model inferenceRebuildModel, Model scratchpadModel) { + this.rdfService = rdfService; this.tboxModel = tboxModel; - this.aboxModel = aboxModel; + this.aboxModel = ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, ModelFactory.createModelForGraph( + new DifferenceGraph(new RDFServiceGraph(rdfService), inferenceModel.getGraph()))); this.inferenceModel = inferenceModel; this.inferenceRebuildModel = inferenceRebuildModel; this.scratchpadModel = scratchpadModel; @@ -91,8 +100,16 @@ public class SimpleReasoner extends StatementListener { aBoxDeltaModeler1 = new CumulativeDeltaModeler(); aBoxDeltaModeler2 = new CumulativeDeltaModeler(); stopRequested = false; - - aboxModel.getBaseModel().register(this); + + if (rdfService == null) { + aboxModel.register(this); + } else { + try { + rdfService.registerListener(new ABoxJenaChangeListener(this)); + } catch (RDFServiceException e) { + throw new RuntimeException("Unable to register change listener", e); + } + } } /** @@ -174,8 +191,7 @@ public class SimpleReasoner extends StatementListener { * Synchronized part of removedStatement. Interacts * with DeltaComputer. */ - protected synchronized void handleRemovedStatement(Statement stmt) { - + protected synchronized void handleRemovedStatement(Statement stmt) { if (batchMode1) { aBoxDeltaModeler1.removedStatement(stmt); } else if (batchMode2) { @@ -443,6 +459,7 @@ public class SimpleReasoner extends StatementListener { Iterator parentIt = parents.iterator(); while (parentIt.hasNext()) { + OntClass parentClass = parentIt.next(); // VIVO doesn't materialize statements that assert anonymous types @@ -451,7 +468,9 @@ public class SimpleReasoner extends StatementListener { // of classes not individuals. if (parentClass.isAnon()) continue; - if (entailedType(stmt.getSubject(),parentClass)) continue; // if a type is still entailed without the + if (entailedType(stmt.getSubject(),parentClass)) { + continue; // if a type is still entailed without the + } // removed statement, then don't remove it // from the inferences @@ -900,7 +919,6 @@ public class SimpleReasoner extends StatementListener { List subclasses = null; subclasses = (cls.listSubClasses(false)).toList(); subclasses.addAll((cls.listEquivalentClasses()).toList()); - Iterator iter = subclasses.iterator(); while (iter.hasNext()) { OntClass childClass = iter.next(); @@ -908,8 +926,9 @@ public class SimpleReasoner extends StatementListener { Iterator sameIter = sameIndividuals.iterator(); while (sameIter.hasNext()) { Statement stmt = ResourceFactory.createStatement(sameIter.next(), RDF.type, childClass); - if (aboxModel.contains(stmt)) - return true; + if (aboxModel.contains(stmt)) { + return true; + } } } return false; @@ -1678,7 +1697,7 @@ public class SimpleReasoner extends StatementListener { @Override public synchronized void notifyEvent(Model model, Object event) { - + if (event instanceof BulkUpdateEvent) { if (((BulkUpdateEvent) event).getBegin()) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index fd877c6d6..e5e9516c1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -19,245 +19,246 @@ import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.ontology.OntDocumentManager; import com.hp.hpl.jena.ontology.OntDocumentManager; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.sdb.SDBFactory; -import com.hp.hpl.jena.sdb.Store; -import com.hp.hpl.jena.sdb.util.StoreUtils; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph; // This ContextListener must run after the JenaDataSourceSetup ContextListener public class FileGraphSetup implements ServletContextListener { - private static final String ABOX = "abox"; - private static final String TBOX = "tbox"; - private static final String PATH_ROOT = "/WEB-INF/filegraph/"; - public static final String FILEGRAPH_URI_ROOT = "http://vitro.mannlib.cornell.edu/filegraph/"; - - private static final Log log = LogFactory.getLog(FileGraphSetup.class); - - public void contextInitialized(ServletContextEvent sce) { - - boolean aboxChanged = false; // indicates whether any ABox file graph model has changed - boolean tboxChanged = false; // indicates whether any TBox file graph model has changed - OntModelSelector baseOms = null; - - try { - - OntDocumentManager.getInstance().setProcessImports(true); - baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); - Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore"); - - // ABox files - Set pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + ABOX); - - cleanupDB(kbStore, pathToURI(pathSet, ABOX), ABOX); - - if (pathSet != null) { - OntModel aboxBaseModel = baseOms.getABoxModel(); - aboxChanged = readGraphs(sce, pathSet, kbStore, ABOX, aboxBaseModel); - } - - // TBox files - pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + TBOX); - - cleanupDB(kbStore, pathToURI(pathSet, TBOX),TBOX); - - if (pathSet != null) { - OntModel tboxBaseModel = baseOms.getTBoxModel(); - tboxChanged = readGraphs(sce, pathSet, kbStore, TBOX, tboxBaseModel); - } - } catch (ClassCastException cce) { - String errMsg = "Unable to cast servlet context attribute to the appropriate type " + cce.getLocalizedMessage(); - log.error(errMsg); - throw new ClassCastException(errMsg); - } catch (Throwable t) { - System.out.println("Throwable in listener " + this.getClass().getName()); - log.error(t); - t.printStackTrace(); - } finally { - OntDocumentManager.getInstance().setProcessImports(false); - } - - if (isUpdateRequired(sce.getServletContext())) { - log.info("mostSpecificType will be computed because a knowledge base migration was performed." ); + private static final String ABOX = "abox"; + private static final String TBOX = "tbox"; + private static final String PATH_ROOT = "/WEB-INF/filegraph/"; + public static final String FILEGRAPH_URI_ROOT = "http://vitro.mannlib.cornell.edu/filegraph/"; + + private static final Log log = LogFactory.getLog(FileGraphSetup.class); + + public void contextInitialized(ServletContextEvent sce) { + + boolean aboxChanged = false; // indicates whether any ABox file graph model has changed + boolean tboxChanged = false; // indicates whether any TBox file graph model has changed + OntModelSelector baseOms = null; + + try { + + OntDocumentManager.getInstance().setProcessImports(true); + baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); + Dataset dataset = JenaDataSourceSetupBase.getStartupDataset(sce.getServletContext()); + + // ABox files + Set pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + ABOX); + + cleanupDB(dataset, pathToURI(pathSet, ABOX), ABOX); + + if (pathSet != null) { + OntModel aboxBaseModel = baseOms.getABoxModel(); + aboxChanged = readGraphs(sce, pathSet, dataset, ABOX, aboxBaseModel); + } + + // TBox files + pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + TBOX); + + cleanupDB(dataset, pathToURI(pathSet, TBOX),TBOX); + + if (pathSet != null) { + OntModel tboxBaseModel = baseOms.getTBoxModel(); + tboxChanged = readGraphs(sce, pathSet, dataset, TBOX, tboxBaseModel); + } + } catch (ClassCastException cce) { + String errMsg = "Unable to cast servlet context attribute to the appropriate type " + cce.getLocalizedMessage(); + log.error(errMsg); + throw new ClassCastException(errMsg); + } catch (Throwable t) { + log.error(t, t); + } finally { + OntDocumentManager.getInstance().setProcessImports(false); + } + + if (isUpdateRequired(sce.getServletContext())) { + log.info("mostSpecificType will be computed because a knowledge base migration was performed." ); SimpleReasonerSetup.setMSTComputeRequired(sce.getServletContext()); - } else if (aboxChanged || tboxChanged) { - log.info("a full recompute of the Abox will be performed because" + - " the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." ); - SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext()); - } - } - - /* - * Reads the graphs stored as files in sub-directories of - * 1. updates the SDB 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 - * graph and the DB copy. - */ - public boolean readGraphs(ServletContextEvent sce, Set pathSet, Store kbStore, String type, OntModel baseModel) { - - int count = 0; - - 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 - for ( String p : pathSet ) { + } else if (aboxChanged || tboxChanged) { + log.info("a full recompute of the Abox will be performed because" + + " the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." ); + SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext()); + } + } - count++; // note this will count the empty files too - File file = new File(sce.getServletContext().getRealPath(p)); - - try { - FileInputStream fis = new FileInputStream( file ); - try { - OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); - if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) { - model.read( fis, null, "N3" ); - } else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) { - model.read( fis, null, "RDF/XML" ); - } else { - log.warn("Ignoring " + type + " file graph " + p + " because the file extension is unrecognized."); - } - - if ( !model.isEmpty() ) { - baseModel.addSubModel(model); - log.info("Attached file graph as " + type + " submodel " + p); - } - - modelChanged = modelChanged | updateGraphInDB(kbStore, model, type, p); - - } catch (Exception ioe) { - log.error("Unable to process file graph " + p, ioe); - System.out.println("Unable to process file graph " + p); - ioe.printStackTrace(); - } finally { - fis.close(); - } - } catch (FileNotFoundException fnfe) { - log.warn(p + " not found. Unable to process file graph" + - ((fnfe.getLocalizedMessage() != null) ? - fnfe.getLocalizedMessage() : "") ); - } catch (IOException ioe) { - // this is for the fis.close() above. - log.warn("Exception while trying to close file graph file: " + p,ioe); - } - } // end - for - - System.out.println("Read " + count + " " + type + " file graph" + ((count == 1) ? "" : "s") + " from " + PATH_ROOT + type); - - return modelChanged; - } - - /* - * If a graph with the given name doesn't exist in the DB then add it. + /* + * Reads the graphs stored as files in sub-directories of + * 1. updates the SDB 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 + * graph and the DB copy. + */ + public boolean readGraphs(ServletContextEvent sce, Set pathSet, Dataset dataset, String type, OntModel baseModel) { + + int count = 0; + + 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 + for ( String p : pathSet ) { + + count++; // note this will count the empty files too + File file = new File(sce.getServletContext().getRealPath(p)); + + try { + FileInputStream fis = new FileInputStream( file ); + try { + OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) { + model.read( fis, null, "N3" ); + } else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) { + model.read( fis, null, "RDF/XML" ); + } else { + log.warn("Ignoring " + type + " file graph " + p + " because the file extension is unrecognized."); + } + + if ( !model.isEmpty() ) { + baseModel.addSubModel(model); + log.info("Attached file graph as " + type + " submodel " + p); + } + + modelChanged = modelChanged | updateGraphInDB(dataset, model, type, p); + + } catch (Exception ioe) { + log.error("Unable to process file graph " + p, ioe); + System.out.println("Unable to process file graph " + p); + ioe.printStackTrace(); + } finally { + fis.close(); + } + } catch (FileNotFoundException fnfe) { + log.warn(p + " not found. Unable to process file graph" + + ((fnfe.getLocalizedMessage() != null) ? + fnfe.getLocalizedMessage() : "") ); + } catch (IOException ioe) { + // this is for the fis.close() above. + log.warn("Exception while trying to close file graph file: " + p,ioe); + } + } // end - for + + System.out.println("Read " + count + " " + type + " file graph" + ((count == 1) ? "" : "s") + " from " + PATH_ROOT + type); + + return modelChanged; + } + + /* + * If a graph with the given name doesn't exist in the DB then add it. * - * Otherwise, if a graph with the given name is in the DB and is not isomorphic with - * the graph that was read from the file system then replace the graph - * in the DB with the one read from the file system. - * - * Otherwise, if a graph with the given name is in the DB and is isomorphic with - * the graph that was read from the files system, then do nothing. - */ - public boolean updateGraphInDB(Store kbStore, Model fileModel, String type, String path) { - - String graphURI = pathToURI(path,type); - Model dbModel = SDBFactory.connectNamedModel(kbStore, graphURI); - boolean modelChanged = false; - - if (dbModel.isEmpty() ) { - dbModel.add(fileModel); - modelChanged = true; - } else if (!dbModel.isIsomorphicWith(fileModel)) { - dbModel.removeAll(); - dbModel.add(fileModel); - modelChanged = true; - } - - return modelChanged; - } - - /* - * Deletes any file graphs that are no longer present in the file system - * from the DB. - * - * @param uriSet (input) - a set of graph URIs representing the file - * graphs (of the given type) in the file - * system. - * @param type (input) - abox or tbox. - * @param kbStore (output) - the SDB store for the application - */ - public void cleanupDB(Store kbStore, Set uriSet, String type) { - - Pattern graphURIPat = Pattern.compile("^" + FILEGRAPH_URI_ROOT + type); - - Iterator iter = StoreUtils.storeGraphNames(kbStore); - - while (iter.hasNext()) { - Node node = iter.next(); - Matcher matcher = graphURIPat.matcher(node.getURI()); - + * Otherwise, if a graph with the given name is in the DB and is not isomorphic with + * the graph that was read from the file system then replace the graph + * in the DB with the one read from the file system. + * + * Otherwise, if a graph with the given name is in the DB and is isomorphic with + * the graph that was read from the files system, then do nothing. + */ + public boolean updateGraphInDB(Dataset dataset, Model fileModel, String type, String path) { + + String graphURI = pathToURI(path,type); + Model dbModel = dataset.getNamedModel(graphURI); + boolean modelChanged = false; + + boolean isIsomorphic = dbModel.isIsomorphicWith(fileModel); + + if (dbModel.isEmpty() ) { + dbModel.add(fileModel); + modelChanged = true; + } else if (!isIsomorphic) { + log.info("Updating " + path + " because graphs are not isomorphic"); + log.info("dbModel: " + dbModel.size() + " ; fileModel: " + fileModel.size()); + dbModel.removeAll(); + dbModel.add(fileModel); + modelChanged = true; + } + + return modelChanged; + } + + /* + * Deletes any file graphs that are no longer present in the file system + * from the DB. + * + * @param uriSet (input) - a set of graph URIs representing the file + * graphs (of the given type) in the file + * system. + * @param type (input) - abox or tbox. + * @param kbStore (output) - the SDB store for the application + */ + public void cleanupDB(Dataset dataset, Set uriSet, String type) { + + Pattern graphURIPat = Pattern.compile("^" + FILEGRAPH_URI_ROOT + type); + + Iterator iter = dataset.listNames(); + + while (iter.hasNext()) { + String graphURI = iter.next(); + Matcher matcher = graphURIPat.matcher(graphURI); + if (matcher.find()) { - if (!uriSet.contains(node.getURI())) { - Model model = SDBFactory.connectNamedModel(kbStore, node.getURI()); - model.removeAll(); // delete the graph from the DB - log.info("Removed " + type + " file graph " + node.getURI() + " from the DB store because the file no longer exists in the file system"); - } + if (!uriSet.contains(graphURI)) { + Model model = dataset.getNamedModel(graphURI); + model.removeAll(); // delete the graph from the DB + log.info("Removed " + type + " file graph " + graphURI + " from the DB store because the file no longer exists in the file system"); + } } - } - - return; - } - - /* - * Takes a set of path names for file graphs and returns a set containing - * a graph uri for each path name in the input set. If pathSet is null - * returns an empty set. - */ - public Set pathToURI (Set pathSet, String type) { - - HashSet uriSet = new HashSet(); - - if (pathSet != null) { - for ( String path : pathSet ) { - uriSet.add(pathToURI(path,type)); - } - } - - return uriSet; - } + } - /* - * Takes a path name for a file graph and returns the corresponding SDB URI - * for the graph. The correspondence is by defined convention. - */ - public String pathToURI(String path, String type) { - - String uri = null; - - if (path != null) { - File file = new File(path); - uri = FILEGRAPH_URI_ROOT + type + "/" + file.getName(); - } - - return uri; - } + return; + } - public void contextDestroyed( ServletContextEvent sce ) { - // nothing to do - } - -private static boolean isUpdateRequired(ServletContext ctx) { - return (ctx.getAttribute(UpdateKnowledgeBase.KBM_REQURIED_AT_STARTUP) != null); -} + /* + * Takes a set of path names for file graphs and returns a set containing + * a graph uri for each path name in the input set. If pathSet is null + * returns an empty set. + */ + public Set pathToURI (Set pathSet, String type) { + + HashSet uriSet = new HashSet(); + + if (pathSet != null) { + for ( String path : pathSet ) { + uriSet.add(pathToURI(path,type)); + } + } + + return uriSet; + } + + /* + * Takes a path name for a file graph and returns the corresponding SDB URI + * for the graph. The correspondence is by defined convention. + */ + public String pathToURI(String path, String type) { + + String uri = null; + + if (path != null) { + File file = new File(path); + uri = FILEGRAPH_URI_ROOT + type + "/" + file.getName(); + } + + return uri; + } + + public void contextDestroyed( ServletContextEvent sce ) { + // nothing to do + } + + private static boolean isUpdateRequired(ServletContext ctx) { + return (ctx.getAttribute(UpdateKnowledgeBase.KBM_REQURIED_AT_STARTUP) != null); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index 2cfbecbb5..eddee1b45 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -2,9 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.io.File; import java.sql.SQLException; import java.util.Set; @@ -18,6 +18,7 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -25,6 +26,7 @@ import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.sdb.Store; import com.hp.hpl.jena.sdb.StoreDesc; import com.hp.hpl.jena.sdb.store.DatabaseType; @@ -73,7 +75,6 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { public static String APPPATH = BASE+"app/"; //these files are loaded everytime the system starts up public static String APPPATH_LOAD = APPPATH + "menuload/"; - protected static String SUBMODELS = "/WEB-INF/submodels/"; //All files in this directory will be reloaded every startup //and attached as sub-models to the displayOntModel. @@ -404,7 +405,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } private static VitroJenaModelMaker vjmm = null; - private static VitroJenaSDBModelMaker vsmm = null; + private static ModelMaker vsmm = null; private static VitroModelSource vms = null; private static final String sdbModelMaker = "vitroJenaSDBModelMaker"; private static final String rdbModelMaker = "vitroJenaModelMaker"; @@ -428,7 +429,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } else if (TripleStoreType.SDB.equals(type)) { StoreDesc storeDesc = new StoreDesc( LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr)); - BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource( + BasicDataSource bds = WebappDaoSetup.makeBasicDataSource( getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); bds.setMaxActive(4); // for now, the SDB model makers should not use more // than a small handful of connections @@ -485,7 +486,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { ctx.setAttribute(rdbModelMaker, vjmm); } - public static void setVitroJenaSDBModelMaker(VitroJenaSDBModelMaker vsmm, + public static void setVitroJenaSDBModelMaker(ModelMaker vsmm, ServletContext ctx){ ctx.setAttribute(sdbModelMaker, vsmm); } @@ -510,7 +511,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { return vjmm; } - protected VitroJenaSDBModelMaker getVitroJenaSDBModelMaker(){ + protected ModelMaker getVitroJenaSDBModelMaker(){ return vsmm; } @@ -533,6 +534,15 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { return ConfigurationProperties.getBean(ctx).getProperty( "VitroConnection.DataSource.validationQuery", "SELECT 1"); } + + public static void setStartupDataset(Dataset dataset, ServletContext ctx) { + ctx.setAttribute("startupDataset", dataset); + } + + public static Dataset getStartupDataset(ServletContext ctx) { + Object o = ctx.getAttribute("startupDataset"); + return (o instanceof Dataset) ? ((Dataset) o) : null; + } protected OntModel ontModelFromContextAttribute(ServletContext ctx, String attribute) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelSetup.java deleted file mode 100644 index 7de262fc4..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelSetup.java +++ /dev/null @@ -1,239 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.servlet.setup; - -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import org.apache.commons.dbcp.BasicDataSource; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.Syntax; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase.TripleStoreType; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; -import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; - -/** - * Setup the ABox, TBox, inference and Union models. - * Also setup the OntModelSelectors. - */ -public class ModelSetup extends JenaDataSourceSetupBase -implements javax.servlet.ServletContextListener { - private static final Log log = LogFactory.getLog(ModelSetup.class); - - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - - BasicDataSource bds = getApplicationDataSource(ctx); - if( bds == null ){ - ss.fatal(this, "A DataSource must be setup before ModelSetup "+ - "is run. Make sure that JenaPersistentDataSourceSetup runs before "+ - "ModelSetup."); - return; - } - - setupModels(ctx,ss,bds); - } - - private void setupModels(ServletContext ctx, StartupStatus ss, BasicDataSource bds){ - log.info("Setting up model makers and union models"); - - /////////////////////////////////////////////////////////////// - //set up the OntModelSelectors - - OntModelSelectorImpl baseOms = new OntModelSelectorImpl(); - OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl(); - OntModelSelectorImpl unionOms = new OntModelSelectorImpl(); - - //Put OntModelSelectorImpl objs into the context - ModelContext.setOntModelSelector(unionOms, ctx); - ModelContext.setUnionOntModelSelector(unionOms, ctx); - // assertions and inferences - ModelContext.setBaseOntModelSelector(baseOms, ctx); - // assertions - ModelContext.setInferenceOntModelSelector(inferenceOms, ctx); - // inferences - - //add userAccountsModel to OntModelSelectors - OntModel userAccountsModel = ontModelFromContextAttribute( - ctx, "userAccountsOntModel"); - baseOms.setUserAccountsModel(userAccountsModel); - inferenceOms.setUserAccountsModel(userAccountsModel); - unionOms.setUserAccountsModel(userAccountsModel); - - //add display to OntModelSelectors - OntModel displayModel = ontModelFromContextAttribute( - ctx,DISPLAY_ONT_MODEL); - baseOms.setDisplayModel(displayModel); - inferenceOms.setDisplayModel(displayModel); - unionOms.setDisplayModel(displayModel); - - // The code below, which sets up the OntModelSelectors, controls whether - // each model is maintained in memory, in the DB, or both while the - // application is running. - - // Populate the three OntModelSelectors (BaseOntModel = assertions, - // InferenceOntModel = inferences and JenaOntModel = union of assertions - // and inferences) with the post-SDB-conversion models. - - // ABox assertions - Model aboxAssertions = makeDBModel( - bds, JenaDataSourceSetupBase.JENA_DB_MODEL, DB_ONT_MODEL_SPEC, - TripleStoreType.SDB, ctx); - Model listenableAboxAssertions = ModelFactory.createUnion( - aboxAssertions, ModelFactory.createDefaultModel()); - baseOms.setABoxModel( - ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, listenableAboxAssertions)); - - // ABox inferences - Model aboxInferences = makeDBModel( - bds, JenaDataSourceSetupBase.JENA_INF_MODEL, DB_ONT_MODEL_SPEC, - TripleStoreType.SDB, ctx); - Model listenableAboxInferences = ModelFactory.createUnion( - aboxInferences, ModelFactory.createDefaultModel()); - inferenceOms.setABoxModel(ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, listenableAboxInferences)); - - - // Since the TBox models are in memory, they do not have timeout issues - // like the like the ABox models do (and so don't need the extra step - // to make them listenable.) - - // TBox assertions - try { - Model tboxAssertionsDB = makeDBModel( - bds, JENA_TBOX_ASSERTIONS_MODEL, DB_ONT_MODEL_SPEC, - TripleStoreType.SDB, ctx); - OntModel tboxAssertions = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC); - - if (tboxAssertionsDB != null) { - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached tbox assertions into memory"); - tboxAssertions.add(tboxAssertionsDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load tbox assertions"); - } - - tboxAssertions.getBaseModel().register(new ModelSynchronizer( - tboxAssertionsDB)); - baseOms.setTBoxModel(tboxAssertions); - } catch (Throwable e) { - log.error("Unable to load tbox assertion cache from DB", e); - } - - // TBox inferences - try { - Model tboxInferencesDB = makeDBModel( - bds, JENA_TBOX_INF_MODEL, DB_ONT_MODEL_SPEC, - TripleStoreType.SDB, ctx); - OntModel tboxInferences = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC); - - if (tboxInferencesDB != null) { - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached tbox inferences into memory"); - tboxInferences.add(tboxInferencesDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load tbox inferences"); - } - - tboxInferences.getBaseModel().register(new ModelSynchronizer( - tboxInferencesDB)); - inferenceOms.setTBoxModel(tboxInferences); - } catch (Throwable e) { - log.error("Unable to load tbox inference cache from DB", e); - } - - // union ABox - OntModel unionABoxModel = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC,ModelFactory.createUnion( - baseOms.getABoxModel(), inferenceOms.getABoxModel())); - unionOms.setABoxModel(unionABoxModel); - - // union TBox - OntModel unionTBoxModel = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC,ModelFactory.createUnion( - baseOms.getTBoxModel(), inferenceOms.getTBoxModel())); - unionOms.setTBoxModel(unionTBoxModel); - - - // Application metadata model is cached in memory. - try { - - Model applicationMetadataModelDB = makeDBModel( - bds, JENA_APPLICATION_METADATA_MODEL, DB_ONT_MODEL_SPEC, - TripleStoreType.SDB, ctx); - OntModel applicationMetadataModel = - ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); - - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached application metadata model into memory"); - applicationMetadataModel.add(applicationMetadataModelDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load application metadata model " + - "assertions of size " + applicationMetadataModel.size()); - applicationMetadataModel.getBaseModel().register( - new ModelSynchronizer(applicationMetadataModelDB)); - - if (isFirstStartup()) { - applicationMetadataModel.add( - InitialJenaModelUtils.loadInitialModel( - ctx, getDefaultNamespace(ctx))); - - } else if (applicationMetadataModelDB.size() == 0) { - repairAppMetadataModel( - applicationMetadataModel, aboxAssertions, - aboxInferences); - } - - baseOms.setApplicationMetadataModel(applicationMetadataModel); - inferenceOms.setApplicationMetadataModel( - baseOms.getApplicationMetadataModel()); - unionOms.setApplicationMetadataModel( - baseOms.getApplicationMetadataModel()); - - } catch (Throwable e) { - log.error("Unable to load application metadata model cache from DB" - , e); - } - - // create TBox + ABox union models - OntModel baseUnion = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, - ModelFactory.createUnion(baseOms.getABoxModel(), - baseOms.getTBoxModel())); - baseOms.setFullModel(baseUnion); - ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx); - - log.info("Model makers and union set up"); - } - - @Override - public void contextDestroyed(ServletContextEvent arg0) { - // nothing to do. - - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java index 653392e1f..ebba991b6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java @@ -2,10 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFServiceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFServiceSetup.java new file mode 100644 index 000000000..63a0f3a18 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFServiceSetup.java @@ -0,0 +1,139 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ +package edu.cornell.mannlib.vitro.webapp.servlet.setup; + +import java.sql.SQLException; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.sdb.SDB; +import com.hp.hpl.jena.sdb.SDBFactory; +import com.hp.hpl.jena.sdb.Store; +import com.hp.hpl.jena.sdb.StoreDesc; +import com.hp.hpl.jena.sdb.sql.SDBConnection; +import com.hp.hpl.jena.sdb.store.DatabaseType; +import com.hp.hpl.jena.sdb.store.LayoutType; +import com.hp.hpl.jena.sdb.util.StoreUtils; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb.RDFServiceSDB; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql.RDFServiceSparql; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + +public class RDFServiceSetup extends JenaDataSourceSetupBase +implements javax.servlet.ServletContextListener { + private static final Log log = LogFactory.getLog(RDFServiceSetup.class); + + @Override + public void contextDestroyed(ServletContextEvent arg0) { + // nothing to do + } + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + try { + String endpointURI = ConfigurationProperties.getBean(sce).getProperty( + "VitroConnection.DataSource.endpointURI"); + if (endpointURI != null) { + useEndpoint(endpointURI, ctx); + } else { + useSDB(ctx, ss); + } + } catch (SQLException e) { + ss.fatal(this, "Exception in RDFServiceSetup", e); + } + } + + private void useEndpoint(String endpointURI, ServletContext ctx) { + RDFService rdfService = new RDFServiceSparql(endpointURI); + RDFServiceFactory rdfServiceFactory = new RDFServiceFactorySingle(rdfService); + RDFServiceUtils.setRDFServiceFactory(ctx, rdfServiceFactory); + } + + private void useSDB(ServletContext ctx, StartupStatus ss) throws SQLException { + BasicDataSource bds = getApplicationDataSource(ctx); + if( bds == null ){ + ss.fatal(this, "A DataSource must be setup before SDBSetup "+ + "is run. Make sure that JenaPersistentDataSourceSetup runs before "+ + "SDBSetup."); + return; + } + + // union default graph + SDB.getContext().set(SDB.unionDefaultGraph, true) ; + + StoreDesc storeDesc = makeStoreDesc(ctx); + setApplicationStoreDesc(storeDesc, ctx); + + Store store = connectStore(bds, storeDesc); + setApplicationStore(store, ctx); + + if (!isSetUp(store)) { + JenaPersistentDataSourceSetup.thisIsFirstStartup(); + setupSDB(ctx, store); + } + + RDFService rdfService = new RDFServiceSDB(bds, storeDesc); + RDFServiceFactory rdfServiceFactory = new RDFServiceFactorySingle(rdfService); + RDFServiceUtils.setRDFServiceFactory(ctx, rdfServiceFactory); + + log.info("SDB store ready for use"); + + } + + + /** + * Tests whether an SDB store has been formatted and populated for use. + * @param store + * @return + */ + 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, + JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL)) + .size() > 0; + } catch (Exception e) { + return false; + } + } + + public static StoreDesc makeStoreDesc(ServletContext ctx) { + String layoutStr = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.sdb.layout", "layout2/hash"); + String dbtypeStr = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.dbtype", "MySQL"); + return new StoreDesc( + LayoutType.fetch(layoutStr), + DatabaseType.fetch(dbtypeStr) ); + } + + public static Store connectStore(BasicDataSource bds, StoreDesc storeDesc) + throws SQLException { + SDBConnection conn = new SDBConnection(bds.getConnection()); + return SDBFactory.connectStore(conn, storeDesc); + } + + protected static void setupSDB(ServletContext ctx, Store store) { + log.info("Initializing SDB store"); + store.getTableFormatter().create(); + store.getTableFormatter().truncate(); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SDBSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SDBSetup.java deleted file mode 100644 index da71d65eb..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SDBSetup.java +++ /dev/null @@ -1,231 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vitro.webapp.servlet.setup; - -import java.sql.SQLException; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import org.apache.commons.dbcp.BasicDataSource; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.sdb.SDB; -import com.hp.hpl.jena.sdb.SDBFactory; -import com.hp.hpl.jena.sdb.Store; -import com.hp.hpl.jena.sdb.StoreDesc; -import com.hp.hpl.jena.sdb.sql.SDBConnection; -import com.hp.hpl.jena.sdb.store.DatabaseType; -import com.hp.hpl.jena.sdb.store.LayoutType; -import com.hp.hpl.jena.sdb.util.StoreUtils; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -public class SDBSetup extends JenaDataSourceSetupBase -implements javax.servlet.ServletContextListener { - private static final Log log = LogFactory.getLog(SDBSetup.class); - - @Override - public void contextDestroyed(ServletContextEvent arg0) { - // nothing to do - - } - - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - try { - setupSDB(ctx, ss); - log.info("SDB store ready for use"); - } catch (SQLException e) { - ss.fatal(this, "Exception in setupSDB", e); - } - } - - private void setupSDB(ServletContext ctx, StartupStatus ss) throws SQLException { - BasicDataSource bds = getApplicationDataSource(ctx); - if( bds == null ){ - ss.fatal(this, "A DataSource must be setup before SDBSetup "+ - "is run. Make sure that JenaPersistentDataSourceSetup runs before "+ - "SDBSetup."); - return; - } - - // union default graph - SDB.getContext().set(SDB.unionDefaultGraph, true) ; - - StoreDesc storeDesc = makeStoreDesc(ctx); - setApplicationStoreDesc(storeDesc, ctx); - - Store store = connectStore(bds, storeDesc); - setApplicationStore(store, ctx); - - if (!isSetUp(store)) { - JenaPersistentDataSourceSetup.thisIsFirstStartup(); - setupSDB(ctx, store); - } - } - - - /** - * Tests whether an SDB store has been formatted and populated for use. - * @param store - * @return - */ - 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, - JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL)) - .size() > 0; - } catch (Exception e) { - return false; - } - } - - public static StoreDesc makeStoreDesc(ServletContext ctx) { - String layoutStr = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.sdb.layout", "layout2/hash"); - String dbtypeStr = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.dbtype", "MySQL"); - return new StoreDesc( - LayoutType.fetch(layoutStr), - DatabaseType.fetch(dbtypeStr) ); - } - - public static Store connectStore(BasicDataSource bds, StoreDesc storeDesc) - throws SQLException { - SDBConnection conn = new SDBConnection(bds.getConnection()); - return SDBFactory.connectStore(conn, storeDesc); - } - - protected static void setupSDB(ServletContext ctx, Store store) { - setupSDB(ctx, store, ModelFactory.createDefaultModel(), - ModelFactory.createDefaultModel()); - } - - protected static void setupSDB(ServletContext ctx, Store store, - Model memModel, Model inferenceModel) { - log.info("Initializing SDB store"); - - store.getTableFormatter().create(); - store.getTableFormatter().truncate(); - - store.getTableFormatter().dropIndexes(); // improve load performance - - try { - - // This is a one-time copy of stored KB data - from a Jena RDB store - // to a Jena SDB store. In the process, we will also separate out - // the TBox from the Abox; these are in the same graph in pre-1.2 - // VIVO versions and will now be stored and maintained in separate - // models. Access to the Jena RDB data is through the - // OntModelSelectors that have been set up earlier in the current - // session by JenaPersistentDataSourceSetup.java. In the code - // below, note that the current getABoxModel() methods on the - // OntModelSelectors return a graph with both ABox and TBox data. - - OntModel submodels = ModelFactory - .createOntologyModel(MEM_ONT_MODEL_SPEC); - readOntologyFilesInPathSet(SUBMODELS, ctx, submodels); - - Model tboxAssertions = SDBFactory.connectNamedModel(store, - JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); - // initially putting the results in memory so we have a - // cheaper way of computing the difference when we copy the ABox - Model memTboxAssertions = ModelFactory.createDefaultModel(); - getTBoxModel(memModel, submodels, memTboxAssertions); - tboxAssertions.add(memTboxAssertions); - - Model tboxInferences = SDBFactory.connectNamedModel(store, - JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL); - // initially putting the results in memory so we have a - // cheaper way of computing the difference when we copy the ABox - Model memTboxInferences = ModelFactory.createDefaultModel(); - getTBoxModel(inferenceModel, submodels, memTboxInferences); - tboxInferences.add(memTboxInferences); - - Model aboxAssertions = SDBFactory.connectNamedModel(store, - JenaDataSourceSetupBase.JENA_DB_MODEL); - copyDifference(memModel, memTboxAssertions, aboxAssertions); - - Model aboxInferences = SDBFactory.connectNamedModel(store, - JenaDataSourceSetupBase.JENA_INF_MODEL); - copyDifference(inferenceModel, memTboxInferences, aboxInferences); - - // Set up the application metadata model - Model applicationMetadataModel = SDBFactory.connectNamedModel( - store, - JenaDataSourceSetupBase.JENA_APPLICATION_METADATA_MODEL); - getAppMetadata(memModel, applicationMetadataModel); - log.info("During initial SDB setup, created an application " - + "metadata model of size " - + applicationMetadataModel.size()); - - // remove application metadata from ABox model - aboxAssertions.remove(applicationMetadataModel); - aboxInferences.remove(applicationMetadataModel); - - // Make sure the reasoner takes into account the newly-set-up data. - SimpleReasonerSetup.setRecomputeRequired(ctx); - - } finally { - log.info("Adding indexes to SDB database tables."); - store.getTableFormatter().addIndexes(); - log.info("Indexes created."); - } - } - - /* - * Copy all statements from model 1 that are not in model 2 to model 3. - */ - private static void copyDifference(Model model1, Model model2, Model model3) { - - StmtIterator iter = model1.listStatements(); - - while (iter.hasNext()) { - Statement stmt = iter.next(); - if (!model2.contains(stmt)) { - model3.add(stmt); - } - } - - return; - } - - private static void getTBoxModel(Model fullModel, Model submodels, - Model tboxModel) { - - JenaModelUtils modelUtils = new JenaModelUtils(); - - Model tempModel = ModelFactory.createUnion(fullModel, submodels); - Model tempTBoxModel = modelUtils.extractTBox(tempModel); - - // copy intersection of tempTBoxModel and fullModel to tboxModel. - StmtIterator iter = tempTBoxModel.listStatements(); - - while (iter.hasNext()) { - Statement stmt = iter.next(); - if (fullModel.contains(stmt)) { - tboxModel.add(stmt); - } - } - - return; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index 19266ab7d..60a6ee5d8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -16,7 +16,6 @@ import javax.servlet.ServletContextListener; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.mindswap.pellet.PelletOptions; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; @@ -27,6 +26,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.ReasonerConfiguration; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasonerTBoxListener; @@ -45,6 +46,7 @@ public class SimpleReasonerSetup implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { + try { // set up Pellet reasoning for the TBox @@ -101,7 +103,9 @@ public class SimpleReasonerSetup implements ServletContextListener { // the simple reasoner will register itself as a listener to the ABox assertions - SimpleReasoner simpleReasoner = new SimpleReasoner(unionOms.getTBoxModel(), assertionsOms.getABoxModel(), inferencesOms.getABoxModel(), rebuildModel, scratchModel); + RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(); + SimpleReasoner simpleReasoner = new SimpleReasoner( + unionOms.getTBoxModel(), rdfService, inferencesOms.getABoxModel(), rebuildModel, scratchModel); sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner); StartupStatus ss = StartupStatus.getBean(ctx); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 72d011a81..59a99fe8b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -20,16 +20,8 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSDBSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java similarity index 50% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSDBSetup.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java index 458aa42fc..cb87bed44 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSDBSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; + import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -15,8 +17,10 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ResIterator; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; @@ -27,25 +31,33 @@ import com.hp.hpl.jena.util.ResourceUtils; import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.RDF; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; 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.RDFServiceModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase.TripleStoreType; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; +import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; /** * Primarily sets up webapp DAO factories. */ -public class WebappDaoSDBSetup extends JenaDataSourceSetupBase +public class WebappDaoSetup extends JenaDataSourceSetupBase implements javax.servlet.ServletContextListener { - private static final Log log = LogFactory.getLog(WebappDaoSDBSetup.class); + private static final Log log = LogFactory.getLog(WebappDaoSetup.class); @Override public void contextInitialized(ServletContextEvent sce) { @@ -56,11 +68,7 @@ public class WebappDaoSDBSetup extends JenaDataSourceSetupBase long startTime = System.currentTimeMillis(); setUpJenaDataSource(ctx, ss); log.info((System.currentTimeMillis() - startTime) / 1000 + - " seconds to set up SDB store"); - } catch (SQLException sqle) { - // SQL exceptions are fatal and should halt startup - log.error("Error using SQL database; startup aborted.", sqle); - ss.fatal(this, "Error using SQL database; startup aborted.", sqle); + " seconds to set up models and DAO factories"); } catch (Throwable t) { log.error("Throwable in " + this.getClass().getName(), t); ss.fatal(this, "Throwable in " + this.getClass().getName(), t); @@ -68,53 +76,158 @@ public class WebappDaoSDBSetup extends JenaDataSourceSetupBase } - private void setUpJenaDataSource(ServletContext ctx, StartupStatus ss) throws SQLException { + private void setUpJenaDataSource(ServletContext ctx, StartupStatus ss) { + OntModelSelectorImpl baseOms = new OntModelSelectorImpl(); + OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl(); + OntModelSelectorImpl unionOms = new OntModelSelectorImpl(); - BasicDataSource bds = getApplicationDataSource(ctx); - if( bds == null ){ - ss.fatal(this, "A DataSource must be setup before "+ WebappDaoSDBSetup.class.getName() + - "is run. Make sure that JenaPersistentDataSourceSetup runs before "+ - WebappDaoSDBSetup.class.getName() ); - return; + OntModel userAccountsModel = ontModelFromContextAttribute( + ctx, "userAccountsOntModel"); + baseOms.setUserAccountsModel(userAccountsModel); + inferenceOms.setUserAccountsModel(userAccountsModel); + unionOms.setUserAccountsModel(userAccountsModel); + + OntModel displayModel = ontModelFromContextAttribute( + ctx,DISPLAY_ONT_MODEL); + baseOms.setDisplayModel(displayModel); + inferenceOms.setDisplayModel(displayModel); + unionOms.setDisplayModel(displayModel); + + RDFServiceFactory rdfServiceFactory = RDFServiceUtils.getRDFServiceFactory(ctx); + RDFService rdfService = rdfServiceFactory.getRDFService(); + Dataset dataset = new RDFServiceDataset(rdfService); + setStartupDataset(dataset, ctx); + + // ABox assertions + Model aboxAssertions = dataset.getNamedModel( + JenaDataSourceSetupBase.JENA_DB_MODEL); + baseOms.setABoxModel( + ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, aboxAssertions)); + + // ABox inferences + Model aboxInferences = dataset.getNamedModel( + JenaDataSourceSetupBase.JENA_INF_MODEL); + inferenceOms.setABoxModel(ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, aboxInferences)); + + // TBox assertions + try { + Model tboxAssertionsDB = dataset.getNamedModel( + JENA_TBOX_ASSERTIONS_MODEL); + OntModel tboxAssertions = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC); + + if (tboxAssertionsDB != null) { + long startTime = System.currentTimeMillis(); + System.out.println( + "Copying cached tbox assertions into memory"); + tboxAssertions.add(tboxAssertionsDB); + System.out.println((System.currentTimeMillis() - startTime) + / 1000 + " seconds to load tbox assertions"); + } + + tboxAssertions.getBaseModel().register(new ModelSynchronizer( + tboxAssertionsDB)); + + baseOms.setTBoxModel(tboxAssertions); + } catch (Throwable e) { + log.error("Unable to load tbox assertion cache from DB", e); } - //Get the OntModelSelectors - OntModelSelectorImpl baseOms = - (OntModelSelectorImpl) ModelContext.getBaseOntModelSelector(ctx); - OntModelSelectorImpl inferenceOms = - (OntModelSelectorImpl) ModelContext.getInferenceOntModelSelector(ctx); - OntModelSelectorImpl unionOms = - (OntModelSelectorImpl) ModelContext.getUnionOntModelSelector(ctx); + // TBox inferences + try { + Model tboxInferencesDB = dataset.getNamedModel(JENA_TBOX_INF_MODEL); + OntModel tboxInferences = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC); + + if (tboxInferencesDB != null) { + long startTime = System.currentTimeMillis(); + System.out.println( + "Copying cached tbox inferences into memory"); + tboxInferences.add(tboxInferencesDB); + System.out.println((System.currentTimeMillis() - startTime) + / 1000 + " seconds to load tbox inferences"); + } + + tboxInferences.getBaseModel().register(new ModelSynchronizer( + tboxInferencesDB)); + inferenceOms.setTBoxModel(tboxInferences); + } catch (Throwable e) { + log.error("Unable to load tbox inference cache from DB", e); + } + + // union ABox + OntModel unionABoxModel = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC,ModelFactory.createUnion( + baseOms.getABoxModel(), inferenceOms.getABoxModel())); + unionOms.setABoxModel(unionABoxModel); - /////////////////////////////////////////////////////////////// - // Check for namespace mismatch + // union TBox + OntModel unionTBoxModel = ModelFactory.createOntologyModel( + MEM_ONT_MODEL_SPEC,ModelFactory.createUnion( + baseOms.getTBoxModel(), inferenceOms.getTBoxModel())); + unionOms.setTBoxModel(unionTBoxModel); + + + // Application metadata model is cached in memory. + try { + + Model applicationMetadataModelDB = dataset.getNamedModel( + JENA_APPLICATION_METADATA_MODEL); + OntModel applicationMetadataModel = + ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); + + long startTime = System.currentTimeMillis(); + System.out.println( + "Copying cached application metadata model into memory"); + applicationMetadataModel.add(applicationMetadataModelDB); + System.out.println((System.currentTimeMillis() - startTime) + / 1000 + " seconds to load application metadata model " + + "assertions of size " + applicationMetadataModel.size()); + applicationMetadataModel.getBaseModel().register( + new ModelSynchronizer(applicationMetadataModelDB)); + + if (applicationMetadataModel.size()== 0 /* isFirstStartup() */) { + applicationMetadataModel.add( + InitialJenaModelUtils.loadInitialModel( + ctx, getDefaultNamespace(ctx))); + + } + + baseOms.setApplicationMetadataModel(applicationMetadataModel); + inferenceOms.setApplicationMetadataModel( + baseOms.getApplicationMetadataModel()); + unionOms.setApplicationMetadataModel( + baseOms.getApplicationMetadataModel()); + + } catch (Throwable e) { + log.error("Unable to load application metadata model cache from DB" + , e); + } checkForNamespaceMismatch( baseOms.getApplicationMetadataModel(), ctx ); - ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); - - /////////////////////////////////////////////////////////////// - // first startup? if (isFirstStartup()) { loadDataFromFilesystem(baseOms, ctx); } - log.info("Setting up DAO factories"); - - /////////////////////////////////////////////////////////////// - //create assertions webapp DAO factory + log.info("Setting up union models and DAO factories"); - StoreDesc storeDesc = getApplicationStoreDesc(ctx); + // create TBox + ABox union models and set up webapp DAO factories + OntModel baseUnion = ModelFactory.createOntologyModel( + OntModelSpec.OWL_MEM, + ModelFactory.createUnion(baseOms.getABoxModel(), + baseOms.getTBoxModel())); + baseOms.setFullModel(baseUnion); + ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx); WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); config.setDefaultNamespace(getDefaultNamespace(ctx)); WebappDaoFactory baseWadf = new WebappDaoFactorySDB( - baseOms, bds, storeDesc, config, + rdfService, baseOms, config, WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY); ctx.setAttribute("assertionsWebappDaoFactory",baseWadf); - /////////////////////////////////////////////////////////////// - //create inference webapp DAO factory - OntModel inferenceUnion = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, ModelFactory.createUnion( @@ -123,35 +236,40 @@ public class WebappDaoSDBSetup extends JenaDataSourceSetupBase inferenceOms.setFullModel(inferenceUnion); ModelContext.setInferenceOntModel(inferenceOms.getFullModel(), ctx); WebappDaoFactory infWadf = new WebappDaoFactorySDB( - inferenceOms, bds, storeDesc, config, + rdfService, inferenceOms, config, WebappDaoFactorySDB.SDBDatasetMode.INFERENCES_ONLY); ctx.setAttribute("deductionsWebappDaoFactory", infWadf); - /////////////////////////////////////////////////////////////// - //create default union webapp DAO factory - OntModel masterUnion = ModelFactory.createOntologyModel( - DB_ONT_MODEL_SPEC, makeDBModel( - bds, WebappDaoFactorySDB.UNION_GRAPH, - DB_ONT_MODEL_SPEC, TripleStoreType.SDB, ctx)); + DB_ONT_MODEL_SPEC, dataset.getDefaultModel()); unionOms.setFullModel(masterUnion); ctx.setAttribute("jenaOntModel", masterUnion); WebappDaoFactory wadf = new WebappDaoFactorySDB( - unionOms, bds, storeDesc, config); - ctx.setAttribute("webappDaoFactory",wadf); + rdfService, unionOms, config); + ctx.setAttribute("webappDaoFactory",wadf); + + ModelContext.setOntModelSelector(unionOms, ctx); + ModelContext.setUnionOntModelSelector(unionOms, ctx); + // assertions and inferences + ModelContext.setBaseOntModelSelector(baseOms, ctx); + // assertions + ModelContext.setInferenceOntModelSelector(inferenceOms, ctx); + // inferences + + ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx); VitroJenaModelMaker vjmm = getVitroJenaModelMaker(); setVitroJenaModelMaker(vjmm, ctx); makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx); - VitroJenaSDBModelMaker vsmm = getVitroJenaSDBModelMaker(); + RDFServiceModelMaker vsmm = new RDFServiceModelMaker(rdfServiceFactory); setVitroJenaSDBModelMaker(vsmm, ctx); //bdc34: I have no reason for vsmm vs vjmm. //I don't know what are the implications of this choice. setVitroModelSource( new VitroModelSource(vsmm,ctx), ctx); - log.info("DAOs set up"); + log.info("Model makers set up"); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java index 5c76f0e1b..c523e3a5e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java @@ -100,7 +100,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{ } } }else{ - log.error("classgroup " + classGroupUri + " does not exist in the system"); + throw new RuntimeException("classgroup " + classGroupUri + " does not exist in the system"); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 61bbe0e6e..a080cde0b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -207,7 +207,7 @@ public class GroupedPropertyList extends BaseTemplateModel { ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri); if (op == null) { - log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI()"); + log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")"); } else if (op.getURI() == null) { log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()"); } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java index 9d8eb4638..6569e28d0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java @@ -111,7 +111,8 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { } public String getAddUrl() { - return addUrl; + //log.info("addUrl=" + addUrl); + return (addUrl != null) ? addUrl : ""; } public Map getVerboseDisplay() { diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index da63256dc..5ab45b8b0 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -16,13 +16,12 @@ edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup ### this listener must be run before SDBSetup, all models setups and WebappDaoSetup ### edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaPersistentDataSourceSetup -edu.cornell.mannlib.vitro.webapp.servlet.setup.SDBSetup +edu.cornell.mannlib.vitro.webapp.servlet.setup.RDFServiceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ApplicationModelSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup -edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelSetup -edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup +edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase