blob: e58cf9e50899200e6c664350642e495d9b060a8e [file] [log] [blame]
/*
* 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.
*/
package org.apache.jena.sparql.core;
import java.util.Iterator ;
import java.util.stream.Stream ;
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.sparql.core.mem.DatasetGraphInMemory ;
/**
* DatasetGraph framework.
* This class contains a convenience implementation of find that maps to a split between
* defaultGraph/named graphs.
* @see DatasetGraphTriplesQuads
* @see DatasetGraphCollection
* @see DatasetGraphOne
* @see DatasetGraphInMemory
*/
abstract public class DatasetGraphBaseFind extends DatasetGraphBase
{
protected DatasetGraphBaseFind() {}
/** Implementation of find based on splitting into triples (default graph) and quads (named graph) */
@Override
public Iterator<Quad> find(Node g, Node s, Node p, Node o) {
if ( Quad.isDefaultGraph(g))
return findInDftGraph(s, p, o) ;
if ( ! isWildcard(g) )
return findNG(g, s, p, o) ;
return findAny(s, p, o) ;
}
@Override
public Iterator<Quad> findNG(Node g, Node s, Node p , Node o) {
Iterator<Quad> qIter ;
if ( Quad.isUnionGraph(g))
qIter = findQuadsInUnionGraph(s, p, o) ;
else if ( isWildcard(g) )
qIter = findInAnyNamedGraphs(s, p, o) ;
else if ( Quad.isDefaultGraph(g) )
qIter = findInDftGraph(s, p, o) ;
else
// Not wildcard, not union graph, not default graph.
qIter = findInSpecificNamedGraph(g, s, p, o) ;
if ( qIter == null )
return Iter.nullIterator() ;
return qIter ;
}
protected Iterator<Quad> findAny(Node s, Node p, Node o) {
// Default graph
Iterator<Quad> iter1 = findInDftGraph(s, p, o);
if ( ! iter1.hasNext() )
iter1 = null;
Iterator<Quad> iter2 = findInAnyNamedGraphs(s, p, o);
if ( ! iter2.hasNext() )
iter2 = null;
// Copes with null in either or both positions.
return Iter.append(iter1, iter2);
}
/** Find matches in the default graph.
* Return as quads; the default graph is {@link Quad#defaultGraphIRI}
* To get Triples, use {@code DatasetGraph.getDefaultGraph().find(...)}.
*/
protected abstract Iterator<Quad> findInDftGraph(Node s, Node p , Node o) ;
/** Find matches in the notional union of all named graphs - return as triples.
* No duplicates - the union graph is a <em>set</em> of triples.
* See {@link #findInAnyNamedGraphs}, where there may be duplicates.
* <p>
* Implementations are encouraged to override this method. For example, it
* may be possible to avoid "distinct".
*/
public Iterator<Triple> findInUnionGraph(Node s, Node p , Node o) {
return findUnionGraphTriples(s,p,o).iterator() ;
}
/** Find matches in the notional union of all named graphs - return as quads.
* No duplicates - the union graph is a <em>set</em> of triples.
* See {@link #findInAnyNamedGraphs}, where there may be duplicates.
* <p>
* Implementations are encouraged to override this method or {@link #findUnionGraphTriples}.
* For example, it may be possible to avoid "distinct".
*/
public Iterator<Quad> findQuadsInUnionGraph(Node s, Node p , Node o) {
return findUnionGraphTriples(s,p,o).map(t -> new Quad(Quad.unionGraph, t)).iterator() ;
}
/** Find matches in the notional union of all named graphs - return as triples.
* No duplicates - the union graph is a <em>set</em> of triples.
* See {@link #findInAnyNamedGraphs}, where there may be duplicates.
* <p>
* Implementations are encouraged to override this method. For example, it
* may be possible to avoid "distinct".
*/
private Stream<Triple> findUnionGraphTriples(Node s, Node p , Node o) {
return Iter.asStream(findInAnyNamedGraphs(s,p,o)).map(Quad::asTriple).distinct() ;
}
/** Find in a specific named graph - {@code g} is a ground term (IRI or bNode), not a wild card (or null). */
protected abstract Iterator<Quad> findInSpecificNamedGraph(Node g, Node s, Node p , Node o) ;
/** Find in any named graph - return quads.
* If a triple matches in two different graph, return a quad for each.
* See {@link #findInUnionGraph} for matching without duplicate triples.
*/
protected abstract Iterator<Quad> findInAnyNamedGraphs(Node s, Node p , Node o) ;
}