7.11 Support for Server-Side APIs

This section describes some of the RDF Graph features that are exposed by RDF Graph support for Apache Jena.

For comprehensive documentation of the API calls that support the available features, see the RDF Graph support for Apache Jena reference information (Javadoc). For additional information about the server-side features exposed by the support for Apache Jena, see the relevant chapters in this manual.

7.11.1 RDF Graph Collections Support

RDF graph collections (explained in RDF Graph Collections) are specified in the GraphOracleSem constructor, and they are handled transparently. If an RDF graph collection exists for the model-rulebase combination, it is used in query answering; if such an RDF graph collection does not exist, it is created in the database.

Note:

RDF graph collection support through the support for Apache Jena is available only with Oracle Database Release 11.2 or later.

The following example reuses an existing RDF graph collection.

String modelName = "EX";
String m1 = "EX_1";
 
ModelOracleSem defaultModel = 
  ModelOracleSem.createOracleSemModel(oracle, modelName);
 
// create these RDF graphs in case they don't exist
ModelOracleSem model1 = ModelOracleSem.createOracleSemModel(oracle, m1);
 
String vmName = "VM_" + modelName;
 
 
//create an RDF graph collection containing EX and EX_1
oracle.executeCall(
"begin sem_apis.create_virtual_model(?,sem_models('"+ m1 + "','"+ modelName+"'),null); end;",vmName);
 
String[] modelNames = {m1};
String[] rulebaseNames = {};
 
Attachment attachment = Attachment.createInstance(modelNames, rulebaseNames, 
InferenceMaintenanceMode.NO_UPDATE, QueryOptions.ALLOW_QUERY_VALID_AND_DUP);
 
// vmName is passed to the constructor, so GraphOracleSem will use the RDF graph collection 
// named vmname (if the current user has read privileges on it)
GraphOracleSem graph = new GraphOracleSem(oracle, modelName, attachment, vmName);
graph.add(Triple.create(Node.createURI("urn:alice"),
                        Node.createURI("http://xmlns.com/foaf/0.1/mbox"),
                        Node.createURI("mailto:alice@example")));
ModelOracleSem model = new ModelOracleSem(graph);	  
 
String queryString =
 
   " SELECT ?subject ?object WHERE { ?subject ?p ?object } ";
 
Query query = QueryFactory.create(queryString) ;
QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
 
try {
   ResultSet results = qexec.execSelect() ;
   for ( ; results.hasNext() ; ) {
      QuerySolution soln = results.nextSolution() ;
      psOut.println("soln " + soln);
   }
} 
finally { 
   qexec.close() ; 
}
 
OracleUtils.dropSemanticModel(oracle, modelName);
OracleUtils.dropSemanticModel(oracle, m1);
 
oracle.dispose();

You can also use the GraphOracleSem constructor to create an RDF graph collection, as in the following example:

GraphOracleSem graph = new GraphOracleSem(oracle, modelName, attachment, true);

In this example, the fourth parameter (true) specifies that an RDF graph collection needs to be created for the specified modelName and attachment.

7.11.2 Connection Pooling Support

Oracle Database Connection Pooling is provided through the support for Apache Jena OraclePool class. Once this class is initialized, it can return Oracle objects out of its pool of available connections. Oracle objects are essentially database connection wrappers. After dispose is called on the Oracle object, the connection is returned to the pool. More information about using OraclePool can be found in the API reference information (Javadoc).

The following example sets up an OraclePool object with five (5) initial connections.

