├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── caching-sail ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── caching │ │ ├── CachingSail.java │ │ └── CachingSailConnection.java │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── caching │ │ └── CachingSailTest.java │ └── resources │ ├── log4j.properties │ └── net │ └── fortytwo │ └── sesametools │ └── caching │ └── cachingSailTest.trig ├── common ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── fortytwo │ │ │ └── sesametools │ │ │ ├── CloseableGraphQueryResult.java │ │ │ ├── CloseableTupleQueryResult.java │ │ │ ├── CompoundCloseableIteration.java │ │ │ ├── ContextInsensitiveStatementComparator.java │ │ │ ├── EmptyCloseableIteration.java │ │ │ ├── Formatting.java │ │ │ ├── MultiStackableSail.java │ │ │ ├── PatternIterator.java │ │ │ ├── RandomValueFactory.java │ │ │ ├── RdfListUtil.java │ │ │ ├── RepositoryGraph.java │ │ │ ├── ReusableRDFHandler.java │ │ │ ├── SailConnectionTripleSource.java │ │ │ ├── SailWriter.java │ │ │ ├── SesameTools.java │ │ │ ├── SingleContextHandler.java │ │ │ ├── SingleContextSail.java │ │ │ ├── SingleContextSailConnection.java │ │ │ ├── StatementComparator.java │ │ │ └── ValueComparator.java │ └── resources │ │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── sesametools.properties │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ ├── RdfListUtilTest.java │ │ ├── SingleContextSailTest.java │ │ └── StatementComparatorTest.java │ └── resources │ └── log4j.properties ├── constrained-sail ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── constrained │ │ ├── ConstrainedSail.java │ │ └── ConstrainedSailConnection.java │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── constrained │ │ └── ConstrainedSailTest.java │ └── resources │ └── log4j.properties ├── deduplication-sail ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── deduplication │ │ ├── DeduplicationSail.java │ │ ├── DeduplicationSailConnection.java │ │ └── DuplicateStatementFinder.java │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── deduplication │ │ └── DuplicateStatementFinderTest.java │ └── resources │ └── log4j.properties ├── linked-data-server ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── fortytwo │ │ │ └── sesametools │ │ │ └── ldserver │ │ │ ├── GraphResource.java │ │ │ ├── LinkedDataServer.java │ │ │ ├── RDFMediaTypes.java │ │ │ ├── RDFRepresentation.java │ │ │ ├── ServerException.java │ │ │ ├── WebResource.java │ │ │ └── query │ │ │ ├── QueryException.java │ │ │ ├── QueryResource.java │ │ │ ├── SparqlQueryRepresentation.java │ │ │ ├── SparqlResource.java │ │ │ └── SparqlTools.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.openrdf.rio.RDFWriterFactory │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── ldserver │ │ ├── DemoApp.java │ │ └── SparqlAskTest.java │ └── resources │ ├── META-INF │ └── services │ │ └── org.openrdf.rio.RDFParserFactory │ └── net │ └── fortytwo │ └── sesametools │ └── ldserver │ └── demoApp.trig ├── mapping-sail ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── fortytwo │ └── sesametools │ └── mappingsail │ ├── MappingSail.java │ ├── MappingSailConnection.java │ ├── MappingSchema.java │ └── RewriteRule.java ├── pom.xml ├── rdf-transaction-sail ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── fortytwo │ └── sesametools │ └── rdftransaction │ ├── RDFTransactionSail.java │ └── RDFTransactionSailConnection.java ├── readonly-sail ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── fortytwo │ └── sesametools │ └── readonly │ ├── ReadOnlySail.java │ └── ReadOnlySailConnection.java ├── replay-sail ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── fortytwo │ └── sesametools │ └── replay │ ├── Handler.java │ ├── PlaybackSail.java │ ├── RecorderIteration.java │ ├── RecorderSail.java │ ├── RecorderSailConnection.java │ ├── ReplayConfiguration.java │ ├── SailConnectionCall.java │ ├── Source.java │ └── calls │ ├── AddStatementCall.java │ ├── BeginCall.java │ ├── ClearCall.java │ ├── ClearNamespacesCall.java │ ├── CloseConnectionCall.java │ ├── CloseIterationCall.java │ ├── CommitCall.java │ ├── ConstructorCall.java │ ├── EvaluateCall.java │ ├── GetContextIDsCall.java │ ├── GetNamespaceCall.java │ ├── GetNamespacesCall.java │ ├── GetStatementsCall.java │ ├── HasNextCall.java │ ├── NextCall.java │ ├── RemoveCall.java │ ├── RemoveNamespaceCall.java │ ├── RemoveStatementsCall.java │ ├── RollbackCall.java │ ├── SetNamespaceCall.java │ └── SizeCall.java ├── repository-sail ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── fortytwo │ └── sesametools │ └── reposail │ ├── RepositoryNamespaceIteration.java │ ├── RepositoryResourceIteration.java │ ├── RepositorySail.java │ ├── RepositorySailConnection.java │ └── RepositoryStatementIteration.java ├── sesamize ├── .gitignore ├── pom.xml ├── sesamize.sh └── src │ └── main │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── sesamize │ │ ├── Command.java │ │ ├── Sesamize.java │ │ ├── SesamizeArgs.java │ │ ├── SparqlResultFormat.java │ │ └── commands │ │ ├── Construct.java │ │ ├── Dump.java │ │ ├── Import.java │ │ ├── Random.java │ │ ├── Select.java │ │ └── Translate.java │ └── resources │ ├── META-INF │ └── services │ │ ├── org.openrdf.query.parser.QueryParserFactory │ │ ├── org.openrdf.rio.RDFParserFactory │ │ └── org.openrdf.rio.RDFWriterFactory │ └── log4j.properties ├── uri-translator ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── URITranslator.java │ └── test │ ├── java │ └── net │ │ └── fortytwo │ │ └── sesametools │ │ └── URITranslatorTest.java │ └── resources │ └── log4j.properties └── writeonly-sail ├── .gitignore ├── pom.xml └── src └── main └── java └── net └── fortytwo └── sesametools └── writeonly ├── WriteOnlySail.java └── WriteOnlySailConnection.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | .idea 6 | *.iml 7 | *~ 8 | pom.xml.versionsBackup 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | after_success: 5 | - mvn clean test jacoco:report coveralls:report 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | SesameTools, Copyright (C) 2010-2016 Joshua Shinavier and collaborators. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![SesameTools logo|width=322px|height=60px](https://github.com/joshsh/sesametools/wiki/graphics/SesameTools-logo.png) 4 | 5 | Welcome to the SesameTools wiki! 6 | SesameTools is a collection of general-purpose components for use with the [Sesame](http://rdf4j.org) RDF framework. It includes: 7 | 8 | * **SesameTools common utilities**: miscellaneous useful classes 9 | * **CachingSail**: an in-memory cache for RDF data 10 | * **ConstrainedSail**: a Sail implementation which interacts only with given named graphs. Useful for simple access control. 11 | * **DeduplicationSail**: a Sail implementation which avoids duplicate statements. For use with triple stores such as AllegroGraph which otherwise allow duplicates. 12 | * [LinkedDataServer](https://github.com/joshsh/sesametools/wiki/LinkedDataServer): a RESTful web service to publish a Sesame data store as Linked Data 13 | * **MappingSail**: a Sail which translates between two URI spaces. Used by LinkedDataServer. 14 | * **RDFTransactionSail**: a write-only Sail which generates RDF transactions instead of performing per-call updates. Useful for streaming RDF data as described [here](http://arxiv.org/abs/1011.3595) 15 | * **ReadOnlySail**: a read-only Sail implementation 16 | * **ReplaySail**: a pair of Sail implementations which allow Sail operations to be first recorded to a log file, then reproduced from the log file 17 | * **RepositorySail**: a Sail implementation which wraps a Repository object. This is essentially the inverse of Sesame's [SailRepository](http://rdf4j.org/sesame/2.7/apidocs/org/openrdf/repository/sail/SailRepository.html) 18 | * **Sesamize**: command-line tools for Sesame 19 | * **URI Translator**: a utility which runs SPARQL-1.1 Update queries against a Repository to convert URIs between different prefixes 20 | * **WriteOnlySail**: a write-only Sail implementation 21 | 22 | See also the [Sesametools API](http://fortytwo.net/projects/sesametools/api/latest/index.html). 23 | 24 | For projects which use Maven, SesameTools snapshots and release packages can be imported by adding configuration like the following to the project's POM: 25 | 26 | ```xml 27 | 28 | net.fortytwo.sesametools 29 | linked-data-server 30 | 1.10 31 | 32 | ``` 33 | 34 | The latest Maven packages can be browsed [here](http://search.maven.org/#search%7Cga%7C1%7Csesametools). 35 | 36 | **Credits**: SesameTools is written and maintained by [Joshua Shinavier](https://github.com/joshsh) and [Peter Ansell](https://github.com/ansell). Patches have been contributed by [Faisal Hameed](https://github.com/faisal-hameed), [Florian Kleedorfer](https://github.com/fkleedorfer), [Olaf Görlitz](https://github.com/goerlitz), and [Michal Klempa](https://github.com/michalklempa). An RDF/JSON parser and writer present in releases 1.7 and earlier contain code by [Hannes Ebner](http://ebner.wordpress.com/). 37 | -------------------------------------------------------------------------------- /caching-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /caching-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | caching-sail 6 | jar 7 | CachingSail 8 | An in-memory cache for Sail data 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-memory 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | test 32 | 33 | 34 | net.fortytwo.sesametools 35 | replay-sail 36 | test 37 | 38 | 39 | org.eclipse.rdf4j 40 | rdf4j-rio-trig 41 | test 42 | 43 | 44 | org.eclipse.rdf4j 45 | rdf4j-repository-sail 46 | test 47 | 48 | 49 | log4j 50 | log4j 51 | test 52 | 53 | 54 | org.slf4j 55 | slf4j-log4j12 56 | test 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-compiler-plugin 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-source-plugin 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-jar-plugin 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-javadoc-plugin 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-surefire-plugin 81 | 82 | 83 | org.eluder.coveralls 84 | coveralls-maven-plugin 85 | 86 | 87 | org.jacoco 88 | jacoco-maven-plugin 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /caching-sail/src/main/java/net/fortytwo/sesametools/caching/CachingSail.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.caching; 3 | 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.model.Value; 7 | import org.eclipse.rdf4j.model.ValueFactory; 8 | import org.eclipse.rdf4j.sail.Sail; 9 | import org.eclipse.rdf4j.sail.SailConnection; 10 | import org.eclipse.rdf4j.sail.SailException; 11 | import org.eclipse.rdf4j.sail.StackableSail; 12 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 13 | import org.eclipse.rdf4j.sail.memory.MemoryStore; 14 | 15 | import java.io.File; 16 | import java.util.HashSet; 17 | import java.util.Set; 18 | 19 | /** 20 | * A Sail which caches statements retrieved from a base Sail 21 | * in an internal MemoryStore, speeding up subsequent queries for the same data. 22 | * 23 | * @author Joshua Shinavier (http://fortytwo.net) 24 | */ 25 | // Note: assumes that the value factories of the base Sail and the MemoryStore 26 | // cache are compatible. 27 | public class CachingSail extends AbstractSail implements StackableSail { 28 | private static final long DEFAULT_CAPACITY = 1000000L; 29 | 30 | private boolean cacheSubject, cachePredicate, cacheObject; 31 | 32 | private Sail baseSail; 33 | private Sail cache; 34 | 35 | private Set cachedSubjects; 36 | private Set cachedPredicates; 37 | private Set cachedObjects; 38 | 39 | private long capacity; 40 | 41 | public CachingSail(final Sail baseSail, 42 | final boolean cacheSubject, 43 | final boolean cachePredicate, 44 | final boolean cacheObject, 45 | final long capacity) { 46 | this.baseSail = baseSail; 47 | this.cacheSubject = cacheSubject; 48 | this.cachePredicate = cachePredicate; 49 | this.cacheObject = cacheObject; 50 | 51 | this.capacity = (capacity <= 0) ? DEFAULT_CAPACITY : capacity; 52 | } 53 | 54 | public SailConnection getConnectionInternal() throws SailException { 55 | return new CachingSailConnection(this, baseSail, cache, 56 | cacheSubject, cachePredicate, cacheObject, 57 | cachedSubjects, cachedPredicates, cachedObjects); 58 | } 59 | 60 | @Override 61 | public File getDataDir() { 62 | return baseSail.getDataDir(); 63 | } 64 | 65 | @Override 66 | public ValueFactory getValueFactory() { 67 | return baseSail.getValueFactory(); 68 | } 69 | 70 | public void initializeInternal() throws SailException { 71 | baseSail.initialize(); 72 | 73 | cache = new MemoryStore(); 74 | cache.initialize(); 75 | 76 | if (cacheSubject) { 77 | cachedSubjects = new HashSet<>(); 78 | } 79 | 80 | if (cachePredicate) { 81 | cachedPredicates = new HashSet<>(); 82 | } 83 | 84 | if (cacheObject) { 85 | cachedObjects = new HashSet<>(); 86 | } 87 | } 88 | 89 | @Override 90 | public boolean isWritable() throws SailException { 91 | return baseSail.isWritable(); 92 | } 93 | 94 | @Override 95 | public void setDataDir(final File dir) { 96 | baseSail.setDataDir(dir); 97 | } 98 | 99 | public void shutDownInternal() throws SailException { 100 | baseSail.shutDown(); 101 | cache.shutDown(); 102 | } 103 | 104 | public Sail getBaseSail() { 105 | return baseSail; 106 | } 107 | 108 | public void setBaseSail(final Sail sail) { 109 | baseSail = sail; 110 | } 111 | 112 | public long getCapacity() { 113 | return this.capacity; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /caching-sail/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, R 2 | 3 | log4j.appender.R=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.R.layout.ConversionPattern=%-5p - %d{dd/MM/yyyy HH:mm:ss} - %m%n 6 | 7 | log4j.logger.org.openrdf=INFO 8 | log4j.logger.net.fortytwo.sesametools=INFO 9 | -------------------------------------------------------------------------------- /caching-sail/src/test/resources/net/fortytwo/sesametools/caching/cachingSailTest.trig: -------------------------------------------------------------------------------- 1 | @prefix : . 2 | 3 | :ctxA 4 | { 5 | :one 6 | :two :three; 7 | :four :five; 8 | . 9 | 10 | :six 11 | :seven :three; 12 | :eight :nine; 13 | . 14 | } 15 | 16 | :ctxB 17 | { 18 | 19 | } -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | common 7 | jar 8 | SesameTools common utilities 9 | Common utilities for Sesametools 10 | 11 | 12 | net.fortytwo.sesametools 13 | sesametools-all 14 | 2.0-SNAPSHOT 15 | ../pom.xml 16 | 17 | 18 | 19 | 20 | org.eclipse.rdf4j 21 | rdf4j-model 22 | 23 | 24 | org.eclipse.rdf4j 25 | rdf4j-sail-api 26 | 27 | 28 | org.eclipse.rdf4j 29 | rdf4j-util 30 | 31 | 32 | org.eclipse.rdf4j 33 | rdf4j-queryalgebra-evaluation 34 | 35 | 36 | org.eclipse.rdf4j 37 | rdf4j-sail-memory 38 | test 39 | 40 | 41 | org.eclipse.rdf4j 42 | rdf4j-repository-sail 43 | test 44 | 45 | 46 | 47 | 48 | junit 49 | junit 50 | test 51 | 52 | 53 | 54 | 55 | 56 | 57 | src/main/resources 58 | true 59 | 60 | **/sesametools.properties 61 | 62 | 63 | 64 | src/main/resources 65 | false 66 | 67 | **/sesametools.properties 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-compiler-plugin 75 | 76 | 77 | org.apache.maven.plugins 78 | maven-source-plugin 79 | 80 | 81 | org.apache.maven.plugins 82 | maven-jar-plugin 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-javadoc-plugin 87 | 88 | 89 | org.apache.maven.plugins 90 | maven-surefire-plugin 91 | 92 | 93 | org.eluder.coveralls 94 | coveralls-maven-plugin 95 | 96 | 97 | org.jacoco 98 | jacoco-maven-plugin 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/CloseableGraphQueryResult.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.model.Statement; 4 | import org.eclipse.rdf4j.query.GraphQueryResult; 5 | import org.eclipse.rdf4j.query.QueryEvaluationException; 6 | import org.eclipse.rdf4j.repository.RepositoryConnection; 7 | import org.eclipse.rdf4j.repository.RepositoryException; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * Auto-closing tuple query result. 13 | * 14 | * @author Peter Ansell p_ansell@yahoo.com 15 | */ 16 | public class CloseableGraphQueryResult implements GraphQueryResult { 17 | private RepositoryConnection connection; 18 | private GraphQueryResult result; 19 | 20 | public CloseableGraphQueryResult(RepositoryConnection connection, GraphQueryResult result) { 21 | this.connection = connection; 22 | this.result = result; 23 | } 24 | 25 | @Override 26 | public void close() throws QueryEvaluationException { 27 | try { 28 | result.close(); 29 | } finally { 30 | try { 31 | connection.close(); 32 | } catch (RepositoryException e) { 33 | throw new QueryEvaluationException("Exception closing connection.", e); 34 | } 35 | } 36 | } 37 | 38 | @Override 39 | public boolean hasNext() throws QueryEvaluationException { 40 | final boolean hasNext = result.hasNext(); 41 | if (!hasNext) { 42 | close(); 43 | } 44 | return hasNext; 45 | } 46 | 47 | @Override 48 | public void remove() throws QueryEvaluationException { 49 | result.remove(); 50 | } 51 | 52 | @Override 53 | public Map getNamespaces() throws QueryEvaluationException { 54 | return result.getNamespaces(); 55 | } 56 | 57 | @Override 58 | public Statement next() throws QueryEvaluationException 59 | { 60 | return result.next(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/CloseableTupleQueryResult.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.query.BindingSet; 4 | import org.eclipse.rdf4j.query.QueryEvaluationException; 5 | import org.eclipse.rdf4j.query.TupleQueryResult; 6 | import org.eclipse.rdf4j.repository.RepositoryConnection; 7 | import org.eclipse.rdf4j.repository.RepositoryException; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Auto-closing tuple query result. 13 | * 14 | * @author Peter Ansell p_ansell@yahoo.com 15 | */ 16 | public class CloseableTupleQueryResult implements TupleQueryResult { 17 | private RepositoryConnection connection; 18 | private TupleQueryResult result; 19 | 20 | public CloseableTupleQueryResult(RepositoryConnection connection, TupleQueryResult result) { 21 | this.connection = connection; 22 | this.result = result; 23 | } 24 | 25 | @Override 26 | public List getBindingNames() throws QueryEvaluationException { 27 | return result.getBindingNames(); 28 | } 29 | 30 | @Override 31 | public void close() throws QueryEvaluationException { 32 | try { 33 | result.close(); 34 | } finally { 35 | try { 36 | connection.close(); 37 | } catch (RepositoryException e) { 38 | throw new QueryEvaluationException("Exception closing connection.", e); 39 | } 40 | } 41 | } 42 | 43 | @Override 44 | public boolean hasNext() throws QueryEvaluationException { 45 | final boolean hasNext = result.hasNext(); 46 | if (!hasNext) { 47 | close(); 48 | } 49 | return hasNext; 50 | } 51 | 52 | @Override 53 | public BindingSet next() throws QueryEvaluationException { 54 | return result.next(); 55 | } 56 | 57 | @Override 58 | public void remove() throws QueryEvaluationException { 59 | result.remove(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/CompoundCloseableIteration.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | 6 | import java.util.Collection; 7 | import java.util.Iterator; 8 | 9 | /** 10 | * A CloseableIteration which wraps an ordered collection of other CloseableIterations. 11 | * 12 | * @author Joshua Shinavier (http://fortytwo.net) 13 | */ 14 | public class CompoundCloseableIteration implements CloseableIteration { 15 | private Iterator> iterations; 16 | private CloseableIteration currentIteration; 17 | 18 | public CompoundCloseableIteration(final Collection> childIterations) { 19 | iterations = childIterations.iterator(); 20 | if (iterations.hasNext()) { 21 | currentIteration = iterations.next(); 22 | } else { 23 | currentIteration = null; 24 | } 25 | } 26 | 27 | public void close() throws E { 28 | if (null != currentIteration) { 29 | currentIteration.close(); 30 | currentIteration = null; 31 | } 32 | 33 | while (iterations.hasNext()) { 34 | iterations.next().close(); 35 | } 36 | } 37 | 38 | public boolean hasNext() throws E { 39 | if (null == currentIteration) { 40 | return false; 41 | } else if (currentIteration.hasNext()) { 42 | return true; 43 | } else { 44 | currentIteration.close(); 45 | if (iterations.hasNext()) { 46 | currentIteration = iterations.next(); 47 | 48 | // Recurse until a non-empty iteration is found. 49 | return hasNext(); 50 | } else { 51 | currentIteration = null; 52 | return false; 53 | } 54 | } 55 | } 56 | 57 | public T next() throws E { 58 | return currentIteration.next(); 59 | } 60 | 61 | public void remove() throws E { 62 | currentIteration.remove(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/ContextInsensitiveStatementComparator.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.model.Statement; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * Implements a Comparator for OpenRDF Statements 9 | * using the order Subject->Predicate->Object 10 | * 11 | * @author Peter Ansell p_ansell@yahoo.com 12 | */ 13 | public class ContextInsensitiveStatementComparator implements Comparator { 14 | public final static int BEFORE = -1; 15 | public final static int EQUAL = 0; 16 | public final static int AFTER = 1; 17 | 18 | @Override 19 | public int compare(Statement first, Statement second) { 20 | if (first == second) { 21 | return EQUAL; 22 | } 23 | 24 | if (first.getSubject().equals(second.getSubject())) { 25 | if (first.getPredicate().equals(second.getPredicate())) { 26 | if (first.getObject().equals(second.getObject())) { 27 | return EQUAL; 28 | } else { 29 | return ValueComparator.getInstance().compare(first.getObject(), second.getObject()); 30 | } 31 | } else { 32 | return ValueComparator.getInstance().compare(first.getPredicate(), second.getPredicate()); 33 | } 34 | } else { 35 | return ValueComparator.getInstance().compare(first.getSubject(), second.getSubject()); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/EmptyCloseableIteration.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | 6 | /** 7 | * @author Joshua Shinavier (http://fortytwo.net) 8 | */ 9 | public class EmptyCloseableIteration implements CloseableIteration { 10 | 11 | public void close() throws E { 12 | } 13 | 14 | public boolean hasNext() throws E { 15 | return false; 16 | } 17 | 18 | public T next() throws E { 19 | return null; 20 | } 21 | 22 | public void remove() throws E { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/Formatting.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | 5 | /** 6 | * Miscellaneous helper methods for string formatting 7 | * 8 | * @author Joshua Shinavier (http://fortytwo.net) 9 | */ 10 | public class Formatting { 11 | 12 | private Formatting() { 13 | 14 | } 15 | 16 | private static final int 17 | FOUR = 4, 18 | EIGHT = 8, 19 | SIXTEEN = 16; 20 | 21 | // Note: extended characters are not escaped for printing. 22 | public static String escapeString(final String s) { 23 | StringBuilder sb = new StringBuilder(); 24 | for (int i = 0; i < s.length(); i++) { 25 | char c = s.charAt(i); 26 | switch (c) { 27 | case '\\': 28 | sb.append("\\\\"); 29 | break; 30 | case '\"': 31 | sb.append("\\\""); 32 | break; 33 | case '\t': 34 | sb.append("\\t"); 35 | break; 36 | case '\n': 37 | sb.append("\\n"); 38 | break; 39 | case '\r': 40 | sb.append("\\r"); 41 | break; 42 | default: 43 | sb.append(c); 44 | } 45 | } 46 | 47 | return sb.toString(); 48 | } 49 | 50 | // Note: assumes a properly formatted (escaped) String argument. 51 | public static String unescapeString(final String s) { 52 | StringBuilder sb = new StringBuilder(); 53 | String seq; 54 | 55 | for (int i = 0; i < s.length(); i++) { 56 | char c = s.charAt(i); 57 | 58 | if ('\\' == c) { 59 | i++; 60 | 61 | switch (s.charAt(i)) { 62 | case '\\': 63 | sb.append('\\'); 64 | break; 65 | case '\'': 66 | sb.append('\''); 67 | break; 68 | case '\"': 69 | sb.append('\"'); 70 | break; 71 | case 't': 72 | sb.append('\t'); 73 | break; 74 | case 'n': 75 | sb.append('\n'); 76 | break; 77 | case 'r': 78 | sb.append('\r'); 79 | break; 80 | case 'u': 81 | seq = s.substring(i + 1, i + FOUR + 1); 82 | sb.append(toUnicodeChar(seq)); 83 | i += FOUR; 84 | break; 85 | case 'U': 86 | seq = s.substring(i + 1, i + EIGHT + 1); 87 | sb.append(toUnicodeChar(seq)); 88 | i += EIGHT; 89 | break; 90 | default: 91 | throw new IllegalArgumentException("bad escape sequence: \\" 92 | + s.charAt(i) + " at character " + (i - 1)); 93 | } 94 | } else { 95 | sb.append(c); 96 | } 97 | } 98 | 99 | return sb.toString(); 100 | } 101 | 102 | private static char toUnicodeChar(final String unicode) { 103 | return (char) Integer.parseInt(unicode, SIXTEEN); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/MultiStackableSail.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.IsolationLevel; 5 | import org.eclipse.rdf4j.model.ValueFactory; 6 | import org.eclipse.rdf4j.sail.Sail; 7 | import org.eclipse.rdf4j.sail.SailConnection; 8 | import org.eclipse.rdf4j.sail.SailException; 9 | import org.eclipse.rdf4j.sail.StackableSail; 10 | 11 | import java.io.File; 12 | import java.util.List; 13 | 14 | /** 15 | * A StackableSail which allows multiple Sails to be stacked upon the same base 16 | * Sail (avoiding re-initialization of the base Sail as the individual stacked 17 | * Sails are initialized) 18 | * 19 | * @author Joshua Shinavier (http://fortytwo.net) 20 | */ 21 | public class MultiStackableSail implements StackableSail { 22 | private Sail baseSail; 23 | 24 | public MultiStackableSail(final Sail baseSail) { 25 | setBaseSail(baseSail); 26 | } 27 | 28 | public void setBaseSail(Sail sail) { 29 | this.baseSail = sail; 30 | } 31 | 32 | public Sail getBaseSail() { 33 | return baseSail; 34 | } 35 | 36 | public void setDataDir(File file) { 37 | baseSail.setDataDir(file); 38 | } 39 | 40 | public File getDataDir() { 41 | return baseSail.getDataDir(); 42 | } 43 | 44 | public void initialize() throws SailException { 45 | // Do nothing -- assume that the base Sail is initialized elsewhere 46 | } 47 | 48 | public void shutDown() throws SailException { 49 | // Do nothing -- assume that the base Sail will be shut down elsewhere 50 | } 51 | 52 | public boolean isWritable() throws SailException { 53 | return baseSail.isWritable(); 54 | } 55 | 56 | public SailConnection getConnection() throws SailException { 57 | return baseSail.getConnection(); 58 | } 59 | 60 | public ValueFactory getValueFactory() { 61 | return baseSail.getValueFactory(); 62 | } 63 | 64 | @Override 65 | public List getSupportedIsolationLevels() { 66 | return baseSail.getSupportedIsolationLevels(); 67 | } 68 | 69 | @Override 70 | public IsolationLevel getDefaultIsolationLevel() { 71 | return baseSail.getDefaultIsolationLevel(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/PatternIterator.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.model.IRI; 4 | import org.eclipse.rdf4j.model.Resource; 5 | import org.eclipse.rdf4j.model.Statement; 6 | import org.eclipse.rdf4j.model.Value; 7 | import org.eclipse.rdf4j.util.iterators.FilterIterator; 8 | 9 | import java.util.Iterator; 10 | 11 | /** 12 | * A FilterIterator which matches statements against a given 13 | * subject, predicate, object, and optional context(s). 14 | */ 15 | public class PatternIterator extends FilterIterator { 16 | 17 | private Resource subj; 18 | 19 | private IRI pred; 20 | 21 | private Value obj; 22 | 23 | private Resource[] contexts; 24 | 25 | public PatternIterator(Iterator iter, Resource subj, IRI pred, Value obj, 26 | Resource... contexts) { 27 | super(iter); 28 | this.subj = subj; 29 | this.pred = pred; 30 | this.obj = obj; 31 | this.contexts = contexts; 32 | } 33 | 34 | @Override 35 | protected boolean accept(Statement st) { 36 | if (subj != null && !subj.equals(st.getSubject())) { 37 | return false; 38 | } 39 | if (pred != null && !pred.equals(st.getPredicate())) { 40 | return false; 41 | } 42 | if (obj != null && !obj.equals(st.getObject())) { 43 | return false; 44 | } 45 | 46 | if (contexts.length == 0) { 47 | // Any context matches 48 | return true; 49 | } else { 50 | // Accept if one of the contexts from the pattern matches 51 | Resource stContext = st.getContext(); 52 | 53 | for (Resource context : contexts) { 54 | if (context == null && stContext == null) { 55 | return true; 56 | } 57 | if (context != null && context.equals(stContext)) { 58 | return true; 59 | } 60 | } 61 | 62 | return false; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/ReusableRDFHandler.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.model.Statement; 5 | import org.eclipse.rdf4j.rio.RDFHandler; 6 | import org.eclipse.rdf4j.rio.RDFHandlerException; 7 | 8 | /** 9 | * An RDFHandler which wraps another handler and ignores calls 10 | * to startRDF and endRDF, 11 | * allowing the base handler to be used multiple times. 12 | * For example, there may be several distinct operations which push RDF statements 13 | * into a wrapped RDFWriter before the document is terminated. 14 | * To actually call the base handler's startRDF and endRDF methods, 15 | * use reallyStartRDF and reallyEndRDF, respectively. 16 | * 17 | * @author Joshua Shinavier (http://fortytwo.net) 18 | */ 19 | public class ReusableRDFHandler implements RDFHandler { 20 | private RDFHandler baseHandler; 21 | 22 | public ReusableRDFHandler(final RDFHandler base) { 23 | this.baseHandler = base; 24 | } 25 | 26 | public void startRDF() throws RDFHandlerException { 27 | } 28 | 29 | public void endRDF() throws RDFHandlerException { 30 | } 31 | 32 | public void reallyStartRDF() throws RDFHandlerException { 33 | baseHandler.startRDF(); 34 | } 35 | 36 | public void reallyEndRDF() throws RDFHandlerException { 37 | baseHandler.endRDF(); 38 | } 39 | 40 | public void handleNamespace(final String prefix, final String uri) throws RDFHandlerException { 41 | baseHandler.handleNamespace(prefix, uri); 42 | } 43 | 44 | public void handleStatement(final Statement st) throws RDFHandlerException { 45 | baseHandler.handleStatement(st); 46 | } 47 | 48 | public void handleComment(final String comment) throws RDFHandlerException { 49 | baseHandler.handleComment(comment); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/SailConnectionTripleSource.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | import org.eclipse.rdf4j.model.IRI; 6 | import org.eclipse.rdf4j.query.QueryEvaluationException; 7 | import org.eclipse.rdf4j.query.algebra.evaluation.TripleSource; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | import org.eclipse.rdf4j.model.Resource; 11 | import org.eclipse.rdf4j.model.ValueFactory; 12 | import org.eclipse.rdf4j.model.Statement; 13 | import org.eclipse.rdf4j.model.Value; 14 | 15 | /** 16 | * A TripleSource which is based on a SailConnection 17 | * 18 | * @author Joshua Shinavier (http://fortytwo.net) 19 | */ 20 | public class SailConnectionTripleSource implements TripleSource { 21 | private SailConnection baseConnection; 22 | private ValueFactory valueFactory; 23 | private boolean includeInferred; 24 | 25 | public SailConnectionTripleSource(final SailConnection conn, 26 | final ValueFactory valueFactory, 27 | final boolean includeInferred) { 28 | baseConnection = conn; 29 | this.valueFactory = valueFactory; 30 | this.includeInferred = includeInferred; 31 | } 32 | 33 | public CloseableIteration getStatements(final Resource subj, 34 | final IRI pred, 35 | final Value obj, 36 | final Resource... contexts) { 37 | try { 38 | return new QueryEvaluationIteration( 39 | baseConnection.getStatements(subj, pred, obj, includeInferred, contexts)); 40 | } catch (SailException e) { 41 | return new EmptyCloseableIteration<>(); 42 | } 43 | } 44 | 45 | public ValueFactory getValueFactory() { 46 | return valueFactory; 47 | } 48 | 49 | public static class QueryEvaluationIteration implements CloseableIteration { 50 | private CloseableIteration baseIteration; 51 | 52 | public QueryEvaluationIteration(final CloseableIteration baseIteration) { 53 | this.baseIteration = baseIteration; 54 | } 55 | 56 | public void close() throws QueryEvaluationException { 57 | try { 58 | baseIteration.close(); 59 | } catch (SailException e) { 60 | throw new QueryEvaluationException(e); 61 | } 62 | } 63 | 64 | public boolean hasNext() throws QueryEvaluationException { 65 | try { 66 | return baseIteration.hasNext(); 67 | } catch (SailException e) { 68 | throw new QueryEvaluationException(e); 69 | } 70 | } 71 | 72 | public Statement next() throws QueryEvaluationException { 73 | try { 74 | return baseIteration.next(); 75 | } catch (SailException e) { 76 | throw new QueryEvaluationException(e); 77 | } 78 | } 79 | 80 | public void remove() throws QueryEvaluationException { 81 | try { 82 | baseIteration.remove(); 83 | } catch (SailException e) { 84 | throw new QueryEvaluationException(e); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/SailWriter.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.rio.RDFHandler; 4 | import org.eclipse.rdf4j.rio.RDFHandlerException; 5 | import org.eclipse.rdf4j.model.Statement; 6 | import org.eclipse.rdf4j.sail.Sail; 7 | import org.eclipse.rdf4j.sail.SailConnection; 8 | import org.eclipse.rdf4j.sail.SailException; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * An RDFHandler which either adds or removes received Statements from a Sail 14 | * @author Joshua Shinavier (http://fortytwo.net) 15 | */ 16 | public class SailWriter implements RDFHandler { 17 | 18 | private final Logger log = LoggerFactory.getLogger(this.getClass()); 19 | 20 | public enum Action { 21 | ADD, REMOVE 22 | } 23 | 24 | private final Sail sail; 25 | private final Action action; 26 | private SailConnection sailConnection; 27 | 28 | public SailWriter(final Sail sail, final Action action) { 29 | this.sail = sail; 30 | this.action = action; 31 | } 32 | 33 | protected void finalize() throws Throwable { 34 | super.finalize(); 35 | 36 | if (null != sailConnection) { 37 | sailConnection.close(); 38 | } 39 | 40 | sailConnection = null; 41 | } 42 | 43 | public void startRDF() throws RDFHandlerException { 44 | try { 45 | sailConnection = sail.getConnection(); 46 | } catch (SailException e) { 47 | throw new RDFHandlerException(e); 48 | } 49 | } 50 | 51 | public void endRDF() throws RDFHandlerException { 52 | try { 53 | sailConnection.commit(); 54 | } catch (SailException e) { 55 | throw new RDFHandlerException(e); 56 | } finally { 57 | if(null != sailConnection) { 58 | try { 59 | sailConnection.close(); 60 | } catch(SailException e) { 61 | log.error("Found SailException while trying to close Sail connection in SailWriter", e); 62 | } 63 | } 64 | sailConnection = null; 65 | } 66 | } 67 | 68 | public void handleNamespace(String s, String s1) throws RDFHandlerException { 69 | try { 70 | switch (action) { 71 | case ADD: 72 | sailConnection.setNamespace(s, s1); 73 | break; 74 | case REMOVE: 75 | String name = sailConnection.getNamespace(s); 76 | if (null != name && name.equals(s1)) { 77 | sailConnection.removeNamespace(s); 78 | } 79 | break; 80 | } 81 | } catch (SailException e) { 82 | throw new RDFHandlerException(e); 83 | } 84 | } 85 | 86 | public void handleStatement(Statement statement) throws RDFHandlerException { 87 | try { 88 | switch (action) { 89 | case ADD: 90 | sailConnection.addStatement( 91 | statement.getSubject(), 92 | statement.getPredicate(), 93 | statement.getObject(), 94 | statement.getContext()); 95 | break; 96 | case REMOVE: 97 | sailConnection.removeStatements( 98 | statement.getSubject(), 99 | statement.getPredicate(), 100 | statement.getObject(), 101 | statement.getContext()); 102 | break; 103 | } 104 | } catch (SailException e) { 105 | throw new RDFHandlerException(e); 106 | } 107 | } 108 | 109 | public void handleComment(String s) throws RDFHandlerException { 110 | // Do nothing. 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/SesameTools.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import java.io.IOException; 4 | import java.util.Properties; 5 | 6 | /** 7 | * Global constants 8 | * 9 | * @author Joshua Shinavier (http://fortytwo.net) 10 | */ 11 | public class SesameTools { 12 | private static final Properties PROPERTIES; 13 | 14 | public static final String 15 | VERSION_PROP = "net.fortytwo.sesametools.version"; 16 | 17 | static { 18 | try { 19 | PROPERTIES = new Properties(); 20 | 21 | PROPERTIES.load(SesameTools.class.getResourceAsStream("sesametools.properties")); 22 | } catch (IOException e) { 23 | throw new ExceptionInInitializerError(e); 24 | } 25 | } 26 | 27 | private SesameTools() { 28 | 29 | } 30 | 31 | public static Properties getProperties() { 32 | return PROPERTIES; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/SingleContextHandler.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools; 3 | 4 | import org.eclipse.rdf4j.rio.RDFHandler; 5 | import org.eclipse.rdf4j.rio.RDFHandlerException; 6 | import org.eclipse.rdf4j.model.ValueFactory; 7 | import org.eclipse.rdf4j.model.Statement; 8 | import org.eclipse.rdf4j.model.IRI; 9 | import org.eclipse.rdf4j.model.Resource; 10 | import org.eclipse.rdf4j.model.Value; 11 | 12 | /** 13 | * An RDFHandler which forces each received statement into a designated Named Graph context. 14 | * 15 | * @author Joshua Shinavier (http://fortytwo.net) 16 | */ 17 | public class SingleContextHandler implements RDFHandler { 18 | private RDFHandler baseHandler; 19 | private ValueFactory valueFactory; 20 | private Resource context; 21 | 22 | public SingleContextHandler(final RDFHandler base, final ValueFactory vf, final Resource singleContext) { 23 | this.baseHandler = base; 24 | this.valueFactory = vf; 25 | this.context = singleContext; 26 | } 27 | 28 | public void startRDF() throws RDFHandlerException { 29 | baseHandler.startRDF(); 30 | } 31 | 32 | public void endRDF() throws RDFHandlerException { 33 | baseHandler.endRDF(); 34 | } 35 | 36 | public void handleNamespace(final String prefix, final String uri) throws RDFHandlerException { 37 | baseHandler.handleNamespace(prefix, uri); 38 | } 39 | 40 | public void handleStatement(final Statement st) throws RDFHandlerException { 41 | Resource subj = st.getSubject(); 42 | IRI pred = st.getPredicate(); 43 | Value obj = st.getObject(); 44 | 45 | Statement newSt = valueFactory.createStatement(subj, pred, obj, context); 46 | 47 | baseHandler.handleStatement(newSt); 48 | } 49 | 50 | public void handleComment(final String comment) throws RDFHandlerException { 51 | baseHandler.handleComment(comment); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/SingleContextSail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.model.Resource; 4 | import org.eclipse.rdf4j.model.ValueFactory; 5 | import org.eclipse.rdf4j.sail.Sail; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | import org.eclipse.rdf4j.sail.StackableSail; 9 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 10 | 11 | import java.io.File; 12 | 13 | /** 14 | * A Sail which treats the wildcard context as a single, specific context, 15 | * and disallows read and write access to all other contexts, including the default context. 16 | * Namespaces may be set and retrieved without restriction. 17 | * 18 | * @author Joshua Shinavier (http://fortytwo.net) 19 | */ 20 | public class SingleContextSail extends AbstractSail implements StackableSail { 21 | private Sail baseSail; 22 | private Resource context; 23 | 24 | /** 25 | * Construct a Sail which is restricted to a single graph context. 26 | * @param baseSail a base Sail for storage 27 | * @param context a single, non-null graph context 28 | */ 29 | public SingleContextSail(final Sail baseSail, final Resource context) { 30 | this.baseSail = baseSail; 31 | this.context = context; 32 | 33 | if (null == context) { 34 | throw new IllegalArgumentException("context may not be null"); 35 | } 36 | } 37 | 38 | public Sail getBaseSail() { 39 | return baseSail; 40 | } 41 | 42 | public void setBaseSail(final Sail baseSail) { 43 | this.baseSail = baseSail; 44 | } 45 | 46 | protected SailConnection getConnectionInternal() throws SailException { 47 | return new SingleContextSailConnection(this, baseSail, context); 48 | } 49 | 50 | @Override 51 | public File getDataDir() { 52 | return baseSail.getDataDir(); 53 | } 54 | 55 | public ValueFactory getValueFactory() { 56 | return baseSail.getValueFactory(); 57 | } 58 | 59 | protected void initializeInternal() throws SailException { 60 | baseSail.initialize(); 61 | } 62 | 63 | @Override 64 | public boolean isWritable() throws SailException { 65 | return baseSail.isWritable(); 66 | } 67 | 68 | @Override 69 | public void setDataDir(final File dir) { 70 | baseSail.setDataDir(dir); 71 | } 72 | 73 | protected void shutDownInternal() throws SailException { 74 | baseSail.shutDown(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /common/src/main/java/net/fortytwo/sesametools/StatementComparator.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools; 2 | 3 | import org.eclipse.rdf4j.model.Statement; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * Implements a Comparator for OpenRDF Statements 9 | * using the order Subject->Predicate->Object->Context 10 | * 11 | * @author Peter Ansell p_ansell@yahoo.com 12 | */ 13 | public class StatementComparator implements Comparator { 14 | /** 15 | * A thread-safe pre-instantiated instance of StatementComparator. 16 | */ 17 | private final static StatementComparator INSTANCE = new StatementComparator(); 18 | 19 | /** 20 | * @return A thread-safe pre-instantiated instance of StatementComparator. 21 | */ 22 | public static StatementComparator getInstance() { 23 | return INSTANCE; 24 | } 25 | 26 | public final static int BEFORE = -1; 27 | public final static int EQUAL = 0; 28 | public final static int AFTER = 1; 29 | 30 | @Override 31 | public int compare(Statement first, Statement second) { 32 | // Cannot use Statement.equals as it does not take Context into account, 33 | // but can check for reference equality (==) 34 | if (first == second) { 35 | return EQUAL; 36 | } 37 | 38 | if (first.getSubject().equals(second.getSubject())) { 39 | if (first.getPredicate().equals(second.getPredicate())) { 40 | if (first.getObject().equals(second.getObject())) { 41 | // Context is the only part of a statement that should legitimately be null 42 | if (first.getContext() == null) { 43 | if (second.getContext() == null) { 44 | return EQUAL; 45 | } else { 46 | return BEFORE; 47 | } 48 | } else if (second.getContext() == null) { 49 | return AFTER; 50 | } else { 51 | return ValueComparator.getInstance().compare(first.getContext(), second.getContext()); 52 | } 53 | } else { 54 | return ValueComparator.getInstance().compare(first.getObject(), second.getObject()); 55 | } 56 | } else { 57 | return ValueComparator.getInstance().compare(first.getPredicate(), second.getPredicate()); 58 | } 59 | } else { 60 | return ValueComparator.getInstance().compare(first.getSubject(), second.getSubject()); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /common/src/main/resources/net/fortytwo/sesametools/sesametools.properties: -------------------------------------------------------------------------------- 1 | net.fortytwo.sesametools.version = ${project.version} 2 | 3 | -------------------------------------------------------------------------------- /common/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, R 2 | 3 | log4j.appender.R=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.R.layout.ConversionPattern=%-5p - %d{dd/MM/yyyy HH:mm:ss} - %m%n 6 | 7 | log4j.logger.org.openrdf=INFO 8 | log4j.logger.net.fortytwo.sesametools=INFO 9 | -------------------------------------------------------------------------------- /constrained-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /constrained-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | constrained-sail 6 | jar 7 | ConstrainedSail 8 | A Sail implementation which interacts only with given named graphs 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | 28 | 29 | org.eclipse.rdf4j 30 | rdf4j-sail-memory 31 | test 32 | 33 | 34 | junit 35 | junit 36 | test 37 | 38 | 39 | log4j 40 | log4j 41 | test 42 | 43 | 44 | org.slf4j 45 | slf4j-log4j12 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-compiler-plugin 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-source-plugin 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-jar-plugin 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-javadoc-plugin 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-surefire-plugin 71 | 72 | 73 | org.eluder.coveralls 74 | coveralls-maven-plugin 75 | 76 | 77 | org.jacoco 78 | jacoco-maven-plugin 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /constrained-sail/src/main/java/net/fortytwo/sesametools/constrained/ConstrainedSail.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.constrained; 3 | 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.query.Dataset; 6 | import org.eclipse.rdf4j.query.impl.SimpleDataset; 7 | import org.eclipse.rdf4j.sail.Sail; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | import org.eclipse.rdf4j.sail.helpers.SailWrapper; 11 | 12 | /** 13 | * A StackableSail which is constrained in reading and writing triples by a pair 14 | * of Dataset objects. A connection may only read statements from the set of 15 | * named graphs in the readable Dataset, and may only write statements to the 16 | * named graphs in the writeable Dataset. 17 | * 18 | * @author Joshua Shinavier (http://fortytwo.net) 19 | */ 20 | public class ConstrainedSail extends SailWrapper { 21 | 22 | private final IRI defaultWriteContext; 23 | private final boolean hideNonWritableContexts; 24 | protected final Dataset readableSet; 25 | protected final Dataset writableSet; 26 | 27 | /** 28 | * Constructor. 29 | * 30 | * @param baseSail a Sail upon which to stack this ACLSail 31 | * is to be controlled 32 | * @param readableSet the Dataset from which this Sail may read 33 | * @param writableSet the Dataset to which this Sail may write 34 | * @param defaultWriteContext a context to which statements will be written 35 | * when no other context is specified. May be null, in which case no 36 | * statements will be written unless a context is specified. 37 | * @param hideNonWritableContexts if true, the context information will be 38 | * removed from those statements returned by a generic (context-free) 39 | * getStatements query whenever the context in question is not writable. 40 | * This is a way of letting the user know which statements can be deleted. 41 | */ 42 | public ConstrainedSail(final Sail baseSail, 43 | final Dataset readableSet, 44 | final Dataset writableSet, 45 | final IRI defaultWriteContext, 46 | final boolean hideNonWritableContexts) { 47 | super(baseSail); 48 | this.readableSet = readableSet; 49 | this.writableSet = writableSet; 50 | this.defaultWriteContext = defaultWriteContext; 51 | this.hideNonWritableContexts = hideNonWritableContexts; 52 | } 53 | 54 | public ConstrainedSail(final Sail baseSail, 55 | final IRI defaultWriteContext, 56 | final boolean hideNonWritableContexts) { 57 | this(baseSail, new SimpleDataset(), new SimpleDataset(), defaultWriteContext, hideNonWritableContexts); 58 | } 59 | 60 | public void addReadableGraph(final IRI g) { 61 | readableSet.getDefaultGraphs().add(g); 62 | } 63 | 64 | public void addWritableGraph(final IRI g) { 65 | writableSet.getDefaultGraphs().add(g); 66 | } 67 | 68 | public SailConnection getConnection() throws SailException { 69 | // For now, use reasonable defaults for namespace and null context access. 70 | return new ConstrainedSailConnection(getBaseSail().getConnection(), 71 | getValueFactory(), 72 | readableSet, 73 | writableSet, 74 | defaultWriteContext, 75 | true, true, hideNonWritableContexts); 76 | } 77 | 78 | public IRI getDefaultWriteContext() { 79 | return defaultWriteContext; 80 | } 81 | 82 | public void initialize() throws SailException { 83 | } 84 | 85 | /** 86 | * This Sail is writable if the base Sail is writable, and insofar as the 87 | * the statements to be written are permitted by the access control 88 | * mechanism. 89 | */ 90 | public boolean isWritable() throws SailException { 91 | return getBaseSail().isWritable() 92 | && (!writableSet.getNamedGraphs().isEmpty()); // TODO: OR the default analysis is writable 93 | } 94 | 95 | public void shutDown() throws SailException { 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /constrained-sail/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, R 2 | 3 | log4j.appender.R=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.R.layout.ConversionPattern=%-5p - %d{dd/MM/yyyy HH:mm:ss} - %m%n 6 | 7 | log4j.logger.org.openrdf=INFO 8 | log4j.logger.net.fortytwo.sesametools=INFO 9 | -------------------------------------------------------------------------------- /deduplication-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /deduplication-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | deduplication-sail 6 | jar 7 | DeduplicationSail 8 | A Sail implementation which avoids duplicate statements 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | 28 | 29 | org.eclipse.rdf4j 30 | rdf4j-sail-memory 31 | test 32 | 33 | 34 | junit 35 | junit 36 | test 37 | 38 | 39 | org.eclipse.rdf4j 40 | rdf4j-rio-trig 41 | test 42 | 43 | 44 | org.eclipse.rdf4j 45 | rdf4j-repository-sail 46 | test 47 | 48 | 49 | log4j 50 | log4j 51 | test 52 | 53 | 54 | org.slf4j 55 | slf4j-log4j12 56 | test 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-compiler-plugin 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-source-plugin 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-jar-plugin 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-javadoc-plugin 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-surefire-plugin 81 | 82 | 83 | org.eluder.coveralls 84 | coveralls-maven-plugin 85 | 86 | 87 | org.jacoco 88 | jacoco-maven-plugin 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /deduplication-sail/src/main/java/net/fortytwo/sesametools/deduplication/DeduplicationSail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.deduplication; 2 | 3 | import org.eclipse.rdf4j.sail.Sail; 4 | import org.eclipse.rdf4j.sail.SailConnection; 5 | import org.eclipse.rdf4j.sail.SailException; 6 | import org.eclipse.rdf4j.sail.helpers.SailWrapper; 7 | 8 | /** 9 | * A Sail which avoids adding duplicate statements to a base Sail. 10 | * For use with Sail implementations in which duplicate statements are possible. 11 | * 12 | * @author Joshua Shinavier (http://fortytwo.net) 13 | */ 14 | public class DeduplicationSail extends SailWrapper { 15 | public DeduplicationSail(final Sail baseSail) { 16 | super(baseSail); 17 | } 18 | 19 | @Override 20 | public SailConnection getConnection() throws SailException { 21 | return new DeduplicationSailConnection(this.getBaseSail().getConnection()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /deduplication-sail/src/main/java/net/fortytwo/sesametools/deduplication/DeduplicationSailConnection.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.deduplication; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.model.Statement; 7 | import org.eclipse.rdf4j.model.Value; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | import org.eclipse.rdf4j.sail.helpers.SailConnectionWrapper; 11 | 12 | /** 13 | * @author Joshua Shinavier (http://fortytwo.net) 14 | */ 15 | public class DeduplicationSailConnection extends SailConnectionWrapper { 16 | public DeduplicationSailConnection(final SailConnection baseSailConnection) { 17 | super(baseSailConnection); 18 | } 19 | 20 | @Override 21 | public void addStatement(final Resource subject, 22 | final IRI predicate, 23 | final Value object, 24 | final Resource... contexts) throws SailException { 25 | if (0 == contexts.length) { 26 | boolean includeInferred = false; 27 | try (CloseableIteration iter 28 | = this.getWrappedConnection().getStatements(subject, predicate, object, includeInferred)) { 29 | if (iter.hasNext()) { 30 | return; 31 | } 32 | } 33 | } 34 | 35 | super.addStatement(subject, predicate, object, contexts); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /deduplication-sail/src/main/java/net/fortytwo/sesametools/deduplication/DuplicateStatementFinder.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.deduplication; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import org.eclipse.rdf4j.model.Resource; 5 | import org.eclipse.rdf4j.model.Statement; 6 | import org.eclipse.rdf4j.model.ValueFactory; 7 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | 11 | import java.util.HashSet; 12 | import java.util.Set; 13 | 14 | /** 15 | * @author Joshua Shinavier (http://fortytwo.net) 16 | */ 17 | public class DuplicateStatementFinder { 18 | private static final ValueFactory valueFactory = SimpleValueFactory.getInstance(); 19 | 20 | private DuplicateStatementFinder() { 21 | 22 | } 23 | 24 | public static Set findDuplicateStatements(final SailConnection sc) throws SailException { 25 | boolean includeInferred = false; 26 | 27 | // The HashSet is safe because none of the statements we'll add have a 28 | // non-null named analysis context. 29 | Set results = new HashSet<>(); 30 | 31 | try (CloseableIteration contexts = sc.getContextIDs()) { 32 | while (contexts.hasNext()) { 33 | Resource ctx = contexts.next(); 34 | if (null != ctx) { 35 | 36 | try (CloseableIteration stmts 37 | = sc.getStatements(null, null, null, includeInferred, ctx)) { 38 | while (stmts.hasNext()) { 39 | Statement st = stmts.next(); 40 | 41 | try (CloseableIteration dups = sc.getStatements( 42 | st.getSubject(), st.getPredicate(), st.getObject(), includeInferred)) { 43 | int count = 0; 44 | while (dups.hasNext()) { 45 | count++; 46 | if (2 == count) { 47 | Statement dup = valueFactory.createStatement( 48 | st.getSubject(), st.getPredicate(), st.getObject()); 49 | results.add(dup); 50 | break; 51 | } 52 | 53 | dups.next(); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | return results; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /deduplication-sail/src/test/java/net/fortytwo/sesametools/deduplication/DuplicateStatementFinderTest.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.deduplication; 2 | 3 | import junit.framework.TestCase; 4 | import org.eclipse.rdf4j.model.Statement; 5 | import org.eclipse.rdf4j.model.IRI; 6 | import org.eclipse.rdf4j.model.ValueFactory; 7 | import org.eclipse.rdf4j.model.vocabulary.RDF; 8 | import org.eclipse.rdf4j.model.vocabulary.RDFS; 9 | import org.eclipse.rdf4j.sail.Sail; 10 | import org.eclipse.rdf4j.sail.SailConnection; 11 | import org.eclipse.rdf4j.sail.memory.MemoryStore; 12 | 13 | import java.util.Set; 14 | 15 | /** 16 | * @author Joshua Shinavier (http://fortytwo.net) 17 | */ 18 | public class DuplicateStatementFinderTest extends TestCase { 19 | private static final String NS = "http://example.org/test/"; 20 | 21 | private Sail sail; 22 | private ValueFactory valueFactory; 23 | 24 | public void setUp() throws Exception { 25 | sail = new MemoryStore(); 26 | sail.initialize(); 27 | valueFactory = sail.getValueFactory(); 28 | } 29 | 30 | public void tearDown() throws Exception { 31 | sail.shutDown(); 32 | } 33 | 34 | public void testSimple() throws Exception { 35 | SailConnection sc = sail.getConnection(); 36 | sc.begin(); 37 | 38 | IRI ctx1 = valueFactory.createIRI(NS + "ctx1"); 39 | IRI ctx2 = valueFactory.createIRI(NS + "ctx2"); 40 | 41 | // Not a duplicate. 42 | sc.addStatement(RDF.NIL, RDF.TYPE, RDF.LIST, ctx1); 43 | 44 | // Duplicate: two non-null contexts. 45 | sc.addStatement(RDF.TYPE, RDF.TYPE, RDF.PROPERTY, ctx1); 46 | sc.addStatement(RDF.TYPE, RDF.TYPE, RDF.PROPERTY, ctx2); 47 | 48 | // Duplicate: null and non-null context. 49 | sc.addStatement(RDF.PROPERTY, RDF.TYPE, RDFS.CLASS, ctx1); 50 | sc.addStatement(RDF.PROPERTY, RDF.TYPE, RDFS.CLASS); 51 | 52 | Set dups = DuplicateStatementFinder.findDuplicateStatements(sc); 53 | assertEquals(2, dups.size()); 54 | //... 55 | 56 | sc.rollback(); 57 | sc.close(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /deduplication-sail/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, R 2 | 3 | log4j.appender.R=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.R.layout.ConversionPattern=%-5p - %d{dd/MM/yyyy HH:mm:ss} - %m%n 6 | 7 | log4j.logger.org.openrdf=INFO 8 | log4j.logger.net.fortytwo.sesametools=INFO 9 | -------------------------------------------------------------------------------- /linked-data-server/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/GraphResource.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import org.eclipse.rdf4j.model.Namespace; 5 | import org.eclipse.rdf4j.model.Statement; 6 | import org.eclipse.rdf4j.model.IRI; 7 | import org.eclipse.rdf4j.rio.RDFFormat; 8 | import org.eclipse.rdf4j.sail.Sail; 9 | import org.eclipse.rdf4j.sail.SailConnection; 10 | import org.eclipse.rdf4j.sail.SailException; 11 | import org.restlet.data.MediaType; 12 | import org.restlet.representation.Representation; 13 | import org.restlet.representation.Variant; 14 | import org.restlet.resource.Get; 15 | import org.restlet.resource.ServerResource; 16 | 17 | import java.util.Collection; 18 | import java.util.LinkedList; 19 | import java.util.logging.Level; 20 | import java.util.logging.Logger; 21 | 22 | /** 23 | * Graph resources are information resources which (in the present schema) do not use suffixes identifying the RDF 24 | * format (e.g. .rdf or .ttl). Instead, they use content negotiation to serve an appropriate representation against 25 | * the IRI of the graph, without redirection. 26 | *

27 | * This conforms to the common expectation that RDF documents and corresponding named graphs have the same IRI. 28 | * 29 | * @author Joshua Shinavier (http://fortytwo.net) 30 | */ 31 | public class GraphResource extends ServerResource { 32 | private static final Logger logger = Logger.getLogger(GraphResource.class.getName()); 33 | 34 | protected String selfIRI; 35 | 36 | protected Sail sail; 37 | 38 | public GraphResource() { 39 | super(); 40 | 41 | getVariants().addAll(RDFMediaTypes.getRDFVariants()); 42 | 43 | sail = LinkedDataServer.getInstance().getSail(); 44 | } 45 | 46 | @Override 47 | @Get 48 | public Representation get(final Variant entity) { 49 | MediaType type = entity.getMediaType(); 50 | RDFFormat format = RDFMediaTypes.findRdfFormat(type); 51 | selfIRI = this.getRequest().getResourceRef().toString(); 52 | 53 | try { 54 | IRI subject = sail.getValueFactory().createIRI(selfIRI); 55 | return getRDFRepresentation(subject, format); 56 | } catch (Throwable t) { 57 | t.printStackTrace(); 58 | return null; 59 | } 60 | } 61 | 62 | private void addStatementsInGraph(final org.eclipse.rdf4j.model.Resource graph, 63 | final Collection statements, 64 | final SailConnection c) throws SailException { 65 | try (CloseableIteration stIter 66 | = c.getStatements(null, null, null, false, graph)) { 67 | while (stIter.hasNext()) { 68 | statements.add(stIter.next()); 69 | } 70 | } 71 | } 72 | 73 | private Representation getRDFRepresentation(final IRI graph, 74 | final RDFFormat format) { 75 | try { 76 | Collection namespaces = new LinkedList<>(); 77 | Collection statements = new LinkedList<>(); 78 | 79 | SailConnection c = sail.getConnection(); 80 | try { 81 | // Note: do NOT add graph or document metadata, as this document is to contain only those statements 82 | // asserted in the graph in question. 83 | 84 | // Add statements in this graph, preserving the graph component of the statements. 85 | addStatementsInGraph(graph, statements, c); 86 | 87 | // Select namespaces, for human-friendliness 88 | try (CloseableIteration ns = c.getNamespaces()) { 89 | while (ns.hasNext()) { 90 | namespaces.add(ns.next()); 91 | } 92 | } 93 | } finally { 94 | c.close(); 95 | } 96 | return new RDFRepresentation(statements, namespaces, format); 97 | 98 | } catch (Throwable t) { 99 | logger.log(Level.WARNING, "failed to create RDF representation", t); 100 | t.printStackTrace(System.err); 101 | 102 | return null; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/LinkedDataServer.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import net.fortytwo.sesametools.mappingsail.MappingSail; 4 | import net.fortytwo.sesametools.mappingsail.MappingSchema; 5 | import net.fortytwo.sesametools.mappingsail.RewriteRule; 6 | import org.eclipse.rdf4j.model.IRI; 7 | import org.eclipse.rdf4j.model.ValueFactory; 8 | import org.eclipse.rdf4j.sail.Sail; 9 | import org.restlet.Application; 10 | 11 | /** 12 | * A RESTful web service which publishes the contents of a Sail data store as Linked Data. 13 | * 14 | * @author Joshua Shinavier (http://fortytwo.net) 15 | */ 16 | public class LinkedDataServer extends Application { 17 | 18 | private final Sail sail; 19 | private final IRI datasetURI; 20 | 21 | private static LinkedDataServer SINGLETON = null; 22 | 23 | /** 24 | * @param baseSail the data store published by this server 25 | * @param internalBaseURI the base URI of resources within the data store 26 | * @param externalBaseURI the base URI of resources as they are to be seen in the Linked Data 27 | */ 28 | public LinkedDataServer(final Sail baseSail, 29 | final String internalBaseURI, 30 | final String externalBaseURI) { 31 | this(baseSail, internalBaseURI, externalBaseURI, null); 32 | } 33 | 34 | /** 35 | * @param baseSail the data store published by this server 36 | * @param internalBaseURI the base URI of resources within the data store 37 | * @param externalBaseURI the base URI of resources as they are to be seen in the Linked Data 38 | * @param dataset the URI of the data set to be published. 39 | * This allows resource descriptions to be associated 40 | * with metadata about the data set which contains them. 41 | */ 42 | public LinkedDataServer(final Sail baseSail, 43 | final String internalBaseURI, 44 | final String externalBaseURI, 45 | final String dataset) { 46 | if (null != SINGLETON) { 47 | throw new IllegalStateException("only one LinkedDataServer may be instantiated per JVM"); 48 | } 49 | 50 | SINGLETON = this; 51 | 52 | final ValueFactory vf = baseSail.getValueFactory(); 53 | 54 | if (!internalBaseURI.equals(externalBaseURI)) { 55 | RewriteRule outboundRewriter = new RewriteRule() { 56 | public IRI rewrite(final IRI original) { 57 | 58 | if (null == original) { 59 | return null; 60 | } else { 61 | String s = original.stringValue(); 62 | return s.startsWith(internalBaseURI) 63 | ? vf.createIRI(s.replace(internalBaseURI, externalBaseURI)) 64 | : original; 65 | } 66 | } 67 | }; 68 | 69 | RewriteRule inboundRewriter = new RewriteRule() { 70 | public IRI rewrite(final IRI original) { 71 | if (null == original) { 72 | return null; 73 | } else { 74 | String s = original.stringValue(); 75 | return s.startsWith(externalBaseURI) 76 | ? vf.createIRI(s.replace(externalBaseURI, internalBaseURI)) 77 | : original; 78 | } 79 | } 80 | }; 81 | 82 | MappingSchema schema = new MappingSchema(); 83 | schema.setRewriter(MappingSchema.Direction.INBOUND, inboundRewriter); 84 | schema.setRewriter(MappingSchema.Direction.OUTBOUND, outboundRewriter); 85 | this.sail = new MappingSail(baseSail, schema); 86 | 87 | datasetURI = null == dataset 88 | ? null 89 | : outboundRewriter.rewrite(vf.createIRI(dataset)); 90 | } else { 91 | this.sail = baseSail; 92 | datasetURI = null == dataset 93 | ? null 94 | : vf.createIRI(dataset); 95 | } 96 | } 97 | 98 | /** 99 | * @return the data store published by this server 100 | */ 101 | public Sail getSail() { 102 | return sail; 103 | } 104 | 105 | /** 106 | * @return the internal URI for the data set published by this server 107 | */ 108 | public IRI getDatasetURI() { 109 | return datasetURI; 110 | } 111 | 112 | /** 113 | * @return the single Linked Data server 114 | */ 115 | public static LinkedDataServer getInstance() { 116 | return SINGLETON; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/RDFMediaTypes.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import org.eclipse.rdf4j.rio.RDFFormat; 4 | import org.eclipse.rdf4j.rio.RDFParserRegistry; 5 | import org.restlet.data.MediaType; 6 | import org.restlet.representation.Variant; 7 | 8 | import java.util.HashMap; 9 | import java.util.LinkedHashSet; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * @author Joshua Shinavier (http://fortytwo.net) 16 | */ 17 | public class RDFMediaTypes { 18 | 19 | private static final List RDF_VARIANTS; 20 | private static final Map MEDATYPE_BY_RDFFORMAT; 21 | private static final Map RDFFORMAT_BY_MEDIATYPE; 22 | 23 | static { 24 | RDF_VARIANTS = new LinkedList<>(); 25 | MEDATYPE_BY_RDFFORMAT = new HashMap<>(); 26 | RDFFORMAT_BY_MEDIATYPE = new HashMap<>(); 27 | 28 | LinkedHashSet toAdd = new LinkedHashSet<>(); 29 | // add RDF/XML first, as the default format 30 | toAdd.add(RDFFormat.RDFXML); 31 | // now add the others 32 | toAdd.addAll(RDFParserRegistry.getInstance().getKeys()); 33 | 34 | for (RDFFormat f : toAdd) { 35 | MediaType mt = new MediaType(f.getDefaultMIMEType()); 36 | Variant v = new Variant(mt); 37 | MEDATYPE_BY_RDFFORMAT.put(f, mt); 38 | RDFFORMAT_BY_MEDIATYPE.put(mt, f); 39 | RDF_VARIANTS.add(v); 40 | } 41 | } 42 | 43 | private RDFMediaTypes() { 44 | 45 | } 46 | 47 | public static List getRDFVariants() { 48 | return RDF_VARIANTS; 49 | } 50 | 51 | public static RDFFormat findRdfFormat(final MediaType mediaType) { 52 | return RDFFORMAT_BY_MEDIATYPE.get(mediaType); 53 | } 54 | 55 | public static MediaType findMediaType(final RDFFormat format) { 56 | return MEDATYPE_BY_RDFFORMAT.get(format); 57 | } 58 | 59 | public static Variant findVariant(final RDFFormat format) { 60 | MediaType mt = findMediaType(format); 61 | return null == mt ? null : new Variant(MEDATYPE_BY_RDFFORMAT.get(format)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/RDFRepresentation.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import net.fortytwo.sesametools.SesameTools; 4 | import org.eclipse.rdf4j.model.Namespace; 5 | import org.eclipse.rdf4j.model.Statement; 6 | import org.eclipse.rdf4j.rio.RDFFormat; 7 | import org.eclipse.rdf4j.rio.RDFWriter; 8 | import org.eclipse.rdf4j.rio.Rio; 9 | import org.restlet.representation.OutputRepresentation; 10 | 11 | import java.io.IOException; 12 | import java.io.OutputStream; 13 | import java.util.Collection; 14 | import java.util.logging.Level; 15 | import java.util.logging.Logger; 16 | 17 | /** 18 | * An RDF document as an HTTP entity. 19 | * 20 | * @author Joshua Shinavier (http://fortytwo.net) 21 | */ 22 | public class RDFRepresentation extends OutputRepresentation { 23 | private static final Logger logger 24 | = Logger.getLogger(RDFRepresentation.class.getName()); 25 | 26 | private final Collection statements; 27 | private final Collection namespaces; 28 | private final RDFFormat format; 29 | 30 | public RDFRepresentation(final Collection statements, 31 | final Collection namespaces, 32 | final RDFFormat format) { 33 | super(RDFMediaTypes.findMediaType(format)); 34 | 35 | this.statements = statements; 36 | this.namespaces = namespaces; 37 | this.format = format; 38 | } 39 | 40 | @Override 41 | public void write(final OutputStream os) throws IOException { 42 | try { 43 | RDFWriter writer = Rio.createWriter(format, os); 44 | writer.startRDF(); 45 | try { 46 | for (Namespace ns : namespaces) { 47 | writer.handleNamespace(ns.getPrefix(), ns.getName()); 48 | } 49 | for (Statement st : statements) { 50 | writer.handleStatement(st); 51 | } 52 | writer.handleComment("created by LinkedDataServer " 53 | + SesameTools.getProperties().getProperty(SesameTools.VERSION_PROP) 54 | + " using the Sesame 2 RDF framework"); 55 | } finally { 56 | writer.endRDF(); 57 | } 58 | } catch (Throwable t) { 59 | if (t instanceof IOException) { 60 | throw (IOException) t; 61 | } else { 62 | logger.log(Level.WARNING, "failed to write RDF representation", t); 63 | throw new IOException(t.getMessage()); 64 | } 65 | } 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/ServerException.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net) 5 | */ 6 | public class ServerException extends Exception { 7 | public ServerException(final Throwable cause) { 8 | super(cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/query/QueryException.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver.query; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net) 5 | */ 6 | public class QueryException extends Exception { 7 | public QueryException(final Throwable cause) { 8 | super(cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/query/QueryResource.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver.query; 2 | 3 | import net.fortytwo.sesametools.ldserver.LinkedDataServer; 4 | import org.eclipse.rdf4j.sail.Sail; 5 | import org.restlet.Request; 6 | import org.restlet.Restlet; 7 | import org.restlet.resource.ResourceException; 8 | 9 | import java.io.UnsupportedEncodingException; 10 | import java.net.URLDecoder; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | import java.util.logging.Logger; 14 | 15 | /** 16 | * @author Joshua Shinavier (http://fortytwo.net) 17 | */ 18 | public abstract class QueryResource extends Restlet { 19 | private static final Logger logger = Logger.getLogger(QueryResource.class.getName()); 20 | 21 | private static final String UTF_8 = "UTF-8"; 22 | 23 | private static final int 24 | MAX_LIMIT = 500, 25 | DEFAULT_LIMIT = 300; 26 | 27 | private static final String LIMIT_PARAM = "limit"; 28 | 29 | protected String selfURI; 30 | 31 | protected Sail sail; 32 | //private final String query; 33 | 34 | protected Map getArguments(final Request request) throws ResourceException { 35 | Map arguments; 36 | selfURI = request.getResourceRef().toString(); 37 | 38 | sail = LinkedDataServer.getInstance().getSail(); 39 | 40 | //getVariants().add(new Variant(MediaType.APPLICATION_JSON)); 41 | 42 | int i = selfURI.lastIndexOf("?"); 43 | arguments = new HashMap<>(); 44 | if (0 < i) { 45 | String args = selfURI.substring(i + 1); 46 | if (0 < args.length()) { 47 | try { 48 | arguments = parseParams(args); 49 | } catch (UnsupportedEncodingException e) { 50 | throw new ResourceException(e); 51 | } 52 | } 53 | } 54 | 55 | return arguments; 56 | } 57 | 58 | protected Map parseParams(final String s) throws UnsupportedEncodingException { 59 | Map map = new HashMap<>(); 60 | 61 | String[] a = s.split("&"); 62 | for (String p : a) { 63 | String[] b = p.split("="); 64 | map.put(urlDecode(b[0]), urlDecode(b[1])); 65 | } 66 | 67 | return map; 68 | } 69 | 70 | protected int readLimit(final Map arguments) { 71 | String l = arguments.get(LIMIT_PARAM); 72 | int limit; 73 | if (null == l) { 74 | limit = DEFAULT_LIMIT; 75 | } else { 76 | try { 77 | limit = Integer.valueOf(l); 78 | 79 | if (limit > MAX_LIMIT) { 80 | limit = MAX_LIMIT; 81 | } else if (limit < 1) { 82 | limit = DEFAULT_LIMIT; 83 | } 84 | } catch (NumberFormatException e) { 85 | logger.warning("bad limit value: " + l); 86 | limit = DEFAULT_LIMIT; 87 | } 88 | } 89 | 90 | return limit; 91 | } 92 | 93 | protected String urlDecode(final String encoded) throws UnsupportedEncodingException { 94 | return URLDecoder.decode(encoded, UTF_8); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/query/SparqlQueryRepresentation.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver.query; 2 | 3 | import org.eclipse.rdf4j.sail.Sail; 4 | import org.eclipse.rdf4j.sail.SailConnection; 5 | import org.restlet.data.MediaType; 6 | import org.restlet.representation.OutputRepresentation; 7 | 8 | import java.io.ByteArrayOutputStream; 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | 12 | /** 13 | * A SPARQL query result as an HTTP entity. 14 | * 15 | * @author Joshua Shinavier (http://fortytwo.net) 16 | */ 17 | public class SparqlQueryRepresentation extends OutputRepresentation { 18 | 19 | private final ByteArrayOutputStream data; 20 | 21 | public SparqlQueryRepresentation(final String query, 22 | final Sail sail, 23 | final int limit, 24 | final MediaType mediaType) throws Exception { 25 | super(mediaType); 26 | 27 | try { 28 | data = new ByteArrayOutputStream(); 29 | SailConnection sc = sail.getConnection(); 30 | try { 31 | SparqlTools.SparqlResultFormat format 32 | = SparqlTools.SparqlResultFormat.lookup(this.getMediaType()); 33 | 34 | SparqlTools.executeQuery(query, sc, data, limit, format); 35 | } finally { 36 | sc.close(); 37 | } 38 | } catch (Throwable e) { 39 | // TODO: use logging instead 40 | e.printStackTrace(System.err); 41 | throw new Exception(e); 42 | } 43 | } 44 | 45 | public void write(final OutputStream out) throws IOException { 46 | data.writeTo(out); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /linked-data-server/src/main/java/net/fortytwo/sesametools/ldserver/query/SparqlResource.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver.query; 2 | 3 | import org.restlet.Request; 4 | import org.restlet.Response; 5 | import org.restlet.data.MediaType; 6 | import org.restlet.data.Method; 7 | import org.restlet.data.Status; 8 | import org.restlet.resource.ResourceException; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * A RESTful resource serving as a SPARQL endpoint. 14 | * 15 | * @author Joshua Shinavier (http://fortytwo.net) 16 | */ 17 | public class SparqlResource extends QueryResource { 18 | 19 | @Override 20 | public void handle(final Request request, 21 | final Response response) { 22 | MediaType mt; 23 | String query = null; 24 | Map arguments; 25 | 26 | try { 27 | arguments = getArguments(request); 28 | 29 | if (request.getMethod() == Method.POST) { 30 | String type = request.getEntity().getMediaType().toString(); 31 | String ent = request.getEntity().getText(); 32 | 33 | switch (type) { 34 | case "application/x-www-form-urlencoded": 35 | arguments = parseParams(ent); 36 | break; 37 | case "application/sparql-query": 38 | query = ent; 39 | break; 40 | default: 41 | throw new IllegalArgumentException("POST entity has unsupported media type for SPARQL"); 42 | } 43 | } 44 | 45 | if (null == query) { 46 | query = arguments.get("query"); 47 | } 48 | 49 | if (null == query) { 50 | throw new IllegalArgumentException("no query argument specified"); 51 | } 52 | 53 | String output = arguments.get("output"); 54 | 55 | // If an "output" argument is provided, use it. 56 | if (null != output) { 57 | switch (output) { 58 | case "json": 59 | mt = SparqlTools.SparqlResultFormat.JSON.getMediaType(); 60 | break; 61 | case "xml": 62 | mt = SparqlTools.SparqlResultFormat.XML.getMediaType(); 63 | break; 64 | default: 65 | throw new IllegalArgumentException("bad value for 'output' parameter: " + output); 66 | } 67 | } else { 68 | mt = SparqlTools.SparqlResultFormat.getVariants().get(0).getMediaType(); 69 | } 70 | } catch (Throwable t) { 71 | t.printStackTrace(System.err); 72 | throw new ResourceException(t); 73 | } 74 | 75 | try { 76 | response.setEntity(new SparqlQueryRepresentation(query, sail, readLimit(arguments), mt)); 77 | } catch (QueryException e) { 78 | throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, e); 79 | } catch (Throwable e) { 80 | // TODO: use logging instead 81 | e.printStackTrace(System.err); 82 | System.err.flush(); 83 | throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /linked-data-server/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory: -------------------------------------------------------------------------------- 1 | org.openrdf.rio.n3.N3WriterFactory 2 | org.openrdf.rio.ntriples.NTriplesWriterFactory 3 | org.openrdf.rio.rdfxml.RDFXMLWriterFactory 4 | org.openrdf.rio.trig.TriGWriterFactory 5 | org.openrdf.rio.trix.TriXWriterFactory 6 | org.openrdf.rio.turtle.TurtleWriterFactory 7 | org.openrdf.rio.nquads.NQuadsWriterFactory 8 | org.openrdf.rio.rdfjson.RDFJSONWriterFactory 9 | -------------------------------------------------------------------------------- /linked-data-server/src/test/java/net/fortytwo/sesametools/ldserver/DemoApp.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import net.fortytwo.sesametools.ldserver.query.SparqlResource; 4 | import org.eclipse.rdf4j.repository.Repository; 5 | import org.eclipse.rdf4j.repository.RepositoryConnection; 6 | import org.eclipse.rdf4j.repository.sail.SailRepository; 7 | import org.eclipse.rdf4j.rio.RDFFormat; 8 | import org.eclipse.rdf4j.sail.Sail; 9 | import org.eclipse.rdf4j.sail.memory.MemoryStore; 10 | import org.restlet.Component; 11 | import org.restlet.data.Protocol; 12 | 13 | /** 14 | * @author Joshua Shinavier (http://fortytwo.net) 15 | */ 16 | public class DemoApp { 17 | public static void main(final String[] args) throws Exception { 18 | Sail sail = new MemoryStore(); 19 | sail.initialize(); 20 | 21 | Repository repo = new SailRepository(sail); 22 | try (RepositoryConnection rc = repo.getConnection()) { 23 | rc.add(DemoApp.class.getResourceAsStream("demoApp.trig"), "", RDFFormat.TRIG); 24 | } 25 | 26 | LinkedDataServer server = new LinkedDataServer( 27 | sail, 28 | "http://example.org", 29 | "http://localhost:8001"); 30 | 31 | Component component = new Component(); 32 | component.getServers().add(Protocol.HTTP, 8001); 33 | component.getDefaultHost().attach("/person", WebResource.class); 34 | component.getDefaultHost().attach("/graph", GraphResource.class); 35 | component.getDefaultHost().attach("/sparql", new SparqlResource()); 36 | server.setInboundRoot(component); 37 | server.start(); 38 | 39 | /* Now try: 40 | wget http://localhost:8001/person/arthur 41 | wget --header="Accept: application/x-trig" http://localhost:8001/person/arthur 42 | wget --header="Accept: application/x-trig" http://localhost:8001/graph/demoGraph 43 | 44 | wget "http://localhost:8001/sparql?query=SELECT%20%3Fs%20%3Fp%20%3Fo%20WHERE%20%7B%20%3Fs%20%3Fp%20%3Fo%20%7D%20LIMIT%2010" 45 | curl --data-urlencode query@/tmp/myquery.rq http://localhost:8001/sparql 46 | */ 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /linked-data-server/src/test/java/net/fortytwo/sesametools/ldserver/SparqlAskTest.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.ldserver; 2 | 3 | import java.net.URI; 4 | import java.util.logging.Level; 5 | 6 | import net.fortytwo.sesametools.ldserver.query.SparqlResource; 7 | 8 | import org.junit.AfterClass; 9 | import org.junit.Assert; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | import org.eclipse.rdf4j.query.QueryLanguage; 13 | import org.eclipse.rdf4j.repository.Repository; 14 | import org.eclipse.rdf4j.repository.RepositoryConnection; 15 | import org.eclipse.rdf4j.repository.sail.SailRepository; 16 | import org.eclipse.rdf4j.repository.sparql.SPARQLRepository; 17 | import org.eclipse.rdf4j.rio.RDFFormat; 18 | import org.eclipse.rdf4j.sail.Sail; 19 | import org.eclipse.rdf4j.sail.memory.MemoryStore; 20 | import org.restlet.Component; 21 | import org.restlet.data.Protocol; 22 | import org.restlet.engine.Engine; 23 | 24 | public class SparqlAskTest { 25 | 26 | private static final URI ENDPOINT_URL = URI.create("http://localhost:8001/sparql"); 27 | private static final String DATA_FILE = "demoApp.trig"; 28 | 29 | private static final Sail sail; 30 | private static final LinkedDataServer server; 31 | 32 | static { 33 | sail = new MemoryStore(); 34 | sail.initialize(); 35 | server = new LinkedDataServer(sail, "", ""); 36 | } 37 | 38 | @BeforeClass 39 | public static void setUp() throws Exception { 40 | // add test data 41 | final Repository repo = new SailRepository(sail); 42 | try (RepositoryConnection con = repo.getConnection()) { 43 | con.add(SparqlAskTest.class.getResourceAsStream(DATA_FILE), "", RDFFormat.TRIG); 44 | } 45 | 46 | // turn off verbose logging in Restlet engine 47 | Engine.setLogLevel(Level.WARNING); 48 | 49 | // configure SPARQL endpoint 50 | final Component component = new Component(); 51 | component.getServers().add(Protocol.HTTP, ENDPOINT_URL.getPort()); 52 | component.getDefaultHost().attach(ENDPOINT_URL.getPath(), new SparqlResource()); 53 | server.setInboundRoot(component); 54 | server.start(); 55 | } 56 | 57 | @AfterClass 58 | public static void tearDown() throws Exception { 59 | server.stop(); 60 | sail.shutDown(); 61 | } 62 | 63 | @Test 64 | public void testSatisfiableAskQuery() throws Exception { 65 | Assert.assertTrue(executeAskQuery(ENDPOINT_URL, "ASK { [] a ?type }")); 66 | } 67 | 68 | @Test 69 | public void testUnsatisfiableAskQuery() throws Exception { 70 | Assert.assertFalse(executeAskQuery(ENDPOINT_URL, "ASK { [] ?p }")); 71 | } 72 | 73 | private Boolean executeAskQuery(final URI endpoint, final String query) { 74 | 75 | final SPARQLRepository repo = new SPARQLRepository(endpoint.toString()); 76 | try { 77 | repo.initialize(); 78 | 79 | try (RepositoryConnection con = repo.getConnection()) { 80 | return con.prepareBooleanQuery(QueryLanguage.SPARQL, query).evaluate(); 81 | } catch (Exception e) { 82 | Assert.fail(e.getMessage()); 83 | } 84 | 85 | } catch (Exception e) { 86 | Assert.fail(e.getMessage()); 87 | } finally { 88 | repo.shutDown(); 89 | } 90 | return null; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /linked-data-server/src/test/resources/META-INF/services/org.openrdf.rio.RDFParserFactory: -------------------------------------------------------------------------------- 1 | org.openrdf.rio.trig.TriGParserFactory 2 | -------------------------------------------------------------------------------- /linked-data-server/src/test/resources/net/fortytwo/sesametools/ldserver/demoApp.trig: -------------------------------------------------------------------------------- 1 | @prefix foaf: . 2 | @prefix rdfs: . 3 | @prefix xsd: . 4 | @prefix p: . 5 | @prefix g: . 6 | 7 | { 8 | p:arthur a foaf:Person; 9 | rdfs:comment "he's a jerk". 10 | } 11 | 12 | g:demoGraph 13 | { 14 | p:ford a foaf:Person; 15 | foaf:knows p:arthur, p:zaphod; 16 | rdfs:comment "he really knows where his towel is". 17 | 18 | p:zaphod a foaf:Person; 19 | foaf:knows p:ford; 20 | rdfs:comment "so cool you could keep a side of meat in him for a month". 21 | } 22 | -------------------------------------------------------------------------------- /mapping-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /mapping-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | mapping-sail 6 | jar 7 | MappingSail 8 | A Sail which translates between two URI spaces 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | 28 | junit 29 | junit 30 | test 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-compiler-plugin 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-source-plugin 43 | 44 | 45 | org.apache.maven.plugins 46 | maven-jar-plugin 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-javadoc-plugin 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | org.eluder.coveralls 58 | coveralls-maven-plugin 59 | 60 | 61 | org.jacoco 62 | jacoco-maven-plugin 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /mapping-sail/src/main/java/net/fortytwo/sesametools/mappingsail/MappingSail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.mappingsail; 2 | 3 | import org.eclipse.rdf4j.sail.Sail; 4 | import org.eclipse.rdf4j.sail.SailConnection; 5 | import org.eclipse.rdf4j.sail.SailException; 6 | import org.eclipse.rdf4j.sail.helpers.SailWrapper; 7 | 8 | /** 9 | * A Sail which maps between the internal URI space of a lower-level data store, 10 | * and an externally visible URI space 11 | * (for example, published Linked Data). 12 | * 13 | * @author Joshua Shinavier (http://fortytwo.net) 14 | */ 15 | public class MappingSail extends SailWrapper { 16 | private final MappingSchema schema; 17 | 18 | /** 19 | * @param baseSail the internal data store 20 | * @param schema a set of rules for URI rewriting 21 | */ 22 | public MappingSail(final Sail baseSail, 23 | final MappingSchema schema) { 24 | this.setBaseSail(baseSail); 25 | this.schema = schema; 26 | } 27 | 28 | @Override 29 | public SailConnection getConnection() throws SailException { 30 | return new MappingSailConnection(this.getBaseSail().getConnection(), schema, this.getValueFactory()); 31 | } 32 | 33 | @Override 34 | public boolean isWritable() throws SailException { 35 | // TODO: handle rewriting for write operations 36 | return false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mapping-sail/src/main/java/net/fortytwo/sesametools/mappingsail/MappingSailConnection.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.mappingsail; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.model.Statement; 7 | import org.eclipse.rdf4j.model.Value; 8 | import org.eclipse.rdf4j.model.ValueFactory; 9 | import org.eclipse.rdf4j.sail.SailConnection; 10 | import org.eclipse.rdf4j.sail.SailException; 11 | import org.eclipse.rdf4j.sail.helpers.SailConnectionWrapper; 12 | 13 | /** 14 | * @author Joshua Shinavier (http://fortytwo.net) 15 | */ 16 | class MappingSailConnection extends SailConnectionWrapper { 17 | private final MappingSchema rewriters; 18 | private final ValueFactory valueFactory; 19 | 20 | public MappingSailConnection(final SailConnection baseConnection, 21 | final MappingSchema rewriters, 22 | final ValueFactory valueFactory) { 23 | super(baseConnection); 24 | this.rewriters = rewriters; 25 | this.valueFactory = valueFactory; 26 | } 27 | 28 | @Override 29 | public CloseableIteration getStatements( 30 | Resource subj, IRI pred, Value obj, final boolean includeInferred, Resource... contexts) 31 | throws SailException { 32 | 33 | if (subj instanceof IRI) { 34 | subj = rewriters.getRewriter( 35 | MappingSchema.PartOfSpeech.SUBJECT, MappingSchema.Direction.INBOUND).rewrite((IRI) subj); 36 | } 37 | pred = rewriters.getRewriter( 38 | MappingSchema.PartOfSpeech.PREDICATE, MappingSchema.Direction.INBOUND).rewrite(pred); 39 | if (obj instanceof IRI) { 40 | obj = rewriters.getRewriter( 41 | MappingSchema.PartOfSpeech.OBJECT, MappingSchema.Direction.INBOUND).rewrite((IRI) obj); 42 | } 43 | for (int i = 0; i < contexts.length; i++) { 44 | if (contexts[i] instanceof IRI) { 45 | contexts[i] = rewriters.getRewriter( 46 | MappingSchema.PartOfSpeech.CONTEXT, MappingSchema.Direction.INBOUND).rewrite((IRI) contexts[i]); 47 | } 48 | } 49 | 50 | return new RewritingStatementIteration( 51 | this.getWrappedConnection().getStatements(subj, pred, obj, includeInferred, contexts)); 52 | } 53 | 54 | private class RewritingStatementIteration implements CloseableIteration { 55 | private final CloseableIteration baseIteration; 56 | 57 | public RewritingStatementIteration(final CloseableIteration baseIteration) { 58 | this.baseIteration = baseIteration; 59 | } 60 | 61 | public void close() throws SailException { 62 | baseIteration.close(); 63 | } 64 | 65 | public boolean hasNext() throws SailException { 66 | return baseIteration.hasNext(); 67 | } 68 | 69 | public Statement next() throws SailException { 70 | Statement st = baseIteration.next(); 71 | 72 | Resource subject = st.getSubject(); 73 | IRI predicate = st.getPredicate(); 74 | Value object = st.getObject(); 75 | Resource context = st.getContext(); 76 | 77 | if (subject instanceof IRI) { 78 | subject = rewriters.getRewriter( 79 | MappingSchema.PartOfSpeech.SUBJECT, MappingSchema.Direction.OUTBOUND) 80 | .rewrite((IRI) subject); 81 | } 82 | predicate = rewriters.getRewriter( 83 | MappingSchema.PartOfSpeech.PREDICATE, MappingSchema.Direction.OUTBOUND) 84 | .rewrite(predicate); 85 | if (object instanceof IRI) { 86 | object = rewriters.getRewriter( 87 | MappingSchema.PartOfSpeech.OBJECT, MappingSchema.Direction.OUTBOUND) 88 | .rewrite((IRI) object); 89 | } 90 | if (null != context && context instanceof IRI) { 91 | context = rewriters.getRewriter( 92 | MappingSchema.PartOfSpeech.CONTEXT, MappingSchema.Direction.OUTBOUND) 93 | .rewrite((IRI) context); 94 | } 95 | 96 | return valueFactory.createStatement(subject, predicate, object, context); 97 | } 98 | 99 | public void remove() throws SailException { 100 | baseIteration.remove(); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /mapping-sail/src/main/java/net/fortytwo/sesametools/mappingsail/MappingSchema.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.mappingsail; 2 | 3 | import org.eclipse.rdf4j.model.IRI; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * A set of rules for rewriting URIs based on direction (to or from the data store) 10 | * and part of speech (the position in an RDF statement in which a URI appears) 11 | * 12 | * @author Joshua Shinavier (http://fortytwo.net) 13 | */ 14 | public class MappingSchema { 15 | /** 16 | * The position in an RDF statement in which a URI appears 17 | */ 18 | public enum PartOfSpeech { 19 | SUBJECT, PREDICATE, OBJECT, CONTEXT 20 | } 21 | 22 | /** 23 | * The direction of a URI rewriting rule: inbound rules map externally visible URIs 24 | * to the URIs found in the data store, while outbound rules do the opposite. 25 | */ 26 | public enum Direction { 27 | INBOUND, OUTBOUND 28 | } 29 | 30 | private final RewriteRule defaultRewriter = new RewriteRule() { 31 | public IRI rewrite(final IRI original) { 32 | return original; 33 | } 34 | }; 35 | 36 | private final Map rewriters 37 | = new HashMap<>(); 38 | 39 | /** 40 | * @param partOfSpeech the position in an RDF statement (subject, predicate, object or context) 41 | * in which the URI appears 42 | * @param direction whether this is a rule to map externally visible URIs to internal URIs (inbound) 43 | * or the reverse (outbound) 44 | * @return the matching rewriting rule. 45 | * If no such rule has been explicitly defined, the default rule (the identity mapping) is returned. 46 | */ 47 | public RewriteRule getRewriter(final PartOfSpeech partOfSpeech, 48 | final Direction direction) { 49 | RewriteRule r = rewriters.get("" + partOfSpeech + direction); 50 | return null == r 51 | ? defaultRewriter 52 | : r; 53 | } 54 | 55 | /** 56 | * Defines an inbound or outbound URI rewriter. 57 | * 58 | * @param direction whether this is a rule to map externally visible URIs to internal URIs (inbound) 59 | * or the reverse (outbound) 60 | * @param rule the rewriting rule 61 | */ 62 | public void setRewriter(final Direction direction, 63 | final RewriteRule rule) { 64 | for (PartOfSpeech p : PartOfSpeech.values()) { 65 | setRewriter(direction, p, rule); 66 | } 67 | } 68 | 69 | /** 70 | * Defines an inbound or outbound URI rewriter for a specific part of speech 71 | * (subject, predicate, object, or context). 72 | * 73 | * @param partOfSpeech the part of speech to which this rewriter applies 74 | * @param direction whether this is a rule to map externally visible URIs to internal URIs (inbound) 75 | * or the reverse (outbound) 76 | * @param rule the rewriting rule 77 | */ 78 | public void setRewriter(final Direction direction, 79 | final PartOfSpeech partOfSpeech, 80 | final RewriteRule rule) { 81 | rewriters.put("" + partOfSpeech + direction, rule); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /mapping-sail/src/main/java/net/fortytwo/sesametools/mappingsail/RewriteRule.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.mappingsail; 2 | 3 | import org.eclipse.rdf4j.model.IRI; 4 | 5 | /** 6 | * Represents a rule to map an original URI to a new URI. 7 | * Rules are considered to be complete and self contained: MappingSail does not impose its own rewriting logic. 8 | * 9 | * @author Joshua Shinavier (http://fortytwo.net) 10 | */ 11 | public interface RewriteRule { 12 | /** 13 | * @param original an complete URI (i.e. not only a URI prefix) to be rewritten 14 | * @return the resulting URI 15 | */ 16 | IRI rewrite(IRI original); 17 | } 18 | -------------------------------------------------------------------------------- /rdf-transaction-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /rdf-transaction-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | rdf-transaction-sail 6 | jar 7 | RDFTransactionSail 8 | A write-only Sail which generates RDF transactions instead of performing per-call updates 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | org.eclipse.rdf4j 28 | rdf4j-http-protocol 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-source-plugin 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-jar-plugin 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-javadoc-plugin 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-surefire-plugin 60 | 61 | 62 | org.eluder.coveralls 63 | coveralls-maven-plugin 64 | 65 | 66 | org.jacoco 67 | jacoco-maven-plugin 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /rdf-transaction-sail/src/main/java/net/fortytwo/sesametools/rdftransaction/RDFTransactionSail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.rdftransaction; 2 | 3 | import org.eclipse.rdf4j.http.protocol.transaction.TransactionWriter; 4 | import org.eclipse.rdf4j.http.protocol.transaction.operations.TransactionOperation; 5 | import org.eclipse.rdf4j.sail.Sail; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | import org.eclipse.rdf4j.sail.helpers.SailWrapper; 9 | 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.util.List; 13 | 14 | /** 15 | * A Sail which uploads committed transactions in the application/x-rdftransaction format 16 | * 17 | * @author Joshua Shinavier (http://fortytwo.net). 18 | */ 19 | public abstract class RDFTransactionSail extends SailWrapper { 20 | private final int commitsPerTransaction; 21 | private final TransactionWriter writer = new TransactionWriter(); 22 | 23 | public RDFTransactionSail(final Sail baseSail, 24 | final int commitsPerTransaction) { 25 | super(baseSail); 26 | this.commitsPerTransaction = commitsPerTransaction; 27 | } 28 | 29 | public RDFTransactionSail(final Sail baseSail) { 30 | this(baseSail, 1); 31 | } 32 | 33 | @Override 34 | public SailConnection getConnection() throws SailException { 35 | SailConnection b = this.getBaseSail().getConnection(); 36 | 37 | return new RDFTransactionSailConnection(b, this, commitsPerTransaction); 38 | } 39 | 40 | protected byte[] createTransactionEntity(final List operations) throws SailException { 41 | try { 42 | try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { 43 | writer.serialize(operations, bos); 44 | return bos.toByteArray(); 45 | } 46 | } catch (IOException e) { 47 | throw new SailException(e); 48 | } 49 | } 50 | 51 | public abstract void handleTransaction(final List operations) throws SailException; 52 | } 53 | -------------------------------------------------------------------------------- /rdf-transaction-sail/src/main/java/net/fortytwo/sesametools/rdftransaction/RDFTransactionSailConnection.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.rdftransaction; 2 | 3 | import org.eclipse.rdf4j.http.protocol.transaction.operations.AddStatementOperation; 4 | import org.eclipse.rdf4j.http.protocol.transaction.operations.ClearNamespacesOperation; 5 | import org.eclipse.rdf4j.http.protocol.transaction.operations.ClearOperation; 6 | import org.eclipse.rdf4j.http.protocol.transaction.operations.RemoveNamespaceOperation; 7 | import org.eclipse.rdf4j.http.protocol.transaction.operations.RemoveStatementsOperation; 8 | import org.eclipse.rdf4j.http.protocol.transaction.operations.SetNamespaceOperation; 9 | import org.eclipse.rdf4j.http.protocol.transaction.operations.TransactionOperation; 10 | import org.eclipse.rdf4j.model.IRI; 11 | import org.eclipse.rdf4j.model.Resource; 12 | import org.eclipse.rdf4j.model.Value; 13 | import org.eclipse.rdf4j.sail.SailConnection; 14 | import org.eclipse.rdf4j.sail.SailException; 15 | import org.eclipse.rdf4j.sail.helpers.SailConnectionWrapper; 16 | 17 | import java.util.LinkedList; 18 | import java.util.List; 19 | 20 | /** 21 | * @author Joshua Shinavier (http://fortytwo.net). 22 | */ 23 | public class RDFTransactionSailConnection extends SailConnectionWrapper { 24 | private final List operations; 25 | private final List buffer; 26 | private final RDFTransactionSail sail; 27 | private final int commitsPerUpload; 28 | private int commits = 0; 29 | 30 | /** 31 | * @param c the wrapped connection 32 | * @param sail the owner Sail 33 | * @param commitsPerUpload if transactions should be grouped together, rather than uploaded 34 | * individually. Note: when the SailConnection is closed, any leftover 35 | * transactions (committed but not uploaded) will be uploaded. 36 | */ 37 | public RDFTransactionSailConnection(final SailConnection c, 38 | final RDFTransactionSail sail, 39 | final int commitsPerUpload) { 40 | super(c); 41 | this.sail = sail; 42 | this.operations = new LinkedList<>(); 43 | this.buffer = new LinkedList<>(); 44 | this.commitsPerUpload = commitsPerUpload; 45 | } 46 | 47 | @Override 48 | public void commit() throws SailException { 49 | 50 | this.getWrappedConnection().commit(); 51 | 52 | buffer.addAll(operations); 53 | operations.clear(); 54 | 55 | commits++; 56 | if (commits == commitsPerUpload) { 57 | commitAll(); 58 | } 59 | } 60 | 61 | private void commitAll() throws SailException { 62 | if (!buffer.isEmpty()) { 63 | sail.handleTransaction(buffer); 64 | } 65 | 66 | buffer.clear(); 67 | commits = 0; 68 | } 69 | 70 | @Override 71 | public void rollback() throws SailException { 72 | this.getWrappedConnection().rollback(); 73 | 74 | operations.clear(); 75 | } 76 | 77 | @Override 78 | public void addStatement(Resource subject, IRI predicate, Value object, Resource... contexts) 79 | throws SailException { 80 | 81 | this.getWrappedConnection().addStatement(subject, predicate, object, contexts); 82 | 83 | operations.add(new AddStatementOperation(subject, predicate, object, contexts)); 84 | } 85 | 86 | @Override 87 | public void removeStatements(Resource subject, IRI predicate, Value object, Resource... contexts) 88 | throws SailException { 89 | 90 | this.getWrappedConnection().removeStatements(subject, predicate, object, contexts); 91 | 92 | operations.add(new RemoveStatementsOperation(subject, predicate, object, contexts)); 93 | } 94 | 95 | @Override 96 | public void clear(Resource... contexts) throws SailException { 97 | this.getWrappedConnection().clear(contexts); 98 | 99 | operations.add(new ClearOperation(contexts)); 100 | } 101 | 102 | @Override 103 | public void setNamespace(String prefix, String uri) throws SailException { 104 | this.getWrappedConnection().setNamespace(prefix, uri); 105 | 106 | operations.add(new SetNamespaceOperation(prefix, uri)); 107 | } 108 | 109 | @Override 110 | public void removeNamespace(String prefix) throws SailException { 111 | this.getWrappedConnection().removeNamespace(prefix); 112 | 113 | operations.add(new RemoveNamespaceOperation(prefix)); 114 | } 115 | 116 | @Override 117 | public void clearNamespaces() throws SailException { 118 | this.getWrappedConnection().clearNamespaces(); 119 | 120 | operations.add(new ClearNamespacesOperation()); 121 | } 122 | 123 | @Override 124 | public void close() throws SailException { 125 | commitAll(); 126 | super.close(); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /readonly-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /readonly-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | readonly-sail 6 | jar 7 | ReadOnlySail 8 | A read-only Sail implementation 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-compiler-plugin 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-source-plugin 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-jar-plugin 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-javadoc-plugin 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | org.eluder.coveralls 59 | coveralls-maven-plugin 60 | 61 | 62 | org.jacoco 63 | jacoco-maven-plugin 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /readonly-sail/src/main/java/net/fortytwo/sesametools/readonly/ReadOnlySail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.readonly; 2 | 3 | import org.eclipse.rdf4j.model.ValueFactory; 4 | import org.eclipse.rdf4j.sail.Sail; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | import org.eclipse.rdf4j.sail.StackableSail; 8 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 9 | 10 | import java.io.File; 11 | 12 | /** 13 | * A Sail implementation which protects a base Sail from write operations. 14 | * This Sail does not throw exceptions when write operations are attempted; 15 | * it simply ignores them so that they have no effect. 16 | * 17 | * @author Joshua Shinavier (http://fortytwo.net). 18 | */ 19 | public class ReadOnlySail extends AbstractSail implements StackableSail { 20 | private Sail baseSail; 21 | 22 | public ReadOnlySail(final Sail baseSail) { 23 | this.baseSail = baseSail; 24 | } 25 | 26 | @Override 27 | public void setDataDir(final File dir) { 28 | baseSail.setDataDir(dir); 29 | } 30 | 31 | @Override 32 | public File getDataDir() { 33 | return baseSail.getDataDir(); 34 | } 35 | 36 | protected void initializeInternal() throws SailException { 37 | // Do nothing. 38 | } 39 | 40 | protected void shutDownInternal() throws SailException { 41 | // Do nothing. 42 | } 43 | 44 | @Override 45 | public boolean isWritable() throws SailException { 46 | return false; 47 | } 48 | 49 | protected SailConnection getConnectionInternal() throws SailException { 50 | return new ReadOnlySailConnection(this, baseSail); 51 | } 52 | 53 | public ValueFactory getValueFactory() { 54 | return baseSail.getValueFactory(); 55 | } 56 | 57 | public void setBaseSail(final Sail sail) { 58 | this.baseSail = sail; 59 | } 60 | 61 | public Sail getBaseSail() { 62 | return baseSail; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /readonly-sail/src/main/java/net/fortytwo/sesametools/readonly/ReadOnlySailConnection.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.readonly; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.model.Namespace; 6 | import org.eclipse.rdf4j.model.Resource; 7 | import org.eclipse.rdf4j.model.Statement; 8 | import org.eclipse.rdf4j.model.Value; 9 | import org.eclipse.rdf4j.query.BindingSet; 10 | import org.eclipse.rdf4j.query.Dataset; 11 | import org.eclipse.rdf4j.query.QueryEvaluationException; 12 | import org.eclipse.rdf4j.query.algebra.TupleExpr; 13 | import org.eclipse.rdf4j.sail.Sail; 14 | import org.eclipse.rdf4j.sail.SailConnection; 15 | import org.eclipse.rdf4j.sail.SailException; 16 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 17 | import org.eclipse.rdf4j.sail.helpers.AbstractSailConnection; 18 | 19 | /** 20 | * @author Joshua Shinavier (http://fortytwo.net). 21 | */ 22 | public class ReadOnlySailConnection extends AbstractSailConnection { 23 | private final SailConnection baseSailConnection; 24 | 25 | public ReadOnlySailConnection(final AbstractSail sail, 26 | final Sail baseSail) throws SailException { 27 | super(sail); 28 | baseSailConnection = baseSail.getConnection(); 29 | } 30 | 31 | protected void closeInternal() throws SailException { 32 | baseSailConnection.close(); 33 | } 34 | 35 | protected CloseableIteration evaluateInternal( 36 | final TupleExpr tupleExpr, final Dataset dataset, final BindingSet bindings, final boolean includeInferred) 37 | throws SailException { 38 | 39 | return baseSailConnection.evaluate(tupleExpr, dataset, bindings, includeInferred); 40 | } 41 | 42 | protected CloseableIteration getContextIDsInternal() throws SailException { 43 | return baseSailConnection.getContextIDs(); 44 | } 45 | 46 | protected CloseableIteration getStatementsInternal( 47 | final Resource subject, final IRI predicate, final Value object, final boolean includeInferred, 48 | final Resource... contexts) throws SailException { 49 | 50 | return baseSailConnection.getStatements(subject, predicate, object, includeInferred, contexts); 51 | } 52 | 53 | protected long sizeInternal(final Resource... contexts) throws SailException { 54 | return baseSailConnection.size(contexts); 55 | } 56 | 57 | protected void commitInternal() throws SailException { 58 | // Do nothing. 59 | } 60 | 61 | protected void rollbackInternal() throws SailException { 62 | // Do nothing. 63 | } 64 | 65 | protected void addStatementInternal(final Resource subject, 66 | final IRI predicate, 67 | final Value object, 68 | final Resource... contexts) throws SailException { 69 | // Do nothing. 70 | } 71 | 72 | protected void removeStatementsInternal(final Resource subject, 73 | final IRI predicate, 74 | final Value object, 75 | final Resource... contexts) throws SailException { 76 | // Do nothing. 77 | } 78 | 79 | protected void clearInternal(final Resource... contexts) throws SailException { 80 | // Do nothing. 81 | } 82 | 83 | protected CloseableIteration getNamespacesInternal() throws SailException { 84 | return baseSailConnection.getNamespaces(); 85 | } 86 | 87 | protected String getNamespaceInternal(final String prefix) throws SailException { 88 | return baseSailConnection.getNamespace(prefix); 89 | } 90 | 91 | protected void setNamespaceInternal(final String prefix, 92 | final String uri) throws SailException { 93 | // Do nothing. 94 | } 95 | 96 | protected void removeNamespaceInternal(final String prefix) throws SailException { 97 | // Do nothing. 98 | } 99 | 100 | protected void clearNamespacesInternal() throws SailException { 101 | // Do nothing. 102 | } 103 | 104 | protected void startTransactionInternal() throws SailException { 105 | baseSailConnection.begin(); 106 | } 107 | 108 | @Override 109 | public boolean pendingRemovals() { 110 | return false; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /replay-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /replay-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | replay-sail 6 | jar 7 | ReplaySail 8 | A pair of Sail implementations which allow Sail operations to be first recorded to a log file, then 9 | reproduced from the log file 10 | 11 | 12 | 13 | net.fortytwo.sesametools 14 | sesametools-all 15 | 2.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | net.fortytwo.sesametools 22 | common 23 | 24 | 25 | org.eclipse.rdf4j 26 | rdf4j-sail-api 27 | 28 | 29 | org.eclipse.rdf4j 30 | rdf4j-rio-ntriples 31 | 32 | 33 | 34 | 35 | junit 36 | junit 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-compiler-plugin 46 | 47 | 48 | org.apache.maven.plugins 49 | maven-source-plugin 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-jar-plugin 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-javadoc-plugin 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-surefire-plugin 62 | 63 | 64 | org.eluder.coveralls 65 | coveralls-maven-plugin 66 | 67 | 68 | org.jacoco 69 | jacoco-maven-plugin 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/Handler.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.replay; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net). 5 | */ 6 | @FunctionalInterface 7 | public interface Handler { 8 | void handle(T t) throws E; 9 | } 10 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/RecorderIteration.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.replay; 2 | 3 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 4 | import net.fortytwo.sesametools.replay.calls.HasNextCall; 5 | import net.fortytwo.sesametools.replay.calls.NextCall; 6 | import net.fortytwo.sesametools.replay.calls.RemoveCall; 7 | import net.fortytwo.sesametools.replay.calls.CloseIterationCall; 8 | 9 | /** 10 | * @author Joshua Shinavier (http://fortytwo.net). 11 | */ 12 | public class RecorderIteration implements CloseableIteration { 13 | private final String id; 14 | private final CloseableIteration baseIteration; 15 | private final Handler queryHandler; 16 | 17 | public RecorderIteration(final CloseableIteration baseIteration, 18 | final String id, 19 | final Handler queryHandler) { 20 | this.baseIteration = baseIteration; 21 | this.id = id; 22 | this.queryHandler = queryHandler; 23 | } 24 | 25 | public void close() throws E { 26 | queryHandler.handle(new CloseIterationCall(id)); 27 | baseIteration.close(); 28 | } 29 | 30 | public boolean hasNext() throws E { 31 | queryHandler.handle(new HasNextCall(id)); 32 | return baseIteration.hasNext(); 33 | } 34 | 35 | public T next() throws E { 36 | queryHandler.handle(new NextCall(id)); 37 | return baseIteration.next(); 38 | } 39 | 40 | public void remove() throws E { 41 | queryHandler.handle(new RemoveCall(id)); 42 | baseIteration.remove(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/RecorderSail.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay; 3 | 4 | import org.eclipse.rdf4j.model.ValueFactory; 5 | import org.eclipse.rdf4j.sail.Sail; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | import org.eclipse.rdf4j.sail.StackableSail; 9 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 10 | 11 | import java.io.File; 12 | import java.io.OutputStream; 13 | import java.io.PrintStream; 14 | 15 | /** 16 | * A Sail which creates an ongoing log of operations as they are executed. 17 | * The log can later be used to recreate the operations in order. 18 | * 19 | * @author Joshua Shinavier (http://fortytwo.net). 20 | */ 21 | public class RecorderSail extends AbstractSail implements StackableSail { 22 | private final Sail baseSail; 23 | private final ReplayConfiguration config; 24 | private final Handler queryHandler; 25 | 26 | public RecorderSail(final Sail baseSail, 27 | final Handler queryHandler) { 28 | this.baseSail = baseSail; 29 | config = new ReplayConfiguration(); 30 | 31 | this.queryHandler = queryHandler; 32 | } 33 | 34 | public RecorderSail(final Sail baseSail, final OutputStream out) { 35 | this(baseSail, createDefaultHandler(out)); 36 | } 37 | 38 | private static Handler createDefaultHandler(final OutputStream out) { 39 | final PrintStream ps = (out instanceof PrintStream) 40 | ? (PrintStream) out 41 | : new PrintStream(out); 42 | 43 | return new Handler() { 44 | public void handle(final SailConnectionCall sailQuery) throws SailException { 45 | ps.println(sailQuery.toString()); 46 | } 47 | }; 48 | } 49 | 50 | @Override 51 | public void setDataDir(final File file) { 52 | baseSail.setDataDir(file); 53 | } 54 | 55 | @Override 56 | public File getDataDir() { 57 | return baseSail.getDataDir(); 58 | } 59 | 60 | protected void initializeInternal() throws SailException { 61 | baseSail.initialize(); 62 | } 63 | 64 | protected void shutDownInternal() throws SailException { 65 | baseSail.shutDown(); 66 | } 67 | 68 | @Override 69 | public boolean isWritable() throws SailException { 70 | return baseSail.isWritable(); 71 | } 72 | 73 | protected SailConnection getConnectionInternal() throws SailException { 74 | return new RecorderSailConnection(this, baseSail, config, queryHandler); 75 | } 76 | 77 | public ValueFactory getValueFactory() { 78 | return baseSail.getValueFactory(); 79 | } 80 | 81 | public void setBaseSail(final Sail sail) { 82 | // Do nothing -- base Sail is final 83 | } 84 | 85 | public Sail getBaseSail() { 86 | return baseSail; 87 | } 88 | 89 | public ReplayConfiguration getConfiguration() { 90 | return config; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/ReplayConfiguration.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.replay; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net). 5 | */ 6 | public class ReplayConfiguration { 7 | public static final boolean LOG_TRANSACTIONS = true; 8 | public static final boolean LOG_READ_OPERATIONS = true; 9 | public static final boolean LOG_WRITE_OPERATIONS = true; 10 | } 11 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/Source.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.replay; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net). 5 | */ 6 | public interface Source { 7 | void writeTo(Handler handler) throws E; 8 | } 9 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/AddStatementCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.model.IRI; 6 | import org.eclipse.rdf4j.model.Resource; 7 | import org.eclipse.rdf4j.model.Value; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | 11 | import java.util.StringTokenizer; 12 | 13 | /** 14 | * @author Joshua Shinavier (http://fortytwo.net). 15 | */ 16 | public class AddStatementCall extends SailConnectionCall { 17 | 18 | private final Resource subject; 19 | private final IRI predicate; 20 | private final Value object; 21 | private final Resource[] contexts; 22 | 23 | public AddStatementCall(final String id, 24 | final Resource subj, 25 | final IRI pred, 26 | final Value obj, 27 | final Resource... contexts) { 28 | super(id, Type.ADD_STATEMENT); 29 | this.subject = subj; 30 | this.predicate = pred; 31 | this.object = obj; 32 | this.contexts = contexts; 33 | } 34 | 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 37 | .append(DELIM).append(toString(subject)) 38 | .append(DELIM).append(toString(predicate)) 39 | .append(DELIM).append(toString(object)) 40 | .append(DELIM).append(toString(contexts)); 41 | 42 | return sb.toString(); 43 | } 44 | 45 | public AddStatementCall(final String id, 46 | final Type type, 47 | final StringTokenizer tok) { 48 | super(id, type); 49 | this.subject = parseResource(tok.nextToken()); 50 | this.predicate = parseIRI(tok.nextToken()); 51 | this.object = parseValue(tok.nextToken()); 52 | this.contexts = parseContexts(tok.nextToken()); 53 | } 54 | 55 | public Object execute(final SailConnection sc) throws SailException { 56 | sc.addStatement(subject, predicate, object, contexts); 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/BeginCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class BeginCall extends SailConnectionCall { 14 | public BeginCall(final String id) { 15 | super(id, Type.BEGIN); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public BeginCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final SailConnection sc) throws SailException { 31 | sc.begin(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/ClearCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | import java.util.StringTokenizer; 10 | 11 | /** 12 | * @author Joshua Shinavier (http://fortytwo.net). 13 | */ 14 | public class ClearCall extends SailConnectionCall { 15 | 16 | private final Resource[] contexts; 17 | 18 | public ClearCall(final String id, 19 | final Resource... contexts) { 20 | super(id, Type.CLEAR); 21 | this.contexts = contexts; 22 | } 23 | 24 | public String toString() { 25 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 26 | .append(DELIM).append(toString(contexts)); 27 | 28 | return sb.toString(); 29 | } 30 | 31 | public ClearCall(final String id, 32 | final Type type, 33 | final StringTokenizer tok) { 34 | super(id, type); 35 | this.contexts = parseContexts(tok.nextToken()); 36 | } 37 | 38 | public Object execute(final SailConnection sc) throws SailException { 39 | sc.clear(contexts); 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/ClearNamespacesCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class ClearNamespacesCall extends SailConnectionCall { 14 | 15 | public ClearNamespacesCall(final String id) { 16 | super(id, Type.CLEAR_NAMESPACES); 17 | } 18 | 19 | public String toString() { 20 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 21 | 22 | return sb.toString(); 23 | } 24 | 25 | public ClearNamespacesCall(final String id, 26 | final Type type, 27 | final StringTokenizer tok) { 28 | super(id, type); 29 | } 30 | 31 | public Object execute(final SailConnection sc) throws SailException { 32 | sc.clearNamespaces(); 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/CloseConnectionCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class CloseConnectionCall extends SailConnectionCall { 14 | public CloseConnectionCall(final String id) { 15 | super(id, Type.CLOSE_CONNECTION); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public CloseConnectionCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final SailConnection sc) throws SailException { 31 | sc.close(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/CloseIterationCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class CloseIterationCall extends SailConnectionCall, Object> { 14 | public CloseIterationCall(final String id) { 15 | super(id, Type.CLOSE_ITERATION); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public CloseIterationCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final CloseableIteration t) throws SailException { 31 | t.close(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/CommitCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class CommitCall extends SailConnectionCall { 14 | public CommitCall(final String id) { 15 | super(id, Type.COMMIT); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public CommitCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final SailConnection sc) throws SailException { 31 | sc.commit(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/ConstructorCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class ConstructorCall extends SailConnectionCall { 14 | public ConstructorCall(final String id) { 15 | super(id, Type.CONSTRUCT); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public ConstructorCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final SailConnection sc) throws SailException { 31 | // Do nothing: connection has already been constructed 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/EvaluateCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | import net.fortytwo.sesametools.EmptyCloseableIteration; 6 | import net.fortytwo.sesametools.replay.SailConnectionCall; 7 | import org.eclipse.rdf4j.sail.SailConnection; 8 | import org.eclipse.rdf4j.sail.SailException; 9 | 10 | import java.util.StringTokenizer; 11 | 12 | /** 13 | * @author Joshua Shinavier (http://fortytwo.net). 14 | */ 15 | public class EvaluateCall extends SailConnectionCall { 16 | 17 | private final boolean includeInferred; 18 | 19 | public EvaluateCall(final String id, 20 | final boolean includeInferred) { 21 | super(id, Type.EVALUATE); 22 | this.includeInferred = includeInferred; 23 | } 24 | 25 | public String toString() { 26 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 27 | .append(DELIM).append(toString(includeInferred)); 28 | 29 | return sb.toString(); 30 | } 31 | 32 | public EvaluateCall(final String id, 33 | final Type type, 34 | final StringTokenizer tok) { 35 | super(id, type); 36 | this.includeInferred = parseBoolean(tok.nextToken()); 37 | } 38 | 39 | public CloseableIteration execute(final SailConnection sc) throws SailException { 40 | // not enough information to reconstruct an evaluate call 41 | return new EmptyCloseableIteration(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/GetContextIDsCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | import java.util.StringTokenizer; 10 | 11 | /** 12 | * @author Joshua Shinavier (http://fortytwo.net). 13 | */ 14 | public class GetContextIDsCall extends SailConnectionCall { 15 | public GetContextIDsCall(final String id) { 16 | super(id, Type.GET_CONTEXT_IDS); 17 | } 18 | 19 | public String toString() { 20 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 21 | 22 | return sb.toString(); 23 | } 24 | 25 | public GetContextIDsCall(final String id, 26 | final Type type, 27 | final StringTokenizer tok) { 28 | super(id, type); 29 | } 30 | 31 | public CloseableIteration execute(final SailConnection sc) throws SailException { 32 | return sc.getContextIDs(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/GetNamespaceCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class GetNamespaceCall extends SailConnectionCall { 14 | private final String prefix; 15 | 16 | public GetNamespaceCall(final String id, 17 | final String prefix) { 18 | super(id, Type.GET_NAMESPACE); 19 | this.prefix = prefix; 20 | } 21 | 22 | public String toString() { 23 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 24 | .append(DELIM).append(toString(prefix)); 25 | 26 | return sb.toString(); 27 | } 28 | 29 | public GetNamespaceCall(final String id, 30 | final Type type, 31 | final StringTokenizer tok) { 32 | super(id, type); 33 | this.prefix = parseString(tok.nextToken()); 34 | } 35 | 36 | public String execute(final SailConnection sc) throws SailException { 37 | return sc.getNamespace(prefix); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/GetNamespacesCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | import java.util.StringTokenizer; 10 | 11 | /** 12 | * @author Joshua Shinavier (http://fortytwo.net). 13 | */ 14 | public class GetNamespacesCall extends SailConnectionCall { 15 | 16 | public GetNamespacesCall(final String id) { 17 | super(id, Type.GET_NAMESPACES); 18 | } 19 | 20 | public String toString() { 21 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 22 | 23 | return sb.toString(); 24 | } 25 | 26 | public GetNamespacesCall(final String id, 27 | final Type type, 28 | final StringTokenizer tok) { 29 | super(id, type); 30 | } 31 | 32 | public CloseableIteration execute(final SailConnection sc) throws SailException { 33 | return sc.getNamespaces(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/GetStatementsCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.model.Resource; 7 | import org.eclipse.rdf4j.model.IRI; 8 | import org.eclipse.rdf4j.model.Value; 9 | import org.eclipse.rdf4j.sail.SailConnection; 10 | import org.eclipse.rdf4j.sail.SailException; 11 | 12 | import java.util.StringTokenizer; 13 | 14 | /** 15 | * @author Joshua Shinavier (http://fortytwo.net). 16 | */ 17 | public class GetStatementsCall extends SailConnectionCall { 18 | 19 | private final Resource subject; 20 | private final IRI predicate; 21 | private final Value object; 22 | private final boolean includeInferred; 23 | private final Resource[] contexts; 24 | 25 | public GetStatementsCall(final String id, 26 | final Resource subj, 27 | final IRI pred, 28 | final Value obj, 29 | final boolean includeInferred, 30 | final Resource... contexts) { 31 | super(id, Type.GET_STATEMENTS); 32 | this.subject = subj; 33 | this.predicate = pred; 34 | this.object = obj; 35 | this.includeInferred = includeInferred; 36 | this.contexts = contexts; 37 | } 38 | 39 | public String toString() { 40 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 41 | .append(DELIM).append(toString(subject)) 42 | .append(DELIM).append(toString(predicate)) 43 | .append(DELIM).append(toString(object)) 44 | .append(DELIM).append(toString(includeInferred)) 45 | .append(DELIM).append(toString(contexts)); 46 | 47 | return sb.toString(); 48 | } 49 | 50 | public GetStatementsCall(final String id, 51 | final Type type, 52 | final StringTokenizer tok) { 53 | super(id, type); 54 | this.subject = parseResource(tok.nextToken()); 55 | this.predicate = parseIRI(tok.nextToken()); 56 | this.object = parseValue(tok.nextToken()); 57 | this.includeInferred = parseBoolean(tok.nextToken()); 58 | this.contexts = parseContexts(tok.nextToken()); 59 | } 60 | 61 | public CloseableIteration execute(final SailConnection sc) throws SailException { 62 | return sc.getStatements(subject, predicate, object, includeInferred, contexts); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/HasNextCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class HasNextCall extends SailConnectionCall, Object> { 14 | public HasNextCall(final String id) { 15 | super(id, Type.HAS_NEXT); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public HasNextCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final CloseableIteration t) throws SailException { 31 | t.hasNext(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/NextCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class NextCall extends SailConnectionCall, Object> { 14 | public NextCall(final String id) { 15 | super(id, Type.NEXT); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public NextCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final CloseableIteration t) throws SailException { 31 | t.next(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/RemoveCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class RemoveCall extends SailConnectionCall, Object> { 14 | public RemoveCall(final String id) { 15 | super(id, Type.REMOVE); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public RemoveCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final CloseableIteration t) throws SailException { 31 | t.remove(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/RemoveNamespaceCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class RemoveNamespaceCall extends SailConnectionCall { 14 | private final String prefix; 15 | 16 | public RemoveNamespaceCall(final String id, 17 | final String prefix) { 18 | super(id, Type.REMOVE_NAMESPACE); 19 | this.prefix = prefix; 20 | } 21 | 22 | public String toString() { 23 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 24 | .append(DELIM).append(toString(prefix)); 25 | 26 | return sb.toString(); 27 | } 28 | 29 | public RemoveNamespaceCall(final String id, 30 | final Type type, 31 | final StringTokenizer tok) { 32 | super(id, type); 33 | this.prefix = parseString(tok.nextToken()); 34 | } 35 | 36 | public Object execute(final SailConnection sc) throws SailException { 37 | sc.removeNamespace(prefix); 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/RemoveStatementsCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.model.IRI; 6 | import org.eclipse.rdf4j.model.Resource; 7 | import org.eclipse.rdf4j.model.Value; 8 | import org.eclipse.rdf4j.sail.SailConnection; 9 | import org.eclipse.rdf4j.sail.SailException; 10 | 11 | import java.util.StringTokenizer; 12 | 13 | /** 14 | * @author Joshua Shinavier (http://fortytwo.net). 15 | */ 16 | public class RemoveStatementsCall extends SailConnectionCall { 17 | 18 | private final Resource subject; 19 | private final IRI predicate; 20 | private final Value object; 21 | private final Resource[] contexts; 22 | 23 | public RemoveStatementsCall(final String id, 24 | final Resource subj, 25 | final IRI pred, 26 | final Value obj, 27 | final Resource... contexts) { 28 | super(id, Type.REMOVE_STATEMENTS); 29 | this.subject = subj; 30 | this.predicate = pred; 31 | this.object = obj; 32 | this.contexts = contexts; 33 | } 34 | 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 37 | .append(DELIM).append(toString(subject)) 38 | .append(DELIM).append(toString(predicate)) 39 | .append(DELIM).append(toString(object)) 40 | .append(DELIM).append(toString(contexts)); 41 | 42 | return sb.toString(); 43 | } 44 | 45 | public RemoveStatementsCall(final String id, 46 | final Type type, 47 | final StringTokenizer tok) { 48 | super(id, type); 49 | this.subject = parseResource(tok.nextToken()); 50 | this.predicate = parseIRI(tok.nextToken()); 51 | this.object = parseValue(tok.nextToken()); 52 | this.contexts = parseContexts(tok.nextToken()); 53 | } 54 | 55 | public Object execute(final SailConnection sc) throws SailException { 56 | sc.removeStatements(subject, predicate, object, contexts); 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/RollbackCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class RollbackCall extends SailConnectionCall { 14 | public RollbackCall(final String id) { 15 | super(id, Type.ROLLBACK); 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type); 20 | 21 | return sb.toString(); 22 | } 23 | 24 | public RollbackCall(final String id, 25 | final Type type, 26 | final StringTokenizer tok) { 27 | super(id, type); 28 | } 29 | 30 | public Object execute(final SailConnection sc) throws SailException { 31 | sc.rollback(); 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/SetNamespaceCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.sail.SailConnection; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class SetNamespaceCall extends SailConnectionCall { 14 | private final String prefix; 15 | private final String uri; 16 | 17 | public SetNamespaceCall(final String id, 18 | final String prefix, 19 | final String uri) { 20 | super(id, Type.SET_NAMESPACE); 21 | this.prefix = prefix; 22 | this.uri = uri; 23 | } 24 | 25 | public String toString() { 26 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 27 | .append(DELIM).append(toString(prefix)) 28 | .append(DELIM).append(toString(uri)); 29 | 30 | return sb.toString(); 31 | } 32 | 33 | public SetNamespaceCall(final String id, 34 | final Type type, 35 | final StringTokenizer tok) { 36 | super(id, type); 37 | this.prefix = parseString(tok.nextToken()); 38 | this.uri = parseString(tok.nextToken()); 39 | } 40 | 41 | public Object execute(final SailConnection sc) throws SailException { 42 | sc.setNamespace(prefix, uri); 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /replay-sail/src/main/java/net/fortytwo/sesametools/replay/calls/SizeCall.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.replay.calls; 3 | 4 | import net.fortytwo.sesametools.replay.SailConnectionCall; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | import java.util.StringTokenizer; 10 | 11 | /** 12 | * @author Joshua Shinavier (http://fortytwo.net). 13 | */ 14 | public class SizeCall extends SailConnectionCall { 15 | 16 | private final Resource[] contexts; 17 | 18 | public SizeCall(final String id, 19 | final Resource... contexts) { 20 | super(id, Type.SIZE); 21 | this.contexts = contexts; 22 | } 23 | 24 | public String toString() { 25 | StringBuilder sb = new StringBuilder(id).append(DELIM).append(type) 26 | .append(DELIM).append(toString(contexts)); 27 | 28 | return sb.toString(); 29 | } 30 | 31 | public SizeCall(final String id, 32 | final Type type, 33 | final StringTokenizer tok) { 34 | super(id, type); 35 | this.contexts = parseContexts(tok.nextToken()); 36 | } 37 | 38 | public Long execute(final SailConnection sc) throws SailException { 39 | return sc.size(contexts); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /repository-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /repository-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | repository-sail 6 | jar 7 | RepositorySail 8 | A Sail implementation which wraps a Repository object 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-repository-api 25 | 26 | 27 | org.eclipse.rdf4j 28 | rdf4j-sail-api 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-source-plugin 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-jar-plugin 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-javadoc-plugin 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-surefire-plugin 60 | 61 | 62 | org.eluder.coveralls 63 | coveralls-maven-plugin 64 | 65 | 66 | org.jacoco 67 | jacoco-maven-plugin 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /repository-sail/src/main/java/net/fortytwo/sesametools/reposail/RepositoryNamespaceIteration.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.reposail; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | import org.eclipse.rdf4j.model.Namespace; 6 | import org.eclipse.rdf4j.repository.RepositoryException; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | /** 10 | * @author Joshua Shinavier (http://fortytwo.net). 11 | */ 12 | public class RepositoryNamespaceIteration implements CloseableIteration { 13 | private CloseableIteration innerIter; 14 | 15 | public RepositoryNamespaceIteration(CloseableIteration innerIter) { 16 | this.innerIter = innerIter; 17 | } 18 | 19 | public void close() throws SailException { 20 | try { 21 | innerIter.close(); 22 | } catch (RepositoryException e) { 23 | throw new SailException(e); 24 | } 25 | } 26 | 27 | public boolean hasNext() throws SailException { 28 | try { 29 | return innerIter.hasNext(); 30 | } catch (RepositoryException e) { 31 | throw new SailException(e); 32 | } 33 | } 34 | 35 | public Namespace next() throws SailException { 36 | try { 37 | return innerIter.next(); 38 | } catch (RepositoryException e) { 39 | throw new SailException(e); 40 | } 41 | } 42 | 43 | public void remove() throws SailException { 44 | try { 45 | innerIter.remove(); 46 | } catch (RepositoryException e) { 47 | throw new SailException(e); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /repository-sail/src/main/java/net/fortytwo/sesametools/reposail/RepositoryResourceIteration.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.reposail; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.repository.RepositoryException; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | 9 | /** 10 | * @author Joshua Shinavier (http://fortytwo.net). 11 | */ 12 | public class RepositoryResourceIteration implements CloseableIteration { 13 | private CloseableIteration innerIter; 14 | 15 | public RepositoryResourceIteration(CloseableIteration innerIter) { 16 | this.innerIter = innerIter; 17 | } 18 | 19 | public void close() throws SailException { 20 | try { 21 | innerIter.close(); 22 | } catch (RepositoryException e) { 23 | throw new SailException(e); 24 | } 25 | } 26 | 27 | public boolean hasNext() throws SailException { 28 | try { 29 | return innerIter.hasNext(); 30 | } catch (RepositoryException e) { 31 | throw new SailException(e); 32 | } 33 | } 34 | 35 | public Resource next() throws SailException { 36 | try { 37 | return innerIter.next(); 38 | } catch (RepositoryException e) { 39 | throw new SailException(e); 40 | } 41 | } 42 | 43 | public void remove() throws SailException { 44 | try { 45 | innerIter.remove(); 46 | } catch (RepositoryException e) { 47 | throw new SailException(e); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /repository-sail/src/main/java/net/fortytwo/sesametools/reposail/RepositorySail.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.reposail; 2 | 3 | import org.eclipse.rdf4j.model.ValueFactory; 4 | import org.eclipse.rdf4j.repository.Repository; 5 | import org.eclipse.rdf4j.repository.RepositoryConnection; 6 | import org.eclipse.rdf4j.repository.RepositoryException; 7 | import org.eclipse.rdf4j.sail.SailConnection; 8 | import org.eclipse.rdf4j.sail.SailException; 9 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 10 | 11 | /** 12 | * A Sail which wraps a Repository 13 | * 14 | * @author Joshua Shinavier (http://fortytwo.net). 15 | */ 16 | public class RepositorySail extends AbstractSail { 17 | 18 | private Repository repository; 19 | private boolean inferenceDisabled = false; 20 | 21 | public RepositorySail(final Repository repo) { 22 | this.repository = repo; 23 | } 24 | 25 | public Repository getRepository() { 26 | return repository; 27 | } 28 | 29 | public void disableInference() { 30 | inferenceDisabled = true; 31 | } 32 | 33 | protected SailConnection getConnectionInternal() throws SailException { 34 | RepositoryConnection rc; 35 | 36 | try { 37 | rc = repository.getConnection(); 38 | } catch (RepositoryException e) { 39 | throw new SailException(e); 40 | } 41 | 42 | return new RepositorySailConnection(this, rc, inferenceDisabled, this.getValueFactory()); 43 | } 44 | 45 | public ValueFactory getValueFactory() { 46 | return repository.getValueFactory(); 47 | } 48 | 49 | protected void initializeInternal() throws SailException { 50 | try { 51 | repository.initialize(); 52 | } catch (RepositoryException e) { 53 | throw new SailException(e); 54 | } 55 | } 56 | 57 | public boolean isWritable() throws SailException { 58 | try { 59 | return repository.isWritable(); 60 | } catch (RepositoryException e) { 61 | throw new SailException(e); 62 | } 63 | } 64 | 65 | protected void shutDownInternal() throws SailException { 66 | try { 67 | repository.shutDown(); 68 | } catch (RepositoryException e) { 69 | throw new SailException(e); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /repository-sail/src/main/java/net/fortytwo/sesametools/reposail/RepositoryStatementIteration.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.reposail; 3 | 4 | import org.eclipse.rdf4j.model.Statement; 5 | import org.eclipse.rdf4j.repository.RepositoryException; 6 | import org.eclipse.rdf4j.sail.SailException; 7 | 8 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 9 | 10 | /** 11 | * @author Joshua Shinavier (http://fortytwo.net). 12 | */ 13 | public class RepositoryStatementIteration implements CloseableIteration { 14 | private CloseableIteration innerIter; 15 | 16 | public RepositoryStatementIteration(CloseableIteration innerIter) { 17 | this.innerIter = innerIter; 18 | } 19 | 20 | public void close() throws SailException { 21 | try { 22 | innerIter.close(); 23 | } catch (RepositoryException e) { 24 | throw new SailException(e); 25 | } 26 | } 27 | 28 | public boolean hasNext() throws SailException { 29 | try { 30 | return innerIter.hasNext(); 31 | } catch (RepositoryException e) { 32 | throw new SailException(e); 33 | } 34 | } 35 | 36 | public Statement next() throws SailException { 37 | try { 38 | return innerIter.next(); 39 | } catch (RepositoryException e) { 40 | throw new SailException(e); 41 | } 42 | } 43 | 44 | public void remove() throws SailException { 45 | try { 46 | innerIter.remove(); 47 | } catch (RepositoryException e) { 48 | throw new SailException(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /sesamize/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /sesamize/sesamize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Find Java 4 | if [ "$JAVA_HOME" = "" ] ; then 5 | JAVA="java" 6 | else 7 | JAVA="$JAVA_HOME/bin/java" 8 | fi 9 | 10 | # Set Java options 11 | if [ "$JAVA_OPTIONS" = "" ] ; then 12 | JAVA_OPTIONS="-Xms32M -Xmx512M" 13 | fi 14 | 15 | DIR=`dirname $0` 16 | 17 | # Launch the application 18 | $JAVA $JAVA_OPTIONS -cp $DIR/target/classes:$DIR/"target/dependency/*" net.fortytwo.sesametools.sesamize.Sesamize $* 19 | 20 | # Return the program's exit code 21 | exit $? 22 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/Command.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize; 2 | 3 | import com.google.common.base.Preconditions; 4 | 5 | import java.util.HashMap; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import static net.fortytwo.sesametools.sesamize.Sesamize.DEFAULT_BASEURI; 11 | 12 | public abstract class Command { 13 | private final String name; 14 | private List anonymousParameters = new LinkedList<>(); 15 | private Map namedParameters = new HashMap<>(); 16 | 17 | public Command(final String name) { 18 | Preconditions.checkNotNull(name); 19 | this.name = name; 20 | } 21 | 22 | public abstract void execute(SesamizeArgs args) throws Exception; 23 | 24 | protected void addParameter(final Parameter param) { 25 | if (null == param.getName()) { 26 | anonymousParameters.add(param); 27 | } else { 28 | if (getNamedParameters().keySet().contains(param.getName())) { 29 | throw new ExceptionInInitializerError("duplicate parameter '" + param.getName() + "'"); 30 | } 31 | 32 | getNamedParameters().put(param.getName(), param); 33 | } 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public Map getNamedParameters() { 41 | return namedParameters; 42 | } 43 | 44 | public List getAnonymousParameters() { 45 | return anonymousParameters; 46 | } 47 | 48 | protected static String getBaseURI(final SesamizeArgs args) { 49 | return args.getOption(DEFAULT_BASEURI, "b", "baseuri"); 50 | } 51 | 52 | public static class Parameter { 53 | private final String name; 54 | private final String shortName; 55 | private final boolean required; 56 | private final Class valueClass; 57 | private final T defaultValue; 58 | private final String description; 59 | 60 | public Parameter(String name, 61 | String shortName, 62 | boolean required, 63 | Class valueClass, 64 | T defaultValue, 65 | String description) { 66 | Preconditions.checkNotNull(valueClass); 67 | Preconditions.checkArgument(null == shortName || null != name); 68 | 69 | this.name = name; 70 | this.description = description; 71 | this.shortName = shortName; 72 | this.required = required; 73 | this.valueClass = valueClass; 74 | this.defaultValue = defaultValue; 75 | } 76 | 77 | public String getShortestName() { 78 | return null != getShortName() ? getShortName() : getName(); 79 | } 80 | 81 | public String getName() { 82 | return name; 83 | } 84 | 85 | public String getShortName() { 86 | return shortName; 87 | } 88 | 89 | public boolean isRequired() { 90 | return required; 91 | } 92 | 93 | public boolean isRequiredAndHasNoDefaultValue() { 94 | return required && null == defaultValue; 95 | } 96 | 97 | public Class getValueClass() { 98 | return valueClass; 99 | } 100 | 101 | public T getDefaultValue() { 102 | return defaultValue; 103 | } 104 | 105 | public String getDescription() { 106 | return description; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/SparqlResultFormat.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize; 2 | 3 | /** 4 | * @author Joshua Shinavier (http://fortytwo.net). 5 | */ 6 | public enum SparqlResultFormat { 7 | // Note: the XML format is defined first, so that it is the default format. 8 | XML("application/sparql-results+xml", "xml"), 9 | CSV("text/csv", "csv"), 10 | JSON("application/sparql-results+json", "json"), 11 | TAB("text/tab-delimited-values", "tab", "tsv"); 12 | 13 | private final String mediaType; 14 | private final String[] nicknames; 15 | 16 | SparqlResultFormat(final String mimeType, 17 | final String... nicknames) { 18 | mediaType = mimeType; 19 | this.nicknames = nicknames; 20 | } 21 | 22 | public String getMediaType() { 23 | return mediaType; 24 | } 25 | 26 | public static SparqlResultFormat lookup(final String mediaType) { 27 | for (SparqlResultFormat f : SparqlResultFormat.values()) { 28 | if (f.mediaType.equals(mediaType)) { 29 | return f; 30 | } 31 | } 32 | 33 | return null; 34 | } 35 | 36 | public static SparqlResultFormat lookupByNickname(final String name) { 37 | for (SparqlResultFormat f : SparqlResultFormat.values()) { 38 | for (String s : f.nicknames) { 39 | if (s.equals(name)) { 40 | return f; 41 | } 42 | } 43 | } 44 | 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/commands/Construct.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize.commands; 2 | 3 | import net.fortytwo.sesametools.sesamize.SesamizeArgs; 4 | import net.fortytwo.sesametools.sesamize.Command; 5 | import org.apache.commons.io.IOUtils; 6 | import org.eclipse.rdf4j.query.MalformedQueryException; 7 | import org.eclipse.rdf4j.query.QueryEvaluationException; 8 | import org.eclipse.rdf4j.query.QueryLanguage; 9 | import org.eclipse.rdf4j.repository.Repository; 10 | import org.eclipse.rdf4j.repository.RepositoryConnection; 11 | import org.eclipse.rdf4j.repository.RepositoryException; 12 | import org.eclipse.rdf4j.repository.sail.SailRepository; 13 | import org.eclipse.rdf4j.rio.RDFFormat; 14 | import org.eclipse.rdf4j.rio.RDFHandlerException; 15 | import org.eclipse.rdf4j.rio.RDFParseException; 16 | import org.eclipse.rdf4j.rio.RDFWriter; 17 | import org.eclipse.rdf4j.rio.Rio; 18 | import org.eclipse.rdf4j.sail.Sail; 19 | import org.eclipse.rdf4j.sail.SailException; 20 | import org.eclipse.rdf4j.sail.memory.MemoryStore; 21 | 22 | import java.io.File; 23 | import java.io.FileInputStream; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.io.OutputStream; 27 | 28 | public class Construct extends Command { 29 | 30 | public Construct() { 31 | super("construct"); 32 | 33 | addParameter(new Parameter<>( 34 | "query", null, true, File.class, null, 35 | "file with SPARQL CONSTRUCT query")); 36 | addParameter(new Parameter<>( 37 | "inputFormat", "i", true, RDFFormat.class, RDFFormat.RDFXML, 38 | "input RDF format (e.g. 'Turtle')")); 39 | addParameter(new Parameter<>( 40 | "outputFormat", "o", true, RDFFormat.class, RDFFormat.RDFXML, 41 | "output RDF format (e.g. 'N-Triples')")); 42 | } 43 | 44 | @Override 45 | public void execute(SesamizeArgs args) throws IOException { 46 | File inputFile = new File(args.nonOptions.get(1)); 47 | 48 | RDFFormat inputFormat = args.getRDFFormat(inputFile, RDFFormat.RDFXML, "i", "inputFormat"); 49 | RDFFormat outputFormat = args.getRDFFormat(RDFFormat.RDFXML, "o", "outputFormat"); 50 | 51 | String qFile = args.getOption(null, "query"); 52 | 53 | try (InputStream fileInput = new FileInputStream(qFile)) { 54 | 55 | String query = IOUtils.toString(fileInput, "UTF-8"); 56 | 57 | translateRDFDocumentUseingConstructQuery( 58 | query, inputFile, System.out, inputFormat, outputFormat, getBaseURI(args)); 59 | } 60 | } 61 | 62 | private static void translateRDFDocumentUseingConstructQuery(final String query, 63 | final File inputFile, 64 | final OutputStream out, 65 | final RDFFormat inFormat, 66 | final RDFFormat outFormat, 67 | final String baseURI) 68 | throws SailException, IOException, RDFHandlerException, RDFParseException, RepositoryException, 69 | MalformedQueryException, QueryEvaluationException { 70 | 71 | Sail sail = new MemoryStore(); 72 | sail.initialize(); 73 | 74 | try { 75 | Repository repo = new SailRepository(sail); 76 | try (RepositoryConnection rc = repo.getConnection()) { 77 | rc.add(inputFile, baseURI, inFormat); 78 | rc.commit(); 79 | 80 | RDFWriter w = Rio.createWriter(outFormat, out); 81 | 82 | rc.prepareGraphQuery(QueryLanguage.SPARQL, query).evaluate(w); 83 | } 84 | } finally { 85 | sail.shutDown(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/commands/Dump.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize.commands; 2 | 3 | import net.fortytwo.sesametools.sesamize.SesamizeArgs; 4 | import net.fortytwo.sesametools.sesamize.Command; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.repository.Repository; 7 | import org.eclipse.rdf4j.repository.RepositoryConnection; 8 | import org.eclipse.rdf4j.repository.RepositoryException; 9 | import org.eclipse.rdf4j.repository.sail.SailRepository; 10 | import org.eclipse.rdf4j.rio.RDFFormat; 11 | import org.eclipse.rdf4j.rio.RDFHandler; 12 | import org.eclipse.rdf4j.rio.RDFHandlerException; 13 | import org.eclipse.rdf4j.rio.Rio; 14 | import org.eclipse.rdf4j.sail.Sail; 15 | import org.eclipse.rdf4j.sail.SailException; 16 | import org.eclipse.rdf4j.sail.nativerdf.NativeStore; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | import java.io.File; 21 | import java.io.FileOutputStream; 22 | import java.io.IOException; 23 | import java.io.OutputStream; 24 | 25 | public class Dump extends Command { 26 | private final static Logger logger = LoggerFactory.getLogger(Dump.class); 27 | 28 | public Dump() { 29 | super("dump"); 30 | 31 | addParameter(new Parameter<>(null, null, true, File.class, null, 32 | "NativeStore directory")); 33 | addParameter(new Parameter<>(null, null, true, File.class, null, 34 | "output location (e.g. 'dump.nt')")); 35 | addParameter(new Parameter<>( 36 | "outputFormat", "o", true, RDFFormat.class, RDFFormat.RDFXML, 37 | "output RDF format (e.g. 'N-Triples')")); 38 | } 39 | 40 | @Override 41 | public void execute(SesamizeArgs args) throws Exception { 42 | File dir = new File(args.nonOptions.get(1)); 43 | File file = new File(args.nonOptions.get(2)); 44 | 45 | RDFFormat outputFormat = args.getRDFFormat(RDFFormat.RDFXML, "o", "outputFormat"); 46 | 47 | dumpNativeStoreToRDFDocument(dir, file, outputFormat); 48 | } 49 | 50 | private void dumpNativeStoreToRDFDocument(final File nativeStoreDirectory, 51 | final File dumpFile, 52 | final RDFFormat format, 53 | final Resource... contexts) 54 | throws SailException, RepositoryException, IOException, RDFHandlerException { 55 | 56 | logger.info("dumping store at " + nativeStoreDirectory + " to file " + dumpFile); 57 | 58 | Sail sail = new NativeStore(nativeStoreDirectory); 59 | sail.initialize(); 60 | 61 | try { 62 | Repository repo = new SailRepository(sail); 63 | 64 | try (RepositoryConnection rc = repo.getConnection()) { 65 | try (OutputStream out = new FileOutputStream(dumpFile)) { 66 | RDFHandler h = Rio.createWriter(format, out); 67 | rc.export(h, contexts); 68 | } 69 | } 70 | } finally { 71 | sail.shutDown(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/commands/Import.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize.commands; 2 | 3 | import net.fortytwo.sesametools.sesamize.SesamizeArgs; 4 | import net.fortytwo.sesametools.sesamize.Command; 5 | import org.eclipse.rdf4j.model.Resource; 6 | import org.eclipse.rdf4j.repository.Repository; 7 | import org.eclipse.rdf4j.repository.RepositoryConnection; 8 | import org.eclipse.rdf4j.repository.RepositoryException; 9 | import org.eclipse.rdf4j.repository.sail.SailRepository; 10 | import org.eclipse.rdf4j.rio.RDFFormat; 11 | import org.eclipse.rdf4j.rio.RDFParseException; 12 | import org.eclipse.rdf4j.sail.Sail; 13 | import org.eclipse.rdf4j.sail.SailException; 14 | import org.eclipse.rdf4j.sail.nativerdf.NativeStore; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | 21 | import static net.fortytwo.sesametools.sesamize.Sesamize.DEFAULT_BASEURI; 22 | 23 | public class Import extends Command { 24 | private final static Logger logger = LoggerFactory.getLogger(Import.class); 25 | 26 | public Import() { 27 | super("import"); 28 | 29 | addParameter(new Parameter<>(null, null, true, File.class, null, 30 | "NativeStore directory")); 31 | addParameter(new Parameter<>(null, null, true, File.class, null, 32 | "input location (e.g. 'dump.nt')")); 33 | addParameter(new Parameter<>( 34 | "inputFormat", "i", true, RDFFormat.class, RDFFormat.RDFXML, 35 | "input RDF format (e.g. 'N-Triples')")); 36 | } 37 | 38 | @Override 39 | public void execute(SesamizeArgs args) throws Exception { 40 | File dir = new File(args.nonOptions.get(1)); 41 | File file = new File(args.nonOptions.get(2)); 42 | 43 | RDFFormat inputFormat = args.getRDFFormat(file, RDFFormat.RDFXML, "i", "inputFormat"); 44 | 45 | importRDFDocumentIntoNativeStore(dir, file, inputFormat); 46 | } 47 | 48 | private void importRDFDocumentIntoNativeStore(final File nativeStoreDirectory, 49 | final File dumpFile, 50 | final RDFFormat format, 51 | final Resource... contexts) 52 | throws SailException, RepositoryException, IOException, RDFParseException { 53 | 54 | logger.info("importing file " + dumpFile + " into store at " + nativeStoreDirectory); 55 | Sail sail = new NativeStore(nativeStoreDirectory); 56 | sail.initialize(); 57 | 58 | try { 59 | Repository repo = new SailRepository(sail); 60 | 61 | try (RepositoryConnection rc = repo.getConnection()) { 62 | rc.add(dumpFile, DEFAULT_BASEURI, format, contexts); 63 | rc.commit(); 64 | } 65 | } finally { 66 | sail.shutDown(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/commands/Random.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize.commands; 2 | 3 | import net.fortytwo.sesametools.RandomValueFactory; 4 | import net.fortytwo.sesametools.sesamize.SesamizeArgs; 5 | import net.fortytwo.sesametools.sesamize.Command; 6 | import org.eclipse.rdf4j.model.Statement; 7 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory; 8 | import org.eclipse.rdf4j.rio.RDFFormat; 9 | import org.eclipse.rdf4j.rio.RDFWriter; 10 | import org.eclipse.rdf4j.rio.Rio; 11 | 12 | import java.io.File; 13 | import java.io.OutputStream; 14 | 15 | public class Random extends Command { 16 | 17 | public Random() { 18 | super("random"); 19 | 20 | addParameter(new Parameter<>(null, null, true, Long.class, null, 21 | "total triples")); 22 | addParameter(new Parameter<>( 23 | "outputFormat", "o", true, RDFFormat.class, RDFFormat.RDFXML, 24 | "output RDF format (e.g. 'N-Triples')")); 25 | } 26 | 27 | @Override 28 | public void execute(SesamizeArgs args) throws Exception { 29 | Long totalTriples = Long.valueOf(args.nonOptions.get(1)); 30 | RDFFormat outputFormat = args.getRDFFormat(RDFFormat.RDFXML, "o", "outputFormat"); 31 | 32 | OutputStream os = System.out; 33 | 34 | RandomValueFactory rvf = new RandomValueFactory( 35 | SimpleValueFactory.getInstance()); 36 | 37 | RDFWriter writer = Rio.createWriter(outputFormat, os); 38 | writer.startRDF(); 39 | for (long l = 0L; l < totalTriples; l++) { 40 | Statement st = rvf.randomStatement(); 41 | writer.handleStatement(st); 42 | } 43 | writer.endRDF(); 44 | 45 | os.close(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sesamize/src/main/java/net/fortytwo/sesametools/sesamize/commands/Translate.java: -------------------------------------------------------------------------------- 1 | package net.fortytwo.sesametools.sesamize.commands; 2 | 3 | import net.fortytwo.sesametools.sesamize.SesamizeArgs; 4 | import net.fortytwo.sesametools.sesamize.Command; 5 | import net.fortytwo.sesametools.sesamize.SparqlResultFormat; 6 | import org.eclipse.rdf4j.rio.RDFFormat; 7 | import org.eclipse.rdf4j.rio.RDFHandlerException; 8 | import org.eclipse.rdf4j.rio.RDFParseException; 9 | import org.eclipse.rdf4j.rio.RDFParser; 10 | import org.eclipse.rdf4j.rio.RDFWriter; 11 | import org.eclipse.rdf4j.rio.Rio; 12 | import org.eclipse.rdf4j.sail.SailException; 13 | 14 | import java.io.File; 15 | import java.io.FileInputStream; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | 20 | public class Translate extends Command { 21 | 22 | public Translate() { 23 | super("translate"); 24 | 25 | addParameter(new Parameter<>(null, null, true, File.class, null, 26 | "input file")); 27 | addParameter(new Parameter<>( 28 | "inputFormat", "i", true, RDFFormat.class, RDFFormat.RDFXML, 29 | "input RDF format (e.g. 'N-Triples')")); 30 | addParameter(new Parameter<>( 31 | "outputFormat", "o", true, SparqlResultFormat.class, SparqlResultFormat.XML, 32 | "output SPARQL format (e.g. 'XML')")); 33 | } 34 | 35 | @Override 36 | public void execute(SesamizeArgs args) throws IOException { 37 | File inputFile = new File(args.nonOptions.get(1)); 38 | 39 | RDFFormat inputFormat = args.getRDFFormat(inputFile, RDFFormat.RDFXML, "i", "inputFormat"); 40 | RDFFormat outputFormat = args.getRDFFormat(RDFFormat.RDFXML, "o", "outputFormat"); 41 | 42 | translateRDFDocument(inputFile, System.out, inputFormat, outputFormat, getBaseURI(args)); 43 | } 44 | 45 | private void translateRDFDocument(final File inputFile, 46 | final OutputStream out, 47 | final RDFFormat inFormat, 48 | final RDFFormat outFormat, 49 | final String baseURI) 50 | throws SailException, IOException, RDFHandlerException, RDFParseException { 51 | 52 | try (InputStream in = new FileInputStream(inputFile)) { 53 | translateRDFDocument(in, out, inFormat, outFormat, baseURI); 54 | } 55 | } 56 | 57 | private void translateRDFDocument(final InputStream in, 58 | final OutputStream out, 59 | final RDFFormat inFormat, 60 | final RDFFormat outFormat, 61 | final String baseURI) 62 | throws SailException, IOException, RDFHandlerException, RDFParseException { 63 | 64 | RDFParser p = Rio.createParser(inFormat); 65 | RDFWriter w = Rio.createWriter(outFormat, out); 66 | 67 | p.setRDFHandler(w); 68 | 69 | p.parse(in, baseURI); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /sesamize/src/main/resources/META-INF/services/org.openrdf.query.parser.QueryParserFactory: -------------------------------------------------------------------------------- 1 | org.openrdf.query.parser.sparql.SPARQLParserFactory 2 | 3 | -------------------------------------------------------------------------------- /sesamize/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory: -------------------------------------------------------------------------------- 1 | org.openrdf.rio.n3.N3ParserFactory 2 | org.openrdf.rio.nquads.NQuadsParserFactory 3 | org.openrdf.rio.ntriples.NTriplesParserFactory 4 | org.openrdf.rio.rdfjson.RDFJSONParserFactory 5 | org.openrdf.rio.rdfxml.RDFXMLParserFactory 6 | org.openrdf.rio.trig.TriGParserFactory 7 | org.openrdf.rio.trix.TriXParserFactory 8 | org.openrdf.rio.turtle.TurtleParserFactory 9 | -------------------------------------------------------------------------------- /sesamize/src/main/resources/META-INF/services/org.openrdf.rio.RDFWriterFactory: -------------------------------------------------------------------------------- 1 | org.openrdf.rio.n3.N3WriterFactory 2 | org.openrdf.rio.nquads.NQuadsWriterFactory 3 | org.openrdf.rio.ntriples.NTriplesWriterFactory 4 | org.openrdf.rio.rdfjson.RDFJSONWriterFactory 5 | org.openrdf.rio.rdfxml.RDFXMLWriterFactory 6 | org.openrdf.rio.trig.TriGWriterFactory 7 | org.openrdf.rio.trix.TriXWriterFactory 8 | org.openrdf.rio.turtle.TurtleWriterFactory 9 | -------------------------------------------------------------------------------- /sesamize/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, A1, A2 2 | 3 | log4j.appender.A1=org.apache.log4j.ConsoleAppender 4 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.A1.layout.ConversionPattern=%-5p %c %x - %m%n 6 | log4j.appender.A1.Target = System.err 7 | 8 | log4j.appender.A2=org.apache.log4j.FileAppender 9 | log4j.appender.A2.File=sesamize.log 10 | log4j.appender.A2.layout=org.apache.log4j.PatternLayout 11 | log4j.appender.A2.layout.ConversionPattern=%-5p %c %x - %m%n 12 | 13 | log4j.logger.io.milton=TRACE -------------------------------------------------------------------------------- /uri-translator/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | .idea 6 | *.iml 7 | *~ 8 | -------------------------------------------------------------------------------- /uri-translator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | uri-translator 6 | URI Translator 7 | http://fortytwo.net/projects/sesametools 8 | 9 | 10 | net.fortytwo.sesametools 11 | sesametools-all 12 | 2.0-SNAPSHOT 13 | ../pom.xml 14 | 15 | 16 | 17 | 18 | org.eclipse.rdf4j 19 | rdf4j-model 20 | 21 | 22 | org.eclipse.rdf4j 23 | rdf4j-sail-api 24 | 25 | 26 | org.eclipse.rdf4j 27 | rdf4j-util 28 | 29 | 30 | org.eclipse.rdf4j 31 | rdf4j-queryalgebra-evaluation 32 | 33 | 34 | org.slf4j 35 | slf4j-api 36 | 37 | 38 | 39 | 40 | org.eclipse.rdf4j 41 | rdf4j-repository-sail 42 | test 43 | 44 | 45 | org.eclipse.rdf4j 46 | rdf4j-sail-memory 47 | test 48 | 49 | 50 | org.eclipse.rdf4j 51 | rdf4j-queryparser-serql 52 | 53 | 54 | 55 | 56 | org.eclipse.rdf4j 57 | rdf4j-queryparser-sparql 58 | runtime 59 | 60 | 61 | junit 62 | junit 63 | test 64 | 65 | 66 | log4j 67 | log4j 68 | test 69 | 70 | 71 | org.slf4j 72 | slf4j-log4j12 73 | test 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.apache.maven.plugins 81 | maven-compiler-plugin 82 | 83 | 84 | org.apache.maven.plugins 85 | maven-source-plugin 86 | 87 | 88 | org.apache.maven.plugins 89 | maven-jar-plugin 90 | 91 | 92 | org.apache.maven.plugins 93 | maven-javadoc-plugin 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-surefire-plugin 98 | 99 | 100 | org.eluder.coveralls 101 | coveralls-maven-plugin 102 | 103 | 104 | org.jacoco 105 | jacoco-maven-plugin 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /uri-translator/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, R 2 | 3 | log4j.appender.R=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.R.layout.ConversionPattern=%-5p - %d{dd/MM/yyyy HH:mm:ss} - %m%n 6 | 7 | log4j.logger.org.openrdf=INFO 8 | log4j.logger.net.fortytwo.sesametools=INFO 9 | -------------------------------------------------------------------------------- /writeonly-sail/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .classpath 3 | .project 4 | .settings 5 | *.iml 6 | *~ 7 | -------------------------------------------------------------------------------- /writeonly-sail/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | writeonly-sail 6 | jar 7 | WriteOnlySail 8 | A write-only Sail implementation 9 | 10 | 11 | net.fortytwo.sesametools 12 | sesametools-all 13 | 2.0-SNAPSHOT 14 | ../pom.xml 15 | 16 | 17 | 18 | 19 | net.fortytwo.sesametools 20 | common 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-sail-api 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-compiler-plugin 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-source-plugin 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-jar-plugin 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-javadoc-plugin 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-surefire-plugin 56 | 57 | 58 | org.eluder.coveralls 59 | coveralls-maven-plugin 60 | 61 | 62 | org.jacoco 63 | jacoco-maven-plugin 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /writeonly-sail/src/main/java/net/fortytwo/sesametools/writeonly/WriteOnlySail.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.writeonly; 3 | 4 | import org.eclipse.rdf4j.model.ValueFactory; 5 | import org.eclipse.rdf4j.rio.RDFHandler; 6 | import org.eclipse.rdf4j.sail.SailConnection; 7 | import org.eclipse.rdf4j.sail.SailException; 8 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 9 | 10 | /** 11 | * A Sail which can be written to, but not read from. 12 | * Read operations are simply ignored or return no results. 13 | * 14 | * @author Joshua Shinavier (http://fortytwo.net). 15 | */ 16 | public class WriteOnlySail extends AbstractSail { 17 | private RDFHandler handler; 18 | private ValueFactory valueFactory; 19 | 20 | public WriteOnlySail(final RDFHandler handler, 21 | final ValueFactory valueFactory) { 22 | this.handler = handler; 23 | this.valueFactory = valueFactory; 24 | } 25 | 26 | protected SailConnection getConnectionInternal() throws SailException { 27 | return new WriteOnlySailConnection(this, handler, valueFactory); 28 | } 29 | 30 | public ValueFactory getValueFactory() { 31 | return valueFactory; 32 | } 33 | 34 | protected void initializeInternal() throws SailException { 35 | // Does nothing 36 | } 37 | 38 | public boolean isWritable() throws SailException { 39 | return true; 40 | } 41 | 42 | protected void shutDownInternal() throws SailException { 43 | // Does nothing 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /writeonly-sail/src/main/java/net/fortytwo/sesametools/writeonly/WriteOnlySailConnection.java: -------------------------------------------------------------------------------- 1 | 2 | package net.fortytwo.sesametools.writeonly; 3 | 4 | import org.eclipse.rdf4j.common.iteration.CloseableIteration; 5 | import net.fortytwo.sesametools.EmptyCloseableIteration; 6 | import org.eclipse.rdf4j.model.IRI; 7 | import org.eclipse.rdf4j.model.Namespace; 8 | import org.eclipse.rdf4j.model.Resource; 9 | import org.eclipse.rdf4j.model.Statement; 10 | import org.eclipse.rdf4j.model.Value; 11 | import org.eclipse.rdf4j.model.ValueFactory; 12 | import org.eclipse.rdf4j.query.BindingSet; 13 | import org.eclipse.rdf4j.query.Dataset; 14 | import org.eclipse.rdf4j.query.QueryEvaluationException; 15 | import org.eclipse.rdf4j.query.algebra.TupleExpr; 16 | import org.eclipse.rdf4j.rio.RDFHandler; 17 | import org.eclipse.rdf4j.rio.RDFHandlerException; 18 | import org.eclipse.rdf4j.sail.SailException; 19 | import org.eclipse.rdf4j.sail.helpers.AbstractSail; 20 | import org.eclipse.rdf4j.sail.helpers.AbstractSailConnection; 21 | 22 | /** 23 | * @author Joshua Shinavier (http://fortytwo.net). 24 | */ 25 | public class WriteOnlySailConnection extends AbstractSailConnection { 26 | private RDFHandler handler; 27 | private ValueFactory valueFactory; 28 | 29 | public WriteOnlySailConnection(final AbstractSail sail, 30 | final RDFHandler handler, 31 | final ValueFactory valueFactory) { 32 | super(sail); 33 | this.handler = handler; 34 | this.valueFactory = valueFactory; 35 | } 36 | 37 | protected void addStatementInternal( 38 | final Resource subj, final IRI pred, final Value obj, final Resource... contexts) throws SailException { 39 | 40 | if (null == contexts || 0 == contexts.length) { 41 | Statement st = valueFactory.createStatement(subj, pred, obj); 42 | try { 43 | handler.handleStatement(st); 44 | } catch (RDFHandlerException e) { 45 | throw new SailException(e); 46 | } 47 | } else { 48 | for (Resource ctx : contexts) { 49 | Statement st = valueFactory.createStatement(subj, pred, obj, ctx); 50 | try { 51 | handler.handleStatement(st); 52 | } catch (RDFHandlerException e) { 53 | throw new SailException(e); 54 | } 55 | } 56 | } 57 | } 58 | 59 | protected void clearInternal(Resource... arg0) throws SailException { 60 | // Does nothing. 61 | } 62 | 63 | protected void clearNamespacesInternal() throws SailException { 64 | // Does nothing. 65 | } 66 | 67 | protected void closeInternal() throws SailException { 68 | } 69 | 70 | protected void commitInternal() throws SailException { 71 | } 72 | 73 | protected CloseableIteration evaluateInternal( 74 | TupleExpr arg0, Dataset arg1, BindingSet arg2, boolean arg3) 75 | throws SailException { 76 | return new EmptyCloseableIteration<>(); 77 | } 78 | 79 | protected CloseableIteration getContextIDsInternal() 80 | throws SailException { 81 | return new EmptyCloseableIteration<>(); 82 | } 83 | 84 | protected String getNamespaceInternal(final String prefix) throws SailException { 85 | return null; 86 | } 87 | 88 | protected CloseableIteration getNamespacesInternal() 89 | throws SailException { 90 | return new EmptyCloseableIteration<>(); 91 | } 92 | 93 | protected CloseableIteration getStatementsInternal( 94 | Resource arg0, IRI arg1, Value arg2, boolean arg3, Resource... arg4) 95 | throws SailException { 96 | return new EmptyCloseableIteration<>(); 97 | } 98 | 99 | protected void removeNamespaceInternal(String arg0) throws SailException { 100 | // Does nothing. 101 | } 102 | 103 | protected void removeStatementsInternal(Resource arg0, IRI arg1, Value arg2, 104 | Resource... arg3) throws SailException { 105 | // Does nothing. 106 | } 107 | 108 | protected void rollbackInternal() throws SailException { 109 | } 110 | 111 | protected void setNamespaceInternal(String arg0, String arg1) throws SailException { 112 | // Does nothing. 113 | } 114 | 115 | protected long sizeInternal(final Resource... contexts) throws SailException { 116 | return 0; 117 | } 118 | 119 | protected void startTransactionInternal() throws SailException { 120 | // Does nothing. 121 | } 122 | 123 | @Override 124 | public boolean pendingRemovals() { 125 | return false; 126 | } 127 | } 128 | --------------------------------------------------------------------------------