/* * 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); Iterator<Quad> iter2 = findInAnyNamedGraphs(s, p, o); // 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. 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() ; } 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 group 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) ; }