public static void main(String[] args) throws Exception
  {	
    String szJdbcURL = args[0];
    String szUser    = args[1];
    String szPasswd  = args[2];
    String szModelName = args[3];
 
    // test with connection properties 
    java.util.Properties prop = new java.util.Properties();
    prop.setProperty("MinLimit", "2");     // the cache size is 2 at least 
    prop.setProperty("MaxLimit", "10");
    prop.setProperty("InitialLimit", "2"); // create 2 connections at startup
    prop.setProperty("InactivityTimeout", "1800");    //  seconds
    prop.setProperty("AbandonedConnectionTimeout", "900");  //  seconds
    prop.setProperty("MaxStatementsLimit", "10");
    prop.setProperty("PropertyCheckInterval", "60"); // seconds
 
    System.out.println("Creating OraclePool");
    OraclePool op = new OraclePool(szJdbcURL, szUser, szPasswd, prop, 
               "OracleSemConnPool");
    System.out.println("Done creating OraclePool");
 
    // grab an Oracle and do something with it
    System.out.println("Getting an Oracle from OraclePool");
    Oracle oracle = op.getOracle();
    System.out.println("Done");
    System.out.println("Is logical connection:" +
        oracle.getConnection().isLogicalConnection());
    GraphOracleSem g = new GraphOracleSem(oracle, szModelName);
    g.add(Triple.create(Node.createURI("u:John"), 
                        Node.createURI("u:parentOf"), 
                        Node.createURI("u:Mary")));
    g.close();
    // return the Oracle back to the pool
    oracle.dispose();
    
    // grab another Oracle and do something else 
    System.out.println("Getting an Oracle from OraclePool");
    oracle = op.getOracle();
    System.out.println("Done");
    System.out.println("Is logical connection:" +
        oracle.getConnection().isLogicalConnection());
    g = new GraphOracleSem(oracle, szModelName);
    g.add(Triple.create(Node.createURI("u:John"), 
                        Node.createURI("u:parentOf"), 
                        Node.createURI("u:Jack")));
    g.close();
    
    OracleUtils.dropSemanticModel(oracle, szModelName); 
    
    // return the Oracle object back to the pool
    oracle.dispose();
}

7.11.3 RDF Graph PL/SQL Interfaces

Several RDF PL/SQL subprograms are available through the support for Apache Jena. Table 7-2 lists the subprograms and their corresponding Java class and methods.

Table 7-2 PL/SQL Subprograms and Corresponding RDF graph support for Apache Jena Java Class and Methods

PL/SQL Subprogram Corresponding Java Class and Methods

SEM_APIS.DROP_RDF_GRAPH

OracleUtils.dropSemanticModel

SEM_APIS.MERGE_RDF_GRAPHS

OracleUtils.mergeModels

SEM_APIS.SWAP_NAMES

OracleUtils.swapNames

SEM_APIS.REMOVE_DUPLICATES

OracleUtils.removeDuplicates

SEM_APIS.RENAME_RDF_GRAPH

OracleUtils.renameModels

For information about these PL/SQL utility subprograms, see the reference information in SEM_APIS Package Subprograms. For information about the corresponding Java class and methods, see the RDF graph support for Apache Jena API Reference documentation (Javadoc).

7.11.4 Inference Options

You can add options to inferred graph calls by using the following methods in the Attachment class (in package oracle.spatial.rdf.client.jena):

public void setUseLocalInference(boolean useLocalInference)
public boolean getUseLocalInference()
 
public void setDefGraphForLocalInference(String defaultGraphName)
public String getDefGraphForLocalInference()
 
public String getInferenceOption()
public void setInferenceOption(String inferenceOption)

Example 7-8 Specifying Inference Options

For more information about these methods, see the Javadoc.

Example 7-8 enables parallel inference (with a degree of 4) and RAW format when creating an inferred graph. The example also uses the performInference method to create the inferred graph (comparable to using the SEM_APIS.CREATE_INFERRED_GRAPH PL/SQL procedure).

import java.io.*;
import org.apache.jena.query.*;
import oracle.spatial.rdf.client.jena.*;
import org.apache.jena.update.*;
import org.apache.jena.sparql.core.DatasetImpl;
 
