View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.commons.rdf.simple;
19  
20  import java.util.Optional;
21  import java.util.stream.Stream;
22  
23  import org.apache.commons.rdf.api.BlankNode;
24  import org.apache.commons.rdf.api.BlankNodeOrIRI;
25  import org.apache.commons.rdf.api.Dataset;
26  import org.apache.commons.rdf.api.Graph;
27  import org.apache.commons.rdf.api.IRI;
28  import org.apache.commons.rdf.api.Quad;
29  import org.apache.commons.rdf.api.RDFTerm;
30  import org.apache.commons.rdf.api.Triple;
31  
32  /**
33   * A {@link Graph} view on a {@link Dataset}.
34   * <p>
35   * This view is backed by a {@link Dataset}, and can be constructed in two ways:
36   * 
37   * <dl>
38   * <dt>{@link #DatasetGraphView(Dataset)}</dt>
39   * <dd>Expose a <em>union graph</em> view of the Dataset, where all the
40   * {@link Quad}s of the Dataset is represented as a {@link Triple}. Adding
41   * triples will add them to the <em>default graph</em>, while removing triples
42   * will remove from all graphs.</dd>
43   * 
44   * <dt>{@link #DatasetGraphView(Dataset, BlankNodeOrIRI)}</dt>
45   * <dd>Expose a particular graph of the Dataset, either named by an {@link IRI},
46   * a {@link BlankNode}, or <code>null</code> for the <em>default
47   * graph</em>.</dd>
48   * </dl>
49   * <p>
50   * Changes in the Graph are reflected directly in the Dataset and vice versa.
51   * This class is thread-safe is the underlying Dataset is thread-safe.
52   */
53  public class DatasetGraphView implements Graph {
54  
55      private final boolean unionGraph;
56      private final BlankNodeOrIRI namedGraph;
57      private final Dataset dataset;
58  
59      public DatasetGraphView(final Dataset dataset) {
60          this.dataset = dataset;
61          this.namedGraph = null;
62          this.unionGraph = true;
63      }
64  
65      public DatasetGraphView(final Dataset dataset, final BlankNodeOrIRI namedGraph) {
66          this.dataset = dataset;
67          this.namedGraph = namedGraph;
68          this.unionGraph = false;
69      }
70  
71      @Override
72      public void close() throws Exception {
73          dataset.close();
74  
75      }
76  
77      @Override
78      public void add(final Triple triple) {
79          dataset.add(namedGraph, triple.getSubject(), triple.getPredicate(), triple.getObject());
80      }
81  
82      @Override
83      public void add(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
84          dataset.add(namedGraph, subject, predicate, object);
85      }
86  
87      @Override
88      public boolean contains(final Triple triple) {
89          return dataset.contains(unionOrNamedGraph(), triple.getSubject(), triple.getPredicate(), triple.getObject());
90      }
91  
92      private Optional<BlankNodeOrIRI> unionOrNamedGraph() {
93          if (unionGraph) {
94              return null;
95          }
96          return Optional.ofNullable(namedGraph);
97      }
98  
99      @Override
100     public boolean contains(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
101         return dataset.contains(unionOrNamedGraph(), subject, predicate, object);
102     }
103 
104     @Override
105     public void remove(final Triple triple) {
106         dataset.remove(unionOrNamedGraph(), triple.getSubject(), triple.getPredicate(), triple.getObject());
107     }
108 
109     @Override
110     public void remove(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
111         dataset.remove(unionOrNamedGraph(), subject, predicate, object);
112     }
113 
114     @Override
115     public void clear() {
116         dataset.remove(unionOrNamedGraph(), null, null, null);
117     }
118 
119     @Override
120     public long size() {
121         return stream().count();
122     }
123 
124     @Override
125     public Stream<? extends Triple> stream() {
126         return stream(null, null, null);
127     }
128 
129     @Override
130     public Stream<? extends Triple> stream(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
131         final Stream<Triple> stream = dataset.stream(unionOrNamedGraph(), subject, predicate, object).map(Quad::asTriple);
132         if (unionGraph) {
133             // remove duplicates
134             return stream.distinct();
135         }
136         return stream;
137     }
138 
139 }