Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
handling similar bnodes
  • Loading branch information
retog committed Mar 15, 2015
1 parent 43651da commit 3a09be86c540929b20e82f6b7ffbe1a0bd42b259
Showing 3 changed files with 136 additions and 14 deletions.
@@ -30,12 +30,15 @@
import java.util.logging.Logger;
import org.apache.commons.rdf.BlankNode;
import org.apache.commons.rdf.BlankNodeOrIri;
import org.apache.commons.rdf.Graph;
import org.apache.commons.rdf.ImmutableGraph;
import org.apache.commons.rdf.Iri;
import org.apache.commons.rdf.Literal;
import org.apache.commons.rdf.RdfTerm;
import org.apache.commons.rdf.Triple;
import org.apache.commons.rdf.impl.utils.AbstractGraph;
import org.apache.commons.rdf.impl.utils.TripleImpl;
import org.apache.commons.rdf.impl.utils.simple.SimpleGraph;

/**
*
@@ -47,6 +50,7 @@ public class SparqlGraph extends AbstractGraph {
private static final Logger log = Logger.getLogger(SparqlGraph.class.getName());

final SparqlClient sparqlClient;


/**
* Constructs a Graph representing the default graph at the specified
@@ -82,7 +86,7 @@ protected Iterator<Triple> performFilter(final BlankNodeOrIri filterSubject,
queryBuilder.append(" }");
final List<Map<String, RdfTerm>> sparqlResults = sparqlClient.queryResultSet(queryBuilder.toString());
//first to triples without bnode-conversion
//rawTripkles contains the triples with the BNodes from the result set
//rawTriples contains the triples with the BNodes from the result set
final Collection<Triple> rawTriples = new ArrayList<>();
for (Map<String, RdfTerm> result : sparqlResults) {
rawTriples.add(new TripleImpl(filterSubject != null ? filterSubject : (BlankNodeOrIri) result.get("s"),
@@ -96,6 +100,7 @@ protected Iterator<Triple> performFilter(final BlankNodeOrIri filterSubject,
return (new Callable<Iterator<Triple>>() {

final Map<BlankNode, SparqlBNode> nodeMap = new HashMap<>();
final Set<ImmutableGraph> usedContext = new HashSet<>();

private RdfTerm useSparqlNode(RdfTerm node) throws IOException {
if (node instanceof BlankNodeOrIri) {
@@ -149,7 +154,7 @@ private void createBlankNodesForcontext(final BlankNode node) throws IOException
}
}

private Collection<Triple> getContext(final BlankNode node) throws IOException {
private ImmutableGraph getContext(final BlankNode node) throws IOException {
//we need to get the cntext of the BNode
//if the filter was for (null, null, null) we have the whole
//bnode context in the reuslt set, otherwise we need to get
@@ -159,30 +164,41 @@ private Collection<Triple> getContext(final BlankNode node) throws IOException {
&& (filterObject == null)) {
return getContextInRaw(node);
} else {
final Collection<Triple> startContext = getContextInRaw(node);
final Set<Collection<Triple>> expandedContexts = expandContext(startContext);
final ImmutableGraph startContext = getContextInRaw(node);
final Set<ImmutableGraph> expandedContexts = expandContext(startContext);
//expand bnode context
//note that there might be different contexts for
//a bnode as present in the current result set
//in this case we just haveto make sure we don't
//pick the same context for different bnodes in the resultset

//TODO make sure we don't take one that has already been used
return expandedContexts.iterator().next();
ImmutableGraph result = null;
for (ImmutableGraph expandedContext : expandedContexts) {
if (!usedContext.contains(expandedContext)) {
result = expandedContext;
break;
}
}
if (result == null) {
log.warning("he underlying sparql graph seems to contain redundant triples, this might cause unexpected results");
result = expandedContexts.iterator().next();
} else {
usedContext.add(result);
}
return result;
}

}

private Collection<Triple> getContextInRaw(BlankNode node) {
final Collection<Triple> context = new ArrayList<>();
private ImmutableGraph getContextInRaw(BlankNode node) {
final Graph contextBuilder = new SimpleGraph();
for (Triple rawTriple : rawTriples) {
BlankNodeOrIri rawSubject = rawTriple.getSubject();
RdfTerm rawObject = rawTriple.getObject();
if (rawSubject.equals(node) || rawObject.equals(node)) {
context.add(rawTriple);
contextBuilder.add(rawTriple);
}
}
return context;
return contextBuilder.getImmutableGraph();
}

@Override
@@ -214,7 +230,7 @@ public Triple next() {
* @param startContext
* @return
*/
private Set<Collection<Triple>> expandContext(Collection<Triple> startContext) throws IOException {
private Set<ImmutableGraph> expandContext(Collection<Triple> startContext) throws IOException {
final Collection<String> triplePatterns = new ArrayList<>();
int varCounter = 0;
final Map<BlankNode, String> bNodeVarNameMap = new HashMap<>();
@@ -292,7 +308,7 @@ private Set<Collection<Triple>> expandContext(Collection<Triple> startContext) t
}
queryBuilder.append(" }");
final List<Map<String, RdfTerm>> expansionQueryResults = sparqlClient.queryResultSet(queryBuilder.toString());
Set<Collection<Triple>> expandedContexts = new HashSet<>();
Set<ImmutableGraph> expandedContexts = new HashSet<>();
//the query results may or may be from disjoint supergraphs
//we expand them all as if they are different which may lead
//us to the same MSG multiple times
@@ -362,7 +378,7 @@ private Set<Collection<Triple>> expandContext(Collection<Triple> startContext) t

}
if (expandedContexts.isEmpty()) {
expandedContexts.add(startContext);
expandedContexts.add(new SimpleGraph(startContext).getImmutableGraph());
}
return expandedContexts;
}
@@ -0,0 +1,98 @@
package org.apache.commons.rdf.impl.sparql;

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/


