You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2013/02/19 13:57:40 UTC
[10/11] added missing module from the previous code importation
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;
+ }
+
+}