8.14 Oracle RDF Graph Adapter for Eclipse RDF4Jを使用した問合せの例
この項では、Oracle RDF Graph Adapter for Eclipse RDF4Jを使用するための問合せの例を示します。
これらの例を実行するには、Javaコードでアダプタを使用するためのサポート・ライブラリで説明されているすべてのサポート・ライブラリがCLASSPATH
定義に含まれていることを確認します。
- コード例をJavaソース・ファイルに含めます。
CP
という名前のCLASSPATH
環境変数を定義して、関連するjarファイルを含めます。たとえば、次のように定義できます。setenv CP .:ojdbc8.jar:ucp.jar:oracle-rdf4j-adapter-4.3.14-20250106.jar:sdordf-23.6.0-20241122.jar: sdordf-client-23.6.0-20241122.jar:sdoutl-23.6.0-20241122.jar:log4j-api-2.24.2.jar:log4j-core-2.24.2.jar: log4j-slf4j-impl-2.24.2.jar:slf4j-api-1.7.36.jar:eclipse-rdf4j-4.3.14-onejar.jar:commons-io-2.14.0.jar
ノート:
前述のsetenv
コマンドは、jarファイルが現在のディレクトリにあることを前提としています。コマンドを変更して、これらのjarファイルの環境内の場所を示す必要がある場合があります。- Javaソース・ファイルをコンパイルします。たとえば、ソース・ファイル
Test.java
をコンパイルするには、次のコマンドを実行します。javac -classpath $CP Test.java
- 次のコマンドを実行することで、コンパイルされたファイルを、所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークの
TestModel
という名前のRDFグラフを実行します。java -classpath $CP Test jdbc:oracle:thin:@localhost:1521:orcl scott <password-for-scott> TestModel scott net1
8.14.1 例1: 基本操作
例8-5に、add文やremove文などの基本操作を実行するBasicOper.java
ファイルを示します。
例8-5 基本操作
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.sail.SailException;
public class BasicOper {
public static void main(String[] args) throws ConnectionSetupException, SQLException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
OracleSailConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
ValueFactory f = sr.getValueFactory();
conn = store.getConnection();
// create some resources and literals to make statements out of
IRI p = f.createIRI("http://p");
IRI domain = f.createIRI("http://www.w3.org/2000/01/rdf-schema#domain");
IRI cls = f.createIRI("http://cls");
IRI a = f.createIRI("http://a");
IRI b = f.createIRI("http://b");
IRI ng1 = f.createIRI("http://ng1");
conn.addStatement(p, domain, cls);
conn.addStatement(p, domain, cls, ng1);
conn.addStatement(a, p, b, ng1);
psOut.println("size for given contexts " + ng1 + ": " + conn.size(ng1));
// returns OracleStatements
CloseableIteration < ?extends Statement, SailException > it;
int cnt;
// retrieves all statements that appear in the repository(regardless of context)
cnt = 0;
it = conn.getStatements(null, null, null, false);
while (it.hasNext()) {
Statement stmt = it.next();
psOut.println("getStatements: stmt#" + (++cnt) + ":" + stmt.toString());
}
it.close();
conn.removeStatements(null, null, null, ng1);
psOut.println("size of context " + ng1 + ":" + conn.size(ng1));
conn.removeAll();
psOut.println("size of store: " + conn.size());
}
finally {
if (conn != null && conn.isOpen()) {
conn.close();
}
if (op != null && op.getOracleDB() != null)
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
if (sr != null) sr.shutDown();
if (store != null) store.shutDown();
if (op != null) op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP BasicOper.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP BasicOper jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel scott net1
java
コマンドの出力は、次のようになります。
size for given contexts http://ng1: 2
getStatements: stmt#1: (http://a, http://p, http://b) [http://ng1]
getStatements: stmt#2: (http://p, http://www.w3.org/2000/01/rdf-schema#domain, http://cls) [http://ng1]
getStatements: stmt#3: (http://p, http://www.w3.org/2000/01/rdf-schema#domain, http://cls) [null]
size of context http://ng1:0
size of store: 0
8.14.2 例2: TRIG形式でのデータ・ファイルの追加
LoadFile.java
ファイルを示します。
例8-6 TRIG形式のデータ・ファイルの追加
import java.io. * ;
import java.sql.SQLException;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.RepositoryException;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.rio.RDFFormat;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
public class LoadFile {
public static void main(String[] args) throws ConnectionSetupException,
SQLException, SailException, RDFParseException, RepositoryException,
IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String trigFile = args[4];
String networkOwner = (args.length > 6) ? args[5] : null;
String networkName = (args.length > 6) ? args[6] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection repConn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
repConn = sr.getConnection();
psOut.println("testBulkLoad: start: before-load Size=" + repConn.size());
repConn.add(new File(trigFile), "http://my.com/", RDFFormat.TRIG);
repConn.commit();
psOut.println("size " + Long.toString(repConn.size()));
}
finally {
if (repConn != null) {
repConn.close();
}
if (op != null) OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
if (sr != null) sr.shutDown();
if (store != null) store.shutDown();
if (op != null) op.close();
}
}
}
この例を実行するため、次のようなサンプルのTriGデータ・ファイルがtest.trig
という名前で作成されているとします。
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix swp: <http://www.w3.org/2004/03/trix/swp-1/>.
@prefix dc: <http://purl.org/dc/elements/1.1/>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix ex: <http://example.org/>.
@prefix : <http://example.org/>.
# default graph
{
<http://example.org/bob> dc:publisher "Bob Hacker".
<http://example.org/alice> dc:publisher "Alice Hacker".
}
:bob{
_:a foaf:mbox <mailto:bob@oldcorp.example.org>.
}
:alice{
_:a foaf:name "Alice".
_:a foaf:mbox <mailto:alice@work.example.org>.
}
:jack {
_:a foaf:name "Jack".
_:a foaf:mbox <mailto:jack@oracle.example.org>.
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP LoadFile.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP LoadFile jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel ./test.trig scott net1
java
コマンドの出力は、次のようになります。
testBulkLoad: start: before-load Size=0
size 7
8.14.3 例3: 単純な問合せ
SimpleQuery.java
ファイルを示します。
例8-7 単純な問合せ
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class SimpleQuery {
public static void main(String[] args) throws ConnectionSetupException, SQLException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
ValueFactory f = sr.getValueFactory();
conn = sr.getConnection();
// create some resources and literals to make statements out of
IRI alice = f.createIRI("http://example.org/people/alice");
IRI name = f.createIRI("http://example.org/ontology/name");
IRI person = f.createIRI("http://example.org/ontology/Person");
Literal alicesName = f.createLiteral("Alice");
conn.clear(); // to start from scratch
conn.add(alice, RDF.TYPE, person);
conn.add(alice, name, alicesName);
conn.commit();
//run a query against the repository
String queryString =
"PREFIX ex: <http://example.org/ontology/>\n" +
"SELECT * WHERE {?x ex:name ?y}\n" +
"ORDER BY ASC(STR(?y)) LIMIT 1 ";
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("value of x: " + bindingSet.getValue("x"));
psOut.println("value of y: " + bindingSet.getValue("y"));
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SimpleQuery.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SimpleQuery jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel scott net1
java
コマンドの出力は、次のようになります。
value of x: http://example.org/people/alice
value of y: "Alice"
8.14.4 例4: 単純なバルク・ロード
SimpleBulkload.java
ファイルを示します。
例8-8 単純なバルク・ロード
import java.io. * ;
import java.sql.SQLException;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.repository.RepositoryException;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.repository.Repository;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
public class SimpleBulkLoad {
public static void main(String[] args) throws ConnectionSetupException, SQLException,
SailException, RDFParseException, RepositoryException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String filename = args[4]; // N-TRIPLES file
String networkOwner = (args.length > 6) ? args[5] : null;
String networkName = (args.length > 6) ? args[6] : null;
OraclePool op = new OraclePool(jdbcUrl, user, password);
OracleSailStore store = new OracleSailStore(op, model, networkOwner, networkName);
OracleSailConnection osc = store.getConnection();
Repository sr = new OracleRepository(store);
ValueFactory f = sr.getValueFactory();
try {
psOut.println("testBulkLoad: start");
FileInputStream fis = new
FileInputStream(filename);
long loadBegin = System.currentTimeMillis();
IRI ng1 = f.createIRI("http://QuadFromTriple");
osc.getBulkUpdateHandler().addInBulk(
fis, "http://abc", // baseURI
RDFFormat.NTRIPLES, // dataFormat
null, // tablespaceName
50, // batchSize
null, // flags
ng1 // Resource... for contexts
);
long loadEnd = System.currentTimeMillis();
long size_no_contexts = osc.size((Resource) null);
long size_all_contexts = osc.size();
psOut.println("testBulkLoad: " + (loadEnd - loadBegin) +
"ms. Size:" + " NO_CONTEXTS=" + size_no_contexts + " ALL_CONTEXTS=" + size_all_contexts);
// cleanup
osc.removeAll();
psOut.println("size of store: " + osc.size());
}
finally {
if (osc != null && osc.isOpen()) osc.close();
if (op != null) OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
if (sr != null) sr.shutDown();
if (store != null) store.shutDown();
if (op != null) op.close();
}
}
}
この例を実行するため、次のようなサンプルのntripleデータ・ファイルがtest.ntriples
という名前で作成されているとします。
<urn:JohnFrench> <urn:name> "John".
<urn:JohnFrench> <urn:speaks> "French".
<urn:JohnFrench> <urn:height> <urn:InchValue>.
<urn:InchValue> <urn:value> "63".
<urn:InchValue> <urn:unit> "inch".
<http://data.linkedmdb.org/movie/onto/genreNameChainElem1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://data.linkedmdb.org/movie/genre>.
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SimpleBulkLoad.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SimpleBulkLoad jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel ./test.ntriples scott net1
java
コマンドの出力は、次のようになります。
testBulkLoad: start
testBulkLoad: 8222ms.
Size: NO_CONTEXTS=0 ALL_CONTEXTS=6
size of store: 0
8.14.5 例5: RDF/XMLのバルク・ロード
BulkLoadRDFXML.java
ファイルを示します。
例8-9 RDF/XMLのバルク・ロード
import java.io. * ;
import java.sql.SQLException;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.RepositoryException;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.sail.SailException;
import org.eclipse.rdf4j.rio.RDFFormat;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
public class BulkLoadRDFXML {
public static void main(String[] args) throws
ConnectionSetupException, SQLException, SailException,
RDFParseException, RepositoryException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String rdfxmlFile = args[4]; // RDF/XML-format data file
String networkOwner = (args.length > 6) ? args[5] : null;
String networkName = (args.length > 6) ? args[6] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
OracleSailConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = store.getConnection();
FileInputStream fis = new FileInputStream(rdfxmlFile);
psOut.println("testBulkLoad: start: before-load Size=" + conn.size());
long loadBegin = System.currentTimeMillis();
conn.getBulkUpdateHandler().addInBulk(
fis,
"http://abc", // baseURI
RDFFormat.RDFXML, // dataFormat
null, // tablespaceName
null, // flags
null, // StatusListener
(Resource[]) null // Resource...for contexts
);
long loadEnd = System.currentTimeMillis();
psOut.println("testBulkLoad: " + (loadEnd - loadBegin) + "ms. Size=" + conn.size() + "\n");
}
finally {
if (conn != null && conn.isOpen()) {
conn.close();
}
if (op != null) OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
if (sr != null) sr.shutDown();
if (store != null) store.shutDown();
if (op != null) op.close();
}
}
}
この例を実行するため、次のようなサンプル・ファイルがRdfXmlData.rdfxml
という名前で作成されているとします。
<?xml version="1.0"?>
<!DOCTYPE owl [
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
]>
<rdf:RDF
xmlns = "http://a/b#" xml:base = "http://a/b#" xmlns:my = "http://a/b#"
xmlns:owl = "http://www.w3.org/2002/07/owl#"
xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs= "http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema#">
<owl:Class rdf:ID="Color">
<owl:oneOf rdf:parseType="Collection">
<owl:Thing rdf:ID="Red"/>
<owl:Thing rdf:ID="Blue"/>
</owl:oneOf>
</owl:Class>
</rdf:RDF>
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP BulkLoadRDFXML.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP BulkLoadRDFXML jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel ./RdfXmlData.rdfxml scott net1
java
コマンドの出力は、次のようになります。
testBulkLoad: start: before-load Size=0
testBulkLoad: 6732ms. Size=8
8.14.6 例6: SPARQL ASK問合せ
SparqlASK.java
ファイルを示します。
例8-10 SPARQL ASK問合せ
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailRepositoryConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.query.BooleanQuery;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class SparqlASK {
public static void main(String[] args) throws ConnectionSetupException, SQLException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
OracleSailConnection osc =
(OracleSailConnection)((OracleSailRepositoryConnection) conn).getSailConnection();
ValueFactory vf = sr.getValueFactory();
IRI p = vf.createIRI("http://p");
IRI cls = vf.createIRI("http://cls");
conn.clear();
conn.add(p, RDFS.DOMAIN, cls);
conn.commit();
osc.analyze(); // analyze the semantic model
osc.analyzeApplicationTable(); // and then the application table
BooleanQuery tq = null;
tq = conn.prepareBooleanQuery(QueryLanguage.SPARQL, "ASK { ?x ?p <http://cls> }");
boolean b = tq.evaluate();
psOut.println("\nAnswer is " + Boolean.toString(b));
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SparqlASK.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SparqlASK jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
java
コマンドの出力は、次のようになります。
Answer is true
8.14.7 例7: SPARQLのCONSTRUCT問合せ
SparqlConstruct.java
ファイルを示します。
例8-11 SPARQL CONSTRUCT問合せ
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailRepositoryConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.query.GraphQuery;
import org.eclipse.rdf4j.query.GraphQueryResult;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class SparqlConstruct {
public static void main(String[] args) throws ConnectionSetupException, SQLException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
ValueFactory vf = sr.getValueFactory();
IRI p = vf.createIRI("http://p");
IRI cls = vf.createIRI("http://cls");
conn.clear();
conn.add(p, RDFS.DOMAIN, cls);
conn.commit();
OracleSailConnection osc =
(OracleSailConnection)((OracleSailRepositoryConnection) conn).getSailConnection();
osc.analyze(); // analyze the RDF graph
osc.analyzeApplicationTable(); // and then the application table
GraphQuery tq = null; // Construct Query
tq = conn.prepareGraphQuery(QueryLanguage.SPARQL,
"CONSTRUCT {?x <http://new_eq_p> ?o } WHERE { ?x ?p ?o }");
psOut.println("Start construct query");
try (GraphQueryResult result = tq.evaluate()) {
while (result.hasNext()) {
Statement stmt = (Statement) result.next();
psOut.println(stmt.toString());
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SparqlConstruct.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SparqlConstruct jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
java
コマンドの出力は、次のようになります。
Start construct query
(http://p, http://new_eq_p, http://cls)
8.14.8 例8: 名前付きグラフ問合せ
NamedGraph.java
ファイルを示します。
例8-12 名前付きグラフ問合せ
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailRepositoryConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.rio.RDFFormat;
public class NamedGraph {
public static void main(String[] args) throws ConnectionSetupException, SQLException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String trigFile = args[4]; // TRIG-format data file
String networkOwner = (args.length > 6) ? args[5] : null;
String networkName = (args.length > 6) ? args[6] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
conn.begin();
conn.clear();
// load the data incrementally since it is very small file
conn.add(new File(trigFile), "http://my.com/", RDFFormat.TRIG);
conn.commit();
OracleSailConnection osc = (OracleSailConnection)((OracleSailRepositoryConnection) conn).getSailConnection();
osc.analyze(); // analyze the RDF graph
osc.analyzeApplicationTable(); // and then the application table
TupleQuery tq = null;
tq = conn.prepareTupleQuery(QueryLanguage.SPARQL,
"PREFIX : <http://purl.org/dc/elements/1.1/>\n" +
"SELECT ?g ?s ?p ?o\n" +
"WHERE {?g :publisher ?o1 . GRAPH ?g {?s ?p ?o}}\n" +
"ORDER BY ?g ?s ?p ?o");
try (TupleQueryResult result = tq.evaluate()) {
int idx = 0;
while (result.hasNext()) {
idx++;
BindingSet bindingSet = result.next();
psOut.print("\nsolution " + bindingSet.toString());
}
psOut.println("\ntotal # of solution " + Integer.toString(idx));
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例を実行するため、TRIG
形式のtest.trig
ファイルが次のように作成されているとします。
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix swp: <http://www.w3.org/2004/03/trix/swp-1/>.
@prefix dc: <http://purl.org/dc/elements/1.1/>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix : <http://example.org/>.
# default graph
{
:bobGraph dc:publisher "Bob Hacker" .
:aliceGraph dc:publisher "Alice Hacker" .
}
:bobGraph {
:bob foaf:mbox <mailto:bob@oldcorp.example.org> .
}
:aliceGraph {
:alice foaf:name "Alice" .
:alice foaf:mbox <mailto:alice@work.example.org> .
}
:jackGraph {
:jack foaf:name "Jack" .
:jack foaf:mbox <mailto:jack@oracle.example.org> .
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP NamedGraph.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP NamedGraph jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel ./test.trig scott net1
java
コマンドの出力は、次のようになります。
solution
[p=http://xmlns.com/foaf/0.1/mbox;s=http://example.org/alice;g=http://example.org/aliceGraph;o=mailto:alice@work.example.org]
solution
[p=http://xmlns.com/foaf/0.1/name;s=http://example.org/alice;g=http://example.org/aliceGraph;o="Alice"]
solution
[p=http://xmlns.com/foaf/0.1/mbox;s=http://example.org/bob;g=http://example.org/bobGraph;o=mailto:bob@oldcorp.example.org]
total # of solution 3
8.14.9 例9: 一致件数の取得
CountQuery.java
ファイルを示します。
例8-13 一致件数の取得
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailRepositoryConnection;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class CountQuery {
public static void main(String[] args) throws
ConnectionSetupException, SQLException
{
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
ValueFactory f = conn.getValueFactory();
// create some resources and literals to make statements out of
IRI alice = f.createIRI("http://example.org/people/alice");
IRI name = f.createIRI("http://example.org/ontology/name");
IRI person = f.createIRI("http://example.org/ontology/Person");
Literal alicesName = f.createLiteral("Alice");
conn.begin();
// clear model to start fresh
conn.clear();
conn.add(alice, RDF.TYPE, person);
conn.add(alice, name, alicesName);
conn.commit();
OracleSailConnection osc =
(OracleSailConnection)((OracleSailRepositoryConnection) conn).getSailConnection();
osc.analyze();
osc.analyzeApplicationTable();
// Run a query and only return the number of matches (the count ! )
String queryString = " SELECT (COUNT(*) AS ?totalCount) WHERE {?s ?p ?y} ";
TupleQuery tupleQuery = conn.prepareTupleQuery(
QueryLanguage.SPARQL, queryString);
try (TupleQueryResult result = tupleQuery.evaluate()) {
if (result.hasNext()) {
BindingSet bindingSet = result.next();
String totalCount = bindingSet.getValue("totalCount").stringValue();
psOut.println("number of matches: " + totalCount);
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP CountQuery.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP CountQuery jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
java
コマンドの出力は、次のようになります。
number of matches: 2
8.14.10 例10: 問合せパターンの定数に対するバインド変数の指定
BindVar.java
ファイルを示します。
例8-14 問合せパターンの定数に対するバインド変数の指定
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class BindVar {
public static void main(String[] args) throws ConnectionSetupException, SQLException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
ValueFactory f = conn.getValueFactory();
conn.begin();
conn.clear();
// create some resources and literals to make statements out of
// Alice
IRI alice = f.createIRI("http://example.org/people/alice");
IRI name = f.createIRI("http://example.org/ontology/name");
IRI person = f.createIRI("http://example.org/ontology/Person");
Literal alicesName = f.createLiteral("Alice");
conn.add(alice, RDF.TYPE, person);
conn.add(alice, name, alicesName);
//Bob
IRI bob = f.createIRI("http://example.org/people/bob");
Literal bobsName = f.createLiteral("Bob");
conn.add(bob, RDF.TYPE, person);
conn.add(bob, name, bobsName);
conn.commit();
String queryString =
" PREFIX ex: <http://example.org/ontology/> " +
" Select ?name \n" + " WHERE \n" + " { SELECT * WHERE { ?person ex:name ?name} }\n" +
" ORDER BY ?name";
TupleQuery tupleQuery = conn.prepareTupleQuery(
QueryLanguage.SPARQL, queryString);
// set binding for ?person = Alice
tupleQuery.setBinding("person", alice);
try (TupleQueryResult result = tupleQuery.evaluate()) {
if (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("solution " + bindingSet.toString());
}
}
// re-run with ?person = Bob
tupleQuery.setBinding("person", bob);
try (TupleQueryResult result = tupleQuery.evaluate()) {
if (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("solution " + bindingSet.toString());
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP BindVar.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP BindVar jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
java
コマンドの出力は、次のようになります。
solution [name="Alice";person=http://example.org/people/alice]
solution [name="Bob";person=http://example.org/people/bob]
8.14.11 例11: SPARQLの更新
SparqlUpdate.java
ファイルを示します。
例8-15 SPARQLの更新
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.query.Update;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class SparqlUpdate {
private static final String DATA_1 =
"[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y=\"Sue\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]";
private static final String DATA_2 =
"[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]";
private static final String DATA_3 =
"[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]" +
"[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]";
private static final String DATA_4 =
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]" +
"[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]";
private static final String DATA_5 =
"[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]" +
"[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y=\"Susan\"]" +
"[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]";
private static String getRepositoryData(RepositoryConnection conn, PrintStream out)
{
String dataStr = "";
String queryString = "SELECT * WHERE { GRAPH ?g { ?x ?p ?y } } ORDER BY ?g ?x ?p ?y";
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
out.println(bindingSet.toString());
dataStr += bindingSet.toString();
}
}
return dataStr;
}
public static void main(String[] args) throws
ConnectionSetupException, SQLException
{
PrintStream out = new PrintStream(System.out);
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
conn.clear(); // to start from scratch
// Insert some initial data
String updString = "PREFIX people: <http://example.org/people/>\n" +
"PREFIX ont: <http://example.org/ontology/>\n" +
"INSERT DATA { GRAPH <urn:g1> { \n" +
" people:Sue a ont:Person; \n" +
" ont:name \"Sue\" . } }";
Update upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
String repositoryData = getRepositoryData(conn, out);
if (! (DATA_1.equals(repositoryData)) ) out.println("DATA_1 mismatch");
// Change Sue's name to Susan
updString = "PREFIX people: <http://example.org/people/>\n" +
"PREFIX ont: <http://example.org/ontology/>\n" +
"DELETE { GRAPH ?g { ?s ont:name ?n } }\n" +
"INSERT { GRAPH ?g { ?s ont:name \"Susan\" } }\n" +
"WHERE { GRAPH ?g { ?s ont:name ?n FILTER (?n = \"Sue\") }}";
upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
repositoryData = getRepositoryData(conn, out);
if (! (DATA_2.equals(repositoryData)) ) out.println("DATA_2 mismatch");
// Copy to contents of g1 to a new graph g2
updString = "PREFIX people: <http://example.org/people/>\n" +
"PREFIX ont: <http://example.org/ontology/>\n" +
"COPY <urn:g1> TO <urn:g2>";
upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
repositoryData = getRepositoryData(conn, out);
if (! (DATA_3.equals(repositoryData)) ) out.println("DATA_3 mismatch");
// Delete ont:name triple from graph g1
updString = "PREFIX people: <http://example.org/people/>\n" +
"PREFIX ont: <http://example.org/ontology/>\n" +
"DELETE DATA { GRAPH <urn:g1> { people:Sue ont:name \"Susan\" } }";
upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
repositoryData = getRepositoryData(conn, out);
if (! (DATA_4.equals(repositoryData)) ) out.println("DATA_4 mismatch");
// Add contents of g2 to g1
updString = "PREFIX people: <http://example.org/people/>\n" +
"PREFIX ont: <http://example.org/ontology/>\n" +
"ADD <urn:g2> TO <urn:g1>";
upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
repositoryData = getRepositoryData(conn, out);
if (! (DATA_5.equals(repositoryData)) ) out.println("DATA_5 mismatch");
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SparqlUpdate.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SparqlUpdate jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
java
コマンドの出力は、次のようになります。
[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y="Sue"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g1;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g1;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
[p=http://example.org/ontology/name;g=urn:g2;x=http://example.org/people/Sue;y="Susan"]
[p=http://www.w3.org/1999/02/22-rdf-syntax-ns#type;g=urn:g2;x=http://example.org/people/Sue;y=http://example.org/ontology/Person]
8.14.12 例12: Oracleヒント
OracleHint.java
ファイルを示します。
例8-16 Oracleヒント
import java.sql.SQLException;
import oracle.rdf4j.adapter.OracleDB;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.query.Update;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class OracleHint {
public static void main(String[] args) throws ConnectionSetupException, SQLException {
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
conn.clear(); // to start from scratch
// Insert some initial data
String updString =
"PREFIX ex: <http://example.org/>\n" +
"INSERT DATA { " +
" ex:a ex:p1 ex:b . " +
" ex:b ex:p1 ex:c . " +
" ex:c ex:p1 ex:d . " +
" ex:d ex:p1 ex:e . " +
" ex:e ex:p1 ex:f . " +
" ex:f ex:p1 ex:g . " +
" ex:g ex:p1 ex:h . " +
" ex:h ex:p1 ex:i . " +
" ex:i ex:p1 ex:j . " +
" ex:j ex:p1 ex:k . " +
"}";
Update upd = conn.prepareUpdate(QueryLanguage.SPARQL, updString);
upd.execute();
conn.commit();
// default behavior for property path is 10 hop max, so we get 11 results
String sparql =
"PREFIX ex: <http://example.org/>\n" +
"SELECT (COUNT(*) AS ?cnt)\n" +
"WHERE { ex:a ex:p1* ?y }";
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparql);
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
if (11 != Integer.parseInt(bindingSet.getValue("cnt").stringValue())) System.out.println("cnt mismatch: expecting 11");
}
}
// ORACLE_SEM_FS_NS prefix hint to use parallel(2) and dynamic_sampling(6)
// ORACLE_SEM_SM_NS prefix hint to use a 5 hop max and to use CONNECT BY instead of simple join
sparql =
"PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#dop=2,ods=6>\n" +
"PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#all_max_pp_depth(5),all_disable_pp_sj>\n" +
"PREFIX ex: <http://example.org/>\n" +
"SELECT (COUNT(*) AS ?cnt)\n" +
"WHERE { ex:a ex:p1* ?y }";
tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparql, "http://example.org/");
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
if (6 != Integer.parseInt(bindingSet.getValue("cnt").stringValue())) System.out.println("cnt mismatch: expecting 6");
}
}
// query options for SPARQL Update
sparql =
"PREFIX ORACLE_SEM_UM_NS: <http://oracle.com/semtech#parallel(2)>\n" +
"PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#all_max_pp_depth(5),all_disable_pp_sj>\n" +
"PREFIX ex: <http://example.org/>\n" +
"INSERT { GRAPH ex:g1 { ex:a ex:reachable ?y } }\n" +
"WHERE { ex:a ex:p1* ?y }";
Update u = conn.prepareUpdate(sparql);
u.execute();
// graph ex:g1 should have 6 results because of all_max_pp_depth(5)
sparql =
"PREFIX ex: <http://example.org/>\n" +
"SELECT (COUNT(*) AS ?cnt)\n" +
"WHERE { GRAPH ex:g1 { ?s ?p ?o } }";
tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, sparql, "http://example.org/");
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
if (6 != Integer.parseInt(bindingSet.getValue("cnt").stringValue())) System.out.println("cnt mismatch: expecting 6");
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP OracleHint.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP OracleHint jdbc:oracle:thin:@localhost:1521:ORCL scott <password> TestModel scott net1
8.14.13 例13: JDBCバインド値の使用
JDBCBindVar.java
ファイルを示します。
例8-17 JDBCバインド値の使用
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OracleDB;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
public class JDBCBindVar {
public static void main(String[] args) throws ConnectionSetupException, SQLException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = (networkName == null) ? new OracleSailStore(op, model) : new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
conn = sr.getConnection();
ValueFactory f = conn.getValueFactory();
conn.begin();
conn.clear();
// create some resources and literals to make statements out of
// Alice
IRI alice = f.createIRI("http://example.org/people/alice");
IRI name = f.createIRI("http://example.org/ontology/name");
IRI person = f.createIRI("http://example.org/ontology/Person");
Literal alicesName = f.createLiteral("Alice");
conn.add(alice, RDF.TYPE, person);
conn.add(alice, name, alicesName);
//Bob
IRI bob = f.createIRI("http://example.org/people/bob");
Literal bobsName = f.createLiteral("Bob");
conn.add(bob, RDF.TYPE, person);
conn.add(bob, name, bobsName);
conn.commit();
// Query using USE_BIND_VAR=JDBC option for JDBC bind values
// Simple BIND clause for ?person marks ?person as a bind variable
String queryString =
" PREFIX ORACLE_SEM_SM_NS: <http://oracle.com/semtech#USE_BIND_VAR=JDBC>\n" +
" PREFIX ex: <http://example.org/ontology/>\n" +
" Select ?name \n" +
" WHERE \n" +
" { SELECT * WHERE { \n" +
" BIND (\"\" AS ?person) \n" +
" ?person ex:name ?name } \n" +
" }\n" +
" ORDER BY ?name";
TupleQuery tupleQuery = conn.prepareTupleQuery(
QueryLanguage.SPARQL, queryString);
// set binding for ?person = Alice
tupleQuery.setBinding("person", alice);
try (TupleQueryResult result = tupleQuery.evaluate()) {
if (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("solution " + bindingSet.toString());
}
}
// re-run with ?person = Bob
tupleQuery.setBinding("person", bob);
try (TupleQueryResult result = tupleQuery.evaluate()) {
if (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("solution " + bindingSet.toString());
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
if (op != null) {
OracleDB oracleDB = op.getOracleDB();
if (networkName == null)
OracleUtils.dropSemanticModelAndTables(oracleDB, model);
else
OracleUtils.dropSemanticModelAndTables(oracleDB, model, null, null, networkOwner, networkName);
op.returnOracleDBtoPool(oracleDB);
}
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP JDBCBindVar.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP JDBCBindVar jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel scott net1
Javaコマンドの出力は、次のようになります。
solution [name="Alice";person=http://example.org/people/alice]
solution [name="Bob";person=http://example.org/people/bob]
8.14.14 例14: 単純な推論
SimpleInference.java
ファイルを示します。このファイルは、OWL2RLルール・ベースを使用する単一のRDFグラフの推論を示します。
例8-18 単純な推論
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import oracle.rdf4j.adapter.Attachment;
import oracle.rdf4j.adapter.OracleSailConnection;
import oracle.rdf4j.adapter.OracleSailRepositoryConnection;
public class SimpleInference {
public static void main(String[] args) throws ConnectionSetupException, SQLException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String networkOwner = (args.length > 5) ? args[4] : null;
String networkName = (args.length > 5) ? args[5] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
// create a single-model, single-rulebase OracleSailStore object
Attachment attachment = Attachment.createInstance(Attachment.NO_ADDITIONAL_MODELS, new String[] {"OWL2RL"});
store = new OracleSailStore(op, model, attachment, networkOwner, networkName);
sr = new OracleRepository(store);
ValueFactory f = sr.getValueFactory();
conn = sr.getConnection();
// create some resources and literals to make statements out of
IRI alice = f.createIRI("http://example.org/people/alice");
IRI bob = f.createIRI("http://example.org/people/bob");
IRI friendOf = f.createIRI("http://example.org/ontology/friendOf");
IRI Person = f.createIRI("http://example.org/ontology/Person");
IRI Engineer = f.createIRI("http://example.org/ontology/Engineer");
IRI Doctor = f.createIRI("http://example.org/ontology/Doctor");
conn.clear(); // to start from scratch
// add some statements to the RDF graph
conn.add(alice, RDF.TYPE, Engineer);
conn.add(bob, RDF.TYPE, Doctor);
conn.add(alice, friendOf, bob);
conn.commit();
OracleSailConnection osc = (OracleSailConnection)((OracleSailRepositoryConnection)conn).getSailConnection();
// perform inference (this will not generate any inferred triples)
osc.performInference();
// prepare a query to run against the repository
String queryString =
"PREFIX ex: <http://example.org/ontology/>\n" +
"SELECT * WHERE {?x ex:friendOf ?y . ?x a ex:Person . ?y a ex:Person}\n" ;
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
// run the query: no results will be returned because nobody is a Person
try (TupleQueryResult result = tupleQuery.evaluate()) {
int resultCount = 0;
while (result.hasNext()) {
resultCount++;
BindingSet bindingSet = result.next();
psOut.println("value of x: " + bindingSet.getValue("x"));
psOut.println("value of y: " + bindingSet.getValue("y"));
}
psOut.println("number of results: " + resultCount);
}
// add class hierarchy
conn.add(Doctor, RDFS.SUBCLASSOF, Person);
conn.add(Engineer, RDFS.SUBCLASSOF, Person);
conn.commit();
// perform inference again
osc.performInference();
// run the same query again: returns some results because alice and bob now belong to superclass Person
try (TupleQueryResult result = tupleQuery.evaluate()) {
while (result.hasNext()) {
BindingSet bindingSet = result.next();
psOut.println("value of x: " + bindingSet.getValue("x"));
psOut.println("value of y: " + bindingSet.getValue("y"));
}
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SimpleInference.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SimpleInference jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel scott net1
Javaコマンドの出力は、次のようになります。
number of results: 0
value of x: http://example.org/people/alice
value of y: http://example.org/people/bob
8.14.15 例15: 単純なグラフ・コレクション
SimpleVirtualModel.java
ファイルを示します。
例8-19 単純なグラフ・コレクション
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.exception.ConnectionSetupException;
import oracle.rdf4j.adapter.utils.OracleUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import oracle.rdf4j.adapter.Attachment;
public class SimpleVirtualModel {
public static void main(String[] args) throws ConnectionSetupException, SQLException, IOException {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String model = args[3];
String model2 = args[4];
String virtualModelName = args[5];
String networkOwner = (args.length > 7) ? args[6] : null;
String networkName = (args.length > 7) ? args[7] : null;
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
OracleSailStore store2 = null;
Repository sr2 = null;
RepositoryConnection conn2 = null;
OracleSailStore vmStore = null;
Repository vmSr = null;
RepositoryConnection vmConn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
// create two RDF graphs and then an RDF graph collection that uses those two graphs
// create the first RDF grapj
store = new OracleSailStore(op, model, networkOwner, networkName);
sr = new OracleRepository(store);
ValueFactory f = sr.getValueFactory();
conn = sr.getConnection();
// create the second RDF graph (this one will be used as an additional graph in the attachment object)
store2 = new OracleSailStore(op, model2, networkOwner, networkName);
sr2 = new OracleRepository(store2);
conn2 = sr2.getConnection();
// create a two-graph RDF graph collection OracleSailStore object
Attachment attachment = Attachment.createInstance(model2);
vmStore = new OracleSailStore(op, model, /*ignored*/true, /*useVirtualModel*/true, virtualModelName, attachment, networkOwner, networkName);
vmSr = new OracleRepository(vmStore);
vmConn = vmSr.getConnection();
// create some resources and literals to make statements out of
IRI alice = f.createIRI("http://example.org/people/alice");
IRI bob = f.createIRI("http://example.org/people/bob");
IRI friendOf = f.createIRI("http://example.org/ontology/friendOf");
IRI Person = f.createIRI("http://example.org/ontology/Person");
IRI Engineer = f.createIRI("http://example.org/ontology/Engineer");
IRI Doctor = f.createIRI("http://example.org/ontology/Doctor");
// clear any data (in case any of the two non-virtual models were already present)
conn.clear();
conn2.clear();
// add some statements to the first RDF model
conn.add(alice, RDF.TYPE, Engineer);
conn.add(bob, RDF.TYPE, Doctor);
conn.add(alice, friendOf, bob);
conn.commit();
// prepare a query to run against the virtual model repository
String queryString =
"PREFIX ex: <http://example.org/ontology/>\n" +
"SELECT * WHERE {" +
"?x ex:friendOf ?y . ?x rdf:type/rdfs:subClassOf* ?xC . ?y rdf:type/rdfs:subClassOf* ?yC" +
"} ORDER BY ?x ?xC ?y ?yC\n" ;
;
TupleQuery tupleQuery = vmConn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
// run the query: no results will be returned because nobody is a Person
try (TupleQueryResult result = tupleQuery.evaluate()) {
int resultCount = 0;
while (result.hasNext()) {
resultCount++;
BindingSet bindingSet = result.next();
psOut.println("values of x | xC | y | yC: " +
bindingSet.getValue("x") + " | " + bindingSet.getValue("xC") + " | " +
bindingSet.getValue("y") + " | " + bindingSet.getValue("yC"));
}
psOut.println("number of results: " + resultCount);
}
// add class hierarchy info to the second model
conn2.add(Doctor, RDFS.SUBCLASSOF, Person);
conn2.add(Engineer, RDFS.SUBCLASSOF, Person);
conn2.commit();
// run the same query again: returns some additional info in the results
try (TupleQueryResult result = tupleQuery.evaluate()) {
int resultCount = 0;
while (result.hasNext()) {
resultCount++;
BindingSet bindingSet = result.next();
psOut.println("values of x | xC | y | yC: " +
bindingSet.getValue("x") + " | " + bindingSet.getValue("xC") + " | " +
bindingSet.getValue("y") + " | " + bindingSet.getValue("yC"));
}
psOut.println("number of results: " + resultCount);
}
}
finally {
if (conn != null && conn.isOpen()) {
conn.clear();
conn.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model, null, null, networkOwner, networkName);
sr.shutDown();
store.shutDown();
if (conn2 != null && conn2.isOpen()) {
conn2.clear();
conn2.close();
}
OracleUtils.dropSemanticModelAndTables(op.getOracleDB(), model2, null, null, networkOwner, networkName);
sr2.shutDown();
store2.shutDown();
vmSr.shutDown();
vmStore.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP SimpleVirtualModel.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP SimpleVirtualModel jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel TestOntology TestVM scott net1
Javaコマンドの出力は、次のようになります。
values of x | xC | y | yC: http://example.org/people/alice | http://example.org/ontology/Engineer | http://example.org/people/bob | http://example.org/ontology/Doctor
number of results: 1
values of x | xC | y | yC: http://example.org/people/alice | http://example.org/ontology/Person | http://example.org/people/bob | http://example.org/ontology/Doctor
values of x | xC | y | yC: http://example.org/people/alice | http://example.org/ontology/Person | http://example.org/people/bob | http://example.org/ontology/Person
values of x | xC | y | yC: http://example.org/people/alice | http://example.org/ontology/Engineer | http://example.org/people/bob | http://example.org/ontology/Doctor
values of x | xC | y | yC: http://example.org/people/alice | http://example.org/ontology/Engineer | http://example.org/people/bob | http://example.org/ontology/Person
number of results: 4
8.14.16 例16: SHACLによるグラフ検証
DATA_GRAPH1
にロードしてからこのデータをSHACL形状ex:AgeCountShape
に対して検証する、ShaclExample.java
ファイルを示します。
例8-20 SHACL検証
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.sql.SQLException;
import org.eclipse.rdf4j.common.exception.ValidationException;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.vocabulary.RDF4J;
import org.eclipse.rdf4j.repository.Repository;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.RepositoryException;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.rio.Rio;
import org.eclipse.rdf4j.rio.WriterConfig;
import org.eclipse.rdf4j.rio.helpers.BasicWriterSettings;
import org.eclipse.rdf4j.sail.shacl.ShaclSail;
import oracle.rdf4j.adapter.OracleDB;
import oracle.rdf4j.adapter.OraclePool;
import oracle.rdf4j.adapter.OracleRepository;
import oracle.rdf4j.adapter.OracleSailStore;
import oracle.rdf4j.adapter.shacl.OracleShaclSail;
import oracle.rdf4j.adapter.utils.OracleUtils;
public class ShaclExample {
public static void main(String[] args) {
PrintStream psOut = System.out;
String jdbcUrl = args[0];
String user = args[1];
String password = args[2];
String networkOwner = args[3];
String networkName = args[4];
String model = "DATA_GRAPH1";
OraclePool op = null;
OracleSailStore store = null;
Repository sr = null;
RepositoryConnection conn = null;
try {
op = new OraclePool(jdbcUrl, user, password);
store = new OracleSailStore(op, model, networkOwner, networkName);
// load sample data graph
try {
sr = new OracleRepository(store);
conn = sr.getConnection();
StringReader sampleData = new StringReader(
String.join(
"\n", "",
"@prefix ex: <http://oracle.example.com/ns#> .",
"ex:Alice a ex:Person .",
"ex:Bob a ex:Person ;",
" ex:age 20 .",
"ex:Fred a ex:Person ;",
" ex:age 30 ;",
" ex:age 32 ."
)
);
conn.begin();
conn.add(sampleData, null, RDFFormat.TURTLE);
conn.commit();
}
catch (IOException e) {
e.printStackTrace(psOut);
}
finally {
conn.close();
sr.shutDown();
}
// load SHACL shapes graph and validate data
ShaclSail shaclSail = null;
SailRepository shaclRepo = null;
SailRepositoryConnection shaclConn = null;
try {
shaclSail = new OracleShaclSail(store);
shaclRepo = new SailRepository(shaclSail);
shaclRepo.init();
shaclConn = shaclRepo.getConnection();
// add SHACL shapes in a transaction
// All instances of ex:Person should have exactly one value for ex:age
StringReader sampleShape = new StringReader(
String.join(
"\n", "",
"@prefix ex: <http://oracle.example.com/ns#> .",
"@prefix sh: <http://www.w3.org/ns/shacl#> .",
"ex:AgeCountShape",
" a sh:NodeShape ;",
" sh:targetClass ex:Person ;",
" sh:property [",
" sh:path ex:age ;",
" sh:maxCount 1 ;",
" sh:minCount 1 ;",
" ] ."
)
);
shaclConn.begin();
// add shape to the reserved named graph http://rdf4j.org/schema/rdf4j#SHACLShapeGraph
// clear any existing shapes
shaclConn.clear(RDF4J.SHACL_SHAPE_GRAPH);
// add new shapes graph
shaclConn.add(sampleShape, null, RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH);
// commit runs bulk validation against the data graph
shaclConn.commit();
}
catch (RDFParseException | IOException e) {
e.printStackTrace(psOut);
}
// SHACL violation will throw a Repository Exception
catch (RepositoryException e) {
Throwable cause = e.getCause();
// Handle validation exception
if (cause instanceof ValidationException) {
// Get validation report and print it out
Model validationReportModel = ((ValidationException) cause).validationReportAsModel();
WriterConfig writerConfig = new WriterConfig()
.set(BasicWriterSettings.INLINE_BLANK_NODES, true)
.set(BasicWriterSettings.XSD_STRING_TO_PLAIN_LITERAL, true)
.set(BasicWriterSettings.PRETTY_PRINT, true);
Rio.write(validationReportModel, psOut, RDFFormat.TURTLE, writerConfig);
}
else {
e.printStackTrace(psOut);
}
}
finally {
shaclConn.close();
shaclRepo.shutDown();
shaclSail.shutDown();
}
}
catch (SQLException e) {
e.printStackTrace(psOut);
}
finally {
if (op != null) {
try {
OracleDB oracleDB = op.getOracleDB();
OracleUtils.dropSemanticModelAndTables(oracleDB, model, null, null, networkOwner, networkName);
op.returnOracleDBtoPool(oracleDB);
}
catch (SQLException e) {
e.printStackTrace(psOut);
}
}
store.shutDown();
op.close();
}
}
}
この例をコンパイルするには、次のコマンドを実行します。
javac -classpath $CP ShaclExample.java
所有者がSCOTTで名前がNET1である既存のスキーマプライベート・ネットワークに対してこの例を実行するには、次のコマンドを実行します。
java -classpath $CP ShaclExample jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> scott net1
このJavaコマンドの出力は、想定では次のようになります。なお、この場合は、ex:Alice
はex:age
プロパティがないため制約に違反し、ex:Fred
はex:age
に2つの個別値があるため制約に違反します。
@prefix dash: <http://datashapes.org/dash#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rsx: <http://rdf4j.org/shacl-extensions#> .
@prefix rdf4j: <http://rdf4j.org/schema/rdf4j#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
[] a sh:ValidationReport;
sh:conforms false;
rdf4j:truncated false;
sh:result [ a sh:ValidationResult;
sh:focusNode <http://oracle.example.com/ns#Alice>;
rsx:shapesGraph rdf4j:SHACLShapeGraph;
sh:resultPath <http://oracle.example.com/ns#age>;
sh:sourceConstraintComponent sh:MinCountConstraintComponent;
sh:resultSeverity sh:Violation;
sh:sourceShape _:c0d709142bb44448ad347272955741bc9
], [ a sh:ValidationResult;
sh:focusNode <http://oracle.example.com/ns#Fred>;
rsx:shapesGraph rdf4j:SHACLShapeGraph;
sh:resultPath <http://oracle.example.com/ns#age>;
sh:sourceConstraintComponent sh:MaxCountConstraintComponent;
sh:resultSeverity sh:Violation;
sh:sourceShape _:c0d709142bb44448ad347272955741bc9
] .
_:c0d709142bb44448ad347272955741bc9 a sh:PropertyShape;
sh:path <http://oracle.example.com/ns#age>;
sh:minCount 1;
sh:maxCount 1 .