Hi Andy,
Here is the code I can.
Fill in a rdf file and two directories.
Tested with various different rdf files. 3 triples, a few hundred
triples and 10,000 triples.
Also it appeared to work without the .finishRequest before I updated to
0.8.9
<ver.jena>2.6.4</ver.jena>
<ver.arq>2.8.7</ver.arq>
<ver.tdb>0.8.9</ver.tdb>
<ver.sdb>1.3.3</ver.sdb>
<ver.joseki>3.4.3</ver.joseki>
Christian
PS. Let me know if I am doing something you could do better,
package uk.ac.manchester.cs.fish.link;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query ;
import com.hp.hpl.jena.query.QueryExecution ;
import com.hp.hpl.jena.query.QueryExecutionFactory ;
import com.hp.hpl.jena.query.QueryFactory ;
import com.hp.hpl.jena.query.QuerySolution ;
import com.hp.hpl.jena.query.ResultSet ;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.hp.hpl.jena.tdb.TDBLoader;
import com.hp.hpl.jena.tdb.store.DatasetGraphTDB;
import com.hp.hpl.jena.tdb.store.GraphTDB;
import java.io.File;
import java.util.List;
import org.openjena.atlas.io.IndentedWriter;
public class Mini
{
static public final String NL = System.getProperty("line.separator") ;
static public final String PROLOG = "PREFIX rdf:
<http://www.w3.org/1999/02/22-rdf-syntax-ns#>" + NL +
"PREFIX vocab:
<http://example.com:2020/vocab/resource/>" + NL;
//Fill these in.
static private final String cumbriaTarnsRDF = "any rdf here";
static private final String cumbriaTarnsDirectory = "a directory";
static private final String cumbriaTarnsName =
"http://example.com:2020/rdf/christian.rdf";
static private final String combinedDirectory = "another directory";
public static void main(String... argv)
{
deleteDir (combinedDirectory);
DatasetGraphTDB datasetGraphTDB =
TDBFactory.createDatasetGraph(combinedDirectory);
loadGraph(cumbriaTarnsRDF, cumbriaTarnsDirectory,
cumbriaTarnsName, datasetGraphTDB);
//More loads removed which is why I wrote ot this way!
query(datasetGraphTDB.toDataset(), COUNT_TYPES);
//Works if you uncomment next line
//datasetGraphTDB.finishRequest();
datasetGraphTDB.close();
datasetGraphTDB = TDBFactory.createDatasetGraph(combinedDirectory);
query(datasetGraphTDB.toDataset(), COUNT_TYPES);
datasetGraphTDB.close();
}
private static void loadGraph(String rdfLocation, String
tdbLocation, String nodeName,
DatasetGraphTDB datasetGraphTDB) {
deleteDir(tdbLocation);
GraphTDB graph = (GraphTDB)TDBFactory.createGraph(tdbLocation);
TDBLoader loader = new TDBLoader();
loader.loadGraph(graph, rdfLocation);
Node node = Node.createURI(nodeName);
datasetGraphTDB.addGraph(node, graph);
graph.close();
}
private static void deleteDir (String directoryName){
File directory = new File(directoryName);
if (!directory.exists()){
File parent = directory.getParentFile();
parent.mkdirs();
return;
}
File[] children = directory.listFiles();
if (children.length != 41) {
System.out.println("Unexpected number of children");
System.exit(2);
}
for (int i = 0; i < children.length; i++){
children[i].delete();
}
directory.delete();
}
private static void runQuery(QueryExecution qexec){
try {
ResultSet rs = qexec.execSelect() ;
List<String> fields = rs.getResultVars();
for (int i = 0 ; i < fields.size(); i++){
System.out.print(fields.get(i)+" ");
}
System.out.println();
//The order of results is undefined.
for ( ; rs.hasNext() ; )
{
QuerySolution rb = rs.next() ;
for (int i = 0 ; i < fields.size(); i++){
RDFNode field = rb.get(fields.get(i)) ;
if (field == null){
System.out.print ("<null> ");
} else if (field.isLiteral()){
Literal literal = (Literal)field;
System.out.print(literal.getLexicalForm() + " ");
} else if (field.isResource()) {
Resource resource = (Resource)field;
if (!resource.getLocalName().isEmpty()){
System.out.print(resource.getLocalName() +
" ");
} else if (!resource.getNameSpace().isEmpty()){
System.out.print(resource.getNameSpace()+
" ");
} else {
System.out.print(resource + " ");
}
} else {
System.out.print("???" + field);
}
}
System.out.println() ;
}
}
finally
{
// QueryExecution objects should be closed to free any
system resources
qexec.close() ;
}
}
static private String COUNT_TYPES = PROLOG +
"SELECT ?type (COUNT (DISTINCT ?entry) as ?mycount)" + NL +
"{GRAPH ?anyGraph { " + NL +
" ?entry rdf:type ?type." + NL +
" }" + NL +
"}" + NL +
"GROUP BY ?type" ;
private static void query(Dataset dataSource, String queryString){
Query query = QueryFactory.create(queryString,
Syntax.syntaxSPARQL_11) ;
System.out.println("Query: ") ;
// Print with line numbers
query.serialize(new IndentedWriter(System.out,true)) ;
System.out.println() ;
// Create a single execution of this query, apply to a model
// which is wrapped up as a Dataset
QueryExecution qexec = QueryExecutionFactory.create(query,
dataSource) ;
// Or QueryExecutionFactory.create(queryString, model) ;
runQuery(qexec);
}
}
On 07/02/2011 20:45, Andy Seaborne wrote:
On 07/02/11 14:28, Christian Brenninkmeijer wrote:
Hi,
I noticed (the hard way) that
DatasetGraphTDB.close() does not call DatasetGraphTDB.finishRequest()
before closing the graph.
This then causes a NoSuchElementException when the dataset is later
used.
Could you provide the stacktrace please?
Senario:
I loaded a graph from rdf using TDBLoader.loadGraph
I added the graph to the dataset using addGraph
I queried the dataset with success. Closing the query.
I closed the dataset and then reopened it.
Ah - this might be more the issue. Are you creating the datset via
TDBFactory? That has a cache of datasets (to avoid two attempts to
open the same location withotu sharing the caches).
Exact same query with the exact same code failed.
Yes - close means close, not to be used again.
I then added DatasetGraphTDB.finishRequest()before closing the dataset
and it worked.
How I agree calling finishRequest() is good programing style and I
should have done that.
However writing close() expecting a user to have called finishRequest()
is poor style.
DatasetGraphTDB.finishRequest() calls sync() - close should also be
doing that as well.
Normally, finishRequest() isn't needed and my first attempt to
recreate the situation didn't have any problems. I've probably not
quiet understood the sequence of actions - could you provide a
complete, minimal example so I can run it at my end please?
Andy
-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 10.0.1204 / Virus Database: 1435/3428 - Release Date: 02/07/11
--
Christian Brenninkmeijer
Department of Computer Science
University of Manchester