Repository: incubator-commonsrdf Updated Branches: refs/heads/master 896e3fb59 -> e4522ae91
Avoid velocity template - not sure it worked too well Project: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/commit/50a6c5c8 Tree: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/tree/50a6c5c8 Diff: http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/diff/50a6c5c8 Branch: refs/heads/master Commit: 50a6c5c8661f28656d6929625f1503d57e610a98 Parents: 896e3fb Author: Stian Soiland-Reyes <st...@apache.org> Authored: Mon Aug 10 12:15:51 2015 +0100 Committer: Stian Soiland-Reyes <st...@apache.org> Committed: Mon Aug 10 12:15:51 2015 +0100 ---------------------------------------------------------------------- src/site/markdown/userguide.md | 938 +++++++++++++++++++++++++++++++++ src/site/markdown/userguide.md.vm | 938 --------------------------------- 2 files changed, 938 insertions(+), 938 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/50a6c5c8/src/site/markdown/userguide.md ---------------------------------------------------------------------- diff --git a/src/site/markdown/userguide.md b/src/site/markdown/userguide.md new file mode 100644 index 0000000..2820441 --- /dev/null +++ b/src/site/markdown/userguide.md @@ -0,0 +1,938 @@ +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> + +# User Guide + +This page shows some examples of a client using the Commons RDF API. +It was last updated for version `0.1.0-incubating` of the +Commons RDF [API](apidocs/). + +* [Introduction](#Introduction) + * [RDF concepts](#RDF_concepts) +* [Using Commons RDF from Maven](#Using_Commons_RDF_from_Maven) +* [Creating Commons RDF instances](#Creating_Commons_RDF_instances) +* [RDF terms](#RDF_terms) + * [N-Triples string](#N-Triples_string) + * [IRI](#IRI) + * [Blank node](#Blank_node) + * [Blank node reference](#Blank_node_reference) + * [Literal](#Literal) + * [Datatype](#Datatype) + * [Types](#Types) + * [Language](#Language) +* [Triple](#Triple) +* [Graph](#Graph) + * [Adding triples](#Adding_triples) + * [Finding triples](#Finding_triples) + * [Size](#Size) + * [Iterating over triples](#Iterating_over_triples) + * [Stream of triples](#Stream_of_triples) + * [Removing triples](#Removing_triples) +* [Mutability and thread safety](#Mutability_and_thread_safety) +* [Implementations](#Implementations) + * [Cross-compatibility](#Cross-compatibility) +* [Complete example](#Complete_example) + +## Introduction + +[Commons RDF](index.html) is an API that intends to directly describe +[RDF 1.1 concepts](http://www.w3.org/TR/rdf11-concepts/) as a set +of corresponding interfaces and methods. + +### RDF concepts + +RDF is a [graph-based data model](http://www.w3.org/TR/rdf11-concepts/#data-model), where +a _graph_ contains a series of _triples_, each containing the node-arc-node link +_subject_ -> _predicate_ -> _object_. Nodes in the graph are represented either as _IRIs_, _literals_ and _blank nodes_. +: +This user guide does not intend to give a detailed description of RDF as a data +model. To fully understand this user guide, you should have a brief +understanding of the core RDF concepts mentioned above. + +For more information on RDF, see the +[RDF primer](http://www.w3.org/TR/rdf11-primer/) and the [RDF +concepts](http://www.w3.org/TR/rdf11-concepts/#data-model) specification from +W3C. + + + +## Using Commons RDF from Maven + +To use Commons RDF API from an +[Apache Maven](http://maven.apache.org/) project, +add the following dependency to your `pom.xml`: + +```xml +<dependencies> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-rdf-api</artifactId> + <version>0.1.0-incubating</version> + </dependency> +</dependencies> +``` + +The `<version>` above might not be up to date, +see the [/download.html](download page) for the latest version. + +If you are testing a `SNAPSHOT` version, then you will have to either build +Commons RDF from [source](https://github.com/apache/incubator-commonsrdf), or +add this [snapshot repository](https://github.com/apache/incubator-commonsrdf#snapshot-repository): + +```xml +<repositories> + <repository> + <id>apache.snapshots</id> + <name>Apache Snapshot Repository</name> + <url>http://repository.apache.org/snapshots</url> + <releases> + <enabled>false</enabled> + </releases> + </repository> +</repositories> +``` + +As Commons RDF requires Java 8 or later, you will also need: + +```xml +<properties> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> +</properties> +``` + +In the examples below we will use the +[_simple_ implementation](apidocs/org/apache/commons/rdf/simple/package-summary.html), +but the examples should be equally applicable to other +[implementations](implementations.html). To add a dependency for the +_simple_ implementation, add to your `<dependencies>`: + +```xml + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-rdf-simple</artifactId> + <version>${project.version}</version> + </dependency> +``` + + +## Creating Commons RDF instances + +To create instances of Commons RDF interfaces like +[`Graph`](apidocs/org/apache/commons/rdf/api/Graph.html) and +[`IRI`](apidocs/org/apache/commons/rdf/api/IRI.html) you will need a +[RDFTermFactory](/apidocs/org/apache/commons/rdf/api/RDFTermFactory.html). + +How to get an instance of this factory is implementation specific, for the +_simple_ implementation, you can construct the +[SimpleRDFTermFactory](apidocs/org/apache/commons/rdf/simple/SimpleRDFTermFactory.html): + +```java +import org.apache.commons.rdf.api.*; +import org.apache.commons.rdf.simple.SimpleRDFTermFactory; +// ... +RDFTermFactory factory = new SimpleRDFTermFactory(); +``` + +If you don't want to depend on instantiating a concrete implementation, +you can alternatively use the +[ServiceLoader](http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) +to lookup any `RDFTermFactory` implementations found on the classpath: + +```java +import java.util.Iterator; +import java.util.ServiceLoader; + +import org.apache.commons.rdf.api.*; +// ... +ServiceLoader<RDFTermFactory> loader = ServiceLoader.load(RDFTermFactory.class); +Iterator<RDFTermFactory> iterator = loader.iterator(); +RDFTermFactory factory = iterator.next(); +``` + +Using the factory you can construct +any [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html), e.g. to create a +[BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html), +[IRI](apidocs/org/apache/commons/rdf/api/IRI.html) and +[Literal](apidocs/org/apache/commons/rdf/api/Literal.html): + +```java +BlankNode aliceBlankNode = factory.createBlankNode(); +IRI nameIri = factory.createIRI("http://example.com/name"); +Literal aliceLiteral = factory.createLiteral("Alice"); +``` + +You can also create a stand-alone [Triple](apidocs/org/apache/commons/rdf/api/Triple.html): + +```java +Triple triple = factory.createTriple(aliceBlankNode, nameIri, aliceLiteral); +``` + +The [RDFTermFactory](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html) also +contains more specific variants of some of the methods above, e.g. to create a +typed literal. + +Note that for any given implementation, `RDFTerm` instances need not be created +using a `RDFTermFactory`. More likely, implementation-specific methods might create these +objects as part of data parsing, storage lookup and queries. + + + +## RDF terms + +[RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) is +the super-interface for instances that can be used as subject, predicate and +object of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html). + +The RDF term interfaces are arranged in this class hierarchy: + +* [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) + * [BlankNodeOrIRI](apidocs/org/apache/commons/rdf/api/BlankNodeOrIRI.html) + * [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) + * [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) + * [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) + +### N-Triples string + +All of the [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) types +support the `ntriplesString()` method: + +```java +System.out.println(aliceBlankNode.ntriplesString()); +System.out.println(nameIri.ntriplesString()); +System.out.println(aliceLiteral.ntriplesString()); +``` + +> `_:ef136d20-f1ee-3830-a54b-cd5e489d50fb` +> +> ``<http://example.com/name>`` +> +> ``"Alice"`` + +This returns the [N-Triples](http://www.w3.org/TR/n-triples) canonical form +of the term, which can be useful both for debugging and simple serialization. + +_Note: The `.toString()` of the `simple` implementation used in +some of these examples use `ntriplesString()` internally, but Commons RDF +places no such formal requirement on the `.toString()` method. Clients that +rely on a canonical N-Triples-compatible string should instead use +`ntriplesString()`._ + +<!-- Not relevant here + +As an example of using `ntriplesString()`, here is how one could write a basic +N-Triples-compatible serialization of a +[Graph](apidocs/org/apache/commons/rdf/api/Graph.html): + +```java +public class NTriplesSerializer { + public static String tripleAsString(Triple t) { + return t.getSubject().ntriplesString() + " " + + t.getPredicate().ntriplesString() + " " + + t.getObject().ntriplesString() + " ."; + } + public static void writeGraph(Graph graph, Path graphFile) throws Exception { + Stream<CharSequence> stream = graph.getTriples().map(NTriplesSerializer::tripleAsString); + Files.write(graphFile, stream::iterator, StandardCharsets.UTF_8); + } +} +``` + +Example output: + +> `_:ef136d20-f1ee-3830-a54b-cd5e489d50fb <http://example.com/name> "Alice" .` +> +> `<http://example.com/bob> <http://example.com/name> "Bob" .` +--> + +### IRI + +An [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) +is a representation of an +[Internationalized Resource Identifier](http://www.w3.org/TR/rdf11-concepts/#dfn-iri), +e.g. `http://example.com/alice` or `http://ns.example.org/vocab#term`. + +> IRIs in the RDF abstract syntax MUST be absolute, and MAY contain a fragment identifier. + +In RDF, an IRI identifies a resource that can be used as a _subject_, +_predicate_ or _object_ of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html). + +To create an `IRI` instance from a `RDFTermFactory`, use [createIRI](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createIRI-java.lang.String-): + +```java +IRI iri = factory.createIRI("http://example.com/alice"); +``` + +You can retrieve the IRI string using [getIRIString](apidocs/org/apache/commons/rdf/api/IRI.html#getIRIString--): + +```java +System.out.println(iri.getIRIString()); +``` + +> `http://example.com/alice` + +_Note: The IRI string might contain non-ASCII characters which must be +%-encoded for applications that expect an URI. It is currently +out of scope for Commons RDF to perform such a conversion, +however implementations might provide separate methods for that purpose._ + +Two IRI instances can be compared using the +[equals](apidocs/org/apache/commons/rdf/api/IRI.html#equals-java.lang.Object-) +method, which uses [simple string comparison](http://tools.ietf.org/html/rfc3987#section-5.3.1): + +```java +IRI iri2 = factory.createIRI("http://example.com/alice"); +System.out.println(iri.equals(iri2)); +``` + +> `true` + +```java +IRI iri3 = factory.createIRI("http://example.com/alice/./"); +System.out.println(iri.equals(iri3)); +``` + +> `false` + +Note that IRIs are never equal to objects which are not themselves +instances of [IRI](apidocs/org/apache/commons/rdf/api/IRI.html): + + +```java +System.out.println(iri.equals("http://example.com/alice")); +System.out.println(iri.equals(factory.createLiteral("http://example.com/alice"))); +``` +> `false` +> +> `false` + + +### Blank node + +A [blank node](http://www.w3.org/TR/rdf11-concepts/#section-blank-nodes) is a +resource which, unlike an IRI, is not directly identified. Blank nodes can be +used as _subject_ or _object_ of a `Triple` +[Triple](apidocs/org/apache/commons/rdf/api/Triple.html). + +To create a new +[BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) instance from a +`RDFTermFactory`, use +[createBlankNode](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createBlankNode--): + +```java +BlankNode bnode = factory.createBlankNode(); +``` + +Every call to `createBlankNode()` returns a brand new blank node +which can be used in multiple triples in multiple graphs. Thus +every such blank node can only be +[equal](apidocs/org/apache/commons/rdf/api/BlankNode.html#equals-java.lang.Object-) +to itself: + +```java +System.out.println(bnode.equals(bnode)); +System.out.println(bnode.equals(factory.createBlankNode())); +``` + +> `true` +> +> `false` + +Sometimes it can be beneficial to create a blank node based on a +localized _name_, without needing to keep object references +to earlier `BlankNode` instances. For that purpose, `RDFTermFactory` +may support the +[expanded createBlankNode](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createBlankNode-java.lang.String-) +method: + +```java +BlankNode b1 = factory.createBlankNode("b1"); +``` + +Note that there is no requirement for the +[ntriplesString()](apidocs/org/apache/commons/rdf/api/RDFTerm.html#ntriplesString--) +of the BlankNode to reflect the provided `name`: + +```java +System.out.println(b1.ntriplesString()); +``` + +> `_:6c0f628f-02cb-3634-99db-0e1e99d2e66d` + + + +Any later `createBlankNode("b1")` **on the same factory instance** +returns a `BlankNode` which are +[equal](apidocs/org/apache/commons/rdf/api/BlankNode.html#equals-java.lang.Object-) +to the previous b1: + +```java +System.out.println(b1.equals(factory.createBlankNode("b1"))); +System.out.println(b1.equals(new SimpleRDFTermFactory().createBlankNode("b1"))); +``` + +> `true` +> +> `false` + +#### Blank node reference + +While blank nodes are distinct from IRIs, and don't have inherent +universal identifiers, it can nevertheless be useful +for debugging and testing to have a unique reference string for +a particular blank node. +For that purpose, BlankNode exposes the +[uniqueReference](apidocs/org/apache/commons/rdf/api/BlankNode.html#uniqueReference--) +method: + +```java +System.out.println(bnode.uniqueReference()); +``` + +> `735d5e63-96a4-488b-8613-7037b82c74a5` + +While this reference string might for the _simple_ +implementation also be seen within the `BlankNode.ntriplesString()` +result, there is no such guarantee from the Commons RDF API. +Clients who need a globally unique reference +for a blank node should therefore use the `uniqueReference()` method. + +_Note: While it is recommended for this string to be (or contain) a +[UUID string](http://docs.oracle.com/javase/8/docs/api/java/util/UUID.html), +implementations are free to use any scheme to ensure their +blank node references are globally unique. Therefore no assumptions should +be made about this string except that it is unique per blank node._ + + +### Literal + +A [literal](http://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal) in RDF +is a value such as a string, number or a date. A `Literal` can only be used as +an _object_ of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--). + +To create a [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) instance +from an `RDFTermFactory`, use +[createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-): + +```java +Literal literal = factory.createLiteral("Hello world!"); +System.out.println(literal.ntriplesString()); +``` + +> `"Hello world!"` + +The lexical value (what is inside the quotes) can be retrieved +using [getLexicalForm()](apidocs/org/apache/commons/rdf/api/Literal.html#getLexicalForm--): + +```java +String lexical = literal.getLexicalForm(); +System.out.println(lexical); +``` + +> `Hello world!` + + +#### Datatype + +All literals in RDF 1.1 have a +[datatype](http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri) `IRI`, which +can be retrieved using +[Literal.getDatatype()](apidocs/org/apache/commons/rdf/api/Literal.html#getDatatype--): + +```java +IRI datatype = literal.getDatatype(); +System.out.println(datatype.ntriplesString()); +``` + +> `<http://www.w3.org/2001/XMLSchema#string>` + +In RDF 1.1, a [simple +literal](http://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) (as created +above) always have the type +`http://www.w3.org/2001/XMLSchema#string` (or +[xsd:string](apidocs/org/apache/commons/rdf/simple/Types.html#XSD_STRING) for +short). + +<div class="alert alert-warn" role="alert"><p><span class="glyphicon glyphicon-warn-sign" aria-hidden="true"></span> +<!-- Markdown not supported inside HTML --> +<strong>Note:</strong> +RDF 1.0 had the datatype +<code>http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral</code> to +indicate <em>plain literals</em> (untyped), which were distinct from +<code>http://www.w3.org/2001/XMLSchema#string</code> (typed). Commons +RDF assumes RDF 1.1, which merges the two concepts as the second type, however +particular implementations might have explicit options for RDF 1.0 support, in +which case you might find <code>Literal</code> instances with the deprecated +<a href="apidocs/org/apache/commons/rdf/simple/Types.html#RDF_PLAINLITERAL">plain +literal</a> data type. +</p></div> + + +To create a literal with any other +[datatype](http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri), then +first create the datatype `IRI` and pass it to the expanded +[createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-org.apache.commons.rdf.api.IRI-): + +```java +IRI xsdDouble = factory.createIRI("http://www.w3.org/2001/XMLSchema#double"); +Literal literalDouble = factory.createLiteral("13.37", xsdDouble); +System.out.println(literalDouble.ntriplesString()); +``` + +> `"13.37"^^<http://www.w3.org/2001/XMLSchema#double>` + + + + +##### Types + +The class [Types](apidocs/org/apache/commons/rdf/simple/Types.html), which is +part of the _simple_ implementation, provides `IRI` constants for the standard +XML Schema datatypes like `xsd:dateTime` and `xsd:float`. Using `Types`, +the above example can be simplified to: + +```java +Literal literalDouble2 = factory.createLiteral("13.37", Types.XSD_DOUBLE); +``` + +As the constants in `Types` are all instances of `IRI`, they can +also be used for comparisons: + +```java +System.out.println(literal.getDatatype().equals(Types.XSD_STRING)); +``` + +> `true` + +#### Language + +Literals may be created with an associated +[language tag](http://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) +using the expanded [createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-java.lang.String-): + +```java +Literal inSpanish = factory.createLiteral("¡Hola, Mundo!", "es"); +System.out.println(inSpanish.ntriplesString()); +System.out.println(inSpanish.getLexicalForm()); +``` +> `"¡Hola, Mundo!"@es` +> +> `¡Hola, Mundo!` + +A literal with a language tag always have the +implied type `http://www.w3.org/1999/02/22-rdf-syntax-ns#langString`: + +```java +System.out.println(inSpanish.getDatatype().ntriplesString()); +``` + +> `<http://www.w3.org/1999/02/22-rdf-syntax-ns#langString>` + +The language tag can be retrieved using +[getLanguageTag()](apidocs/org/apache/commons/rdf/api/Literal.html#getLanguageTag--): + +```java +Optional<String> tag = inSpanish.getLanguageTag(); +if (tag.isPresent()) { + System.out.println(tag.get()); +} +``` + +> `es` + +The language tag is behind an +[Optional](http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) as +it cannot be present for any other datatypes than +`http://www.w3.org/1999/02/22-rdf-syntax-ns#langString`: + +```java +System.out.println(literal.getLanguageTag().isPresent()); +System.out.println(literalDouble.getLanguageTag().isPresent()); +``` + +> `false` +> +> `false` + + +## Triple + +A [triple](http://www.w3.org/TR/rdf11-concepts/#section-triples) in +RDF 1.1 consists of: + +* The [subject](apidocs/org/apache/commons/rdf/api/Triple.html#getSubject--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) or a [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) +* The [predicate](apidocs/org/apache/commons/rdf/api/Triple.html#getPredicate--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) +* The [object](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html), a [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) or a [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) + + +To construct a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html) from a +`RDFTermFactory`, use +[createTriple](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createTriple-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-): + +```java +BlankNodeOrIRI subject = factory.createBlankNode(); +IRI predicate = factory.createIRI("http://example.com/says"); +RDFTerm object = factory.createLiteral("Hello"); +Triple triple = factory.createTriple(subject, predicate, object); +``` + +The subject of the triple can be retrieved +using [getSubject](apidocs/org/apache/commons/rdf/api/Triple.html#getSubject--): + +```java +BlankNodeOrIRI subj = triple.getSubject(); +System.out.println(subj.ntriplesString()); +``` + +> `_:7b914fbe-aa2a-4551-b71c-8ac0e2b52b26` + +Likewise the predicate using +[getPredicate](apidocs/org/apache/commons/rdf/api/Triple.html#getPredicate--): + +```java +IRI pred = triple.getPredicate(); +System.out.println(pred.getIRIString()); +``` +> `http://example.com/says` + +Finally, the object of the triple is returned with +[getObject](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--): + +```java +RDFTerm obj = triple.getObject(); +System.out.println(obj.ntriplesString()); +``` + +> `"Hello"` + +For the subject and object you might find it useful to do +Java type checking and casting from the types +[BlankNodeOrIRI](apidocs/org/apache/commons/rdf/api/BlankNodeOrIRI.html) +and [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html): + +```java +if (subj instanceof IRI) { + String s = ((IRI) subj).getIRIString(); + System.out.println(s); +} +// .. +if (obj instanceof Literal) { + IRI type = ((Literal) obj).getDatatype(); + System.out.println(type); +} +``` + +In Commons RDF, `BlankNodeOrIRI` instances are always one of `BlankNode` or +`IRI`, and `RDFTerm` instances one of `BlankNode`, `IRI` or `Literal`. + +A `Triple` is considered +[equal](apidocs/org/apache/commons/rdf/api/Triple.html#equals-java.lang.Object-) +to another `Triple` if each of their subject, predicate and object are also +equal: + +```java +System.out.println(triple.equals(factory.createTriple(subj, pred, obj))); +``` + +> `true` + + +## Graph + +A [graph](http://www.w3.org/TR/rdf11-concepts/#section-rdf-graph) +is a collection of triples. + +To create a [Graph](apidocs/org/apache/commons/rdf/api/Graph.html) instance +from a `RDFTermFactory`, use +[createGraph()](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createGraph--): + +```java +Graph graph = factory.createGraph(); +``` + +Implementations will typically also have other ways of retrieving a `Graph`, +e.g. by parsing a Turtle file or connecting to a storage backend. + +### Adding triples + +_Note: Some `Graph` implementations are immutable, in which case the below +may throw an `UnsupportedOperationException`_. + +Any [Triple](apidocs/org/apache/commons/rdf/api/Triple.html) can be added to the +graph using the +[add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.Triple-) +method: + +```java +graph.add(triple); +``` +As an alternative to creating the `Triple` first, you can use the expanded +_subject/predicate/object_ form of +[Graph.add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-()): + +```java +IRI bob = factory.createIRI("http://example.com/bob"); +IRI nameIri = factory.createIRI("http://example.com/name"); +Literal bobName = factory.createLiteral("Bob"); +graph.add(bob, nameIRI, bobName); +``` + +It is not necessary to check if a triple already exist in the graph, as the +underlying implementation will ignore duplicate triples. + + +### Finding triples + +You can check if the graph +[contains](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.Triple-) +a triple: + +```java +System.out.println(graph.contains(triple)); +``` +> `true` + +The expanded _subject/predicate/object_ call for [Graph.contains()](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) +can be used without needing to create a `Triple` first, and also +allow `null` as a wildcard parameters: + +```java +System.out.println(graph.contains(null, nameIri, bobName)); +``` +> `true` + +### Size + +The [size](apidocs/org/apache/commons/rdf/api/Graph.html#size--) of a graph is +the count of unique triples: + +```java +System.out.println(graph.size()); +``` +> `2` + + +### Iterating over triples + +The [iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate--) method +can be used to sequentially iterate over all the triples of the graph: + +```java +for (Triple t : graph.iterate()) { + System.out.println(t.getObject()); +} +``` +> `"Alice"` +> +> `"Bob"` + +The expanded +[iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) +method takes a _subject/predicate/object_ filter which permits the `null` wildcard: + +```java +for (Triple t : graph.iterate(null, null, bobName)) { + System.out.println(t.getPredicate()); +} +``` +> `<http://example.com/name>` + +### Stream of triples + +For processing of larger graphs, and to access more detailed +filtering and processing, the +[getTriples](apidocs/org/apache/commons/rdf/api/Graph.html#getTriples--) method +return a Java 8 +[Stream](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html). + +```java +Stream<RDFTerm> subjects = graph.getTriples().map(t -> t.getObject()); +String s = subjects.map(RDFTerm::ntriplesString).collect(Collectors.joining(" ")); +System.out.println(s); +``` +> ``"Alice" "Bob"`` + +For details about what can be done with a stream, see the +[java.util.stream documentation](http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html). + +Note that by default the stream will be parallel, use +[.sequential()](http://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#sequential--) +if your stream operations need to interact with objects that are not thread-safe. + +Streams allow advanced [filter predicates](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#filter-java.util.function.Predicate-), but you may find that simple _subject/predicate/object_ patterns +are handled more efficiently by the expanded +[getTriples](http://commonsrdf.incubator.apache.org/apidocs/org/apache/commons/rdf/api/Graph.html#getTriples-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) method. These can of course be combined: + +```java +Stream<? extends Triple> namedB = graph.getTriples(null, nameIri, null). + filter(t -> t.getObject().ntriplesString().contains("B")); +System.out.println(namedB.map(t -> t.getSubject()).findAny().get()); +``` +> `<http://example.com/bob>` + + +### Removing triples + +_Note: Some `Graph` implementations are immutable, in which case the below +may throw an `UnsupportedOperationException`_. + +Triples can be [removed](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.Triple-) from a graph: + +```java +graph.remove(triple); +System.out.println(graph.contains(triple)); +``` + +The expanded _subject/predicate/object_ form of +[remove()](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) +can be used without needing to construct a `Triple` first. It also +allow `null` as a wildcard pattern: + +```java +graph.remove(null, nameIri, null); +``` + +To remove all triples, use [clear](apidocs/org/apache/commons/rdf/api/Graph.html#clear--): + +```java +graph.clear(); +System.out.println(graph.contains(null, null, null)); +``` +> false + +## Mutability and thread safety + +_Note: This section is subject to change - see discussion on [COMMONSRDF-7](https://issues.apache.org/jira/browse/COMMONSRDF-7)_ + +In Commons RDF, all instances of `Triple` and `RDFTerm` (e.g. `IRI`, +`BlankNode`, `Literal`) are considered _immutable_. That is, their content does +not change, and so calling a method like +[IRI.getIRIString](apidocs/org/apache/commons/rdf/api/IRI.html#getIRIString--) +or +[Literal.getDatatype](apidocs/org/apache/commons/rdf/api/Literal.html#getDatatype--) +will always have return values that are `.equal()` to any earlier return +values. Being immutable, the `Triple` and `RDFTerm` types should be +considered thread-safe. + +A `Graph` may be _mutable_, particular if it supports methods like +[Graph.add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) +and [Graph.remove](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.Triple-). That means that responses to methods like [size](apidocs/org/apache/commons/rdf/api/Graph.html#size--) and [contains](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.Triple-) might change during its lifetime. + +Implementations of Commons RDF may specify the (im)mutability of `Graph` in further details. If a graph is immutable, the methods `add` and `remove` may throw a `UnsupportedOperationException`. + +Commons RDF does not specify if methods on a `Graph` are thread-safe. Iterator +methods like [iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate--) +and [getTriples](apidocs/org/apache/commons/rdf/api/Graph.html#getTriples-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) +might throw a +[ConcurrentModificationException](http://docs.oracle.com/javase/8/docs/api/java/util/ConcurrentModificationException.html) +if it detects a thread concurrency modification, although this behaviour is not guaranteed. +Implementations of Commons RDF may specify more specific thread-safety considerations. + +If an implementation does not specify any thread-safety support, then all +potentially concurrent access to a `Graph` must be `synchronized`, e.g.: + +```java +Graph graph; +// ... +synchronized(graph) { + graph.add(triple); +} +// ... +synchronized(graph) { + for (Triple t : graph) { + // ... + } +} +``` + +## Implementations + +The [Commons RDF API](apidocs/org/apache/commons/rdf/api/package-summary.html) +is a set of Java interfaces, with implementations provided by several Java RDF +frameworks. See the [implementations](implementations.html) page for an +updated list of providers. + +Implementations are free to choose their level of integration with Commons RDF. +Several methods defined in Commons RDF therefore explicitly note the +possibility of throwing a `UnsupportedOperationException`. + +Different RDF frameworks might have different mechanisms to retrieve a Commons +RDF objects like `Graph` or `Triple` (e.g. returned from a query). +Commons RDF provides a `RDFTermFactory` interface as a way to create new +instances, but does not mandate how the factory itself should be instantiated +(e.g. a factory might be returned for an open network connection). + +### Cross-compatibility + +While different frameworks will have their own classes implementing the Commons +RDF interfaces, Commons RDF objects are intended to be cross-compatible. Thus a +client would be able to mix and match objects from multiple implementations: + +```java +import com.example.foo.FooRDFTermFactory; +import net.example.bar.BarGraph; + +RDFTermFactory fooFactory = new FooRDFTermFactory(); +FooGraph g1 = (FooGraph) fooFactory.createGraph(); +// Foo-specific load method +g1.load("dataset.ttl"); + +// Another Graph, from a different implementation +Graph g2 = new BarGraph("localhost", 1337); + +// Any factory can be used +IRI iri1 = fooFactory.createIRI("http://example.com/property1"); + +// Both Triple and RDFTerm instances can be used +// +for (Triple t1: g1.getTriples(null, iri1, null)) { + if (g2.contains(t1.getSubject(), null, t1.getObject())) { + g2.remove(t1); + } +} +``` + +_Note: Special care might need to be taken for cross-interoperability of +`BlankNode` instances. This is currently under discussion. See +[COMMONSRDF-15](https://issues.apache.org/jira/browse/COMMONSRDF-15)_ + +The `.equals()` methods of `RDFTerm` interfaces are explicitly defined, so +their instances can be compared across implementations. + +_Note: The `Graph` implementation is not required to keep the JVM object +reference, e.g. after `g2.add(subj1, pred, obj)` it is not required to later +return the same `subj1` implementation in `g2.getTriples()`. Special care +should be taken if returned values are needs to be casted to implementation +specific types._ + +The `.hashCode()` is not currently explicitly defined, hence +special care should be taken for cross-interoperability within hashing data +structures like `HashMap`. See +[COMMONSRDF-14](https://issues.apache.org/jira/browse/COMMONSRDF-14) + +## Complete example + +The complete source code for the examples used in this user guide can be +browsed in +[UserGuideTest.java](https://github.com/apache/incubator-commonsrdf/blob/master/examples/src/example/UserGuideTest.java) +within the +[examples](https://github.com/apache/incubator-commonsrdf/tree/master/examples) +folder of the +Commons RDF [source code repository](source-repository.html). http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/50a6c5c8/src/site/markdown/userguide.md.vm ---------------------------------------------------------------------- diff --git a/src/site/markdown/userguide.md.vm b/src/site/markdown/userguide.md.vm deleted file mode 100644 index 2820441..0000000 --- a/src/site/markdown/userguide.md.vm +++ /dev/null @@ -1,938 +0,0 @@ -<!-- - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ---> - -# User Guide - -This page shows some examples of a client using the Commons RDF API. -It was last updated for version `0.1.0-incubating` of the -Commons RDF [API](apidocs/). - -* [Introduction](#Introduction) - * [RDF concepts](#RDF_concepts) -* [Using Commons RDF from Maven](#Using_Commons_RDF_from_Maven) -* [Creating Commons RDF instances](#Creating_Commons_RDF_instances) -* [RDF terms](#RDF_terms) - * [N-Triples string](#N-Triples_string) - * [IRI](#IRI) - * [Blank node](#Blank_node) - * [Blank node reference](#Blank_node_reference) - * [Literal](#Literal) - * [Datatype](#Datatype) - * [Types](#Types) - * [Language](#Language) -* [Triple](#Triple) -* [Graph](#Graph) - * [Adding triples](#Adding_triples) - * [Finding triples](#Finding_triples) - * [Size](#Size) - * [Iterating over triples](#Iterating_over_triples) - * [Stream of triples](#Stream_of_triples) - * [Removing triples](#Removing_triples) -* [Mutability and thread safety](#Mutability_and_thread_safety) -* [Implementations](#Implementations) - * [Cross-compatibility](#Cross-compatibility) -* [Complete example](#Complete_example) - -## Introduction - -[Commons RDF](index.html) is an API that intends to directly describe -[RDF 1.1 concepts](http://www.w3.org/TR/rdf11-concepts/) as a set -of corresponding interfaces and methods. - -### RDF concepts - -RDF is a [graph-based data model](http://www.w3.org/TR/rdf11-concepts/#data-model), where -a _graph_ contains a series of _triples_, each containing the node-arc-node link -_subject_ -> _predicate_ -> _object_. Nodes in the graph are represented either as _IRIs_, _literals_ and _blank nodes_. -: -This user guide does not intend to give a detailed description of RDF as a data -model. To fully understand this user guide, you should have a brief -understanding of the core RDF concepts mentioned above. - -For more information on RDF, see the -[RDF primer](http://www.w3.org/TR/rdf11-primer/) and the [RDF -concepts](http://www.w3.org/TR/rdf11-concepts/#data-model) specification from -W3C. - - - -## Using Commons RDF from Maven - -To use Commons RDF API from an -[Apache Maven](http://maven.apache.org/) project, -add the following dependency to your `pom.xml`: - -```xml -<dependencies> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-rdf-api</artifactId> - <version>0.1.0-incubating</version> - </dependency> -</dependencies> -``` - -The `<version>` above might not be up to date, -see the [/download.html](download page) for the latest version. - -If you are testing a `SNAPSHOT` version, then you will have to either build -Commons RDF from [source](https://github.com/apache/incubator-commonsrdf), or -add this [snapshot repository](https://github.com/apache/incubator-commonsrdf#snapshot-repository): - -```xml -<repositories> - <repository> - <id>apache.snapshots</id> - <name>Apache Snapshot Repository</name> - <url>http://repository.apache.org/snapshots</url> - <releases> - <enabled>false</enabled> - </releases> - </repository> -</repositories> -``` - -As Commons RDF requires Java 8 or later, you will also need: - -```xml -<properties> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> -</properties> -``` - -In the examples below we will use the -[_simple_ implementation](apidocs/org/apache/commons/rdf/simple/package-summary.html), -but the examples should be equally applicable to other -[implementations](implementations.html). To add a dependency for the -_simple_ implementation, add to your `<dependencies>`: - -```xml - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-rdf-simple</artifactId> - <version>${project.version}</version> - </dependency> -``` - - -## Creating Commons RDF instances - -To create instances of Commons RDF interfaces like -[`Graph`](apidocs/org/apache/commons/rdf/api/Graph.html) and -[`IRI`](apidocs/org/apache/commons/rdf/api/IRI.html) you will need a -[RDFTermFactory](/apidocs/org/apache/commons/rdf/api/RDFTermFactory.html). - -How to get an instance of this factory is implementation specific, for the -_simple_ implementation, you can construct the -[SimpleRDFTermFactory](apidocs/org/apache/commons/rdf/simple/SimpleRDFTermFactory.html): - -```java -import org.apache.commons.rdf.api.*; -import org.apache.commons.rdf.simple.SimpleRDFTermFactory; -// ... -RDFTermFactory factory = new SimpleRDFTermFactory(); -``` - -If you don't want to depend on instantiating a concrete implementation, -you can alternatively use the -[ServiceLoader](http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) -to lookup any `RDFTermFactory` implementations found on the classpath: - -```java -import java.util.Iterator; -import java.util.ServiceLoader; - -import org.apache.commons.rdf.api.*; -// ... -ServiceLoader<RDFTermFactory> loader = ServiceLoader.load(RDFTermFactory.class); -Iterator<RDFTermFactory> iterator = loader.iterator(); -RDFTermFactory factory = iterator.next(); -``` - -Using the factory you can construct -any [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html), e.g. to create a -[BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html), -[IRI](apidocs/org/apache/commons/rdf/api/IRI.html) and -[Literal](apidocs/org/apache/commons/rdf/api/Literal.html): - -```java -BlankNode aliceBlankNode = factory.createBlankNode(); -IRI nameIri = factory.createIRI("http://example.com/name"); -Literal aliceLiteral = factory.createLiteral("Alice"); -``` - -You can also create a stand-alone [Triple](apidocs/org/apache/commons/rdf/api/Triple.html): - -```java -Triple triple = factory.createTriple(aliceBlankNode, nameIri, aliceLiteral); -``` - -The [RDFTermFactory](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html) also -contains more specific variants of some of the methods above, e.g. to create a -typed literal. - -Note that for any given implementation, `RDFTerm` instances need not be created -using a `RDFTermFactory`. More likely, implementation-specific methods might create these -objects as part of data parsing, storage lookup and queries. - - - -## RDF terms - -[RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) is -the super-interface for instances that can be used as subject, predicate and -object of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html). - -The RDF term interfaces are arranged in this class hierarchy: - -* [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) - * [BlankNodeOrIRI](apidocs/org/apache/commons/rdf/api/BlankNodeOrIRI.html) - * [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) - * [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) - * [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) - -### N-Triples string - -All of the [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html) types -support the `ntriplesString()` method: - -```java -System.out.println(aliceBlankNode.ntriplesString()); -System.out.println(nameIri.ntriplesString()); -System.out.println(aliceLiteral.ntriplesString()); -``` - -> `_:ef136d20-f1ee-3830-a54b-cd5e489d50fb` -> -> ``<http://example.com/name>`` -> -> ``"Alice"`` - -This returns the [N-Triples](http://www.w3.org/TR/n-triples) canonical form -of the term, which can be useful both for debugging and simple serialization. - -_Note: The `.toString()` of the `simple` implementation used in -some of these examples use `ntriplesString()` internally, but Commons RDF -places no such formal requirement on the `.toString()` method. Clients that -rely on a canonical N-Triples-compatible string should instead use -`ntriplesString()`._ - -<!-- Not relevant here - -As an example of using `ntriplesString()`, here is how one could write a basic -N-Triples-compatible serialization of a -[Graph](apidocs/org/apache/commons/rdf/api/Graph.html): - -```java -public class NTriplesSerializer { - public static String tripleAsString(Triple t) { - return t.getSubject().ntriplesString() + " " + - t.getPredicate().ntriplesString() + " " + - t.getObject().ntriplesString() + " ."; - } - public static void writeGraph(Graph graph, Path graphFile) throws Exception { - Stream<CharSequence> stream = graph.getTriples().map(NTriplesSerializer::tripleAsString); - Files.write(graphFile, stream::iterator, StandardCharsets.UTF_8); - } -} -``` - -Example output: - -> `_:ef136d20-f1ee-3830-a54b-cd5e489d50fb <http://example.com/name> "Alice" .` -> -> `<http://example.com/bob> <http://example.com/name> "Bob" .` ---> - -### IRI - -An [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) -is a representation of an -[Internationalized Resource Identifier](http://www.w3.org/TR/rdf11-concepts/#dfn-iri), -e.g. `http://example.com/alice` or `http://ns.example.org/vocab#term`. - -> IRIs in the RDF abstract syntax MUST be absolute, and MAY contain a fragment identifier. - -In RDF, an IRI identifies a resource that can be used as a _subject_, -_predicate_ or _object_ of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html). - -To create an `IRI` instance from a `RDFTermFactory`, use [createIRI](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createIRI-java.lang.String-): - -```java -IRI iri = factory.createIRI("http://example.com/alice"); -``` - -You can retrieve the IRI string using [getIRIString](apidocs/org/apache/commons/rdf/api/IRI.html#getIRIString--): - -```java -System.out.println(iri.getIRIString()); -``` - -> `http://example.com/alice` - -_Note: The IRI string might contain non-ASCII characters which must be -%-encoded for applications that expect an URI. It is currently -out of scope for Commons RDF to perform such a conversion, -however implementations might provide separate methods for that purpose._ - -Two IRI instances can be compared using the -[equals](apidocs/org/apache/commons/rdf/api/IRI.html#equals-java.lang.Object-) -method, which uses [simple string comparison](http://tools.ietf.org/html/rfc3987#section-5.3.1): - -```java -IRI iri2 = factory.createIRI("http://example.com/alice"); -System.out.println(iri.equals(iri2)); -``` - -> `true` - -```java -IRI iri3 = factory.createIRI("http://example.com/alice/./"); -System.out.println(iri.equals(iri3)); -``` - -> `false` - -Note that IRIs are never equal to objects which are not themselves -instances of [IRI](apidocs/org/apache/commons/rdf/api/IRI.html): - - -```java -System.out.println(iri.equals("http://example.com/alice")); -System.out.println(iri.equals(factory.createLiteral("http://example.com/alice"))); -``` -> `false` -> -> `false` - - -### Blank node - -A [blank node](http://www.w3.org/TR/rdf11-concepts/#section-blank-nodes) is a -resource which, unlike an IRI, is not directly identified. Blank nodes can be -used as _subject_ or _object_ of a `Triple` -[Triple](apidocs/org/apache/commons/rdf/api/Triple.html). - -To create a new -[BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) instance from a -`RDFTermFactory`, use -[createBlankNode](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createBlankNode--): - -```java -BlankNode bnode = factory.createBlankNode(); -``` - -Every call to `createBlankNode()` returns a brand new blank node -which can be used in multiple triples in multiple graphs. Thus -every such blank node can only be -[equal](apidocs/org/apache/commons/rdf/api/BlankNode.html#equals-java.lang.Object-) -to itself: - -```java -System.out.println(bnode.equals(bnode)); -System.out.println(bnode.equals(factory.createBlankNode())); -``` - -> `true` -> -> `false` - -Sometimes it can be beneficial to create a blank node based on a -localized _name_, without needing to keep object references -to earlier `BlankNode` instances. For that purpose, `RDFTermFactory` -may support the -[expanded createBlankNode](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createBlankNode-java.lang.String-) -method: - -```java -BlankNode b1 = factory.createBlankNode("b1"); -``` - -Note that there is no requirement for the -[ntriplesString()](apidocs/org/apache/commons/rdf/api/RDFTerm.html#ntriplesString--) -of the BlankNode to reflect the provided `name`: - -```java -System.out.println(b1.ntriplesString()); -``` - -> `_:6c0f628f-02cb-3634-99db-0e1e99d2e66d` - - - -Any later `createBlankNode("b1")` **on the same factory instance** -returns a `BlankNode` which are -[equal](apidocs/org/apache/commons/rdf/api/BlankNode.html#equals-java.lang.Object-) -to the previous b1: - -```java -System.out.println(b1.equals(factory.createBlankNode("b1"))); -System.out.println(b1.equals(new SimpleRDFTermFactory().createBlankNode("b1"))); -``` - -> `true` -> -> `false` - -#### Blank node reference - -While blank nodes are distinct from IRIs, and don't have inherent -universal identifiers, it can nevertheless be useful -for debugging and testing to have a unique reference string for -a particular blank node. -For that purpose, BlankNode exposes the -[uniqueReference](apidocs/org/apache/commons/rdf/api/BlankNode.html#uniqueReference--) -method: - -```java -System.out.println(bnode.uniqueReference()); -``` - -> `735d5e63-96a4-488b-8613-7037b82c74a5` - -While this reference string might for the _simple_ -implementation also be seen within the `BlankNode.ntriplesString()` -result, there is no such guarantee from the Commons RDF API. -Clients who need a globally unique reference -for a blank node should therefore use the `uniqueReference()` method. - -_Note: While it is recommended for this string to be (or contain) a -[UUID string](http://docs.oracle.com/javase/8/docs/api/java/util/UUID.html), -implementations are free to use any scheme to ensure their -blank node references are globally unique. Therefore no assumptions should -be made about this string except that it is unique per blank node._ - - -### Literal - -A [literal](http://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal) in RDF -is a value such as a string, number or a date. A `Literal` can only be used as -an _object_ of a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--). - -To create a [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) instance -from an `RDFTermFactory`, use -[createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-): - -```java -Literal literal = factory.createLiteral("Hello world!"); -System.out.println(literal.ntriplesString()); -``` - -> `"Hello world!"` - -The lexical value (what is inside the quotes) can be retrieved -using [getLexicalForm()](apidocs/org/apache/commons/rdf/api/Literal.html#getLexicalForm--): - -```java -String lexical = literal.getLexicalForm(); -System.out.println(lexical); -``` - -> `Hello world!` - - -#### Datatype - -All literals in RDF 1.1 have a -[datatype](http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri) `IRI`, which -can be retrieved using -[Literal.getDatatype()](apidocs/org/apache/commons/rdf/api/Literal.html#getDatatype--): - -```java -IRI datatype = literal.getDatatype(); -System.out.println(datatype.ntriplesString()); -``` - -> `<http://www.w3.org/2001/XMLSchema#string>` - -In RDF 1.1, a [simple -literal](http://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) (as created -above) always have the type -`http://www.w3.org/2001/XMLSchema#string` (or -[xsd:string](apidocs/org/apache/commons/rdf/simple/Types.html#XSD_STRING) for -short). - -<div class="alert alert-warn" role="alert"><p><span class="glyphicon glyphicon-warn-sign" aria-hidden="true"></span> -<!-- Markdown not supported inside HTML --> -<strong>Note:</strong> -RDF 1.0 had the datatype -<code>http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral</code> to -indicate <em>plain literals</em> (untyped), which were distinct from -<code>http://www.w3.org/2001/XMLSchema#string</code> (typed). Commons -RDF assumes RDF 1.1, which merges the two concepts as the second type, however -particular implementations might have explicit options for RDF 1.0 support, in -which case you might find <code>Literal</code> instances with the deprecated -<a href="apidocs/org/apache/commons/rdf/simple/Types.html#RDF_PLAINLITERAL">plain -literal</a> data type. -</p></div> - - -To create a literal with any other -[datatype](http://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri), then -first create the datatype `IRI` and pass it to the expanded -[createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-org.apache.commons.rdf.api.IRI-): - -```java -IRI xsdDouble = factory.createIRI("http://www.w3.org/2001/XMLSchema#double"); -Literal literalDouble = factory.createLiteral("13.37", xsdDouble); -System.out.println(literalDouble.ntriplesString()); -``` - -> `"13.37"^^<http://www.w3.org/2001/XMLSchema#double>` - - - - -##### Types - -The class [Types](apidocs/org/apache/commons/rdf/simple/Types.html), which is -part of the _simple_ implementation, provides `IRI` constants for the standard -XML Schema datatypes like `xsd:dateTime` and `xsd:float`. Using `Types`, -the above example can be simplified to: - -```java -Literal literalDouble2 = factory.createLiteral("13.37", Types.XSD_DOUBLE); -``` - -As the constants in `Types` are all instances of `IRI`, they can -also be used for comparisons: - -```java -System.out.println(literal.getDatatype().equals(Types.XSD_STRING)); -``` - -> `true` - -#### Language - -Literals may be created with an associated -[language tag](http://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) -using the expanded [createLiteral](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createLiteral-java.lang.String-java.lang.String-): - -```java -Literal inSpanish = factory.createLiteral("¡Hola, Mundo!", "es"); -System.out.println(inSpanish.ntriplesString()); -System.out.println(inSpanish.getLexicalForm()); -``` -> `"¡Hola, Mundo!"@es` -> -> `¡Hola, Mundo!` - -A literal with a language tag always have the -implied type `http://www.w3.org/1999/02/22-rdf-syntax-ns#langString`: - -```java -System.out.println(inSpanish.getDatatype().ntriplesString()); -``` - -> `<http://www.w3.org/1999/02/22-rdf-syntax-ns#langString>` - -The language tag can be retrieved using -[getLanguageTag()](apidocs/org/apache/commons/rdf/api/Literal.html#getLanguageTag--): - -```java -Optional<String> tag = inSpanish.getLanguageTag(); -if (tag.isPresent()) { - System.out.println(tag.get()); -} -``` - -> `es` - -The language tag is behind an -[Optional](http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) as -it cannot be present for any other datatypes than -`http://www.w3.org/1999/02/22-rdf-syntax-ns#langString`: - -```java -System.out.println(literal.getLanguageTag().isPresent()); -System.out.println(literalDouble.getLanguageTag().isPresent()); -``` - -> `false` -> -> `false` - - -## Triple - -A [triple](http://www.w3.org/TR/rdf11-concepts/#section-triples) in -RDF 1.1 consists of: - -* The [subject](apidocs/org/apache/commons/rdf/api/Triple.html#getSubject--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) or a [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) -* The [predicate](apidocs/org/apache/commons/rdf/api/Triple.html#getPredicate--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html) -* The [object](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--), which is an [IRI](apidocs/org/apache/commons/rdf/api/IRI.html), a [BlankNode](apidocs/org/apache/commons/rdf/api/BlankNode.html) or a [Literal](apidocs/org/apache/commons/rdf/api/Literal.html) - - -To construct a [Triple](apidocs/org/apache/commons/rdf/api/Triple.html) from a -`RDFTermFactory`, use -[createTriple](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createTriple-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-): - -```java -BlankNodeOrIRI subject = factory.createBlankNode(); -IRI predicate = factory.createIRI("http://example.com/says"); -RDFTerm object = factory.createLiteral("Hello"); -Triple triple = factory.createTriple(subject, predicate, object); -``` - -The subject of the triple can be retrieved -using [getSubject](apidocs/org/apache/commons/rdf/api/Triple.html#getSubject--): - -```java -BlankNodeOrIRI subj = triple.getSubject(); -System.out.println(subj.ntriplesString()); -``` - -> `_:7b914fbe-aa2a-4551-b71c-8ac0e2b52b26` - -Likewise the predicate using -[getPredicate](apidocs/org/apache/commons/rdf/api/Triple.html#getPredicate--): - -```java -IRI pred = triple.getPredicate(); -System.out.println(pred.getIRIString()); -``` -> `http://example.com/says` - -Finally, the object of the triple is returned with -[getObject](apidocs/org/apache/commons/rdf/api/Triple.html#getObject--): - -```java -RDFTerm obj = triple.getObject(); -System.out.println(obj.ntriplesString()); -``` - -> `"Hello"` - -For the subject and object you might find it useful to do -Java type checking and casting from the types -[BlankNodeOrIRI](apidocs/org/apache/commons/rdf/api/BlankNodeOrIRI.html) -and [RDFTerm](apidocs/org/apache/commons/rdf/api/RDFTerm.html): - -```java -if (subj instanceof IRI) { - String s = ((IRI) subj).getIRIString(); - System.out.println(s); -} -// .. -if (obj instanceof Literal) { - IRI type = ((Literal) obj).getDatatype(); - System.out.println(type); -} -``` - -In Commons RDF, `BlankNodeOrIRI` instances are always one of `BlankNode` or -`IRI`, and `RDFTerm` instances one of `BlankNode`, `IRI` or `Literal`. - -A `Triple` is considered -[equal](apidocs/org/apache/commons/rdf/api/Triple.html#equals-java.lang.Object-) -to another `Triple` if each of their subject, predicate and object are also -equal: - -```java -System.out.println(triple.equals(factory.createTriple(subj, pred, obj))); -``` - -> `true` - - -## Graph - -A [graph](http://www.w3.org/TR/rdf11-concepts/#section-rdf-graph) -is a collection of triples. - -To create a [Graph](apidocs/org/apache/commons/rdf/api/Graph.html) instance -from a `RDFTermFactory`, use -[createGraph()](apidocs/org/apache/commons/rdf/api/RDFTermFactory.html#createGraph--): - -```java -Graph graph = factory.createGraph(); -``` - -Implementations will typically also have other ways of retrieving a `Graph`, -e.g. by parsing a Turtle file or connecting to a storage backend. - -### Adding triples - -_Note: Some `Graph` implementations are immutable, in which case the below -may throw an `UnsupportedOperationException`_. - -Any [Triple](apidocs/org/apache/commons/rdf/api/Triple.html) can be added to the -graph using the -[add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.Triple-) -method: - -```java -graph.add(triple); -``` -As an alternative to creating the `Triple` first, you can use the expanded -_subject/predicate/object_ form of -[Graph.add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-()): - -```java -IRI bob = factory.createIRI("http://example.com/bob"); -IRI nameIri = factory.createIRI("http://example.com/name"); -Literal bobName = factory.createLiteral("Bob"); -graph.add(bob, nameIRI, bobName); -``` - -It is not necessary to check if a triple already exist in the graph, as the -underlying implementation will ignore duplicate triples. - - -### Finding triples - -You can check if the graph -[contains](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.Triple-) -a triple: - -```java -System.out.println(graph.contains(triple)); -``` -> `true` - -The expanded _subject/predicate/object_ call for [Graph.contains()](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) -can be used without needing to create a `Triple` first, and also -allow `null` as a wildcard parameters: - -```java -System.out.println(graph.contains(null, nameIri, bobName)); -``` -> `true` - -### Size - -The [size](apidocs/org/apache/commons/rdf/api/Graph.html#size--) of a graph is -the count of unique triples: - -```java -System.out.println(graph.size()); -``` -> `2` - - -### Iterating over triples - -The [iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate--) method -can be used to sequentially iterate over all the triples of the graph: - -```java -for (Triple t : graph.iterate()) { - System.out.println(t.getObject()); -} -``` -> `"Alice"` -> -> `"Bob"` - -The expanded -[iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) -method takes a _subject/predicate/object_ filter which permits the `null` wildcard: - -```java -for (Triple t : graph.iterate(null, null, bobName)) { - System.out.println(t.getPredicate()); -} -``` -> `<http://example.com/name>` - -### Stream of triples - -For processing of larger graphs, and to access more detailed -filtering and processing, the -[getTriples](apidocs/org/apache/commons/rdf/api/Graph.html#getTriples--) method -return a Java 8 -[Stream](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html). - -```java -Stream<RDFTerm> subjects = graph.getTriples().map(t -> t.getObject()); -String s = subjects.map(RDFTerm::ntriplesString).collect(Collectors.joining(" ")); -System.out.println(s); -``` -> ``"Alice" "Bob"`` - -For details about what can be done with a stream, see the -[java.util.stream documentation](http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html). - -Note that by default the stream will be parallel, use -[.sequential()](http://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#sequential--) -if your stream operations need to interact with objects that are not thread-safe. - -Streams allow advanced [filter predicates](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#filter-java.util.function.Predicate-), but you may find that simple _subject/predicate/object_ patterns -are handled more efficiently by the expanded -[getTriples](http://commonsrdf.incubator.apache.org/apidocs/org/apache/commons/rdf/api/Graph.html#getTriples-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) method. These can of course be combined: - -```java -Stream<? extends Triple> namedB = graph.getTriples(null, nameIri, null). - filter(t -> t.getObject().ntriplesString().contains("B")); -System.out.println(namedB.map(t -> t.getSubject()).findAny().get()); -``` -> `<http://example.com/bob>` - - -### Removing triples - -_Note: Some `Graph` implementations are immutable, in which case the below -may throw an `UnsupportedOperationException`_. - -Triples can be [removed](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.Triple-) from a graph: - -```java -graph.remove(triple); -System.out.println(graph.contains(triple)); -``` - -The expanded _subject/predicate/object_ form of -[remove()](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) -can be used without needing to construct a `Triple` first. It also -allow `null` as a wildcard pattern: - -```java -graph.remove(null, nameIri, null); -``` - -To remove all triples, use [clear](apidocs/org/apache/commons/rdf/api/Graph.html#clear--): - -```java -graph.clear(); -System.out.println(graph.contains(null, null, null)); -``` -> false - -## Mutability and thread safety - -_Note: This section is subject to change - see discussion on [COMMONSRDF-7](https://issues.apache.org/jira/browse/COMMONSRDF-7)_ - -In Commons RDF, all instances of `Triple` and `RDFTerm` (e.g. `IRI`, -`BlankNode`, `Literal`) are considered _immutable_. That is, their content does -not change, and so calling a method like -[IRI.getIRIString](apidocs/org/apache/commons/rdf/api/IRI.html#getIRIString--) -or -[Literal.getDatatype](apidocs/org/apache/commons/rdf/api/Literal.html#getDatatype--) -will always have return values that are `.equal()` to any earlier return -values. Being immutable, the `Triple` and `RDFTerm` types should be -considered thread-safe. - -A `Graph` may be _mutable_, particular if it supports methods like -[Graph.add](apidocs/org/apache/commons/rdf/api/Graph.html#add-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) -and [Graph.remove](apidocs/org/apache/commons/rdf/api/Graph.html#remove-org.apache.commons.rdf.api.Triple-). That means that responses to methods like [size](apidocs/org/apache/commons/rdf/api/Graph.html#size--) and [contains](apidocs/org/apache/commons/rdf/api/Graph.html#contains-org.apache.commons.rdf.api.Triple-) might change during its lifetime. - -Implementations of Commons RDF may specify the (im)mutability of `Graph` in further details. If a graph is immutable, the methods `add` and `remove` may throw a `UnsupportedOperationException`. - -Commons RDF does not specify if methods on a `Graph` are thread-safe. Iterator -methods like [iterate](apidocs/org/apache/commons/rdf/api/Graph.html#iterate--) -and [getTriples](apidocs/org/apache/commons/rdf/api/Graph.html#getTriples-org.apache.commons.rdf.api.BlankNodeOrIRI-org.apache.commons.rdf.api.IRI-org.apache.commons.rdf.api.RDFTerm-) -might throw a -[ConcurrentModificationException](http://docs.oracle.com/javase/8/docs/api/java/util/ConcurrentModificationException.html) -if it detects a thread concurrency modification, although this behaviour is not guaranteed. -Implementations of Commons RDF may specify more specific thread-safety considerations. - -If an implementation does not specify any thread-safety support, then all -potentially concurrent access to a `Graph` must be `synchronized`, e.g.: - -```java -Graph graph; -// ... -synchronized(graph) { - graph.add(triple); -} -// ... -synchronized(graph) { - for (Triple t : graph) { - // ... - } -} -``` - -## Implementations - -The [Commons RDF API](apidocs/org/apache/commons/rdf/api/package-summary.html) -is a set of Java interfaces, with implementations provided by several Java RDF -frameworks. See the [implementations](implementations.html) page for an -updated list of providers. - -Implementations are free to choose their level of integration with Commons RDF. -Several methods defined in Commons RDF therefore explicitly note the -possibility of throwing a `UnsupportedOperationException`. - -Different RDF frameworks might have different mechanisms to retrieve a Commons -RDF objects like `Graph` or `Triple` (e.g. returned from a query). -Commons RDF provides a `RDFTermFactory` interface as a way to create new -instances, but does not mandate how the factory itself should be instantiated -(e.g. a factory might be returned for an open network connection). - -### Cross-compatibility - -While different frameworks will have their own classes implementing the Commons -RDF interfaces, Commons RDF objects are intended to be cross-compatible. Thus a -client would be able to mix and match objects from multiple implementations: - -```java -import com.example.foo.FooRDFTermFactory; -import net.example.bar.BarGraph; - -RDFTermFactory fooFactory = new FooRDFTermFactory(); -FooGraph g1 = (FooGraph) fooFactory.createGraph(); -// Foo-specific load method -g1.load("dataset.ttl"); - -// Another Graph, from a different implementation -Graph g2 = new BarGraph("localhost", 1337); - -// Any factory can be used -IRI iri1 = fooFactory.createIRI("http://example.com/property1"); - -// Both Triple and RDFTerm instances can be used -// -for (Triple t1: g1.getTriples(null, iri1, null)) { - if (g2.contains(t1.getSubject(), null, t1.getObject())) { - g2.remove(t1); - } -} -``` - -_Note: Special care might need to be taken for cross-interoperability of -`BlankNode` instances. This is currently under discussion. See -[COMMONSRDF-15](https://issues.apache.org/jira/browse/COMMONSRDF-15)_ - -The `.equals()` methods of `RDFTerm` interfaces are explicitly defined, so -their instances can be compared across implementations. - -_Note: The `Graph` implementation is not required to keep the JVM object -reference, e.g. after `g2.add(subj1, pred, obj)` it is not required to later -return the same `subj1` implementation in `g2.getTriples()`. Special care -should be taken if returned values are needs to be casted to implementation -specific types._ - -The `.hashCode()` is not currently explicitly defined, hence -special care should be taken for cross-interoperability within hashing data -structures like `HashMap`. See -[COMMONSRDF-14](https://issues.apache.org/jira/browse/COMMONSRDF-14) - -## Complete example - -The complete source code for the examples used in this user guide can be -browsed in -[UserGuideTest.java](https://github.com/apache/incubator-commonsrdf/blob/master/examples/src/example/UserGuideTest.java) -within the -[examples](https://github.com/apache/incubator-commonsrdf/tree/master/examples) -folder of the -Commons RDF [source code repository](source-repository.html).