public class TestNewInference
{
  public static void main(String[] args) throws Exception
  {
    String szJdbcURL = args[0];
    String szUser    = args[1];
    String szPasswd  = args[2];
 
    PrintStream psOut = System.out;
 
    Oracle oracle = new Oracle(szJdbcURL, szUser, szPasswd);
    
    String szTBoxName = "test_new_tbox";
    {
      // First construct a TBox and load a few axioms
      ModelOracleSem modelTBox = ModelOracleSem.createOracleSemModel(oracle, szTBoxName);
      String insertString =  
        " PREFIX my:  <http://my.com/> " +
        " PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#> " +
        " INSERT DATA "                                     +
        " { my:C1  rdfs:subClassOf my:C2 .                " +
        "   my:C2  rdfs:subClassOf my:C3 .                " +
        "   my:C3  rdfs:subClassOf my:C4 .                " +
        " }   ";
      UpdateAction.parseExecute(insertString,  modelTBox);
      modelTBox.close();
    }
 
    String szABoxName = "test_new_abox";
    {
      // Construct an ABox and load a few quads
      ModelOracleSem modelABox = ModelOracleSem.createOracleSemModel(oracle, szABoxName);
      DatasetGraphOracleSem dataset = DatasetGraphOracleSem.createFrom(modelABox.getGraph());
      modelABox.close();
 
      String insertString =  
        " PREFIX my:    <http://my.com/> " +
        " PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
        " INSERT DATA                                                 " +
        " { GRAPH my:G1 { my:I1  rdf:type my:C1 .                     " +
        "                 my:I2  rdf:type my:C2 .                     " +
        "               }                                             " +
        " };                                                          " +
        " INSERT DATA                                                 " +
        " { GRAPH my:G2 { my:J1  rdf:type my:C3 .                     " +
        "               }                                             " +
        " }    ";
      UpdateAction.parseExecute(insertString,  dataset);
      dataset.close();
    }
 
 
    String[] attachedModels = new String[1];
    attachedModels[0] = szTBoxName;
 
    String[] attachedRBs = {"OWL2RL"};
 
    Attachment attachment = Attachment.createInstance(
        attachedModels, attachedRBs,
        InferenceMaintenanceMode.NO_UPDATE,
        QueryOptions.ALLOW_QUERY_INVALID);
 
    // We are going to run named graph based local inference
    attachment.setUseLocalInference(true);
 
    // Set the default graph (TBox)
    attachment.setDefGraphForLocalInference(szTBoxName);
 
    // Set the inference option to use parallel inference 
    // with a degree of 4, and RAW format.
    attachment.setInferenceOption("DOP=4,RAW8=T");
 
    GraphOracleSem graph = new GraphOracleSem(
        oracle, 
        szABoxName, 
        attachment
        );
    DatasetGraphOracleSem dsgos = DatasetGraphOracleSem.createFrom(graph);
    graph.close();
 
    // Invoke create_inferred_graph PL/SQL API
    dsgos.performInference();
 
    psOut.println("TestNewInference: # of inferred graph " + 
        Long.toString(dsgos.getInferredGraphSize()));
 
    String queryString = 
      " SELECT ?g ?s ?p ?o WHERE {  GRAPH ?g {?s ?p ?o } } " ;
 
    Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);
    QueryExecution qexec = QueryExecutionFactory.create(
        query, DatasetImpl.wrap(dsgos));
    ResultSet results = qexec.execSelect();
 
    ResultSetFormatter.out(psOut, results);
 
    dsgos.close();
    oracle.dispose();
  }
}

The output of Example 7-8 is as follows.

TestNewInference: # of inferred graph 9
 
--------------------------------------------------------------------------------------------------------------------
| g                  | s                  | p                                                 | o                  |
====================================================================================================================
| <http://my.com/G1> | <http://my.com/I2> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C3> |
| <http://my.com/G1> | <http://my.com/I2> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C2> |
| <http://my.com/G1> | <http://my.com/I2> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C4> |
| <http://my.com/G1> | <http://my.com/I1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C3> |
| <http://my.com/G1> | <http://my.com/I1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C1> |
| <http://my.com/G1> | <http://my.com/I1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C2> |
| <http://my.com/G1> | <http://my.com/I1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C4> |
| <http://my.com/G2> | <http://my.com/J1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C3> |
| <http://my.com/G2> | <http://my.com/J1> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://my.com/C4> |
--------------------------------------------------------------------------------------------------------------------

For information about using OWL inferencing, see Using OWL Inferencing.

7.11.5 PelletInfGraph Class Support Deprecated

The support for the PelletInfGraph class within the support for Apache Jena is deprecated. You should instead use the more optimized Oracle/Pellet integration through the PelletDb OWL 2 reasoner for Oracle Database.