marmotta-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wik...@apache.org
Subject [10/11] added missing module from the previous code importation
Date Tue, 19 Feb 2013 12:57:40 GMT
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/main/java/at/newmedialab/ldpath/backend/file/FileQuery.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/main/java/at/newmedialab/ldpath/backend/file/FileQuery.java b/ldpath/ldpath-backend-file/src/main/java/at/newmedialab/ldpath/backend/file/FileQuery.java
new file mode 100644
index 0000000..0b85b6a
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/main/java/at/newmedialab/ldpath/backend/file/FileQuery.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldpath.backend.file;
+
+import at.newmedialab.ldpath.LDPath;
+import at.newmedialab.ldpath.exception.LDPathParseException;
+import ch.qos.logback.classic.Level;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Value;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Command line application for querying input from files.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class FileQuery {
+
+    private static final Logger log = LoggerFactory.getLogger(FileQuery.class);
+
+    public static void main(String[] args) {
+        Options options = buildOptions();
+
+        CommandLineParser parser = new PosixParser();
+        try {
+            CommandLine cmd = parser.parse( options, args);
+
+            Level logLevel = Level.WARN;
+
+            if(cmd.hasOption("loglevel")) {
+                String logLevelName = cmd.getOptionValue("loglevel");
+                if("DEBUG".equals(logLevelName.toUpperCase())) {
+                    logLevel = Level.DEBUG;
+                } else if("INFO".equals(logLevelName.toUpperCase())) {
+                    logLevel = Level.INFO;
+                } else if("WARN".equals(logLevelName.toUpperCase())) {
+                    logLevel = Level.WARN;
+                } else if("ERROR".equals(logLevelName.toUpperCase())) {
+                    logLevel = Level.ERROR;
+                } else {
+                    log.error("unsupported log level: {}",logLevelName);
+                }
+            }
+
+            if(logLevel != null) {
+                for(String logname : new String [] {"at","org","net","com"}) {
+
+                    ch.qos.logback.classic.Logger logger =
+                            (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(logname);
+                    logger.setLevel(logLevel);
+                }
+            }
+
+
+            String format = null;
+            if(cmd.hasOption("format")) {
+                format = cmd.getOptionValue("format");
+            }
+
+            FileBackend backend = null;
+            if(cmd.hasOption("file")) {
+                backend  = new FileBackend(cmd.getOptionValue("file"),format);
+            } else if(cmd.hasOption("url")) {
+                URL url = new URL(cmd.getOptionValue("url"));
+                backend  = new FileBackend(url,format);
+            }
+
+            Resource context = null;
+            if(cmd.hasOption("context")) {
+                context = backend.getRepository().getValueFactory().createURI(cmd.getOptionValue("context"));
+            }
+
+            if(backend != null && context != null) {
+                LDPath<Value> ldpath = new LDPath<Value>(backend);
+
+                if(cmd.hasOption("path")) {
+                    String path = cmd.getOptionValue("path");
+
+                    for(Value v : ldpath.pathQuery(context,path,null)) {
+                        System.out.println(v.stringValue());
+                    }
+                } else if(cmd.hasOption("program")) {
+                    File file = new File(cmd.getOptionValue("program"));
+
+                    Map<String,Collection<?>> result = ldpath.programQuery(context,new FileReader(file));
+
+                    for(String field : result.keySet()) {
+                        StringBuilder line = new StringBuilder();
+                        line.append(field);
+                        line.append(" = ");
+                        line.append("{");
+                        for(Iterator<?> it = result.get(field).iterator(); it.hasNext(); ) {
+                            line.append(it.next().toString());
+                            if(it.hasNext()) {
+                                line.append(", ");
+                            }
+                        }
+                        line.append("}");
+                        System.out.println(line);
+
+                    }
+                }
+            }
+
+
+        } catch (ParseException e) {
+            System.err.println("invalid arguments");
+            HelpFormatter formatter = new HelpFormatter();
+            formatter.printHelp( "FileQuery", options, true );
+        } catch (MalformedURLException e) {
+            System.err.println("url could not be parsed");
+            HelpFormatter formatter = new HelpFormatter();
+            formatter.printHelp("FileQuery", options, true);
+        } catch (LDPathParseException e) {
+            System.err.println("path or program could not be parsed");
+            e.printStackTrace();
+        } catch (FileNotFoundException e) {
+            System.err.println("file or program could not be found");
+            HelpFormatter formatter = new HelpFormatter();
+            formatter.printHelp("FileQuery", options, true);
+        }
+
+
+    }
+
+    @SuppressWarnings("static-access")
+    private static Options buildOptions() {
+        Options result = new Options();
+
+        OptionGroup input = new OptionGroup();
+        Option file = OptionBuilder.withArgName("file").hasArg().withDescription("query the contents of a file").create("file");
+        Option url = OptionBuilder.withArgName("url").hasArg().withDescription("query the contents of a remote URL").create("url");
+
+        input.addOption(file);
+        input.addOption(url);
+        input.setRequired(true);
+
+        result.addOptionGroup(input);
+
+        Option format = OptionBuilder.withArgName("mimetype").hasArg().withDescription("MIME type of the input document").create("format");
+        result.addOption(format);
+
+        OptionGroup query = new OptionGroup();
+        Option path = OptionBuilder.withArgName("path").hasArg().withDescription("LD Path to evaluate on the file starting from the context").create("path");
+        Option program = OptionBuilder.withArgName("file").hasArg().withDescription("LD Path program to evaluate on the file starting from the context").create("program");
+        query.addOption(path);
+        query.addOption(program);
+        query.setRequired(true);
+        result.addOptionGroup(query);
+
+        Option context = OptionBuilder.withArgName("uri").hasArg().withDescription("URI of the context node to start from").create("context");
+        context.setRequired(true);
+        result.addOption(context);
+
+        Option loglevel = OptionBuilder.withArgName("level").hasArg().withDescription("set the log level; default is 'warn'").create("loglevel");
+        result.addOption(loglevel);
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/java/ParserTest.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/java/ParserTest.java b/ldpath/ldpath-backend-file/src/test/java/ParserTest.java
new file mode 100644
index 0000000..3f0f87a
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/java/ParserTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import at.newmedialab.ldpath.api.selectors.NodeSelector;
+import at.newmedialab.ldpath.backend.sesame.SesameRepositoryBackend;
+import at.newmedialab.ldpath.model.programs.Program;
+import at.newmedialab.ldpath.model.selectors.PathSelector;
+import at.newmedialab.ldpath.model.selectors.PropertySelector;
+import at.newmedialab.ldpath.model.selectors.TestingSelector;
+import at.newmedialab.ldpath.model.selectors.UnionSelector;
+import at.newmedialab.ldpath.model.transformers.StringTransformer;
+import at.newmedialab.ldpath.parser.ParseException;
+import at.newmedialab.ldpath.parser.RdfPathParser;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.model.Value;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.memory.MemoryStore;
+
+import java.io.StringReader;
+import java.util.Map;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class ParserTest {
+
+    private static SesameRepositoryBackend backend;
+
+    @BeforeClass
+    public static void setupRepository() throws RepositoryException {
+        Repository repository = new SailRepository(new MemoryStore());
+        repository.initialize();
+
+        backend = new SesameRepositoryBackend(repository);
+    }
+
+
+
+    @Test
+    public void testParsePath() throws Exception {
+        String path1 = "rdfs:label";
+
+        NodeSelector<Value> s1 = parseSelector(path1, null);
+        Assert.assertTrue(s1 instanceof PropertySelector);
+        Assert.assertEquals("<http://www.w3.org/2000/01/rdf-schema#label>",s1.getPathExpression(backend));
+
+
+        Map<String,String> namespaces2 = ImmutableMap.of(
+                "dct","http://purl.org/dc/terms/",
+                "dbp-ont","http://dbpedia.org/ontology/"
+        );
+        String path2 = "(*[rdf:type is dbp-ont:Person]) | (dct:subject/^dct:subject[rdf:type is dbp-ont:Person]) | (dct:subject/^skos:broader/^dct:subject[rdf:type is dbp-ont:Person])";
+        NodeSelector<Value> s2 = parseSelector(path2,namespaces2);
+        Assert.assertTrue(s2 instanceof UnionSelector);
+
+        String path3 = "*[rdf:type is dbp-ont:Person] | dct:subject/^dct:subject[rdf:type is dbp-ont:Person] | dct:subject/^skos:broader/^dct:subject[rdf:type is dbp-ont:Person]";
+        NodeSelector<Value> s3 = parseSelector(path3,namespaces2);
+        Assert.assertTrue(s3 instanceof UnionSelector);
+        
+        Assert.assertEquals(s2,s3);
+
+        String path4 = "(* | dct:subject/^dct:subject | dct:subject/^skos:broader/^dct:subject)[rdf:type is dbp-ont:Person]";
+        NodeSelector<Value> s4 = parseSelector(path4,namespaces2);
+        Assert.assertTrue(s4 instanceof TestingSelector);
+    }
+
+    private NodeSelector<Value> parseSelector(String selector, Map<String,String> namespaces) throws ParseException {
+        return new RdfPathParser<Value>(backend,new StringReader(selector)).parseSelector(namespaces);
+    }
+
+    @Test
+    public void testParseProgram() throws Exception {
+
+        Program<Value> p1 = parseProgram(IOUtils.toString(ParserTest.class.getResource("stanbol.search")));
+        Assert.assertEquals(12,p1.getFields().size());
+        Assert.assertNull(p1.getBooster());
+        Assert.assertNotNull(p1.getFilter());
+        Assert.assertEquals(5,p1.getNamespaces().size());
+
+
+        Program<Value> p2 = parseProgram(IOUtils.toString(ParserTest.class.getResource("sn.search")));
+        Assert.assertEquals(11,p2.getFields().size());
+        Assert.assertNotNull(p2.getBooster());
+        Assert.assertNotNull(p2.getFilter());
+        Assert.assertEquals(8,p2.getNamespaces().size());
+
+        Program<Value> p3 = parseProgram(IOUtils.toString(ParserTest.class.getResource("orf.search")));
+        Assert.assertEquals(18,p3.getFields().size());
+        Assert.assertNull(p3.getBooster());
+        Assert.assertNotNull(p3.getFilter());
+        Assert.assertEquals(5, p3.getNamespaces().size());
+        Assert.assertNotNull(p3.getField("person"));
+        Assert.assertTrue(p3.getField("person").getSelector() instanceof PathSelector);
+        Assert.assertTrue(p3.getField("person").getTransformer() instanceof StringTransformer);
+
+    }
+
+    private Program<Value> parseProgram(String selector) throws ParseException {
+        return new RdfPathParser<Value>(backend,new StringReader(selector)).parseProgram();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/java/PathTest.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/java/PathTest.java b/ldpath/ldpath-backend-file/src/test/java/PathTest.java
new file mode 100644
index 0000000..f32f6bc
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/java/PathTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import at.newmedialab.ldpath.LDPath;
+import at.newmedialab.ldpath.backend.file.FileBackend;
+import at.newmedialab.ldpath.backend.sesame.SesameRepositoryBackend;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.model.Value;
+import org.openrdf.repository.RepositoryException;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasItems;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class PathTest {
+
+
+    private static SesameRepositoryBackend backend;
+    private static LDPath<Value> ldPath;
+
+    @BeforeClass
+    public static void setupRepository() throws RepositoryException {
+        backend = new FileBackend(PathTest.class.getResource("demo-data.foaf"),"application/rdf+xml");
+        ldPath = new LDPath<Value>(backend);
+    }
+
+    @Test
+    public void simpleResourcePath() throws Exception {
+
+        Map<Value, List<Value>> paths = new HashMap<Value, List<Value>>();
+        Collection<Value> values = ldPath.pathQuery(backend.createURI("http://localhost:8080/LMF/resource/hans_meier"), "foaf:interest", null, paths);
+        Assert.assertEquals(4,values.size());
+        Assert.assertThat(values,hasItems(
+                    backend.createURI("http://rdf.freebase.com/ns/en.software_engineering"),
+                    backend.createURI("http://rdf.freebase.com/ns/en.linux"),
+                    backend.createURI("http://dbpedia.org/resource/Java"),
+                    backend.createURI("http://dbpedia.org/resource/Climbing")
+                ));
+
+    }
+
+    @Test
+    public void simpleValuePath() throws Exception {
+
+        Collection<String> values = ldPath.pathTransform(backend.createURI("http://localhost:8080/LMF/resource/hans_meier"), "foaf:name :: xsd:string", null);
+        Assert.assertEquals(1,values.size());
+        Assert.assertThat(values,hasItem("Hans Meier"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/resources/demo-data.foaf
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/resources/demo-data.foaf b/ldpath/ldpath-backend-file/src/test/resources/demo-data.foaf
new file mode 100644
index 0000000..c80c76e
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/resources/demo-data.foaf
@@ -0,0 +1,62 @@
+<!--
+  ~ Copyright (c) 2011 Salzburg Research.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<rdf:RDF
+        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+        xmlns:foaf="http://xmlns.com/foaf/0.1/"
+        xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/hans_meier" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Hans Meier</foaf:name>
+        <dc:description>Hans Meier is a software engineer living in Salzburg</dc:description>
+        <foaf:interest rdf:resource="http://rdf.freebase.com/ns/en.software_engineering"/>
+        <foaf:interest rdf:resource="http://rdf.freebase.com/ns/en.linux"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Java" />
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Climbing"/>
+        <foaf:based_near rdf:resource="http://sws.geonames.org/2766824/"/>
+        <foaf:depiction rdf:resource="http://localhost:8080/LMF/resource/hans_meier.jpg"/>
+
+        <foaf:knows rdf:resource="http://bblfish.net/people/henry/card#me" />
+        <foaf:knows rdf:resource="http://dbpedia.org/resource/James_Gosling"/>
+    </foaf:Person>
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/sepp_huber" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Sepp Huber</foaf:name>
+        <dc:description>Sepp Huber is an alpinist living in Traunstein. He is a good climber, but not as famous as his cousin Alexander Huber.</dc:description>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Mountaineering"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Climbing"/>
+        <foaf:interest rdf:resource="http://localhost:8080/LMF/resource/Chess" />
+        <foaf:based_near rdf:resource="http://dbpedia.org/resource/Traunstein"/>
+
+        <foaf:knows rdf:resource="http://dbpedia.org/resource/Alexander_Huber" />
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/hans_meier" />
+    </foaf:Person>
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/anna_schmidt" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Anna Schmidt</foaf:name>
+        <dc:description>Anna Schmidt is working as PR manager for mountaineers coming from Garmisch-Partenkirchen. She likes mountaineering and is also a Linux enthusiast.</dc:description>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Mountaineering"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Linux"/>
+        <foaf:interest rdf:resource="http://localhost:8080/LMF/resource/Chess" />
+        <foaf:based_near rdf:resource="http://dbpedia.org/resource/Garmisch-Partenkirchen"/>
+        <foaf:depiction rdf:resource="http://localhost:8080/LMF/resource/anna_schmidt.jpg"/>
+
+        <foaf:knows rdf:resource="http://dbpedia.org/resource/Alexander_Huber" />
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/sepp_huber" />
+    </foaf:Person>
+
+
+</rdf:RDF>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/resources/orf.search
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/resources/orf.search b/ldpath/ldpath-backend-file/src/test/resources/orf.search
new file mode 100644
index 0000000..de5f174
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/resources/orf.search
@@ -0,0 +1,24 @@
+@prefix foaf : <http://xmlns.com/foaf/0.1/> ;
+@prefix geo : <http://www.w3.org/2003/01/geo/wgs84_pos#> ;
+@prefix basket : <http://www.orf.at/ontology/Entry/> ;
+@prefix orf : <http://www.orf.at/ontology/> ;
+@prefix hgtags : <http://www.holygoat.co.uk/owl/redwood/0.1/tags/> ;
+@filter rdf:type is orf:Entry ;
+  summary = basket:inhalt :: xsd:string ;
+  thumbnail = basket:keyframeIn :: xsd:anyURI ;
+  gestaltung = orf:Role_GES / rdfs:label :: xsd:string ;
+  tag = hgtags:taggedWithTag / hgtags:name :: xsd:string ;
+  type = rdf:type :: xsd:anyURI ;
+  other = orf:related / (rdfs:label[@de] | (rdfs:label[@none] | skos:prefLabel[@de])) :: xsd:string ;
+  lat = basket:location / geo:lat :: xsd:double ;
+  key = basket:key :: xsd:string ;
+  title = basket:subTitle :: xsd:string ;
+  pool = basket:pool :: xsd:string ;
+  title2 = basket:title :: xsd:string ;
+  countrycode = basket:location / <http://www.geonames.org/ontology#countryCode> :: xsd:string ;
+  location = (basket:location / <http://www.geonames.org/ontology#name>) | (orf:relatedPlace / (rdfs:label[@de] | rdfs:label[@none])) :: xsd:string ;
+  date = basket:broadcastDate :: xsd:dateTime ;
+  person = (orf:Role_IMB | (orf:Role_RDE | orf:relatedPerson)) / rdfs:label :: xsd:string ;
+  long = basket:location / geo:long :: xsd:double ;
+  moderator = orf:Role_MOD / rdfs:label :: xsd:string ;
+  company = orf:relatedOrganisation / (rdfs:label[@de] | rdfs:label[@none]) :: xsd:string ;

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/resources/sn.search
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/resources/sn.search b/ldpath/ldpath-backend-file/src/test/resources/sn.search
new file mode 100644
index 0000000..4ff01a6
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/resources/sn.search
@@ -0,0 +1,24 @@
+@prefix dc : <http://purl.org/dc/elements/1.1/> ;
+@prefix sn : <http://lmf.salzburg.com/news-ns/> ;
+@prefix snc : <http://lmf.salzburg.com/news-ns/concepts/> ;
+@prefix iptc : <http://iptc.org/std/nar/2006-10-01/> ;
+@prefix hg : <http://www.holygoat.co.uk/owl/redwood/0.1/tags/> ;
+@prefix geo : <http://www.geonames.org/ontology#> ;
+@prefix wgs84 : <http://www.w3.org/2003/01/geo/wgs84_pos#> ;
+@prefix skos : <http://www.w3.org/2004/02/skos/core#> ;
+
+@filter rdf:type is snc:PublicationItem ;
+
+@boost sn:boostFactor ;
+
+  tag = hg:taggedWithTag / hg:name :: xsd:string ;
+  ressort = (sn:inRessort | sn:inCategory | ((sn:inRessort | sn:inCategory) / (skos:narrower)+)) / fn:first(skos:prefLabel[@de], skos:prefLabel) :: xsd:string ;
+  real_ressort = (sn:inRessort | sn:inCategory) / fn:first(skos:prefLabel[@de], skos:prefLabel) :: xsd:string ;
+  ort = iptc:located / fn:first(geo:officialName[@de], geo:alternateName[@de], geo:name[@de], geo:name) :: xsd:string ;
+  countrycode = iptc:located / geo:countryCode :: xsd:string ;
+  title = dc:title :: xsd:string ;
+  summary = fn:removeTags(dc:description) :: xsd:string ;
+  kind = rdf:type / rdfs:label :: xsd:string ;
+  type = rdf:type :: xsd:anyURI ;
+  thumbnail = sn:hasPreviewImage :: xsd:anyURI ;
+  geo =  iptc:located :: xsd:string ;

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-file/src/test/resources/stanbol.search
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-file/src/test/resources/stanbol.search b/ldpath/ldpath-backend-file/src/test/resources/stanbol.search
new file mode 100644
index 0000000..e11062c
--- /dev/null
+++ b/ldpath/ldpath-backend-file/src/test/resources/stanbol.search
@@ -0,0 +1,18 @@
+@prefix foaf : <http://xmlns.com/foaf/0.1/> ;
+@prefix geo : <http://www.w3.org/2003/01/geo/wgs84_pos#> ;
+@prefix hgtags : <http://www.holygoat.co.uk/owl/redwood/0.1/tags/> ;
+@prefix dcterms : <http://purl.org/dc/terms/> ;
+@prefix labs : <http://labs.newmedialab.at/ontology/> ;
+@filter rdf:type is foaf:Document ;
+  summary = fn:removeTags(fn:cleanHtml(dc:description)) :: xsd:string ;
+  tag = hgtags:taggedWithTag / hgtags:name :: xsd:string ;
+  other = labs:related / (rdfs:label[@en] | (rdfs:label[@none] | skos:prefLabel[@en])) :: xsd:string ;
+  lat = labs:relatedLocation / geo:lat :: xsd:double ;
+  title = dcterms:title :: xsd:string ;
+  long = labs:relatedLocation / geo:long :: xsd:double ;
+  location = labs:relatedLocation / rdfs:label[@en] :: xsd:string ;
+  countrycode = labs:relatedLocation / <http://www.geonames.org/ontology#countryCode> :: xsd:string ;
+  type = rdf:type :: xsd:anyURI ;
+  person = labs:relatedPerson / rdfs:label[@en] :: xsd:string ;
+  date = dcterms:created :: xsd:dateTime ;
+  company = labs:relatedOrganisation / rdfs:label[@en] :: xsd:string ;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/.classpath
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/.classpath b/ldpath/ldpath-backend-jena/.classpath
new file mode 100644
index 0000000..595a5bf
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/.project
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/.project b/ldpath/ldpath-backend-jena/.project
new file mode 100644
index 0000000..11bbb46
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ldpath-backend-jena</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/.settings/org.eclipse.core.resources.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/.settings/org.eclipse.core.resources.prefs b/ldpath/ldpath-backend-jena/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..2b76340
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/.settings/org.eclipse.jdt.core.prefs b/ldpath/ldpath-backend-jena/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..60105c1
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/.settings/org.eclipse.m2e.core.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/.settings/org.eclipse.m2e.core.prefs b/ldpath/ldpath-backend-jena/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/pom.xml
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/pom.xml b/ldpath/ldpath-backend-jena/pom.xml
new file mode 100644
index 0000000..fcc3173
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2013 Salzburg Research.
+  ~
+  ~  Licensed under the Apache License, Version 2.0 (the "License");
+  ~  you may not use this file except in compliance with the License.
+  ~  You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>at.newmedialab.ldpath</groupId>
+        <artifactId>ldpath-parent</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+    </parent>
+
+    <name>LDPath Backend: Jena</name>
+    <artifactId>ldpath-backend-jena</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+
+        <dependency>
+            <groupId>at.newmedialab.ldpath</groupId>
+            <artifactId>ldpath-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>at.newmedialab.ldpath</groupId>
+            <artifactId>ldpath-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.jena</groupId>
+            <artifactId>jena-core</artifactId>
+            <version>2.7.3</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-jena/src/main/java/at/newmedialab/ldpath/backend/jena/GenericJenaBackend.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-jena/src/main/java/at/newmedialab/ldpath/backend/jena/GenericJenaBackend.java b/ldpath/ldpath-backend-jena/src/main/java/at/newmedialab/ldpath/backend/jena/GenericJenaBackend.java
new file mode 100644
index 0000000..bac4c91
--- /dev/null
+++ b/ldpath/ldpath-backend-jena/src/main/java/at/newmedialab/ldpath/backend/jena/GenericJenaBackend.java
@@ -0,0 +1,468 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldpath.backend.jena;
+
+import at.newmedialab.ldpath.api.backend.RDFBackend;
+import at.newmedialab.ldpath.util.FormatUtils;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterators;
+import com.hp.hpl.jena.datatypes.TypeMapper;
+import com.hp.hpl.jena.rdf.model.Literal;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.Statement;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Locale;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class GenericJenaBackend implements RDFBackend<RDFNode> {
+
+
+    private Model model;
+
+    public GenericJenaBackend(Model model) {
+        this.model = model;
+    }
+
+
+    /**
+     * Return true if the underlying backend supports the parallel execution of queries.
+     *
+     * @return
+     */
+    @Override
+    public boolean supportsThreading() {
+        return false;
+    }
+
+
+    /**
+     * In case the backend supports threading, this method should return the ExecutorService representing the
+     * thread pool. LDPath lets the backend manage the thread pool to avoid excessive threading.
+     *
+     * @return
+     */
+    @Override
+    public ThreadPoolExecutor getThreadPool() {
+        return null;
+    }
+
+    /**
+     * Test whether the node passed as argument is a literal
+     *
+     * @param n the node to check
+     * @return true if the node is a literal
+     */
+    @Override
+    public boolean isLiteral(RDFNode n) {
+        return n.isLiteral();
+    }
+
+    /**
+     * Test whether the node passed as argument is a URI
+     *
+     * @param n the node to check
+     * @return true if the node is a URI
+     */
+    @Override
+    public boolean isURI(RDFNode n) {
+        return n.isURIResource();
+    }
+
+    /**
+     * Test whether the node passed as argument is a blank node
+     *
+     * @param n the node to check
+     * @return true if the node is a blank node
+     */
+    @Override
+    public boolean isBlank(RDFNode n) {
+        return n.isAnon();
+    }
+
+    /**
+     * Return the language of the literal node passed as argument.
+     *
+     * @param n the literal node for which to return the language
+     * @return a Locale representing the language of the literal, or null if the literal node has no language
+     * @throws IllegalArgumentException in case the node is no literal
+     */
+    @Override
+    public Locale getLiteralLanguage(RDFNode n) {
+        if(n.isLiteral()) {
+            if (((Literal)n).getLanguage() != null) {
+                return new Locale(((Literal)n).getLanguage());
+            } else {
+                return null;
+            }
+        } else {
+            throw new IllegalArgumentException("the node "+n+" is not a literal, cannot return language");
+        }
+    }
+
+    /**
+     * Return the URI of the type of the literal node passed as argument.
+     *
+     * @param n the literal node for which to return the typer
+     * @return a URI representing the type of the literal content, or null if the literal is untyped
+     * @throws IllegalArgumentException in case the node is no literal
+     */
+    @Override
+    public URI getLiteralType(RDFNode n) {
+        if(n.isLiteral()) {
+            if (((Literal)n).getLanguage() != null) {
+                try {
+                    return new URI(((Literal)n).getDatatypeURI());
+                } catch (URISyntaxException e) {
+                    throw new IllegalArgumentException("the type of node "+n+" was not a valid URI");
+                }
+            } else {
+                return null;
+            }
+        } else {
+            throw new IllegalArgumentException("the node "+n+" is not a literal, cannot return literal type");
+        }
+    }
+
+    /**
+     * Create a literal node with the content passed as argument
+     *
+     * @param content string content to represent inside the literal
+     * @return a literal node in using the model used by this backend
+     */
+    @Override
+    public RDFNode createLiteral(String content) {
+        return model.createLiteral(content);
+    }
+
+    /**
+     * Create a literal node with the content passed as argument
+     *
+     * @param content string content to represent inside the literal
+     * @return a literal node in using the model used by this backend
+     */
+    @Override
+    public RDFNode createLiteral(String content, Locale language, URI type) {
+        if(language != null && type == null) {
+            return model.createLiteral(content,language.getLanguage());
+        } else if(language == null && type != null) {
+            return model.createTypedLiteral(content, TypeMapper.getInstance().getSafeTypeByName(type.toString()));
+        } else {
+            return model.createLiteral(content);
+        }
+    }
+
+    /**
+     * Create a URI mode with the URI passed as argument
+     *
+     * @param uri URI of the resource to create
+     * @return a URI node using the model used by this backend
+     */
+    @Override
+    public RDFNode createURI(String uri) {
+        return model.createProperty(uri);
+    }
+
+    /**
+     * Return the lexial representation of a node. For a literal, this will be the content, for a URI node it will be the
+     * URI itself, and for a blank node it will be the identifier of the node.
+     *
+     * @param rdfNode
+     * @return
+     */
+    @Override
+    public String stringValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getString();
+        } else if(isURI(rdfNode)) {
+            return ((Resource)rdfNode).getURI();
+        } else if(isBlank(rdfNode)) {
+            return ((Resource)rdfNode).getId().getLabelString();
+        } else {
+            return rdfNode.toString();
+        }
+    }
+
+    /**
+     * Return the double value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as double, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal
+     *
+     * @param rdfNode the literal node for which to return the double value
+     * @return double value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as double value
+     * @throws ArithmeticException      in case the literal cannot be represented as double value
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Double doubleValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getDouble();
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the long value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as long, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal
+     *
+     * @param rdfNode the literal node for which to return the long value
+     * @return long value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as long value
+     * @throws ArithmeticException      in case the literal cannot be represented as long value
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Long longValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getLong();
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the boolean value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation.
+     * TODO: Define:<ul>
+     * <li> Do we also support '0' '1', 'yes', 'no'; whats about case insensitive
+     * such as TRUE, False
+     * <li> should we throw an RuntimeException of not an boolean value or return
+     * false as {@link Boolean#parseBoolean(String)}
+     * </ul>
+     *
+     * @param rdfNode the literal node for which to return the boolean value
+     * @return long value of the literal node
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Boolean booleanValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getBoolean();
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * TODO
+     *
+     * @param rdfNode the literal node for which to return the dateTime value
+     * @return long value of the literal node
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Date dateTimeValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return FormatUtils.parseDate(((Literal)rdfNode).getString());
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * TODO
+     *
+     * @param rdfNode the literal node for which to return the date value
+     * @return long value of the literal node
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Date dateValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return FormatUtils.parseDate(((Literal)rdfNode).getString());
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * TODO
+     *
+     * @param rdfNode the literal node for which to return the time value
+     * @return long value of the literal node
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Date timeValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return FormatUtils.parseDate(((Literal)rdfNode).getString());
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the float value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as float, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal
+     *
+     * @param rdfNode the literal node for which to return the float value
+     * @return long value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as float value
+     * @throws ArithmeticException      in case the literal cannot be represented as float value
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Float floatValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getFloat();
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the 32bit integer value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as integer, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal.
+     * <p/>
+     * Note that this is restricted to 32bit singed integer values as defined by
+     * xsd:int and {@link Integer}. For bigger nuber one might want to use
+     * xsd:integer represented by {@link java.math.BigInteger}.
+     *
+     * @param rdfNode the literal node for which to return the Integer (xsd:int) value
+     * @return long value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as 32 bit integer value
+     * @throws ArithmeticException      in case the literal cannot be represented as 32 bit integer value
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public Integer intValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return ((Literal)rdfNode).getInt();
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the arbitrary length integer value of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as integer, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal.
+     *
+     * @param rdfNode the literal node for which to return the {@link java.math.BigInteger xsd:integer} value
+     * @return long value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as integer value
+     * @throws ArithmeticException      in case the literal cannot be represented as long value
+     * @throws IllegalArgumentException in case the node passed as argument is integer a literal
+     */
+    @Override
+    public BigInteger integerValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return new BigInteger(((Literal)rdfNode).getString());
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * Return the decimal number of a literal node. Depending on the backend implementing this method,
+     * the value can be retrieved directly or must be parsed from the string representation. The method can throw
+     * a NumberFormatException or ArithmeticException indicating that the value cannot be represented as decimal, and an
+     * IllegalArgumentException, indicating that the passed node is not a literal.
+     *
+     * @param rdfNode the literal node for which to return the xsd:decimal value
+     * @return long value of the literal node
+     * @throws NumberFormatException    in case the literal cannot be represented as decimal value
+     * @throws ArithmeticException      in case the literal cannot be represented as decimal value
+     * @throws IllegalArgumentException in case the node passed as argument is not a literal
+     */
+    @Override
+    public BigDecimal decimalValue(RDFNode rdfNode) {
+        if(isLiteral(rdfNode)) {
+            return new BigDecimal(((Literal)rdfNode).getString());
+        } else {
+            throw new IllegalArgumentException("the node "+rdfNode+" is not a literal value");
+        }
+    }
+
+    /**
+     * List the objects of triples in the triple store underlying this backend that have the subject and
+     * property given as argument.
+     *
+     * @param subject  the subject of the triples to look for
+     * @param property the property of the triples to look for, <code>null</code> is interpreted as wildcard
+     * @return all objects of triples with matching subject and property
+     */
+    @Override
+    public Collection<RDFNode> listObjects(RDFNode subject, RDFNode property) {
+        try {
+            return ImmutableSet.copyOf(
+                    Iterators.transform(
+                            model.listStatements((Resource)subject,(Property)property,(RDFNode)null),
+                            new Function<Statement, RDFNode>() {
+                                @Override
+                                public RDFNode apply(Statement input) {
+                                    return input.getObject();
+                                }
+                            })
+            );
+
+        } catch(ClassCastException ex) {
+            throw new IllegalArgumentException("subject or property where no valid resources in the Jena model",ex);
+        }
+
+    }
+
+    /**
+     * List the subjects of triples in the triple store underlying this backend that have the object and
+     * property given as argument.
+     *
+     * @param object   the object of the triples to look for
+     * @param property the property of the triples to look for, <code>null</code> is interpreted as wildcard
+     * @return all subjects of triples with matching object and property
+     * @throws UnsupportedOperationException in case reverse selection is not supported (e.g. when querying Linked Data)
+     */
+    @Override
+    public Collection<RDFNode> listSubjects(RDFNode property, RDFNode object) {
+        try {
+            return ImmutableSet.copyOf(
+                    Iterators.transform(
+                            model.listStatements((Resource)null,(Property)property,object),
+                            new Function<Statement, RDFNode>() {
+                                @Override
+                                public RDFNode apply(Statement input) {
+                                    return input.getSubject();
+                                }
+                            })
+            );
+            } catch(ClassCastException ex) {
+            throw new IllegalArgumentException("property was no valid resource in the Jena model",ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/.classpath
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/.classpath b/ldpath/ldpath-backend-linkeddata/.classpath
new file mode 100644
index 0000000..da5037b
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/.project
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/.project b/ldpath/ldpath-backend-linkeddata/.project
new file mode 100644
index 0000000..2181a8b
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ldpath-backend-linkeddata</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.core.resources.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.core.resources.prefs b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..8fb0e26
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.jdt.core.prefs b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..60105c1
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.m2e.core.prefs
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.m2e.core.prefs b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/pom.xml
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/pom.xml b/ldpath/ldpath-backend-linkeddata/pom.xml
new file mode 100644
index 0000000..e6638c8
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/pom.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2013 Salzburg Research.
+  ~
+  ~  Licensed under the Apache License, Version 2.0 (the "License");
+  ~  you may not use this file except in compliance with the License.
+  ~  You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>at.newmedialab.ldpath</groupId>
+        <artifactId>ldpath-parent</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+    </parent>
+
+    <name>LDPath Backend: Linked Data</name>
+    <artifactId>ldpath-backend-linkeddata</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>at.newmedialab.ldpath</groupId>
+            <artifactId>ldpath-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>at.newmedialab.ldpath</groupId>
+            <artifactId>ldpath-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>at.newmedialab.ldpath</groupId>
+            <artifactId>ldpath-backend-sesame</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-sail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-event</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-rdfxml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-trix</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-turtle</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-n3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-ntriples</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-trig</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-memory</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-nativerdf</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+       </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.fusesource.jdbm</groupId>
+            <artifactId>jdbm</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+
+
+    </dependencies>
+
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/api/LDCacheProvider.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/api/LDCacheProvider.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/api/LDCacheProvider.java
new file mode 100644
index 0000000..5f0d523
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/api/LDCacheProvider.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.api;
+
+import at.newmedialab.ldclient.model.CacheEntry;
+import at.newmedialab.ldclient.model.Endpoint;
+import org.openrdf.repository.Repository;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * An interface specifying a factory that provides different caching mechanisms, e.g. in-memory or file storage.
+ * A cache provider typically offers two kinds of caching services, one for the retrieved triples (a sesame repository)
+ * and one for the caching metadata (a map from URIs to CacheEntry).
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public interface LDCacheProvider {
+
+    /**
+     * Return the sesame repository used for storing the triples that are retrieved from the Linked Data Cloud.
+     * Triples will always be added to the context http://www.newmedialab.at/ldclient/cache to be able to distinguish
+     * them from other triples.
+     *
+     * @return an initialised Sesame repository that can be used for caching triples
+     */
+    public Repository getTripleRepository();
+
+
+    /**
+     * Return a map that can be used to store caching metadata about resources. The LDCacheProvider should take care
+     * of persisting the metadata if desired.
+     *
+     * @return a map for storing caching metadata
+     */
+    public Map<String,CacheEntry> getMetadataRepository();
+
+    /**
+     * Register a new Linked Data endpoint with this cache provider.
+     *
+     * @param endpoint
+     */
+    public void registerEndpoint(Endpoint endpoint);
+
+
+    /**
+     * List all endpoints currently registered with the Linked Data cache provider.
+     * @return a collection of endpoints
+     */
+    public Collection<Endpoint> listEndpoints();
+
+    /**
+     * Unregister the Linked Data endpoint given as argument.
+     *
+     * @param endpoint the endpoint to unregister
+     */
+    public void unregisterEndpoint(Endpoint endpoint);
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/exception/LDClientException.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/exception/LDClientException.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/exception/LDClientException.java
new file mode 100644
index 0000000..a376df8
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/exception/LDClientException.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.exception;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class LDClientException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new exception with <code>null</code> as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     */
+    public LDClientException() {
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * @param message the detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     */
+    public LDClientException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * <code>cause</code> is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *                by the {@link #getMessage()} method).
+     * @param cause   the cause (which is saved for later retrieval by the
+     *                {@link #getCause()} method).  (A <tt>null</tt> value is
+     *                permitted, and indicates that the cause is nonexistent or
+     *                unknown.)
+     * @since 1.4
+     */
+    public LDClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *              {@link #getCause()} method).  (A <tt>null</tt> value is
+     *              permitted, and indicates that the cause is nonexistent or
+     *              unknown.)
+     * @since 1.4
+     */
+    public LDClientException(Throwable cause) {
+        super(cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/CacheEntry.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/CacheEntry.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/CacheEntry.java
new file mode 100644
index 0000000..6c8e876
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/CacheEntry.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.model;
+
+import org.openrdf.model.URI;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * The cache entry for a URI resource managed by the Linked Data Cache. Contains maintenance information about
+ * the resource, i.e. when it has been retrieved last, when to retrieve it next, etc.
+ * <p/>
+ * User: sschaffe
+ */
+public class CacheEntry implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The URI resource managed by this cache entry.
+     */
+    private URI resource;
+
+    /**
+     * The date when this resource has been retrieved the last time.
+     */
+    private Date lastRetrieved;
+
+
+    /**
+     * The date when this resource needs to be retrieved again according to expiry configuration.
+     */
+    private Date expiryDate;
+
+
+    /**
+     * The number of times this resource has already been updated.
+     */
+    private Long updateCount;
+
+
+
+    public CacheEntry() {
+    }
+
+    public URI getResource() {
+        return resource;
+    }
+
+    public void setResource(URI resource) {
+        this.resource = resource;
+    }
+
+    public Date getLastRetrieved() {
+        return lastRetrieved;
+    }
+
+    public void setLastRetrieved(Date lastRetrieved) {
+        this.lastRetrieved = lastRetrieved;
+    }
+
+    public Date getExpiryDate() {
+        return expiryDate;
+    }
+
+    public void setExpiryDate(Date expiryDate) {
+        this.expiryDate = expiryDate;
+    }
+
+    public Long getUpdateCount() {
+        return updateCount;
+    }
+
+    public void setUpdateCount(Long updateCount) {
+        this.updateCount = updateCount;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/ClientResponse.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/ClientResponse.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/ClientResponse.java
new file mode 100644
index 0000000..ac6e3e0
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/ClientResponse.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.model;
+
+import org.openrdf.repository.Repository;
+
+import java.util.Date;
+
+/**
+ * Add file description here!
+ * <p/>
+ * User: sschaffe
+ */
+public class ClientResponse {
+
+    private Repository triples;
+
+    private Date expires;
+
+    public ClientResponse(Repository triples) {
+        this.triples = triples;
+    }
+
+    public Repository getTriples() {
+        return triples;
+    }
+
+    public void setTriples(Repository triples) {
+        this.triples = triples;
+    }
+
+    public Date getExpires() {
+        return expires;
+    }
+
+    public void setExpires(Date expires) {
+        this.expires = expires;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/Endpoint.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/Endpoint.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/Endpoint.java
new file mode 100644
index 0000000..eccf517
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/model/Endpoint.java
@@ -0,0 +1,270 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.model;
+
+import org.openrdf.model.URI;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Definition of a Linked Data Endpoint. Contains information how to query the
+ * endpoint, what format to expect, and when to expire data from this endpoint.
+ * <p/>
+ * <ul>
+ * <li> {@link EndpointType#LINKEDDATA} endpoints will be accessed by directly
+ * retrieving the URI with appropriate Accept headers following the Linked Data
+ * recommendations
+ * <li> {@link EndpointType#CACHE} endpoints will be accessed by passing the URI
+ * as request parameter to the cache and parsing the response according to the
+ * content type defined for this endpoint (Content-Type header is too
+ * unspecific)
+ * <li> {@link EndpointType#SPARQL} endpoints will be accessed by issuing a query
+ * of <code>SELECT ?p ?o WHERE { {url} ?p ?o }</code> to retrieve all triples
+ * for the requested resource
+ * <li> {@link EndpointType#NONE} act as blacklist. Resources matching handled by
+ * this endpoint are not fetched.
+ * </ul>
+ * <p/>
+ * User: sschaffe
+ */
+
+public class Endpoint {
+
+
+	private Long id;
+
+
+	/**
+	 * A human-readable name for this endpoint.
+	 */
+	private String name;
+
+	/**
+	 * The type of the endpoint. One of LINKEDDATA, CACHE, or SPARQL
+	 */
+	private EndpointType type;
+
+
+	public static final String REGEX_INDICATOR = "~";
+
+	/**
+	 * URI prefix managed by the endpoint. All resources matching the URI prefix
+	 * are handled by this endpoint. {@link #uriPrefix} starting with
+	 * <code>{@value #REGEX_INDICATOR}</code> are interpreted as <i>regular
+	 * expression</i> (which may not be a prefix).
+	 *
+	 * @see java.util.regex.Pattern
+	 */
+	private String uriPrefix;
+
+	private Pattern uriPattern = null;
+
+	/**
+	 * The HTTP URL to access the endpoint. Occurrences of the string {uri} will
+	 * be replaced by the resource URI of the queried resource for CACHE
+	 * endpoints. Occurrences of the string {query} will be replaced by the
+	 * SPARQL query for the requested resource for SPARQL endpoints.
+	 *
+	 * Requried for SPARQL and CACHE endpoints, ignored for LINKEDDATA endpoints
+	 *
+	 * <pre>
+	 * Examples:
+	 * - Sindice: http://api.sindice.com/v2/live?url={uri}
+	 *        or  http://api.sindice.com/v2/cache?url={uri}
+	 *        or  http://sparql.sindice.com/sparql?default-graph-uri=&query={query}&format=text%2Fhtml&debug=on
+	 * - Stanbol: http://dev.iks-project.eu:8080/entityhub/lookup/?id={uri}&create=false
+	 * </pre>
+	 */
+	private String endpointUrl;
+
+
+	/**
+	 * The content type (MIME) returned by this endpoint. Used to determine how to parse the result.
+	 */
+	private String contentType;
+
+
+	/**
+	 * The default expiry time in seconds to use for this endpoint if the HTTP request does not explicitly return an
+	 * expiry time.
+	 */
+	private Long defaultExpiry;
+
+
+
+	public Endpoint() {
+	}
+
+
+	public Endpoint(String name, EndpointType type, String uriPrefix, String endpointUrl, String contentType, Long defaultExpiry) {
+		this.name = name;
+		this.type = type;
+		this.uriPrefix = uriPrefix;
+		this.endpointUrl = endpointUrl;
+		this.contentType = contentType;
+		this.defaultExpiry = defaultExpiry;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public EndpointType getType() {
+		return type;
+	}
+
+	public void setType(EndpointType type) {
+		this.type = type;
+	}
+
+	public String getUriPrefix() {
+		return uriPrefix;
+	}
+
+	public void setUriPrefix(String uriPrefix) {
+		this.uriPrefix = uriPrefix;
+	}
+
+	public String getEndpointUrl() {
+		return endpointUrl;
+	}
+
+	public void setEndpointUrl(String endpointUrl) {
+		this.endpointUrl = endpointUrl;
+	}
+
+	public String getContentType() {
+		return contentType;
+	}
+
+	public void setContentType(String contentType) {
+		this.contentType = contentType;
+	}
+
+	public Long getDefaultExpiry() {
+		return defaultExpiry;
+	}
+
+	public void setDefaultExpiry(Long defaultExpiry) {
+		this.defaultExpiry = defaultExpiry;
+	}
+
+
+	/**
+	 * Check if this {@link Endpoint} handles (is responsible) for this {@link URI}.
+	 *
+	 * @param resource the Resource to check
+	 * @return <code>true</code> if the {@link javax.annotation.Resource}'s uri matches the endpoint's {@link #uriPrefix}
+	 *
+	 * @see #uriPrefix
+	 */
+	public boolean handles(URI resource) {
+		return handles(resource.stringValue());
+	}
+
+
+	/**
+	 * Check if this {@link Endpoint} handles (is responsible) for this URI.
+	 * 
+	 * @param uri the URI to check
+	 * @return <code>true</code> if the uri matches the endpoint's {@link #uriPrefix}
+	 * 
+	 * @see #uriPrefix
+	 */
+	public boolean handles(String uri) {
+		if (uriPrefix.startsWith(REGEX_INDICATOR)) {
+			try {
+				if (uriPattern == null) {
+					uriPattern = Pattern.compile(uriPrefix.substring(REGEX_INDICATOR.length()));
+				}
+				return uriPattern.matcher(uri).find();
+			} catch (PatternSyntaxException pse) {
+				return false;
+			}
+		} else {
+			return uri.startsWith(uriPrefix);
+		}
+	}
+
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) {
+			return true;
+		}
+		if (o == null || getClass() != o.getClass()) {
+			return false;
+		}
+
+		Endpoint endpoint = (Endpoint) o;
+
+		if (name != null ? !name.equals(endpoint.name) : endpoint.name != null) {
+			return false;
+		}
+		if (type != endpoint.type) {
+			return false;
+		}
+		if (uriPrefix != null ? !uriPrefix.equals(endpoint.uriPrefix) : endpoint.uriPrefix != null) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int result = name != null ? name.hashCode() : 0;
+		result = 31 * result + (type != null ? type.hashCode() : 0);
+		result = 31 * result + (uriPrefix != null ? uriPrefix.hashCode() : 0);
+		return result;
+	}
+
+	public enum EndpointType {
+		/**
+		 * Endpoint is a SPARQL endpoint that needs to be queried
+		 */
+		SPARQL,
+
+		/**
+		 * Endpoint is direct access to a linked data source
+		 */
+		LINKEDDATA,
+
+		/**
+		 * Endpoint is a triple cache that can be accessed by passing the resource URI as request parameter
+		 */
+		CACHE,
+
+		/**
+		 * Endpoint does not retrieve external triples
+		 */
+		NONE
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/32a909f7/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/service/LDCache.java
----------------------------------------------------------------------
diff --git a/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/service/LDCache.java b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/service/LDCache.java
new file mode 100644
index 0000000..48228a6
--- /dev/null
+++ b/ldpath/ldpath-backend-linkeddata/src/main/java/at/newmedialab/ldclient/service/LDCache.java
@@ -0,0 +1,212 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.newmedialab.ldclient.service;
+
+import at.newmedialab.ldclient.api.LDCacheProvider;
+import at.newmedialab.ldclient.exception.LDClientException;
+import at.newmedialab.ldclient.model.CacheEntry;
+import at.newmedialab.ldclient.model.ClientResponse;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.RepositoryResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class LDCache {
+
+    private static final String CTX_CACHE = "http://www.newmedialab.at/ldclient/cache";
+
+    private Logger log = LoggerFactory.getLogger(LDCache.class);
+
+    private LDClient clientService;
+
+    private LDEndpoints endpointService;
+
+
+    private ThreadLocal<Boolean> inProgress = new ThreadLocal<Boolean>();
+
+
+    private LDCacheProvider cacheProvider;
+
+    // lock a resource while refreshing it so that not several threads trigger a refresh at the same time
+    private HashMap<URI,Lock> resourceLocks;
+
+    private Configuration config;
+
+
+    public LDCache(LDCacheProvider ldCacheProvider) {
+        log.info("Linked Data Caching Service initialising ...");
+        try {
+            config = new PropertiesConfiguration("ldclient.properties");
+        } catch (ConfigurationException e) {
+            log.warn("could not load configuration file ldclient.properties from current directory, home directory, or classpath");
+        }
+
+        resourceLocks = new HashMap<URI, Lock>();
+
+        cacheProvider   = ldCacheProvider;
+        clientService   = new LDClient();
+        endpointService = new LDEndpoints();
+    }
+
+
+    private void lockResource(URI resource) {
+        Lock lock;
+        synchronized (resourceLocks) {
+            lock = resourceLocks.get(resource);
+            if(lock == null) {
+                lock = new ReentrantLock();
+                resourceLocks.put(resource,lock);
+            }
+        }
+        lock.lock();
+    }
+
+    private void unlockResource(URI resource) {
+        Lock lock;
+        synchronized (resourceLocks) {
+            lock = resourceLocks.remove(resource);
+        }
+        if(lock != null) {
+            lock.unlock();
+        }
+    }
+
+
+    /**
+     * Refresh the cached resource passed as argument. The method will do nothing for local resources.
+     * Calling the method will carry out the following tasks:
+     * 1. check whether the resource is a remote resource; if no, returns immediately
+     * 2. check whether the resource has a cache entry; if no, goto 4
+     * 3. check whether the expiry time of the cache entry has passed; if no, returns immediately
+     * 4. retrieve the triples for the resource from the Linked Data Cloud using the methods offered by the
+     * LinkedDataClientService (registered endpoints etc); returns immediately if the result is null or
+     * an exception is thrown
+     * 5. remove all old triples for the resource and add all new triples for the resource
+     * 6. create new expiry information of the cache entry and persist it in the transaction
+     *
+     * @param resource
+     */
+    public void refreshResource(URI resource) {
+
+        lockResource(resource);
+        try {
+
+            // 2. check whether the resource has a cache entry; if no, goto 4
+            CacheEntry entry = getCacheEntry(resource);
+
+            // 3. check whether the expiry time of the cache entry has passed; if no, returns immediately
+            if(entry != null && entry.getExpiryDate().after(new Date())) {
+                log.info("not refreshing resource {}, as the cached entry is not yet expired",resource);
+                return;
+            }
+
+            // 4.
+            log.debug("refreshing resource {}",resource);
+            try {
+                ClientResponse response = clientService.retrieveResource(resource);
+
+                if(response != null) {
+                    log.info("refreshed resource {}",resource);
+
+                    URI context = cacheProvider.getTripleRepository().getValueFactory().createURI(CTX_CACHE);
+
+
+                    RepositoryConnection lmfConnection = cacheProvider.getTripleRepository().getConnection();
+                    RepositoryConnection respConnection = response.getTriples().getConnection();
+
+                    lmfConnection.remove(resource,null,null,context);
+
+
+                    RepositoryResult<Statement> triples = respConnection.getStatements(null,null,null,true);
+                    while(triples.hasNext()) {
+                        Statement triple = triples.next();
+                        try {
+                            lmfConnection.add(triple,context);
+                        } catch (RuntimeException ex) {
+                            log.warn("not adding triple {}: an exception occurred ({})",triple,ex.getMessage());
+                        }
+                    }
+                    lmfConnection.commit();
+
+                    lmfConnection.close();
+                    respConnection.close();
+
+                    CacheEntry newEntry = new CacheEntry();
+                    newEntry.setResource(resource);
+                    newEntry.setExpiryDate(response.getExpires());
+                    newEntry.setLastRetrieved(new Date());
+                    if(entry != null) {
+                        newEntry.setUpdateCount(entry.getUpdateCount()+1);
+                    } else {
+                        newEntry.setUpdateCount((long)1);
+                    }
+
+                    cacheProvider.getMetadataRepository().put(resource.stringValue(),newEntry);
+
+                }
+
+            } catch (LDClientException e) {
+                // on exception, save an expiry information and retry in one day
+                CacheEntry newEntry = new CacheEntry();
+                newEntry.setResource(resource);
+                newEntry.setExpiryDate(new Date(System.currentTimeMillis() + config.getInt("expiry", 86400)*1000));
+                newEntry.setLastRetrieved(new Date());
+                if(entry != null) {
+                    newEntry.setUpdateCount(entry.getUpdateCount()+1);
+                } else {
+                    newEntry.setUpdateCount((long)1);
+                }
+
+                cacheProvider.getMetadataRepository().put(resource.stringValue(), newEntry);
+
+                log.error("refreshing the remote resource {} from the Linked Data Cloud failed ({})",resource,e.getMessage());
+                return;
+            } catch (RepositoryException e) {
+                log.error("repository error while refreshing the remote resource {} from the Linked Data Cloud", resource, e);
+                return;
+            }
+        } finally {
+            unlockResource(resource);
+        }
+
+    }
+
+
+    private CacheEntry getCacheEntry(URI resource) {
+        return cacheProvider.getMetadataRepository().get(resource.stringValue());
+    }
+
+    public LDEndpoints getEndpointService() {
+        return endpointService;
+    }
+
+}


Mime
View raw message