import org.apache.commons.rdf.impl.sparql.*;
import com.hp.hpl.jena.query.DatasetAccessor;
import com.hp.hpl.jena.query.DatasetAccessorFactory;
import java.io.IOException;
import java.net.ServerSocket;
import org.apache.jena.fuseki.EmbeddedFusekiServer;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.commons.rdf.BlankNode;
import org.apache.commons.rdf.BlankNodeOrIri;
import org.apache.commons.rdf.Graph;
import org.apache.commons.rdf.Iri;
import org.apache.commons.rdf.RdfTerm;
import org.apache.commons.rdf.Triple;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
*
* @author reto
*/
public class SimilarBNodes {

final static int serverPort = findFreePort();
static EmbeddedFusekiServer server;

@BeforeClass
public static void prepare() throws IOException {
final String serviceURI = "http://localhost:" + serverPort + "/ds/data";
final DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceURI);
final InputStream in = SimilarBNodes.class.getResourceAsStream("similar-bnodes.ttl");
final Model m = ModelFactory.createDefaultModel();
String base = "http://example.org/";
m.read(in, base, "TURTLE");
server = EmbeddedFusekiServer.memTDB(serverPort, "/ds");//dataSet.getAbsolutePath());
server.start();
System.out.println("Started fuseki on port " + serverPort);
accessor.putModel(m);
}

@AfterClass
public static void cleanup() {
server.stop();
}

@Test
public void graphSize() {
final Graph graph = new SparqlGraph("http://localhost:" + serverPort + "/ds/query");
Assert.assertEquals("Graph not of the exepected size", 2, graph.size());
}



@Test
public void foafKnowsFilter() {
final Graph graph = new SparqlGraph("http://localhost:" + serverPort + "/ds/query");

final Iri foafKnows = new Iri("http://xmlns.com/foaf/0.1/knows");

final Iterator<Triple> iter = graph.filter(null, foafKnows, null);
Assert.assertTrue(iter.hasNext());
final Triple triple1 = iter.next();
final BlankNodeOrIri subject1 = triple1.getSubject();
Assert.assertTrue(subject1 instanceof BlankNode);
Assert.assertTrue(iter.hasNext());
final Triple triple2 = iter.next();
final BlankNodeOrIri subject2 = triple2.getSubject();
Assert.assertTrue(subject2 instanceof BlankNode);
Assert.assertNotEquals(subject1, subject2);
}




public static int findFreePort() {
int port = 0;
try (ServerSocket server = new ServerSocket(0);) {
port = server.getLocalPort();
} catch (Exception e) {
throw new RuntimeException("unable to find a free port");
}
return port;
}

}
@@ -0,0 +1,8 @@
@base <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .


[] foaf:knows [ foaf:name "Alice"] .
[] foaf:knows [ foaf:name "Bob" ] .

0 comments on commit 3a09be8

Please sign in to comment.