UnionSailDataset.java
/*******************************************************************************
* Copyright (c) 2022 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.sail.base;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.Set;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.common.iteration.DualUnionIteration;
import org.eclipse.rdf4j.common.order.StatementOrder;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Namespace;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.sail.SailException;
/**
* Combines two {@link SailDataset} into a single view.
*
* @author H��vard M. Ottestad
*/
class UnionSailDataset implements SailDataset {
private final SailDataset dataset1;
private final SailDataset dataset2;
private UnionSailDataset(SailDataset dataset1, SailDataset dataset2) {
this.dataset1 = dataset1;
this.dataset2 = dataset2;
}
/**
* Creates a new {@link SailDataset} that includes both the provided {@link SailDataset}s.
*/
public static SailDataset getInstance(SailDataset dataset1, SailDataset dataset2) {
return new UnionSailDataset(dataset1, dataset2);
}
@Override
public String toString() {
return "UnionSailDataset{" +
"dataset1=" + dataset1 +
", dataset2=" + dataset2 +
'}';
}
@Override
public void close() throws SailException {
try {
dataset1.close();
} finally {
dataset2.close();
}
}
@Override
public CloseableIteration<? extends Namespace> getNamespaces() throws SailException {
CloseableIteration<? extends Namespace> iteration1 = null;
CloseableIteration<? extends Namespace> iteration2 = null;
try {
iteration1 = dataset1.getNamespaces();
iteration2 = dataset2.getNamespaces();
return DualUnionIteration.getWildcardInstance(iteration1, iteration2);
} catch (Throwable t) {
try {
if (iteration1 != null) {
iteration1.close();
}
} finally {
if (iteration2 != null) {
iteration2.close();
}
}
throw t;
}
}
@Override
public String getNamespace(String prefix) throws SailException {
String namespace = dataset1.getNamespace(prefix);
if (namespace != null) {
return namespace;
} else {
return dataset2.getNamespace(prefix);
}
}
@Override
public CloseableIteration<? extends Resource> getContextIDs() throws SailException {
CloseableIteration<? extends Resource> iteration1 = null;
CloseableIteration<? extends Resource> iteration2 = null;
try {
iteration1 = dataset1.getContextIDs();
iteration2 = dataset2.getContextIDs();
return DualUnionIteration.getWildcardInstance(iteration1, iteration2);
} catch (Throwable t) {
try {
if (iteration1 != null) {
iteration1.close();
}
} finally {
if (iteration2 != null) {
iteration2.close();
}
}
throw t;
}
}
@Override
public CloseableIteration<? extends Statement> getStatements(Resource subj, IRI pred, Value obj,
Resource... contexts) throws SailException {
CloseableIteration<? extends Statement> iteration1 = null;
CloseableIteration<? extends Statement> iteration2 = null;
try {
iteration1 = dataset1.getStatements(subj, pred, obj, contexts);
iteration2 = dataset2.getStatements(subj, pred, obj, contexts);
return DualUnionIteration.getWildcardInstance(iteration1, iteration2);
} catch (Throwable t) {
try {
if (iteration1 != null) {
iteration1.close();
}
} finally {
if (iteration2 != null) {
iteration2.close();
}
}
throw t;
}
}
@Override
public CloseableIteration<? extends Triple> getTriples(Resource subj, IRI pred, Value obj)
throws SailException {
CloseableIteration<? extends Triple> iteration1 = null;
CloseableIteration<? extends Triple> iteration2 = null;
try {
iteration1 = dataset1.getTriples(subj, pred, obj);
iteration2 = dataset2.getTriples(subj, pred, obj);
return DualUnionIteration.getWildcardInstance(iteration1, iteration2);
} catch (Throwable t) {
try {
if (iteration1 != null) {
iteration1.close();
}
} finally {
if (iteration2 != null) {
iteration2.close();
}
}
throw t;
}
}
@Override
public CloseableIteration<? extends Statement> getStatements(StatementOrder statementOrder, Resource subj, IRI pred,
Value obj, Resource... contexts) throws SailException {
CloseableIteration<? extends Statement> iteration1 = null;
CloseableIteration<? extends Statement> iteration2 = null;
try {
iteration1 = dataset1.getStatements(statementOrder, subj, pred, obj, contexts);
iteration2 = dataset2.getStatements(statementOrder, subj, pred, obj, contexts);
Comparator<Statement> cmp = statementOrder.getComparator(dataset1.getComparator());
return DualUnionIteration.getWildcardInstance(cmp, iteration1, iteration2);
} catch (Throwable t) {
try {
if (iteration1 != null) {
iteration1.close();
}
} finally {
if (iteration2 != null) {
iteration2.close();
}
}
throw t;
}
}
@Override
public Set<StatementOrder> getSupportedOrders(Resource subj, IRI pred, Value obj, Resource... contexts) {
Set<StatementOrder> supportedOrders1 = dataset1.getSupportedOrders(subj, pred, obj, contexts);
if (supportedOrders1.isEmpty()) {
return Set.of();
}
Set<StatementOrder> supportedOrders2 = dataset2.getSupportedOrders(subj, pred, obj, contexts);
if (supportedOrders2.isEmpty()) {
return Set.of();
}
if (supportedOrders1.equals(supportedOrders2)) {
return supportedOrders1;
}
EnumSet<StatementOrder> commonStatementOrders = EnumSet.copyOf(supportedOrders1);
commonStatementOrders.retainAll(supportedOrders2);
return commonStatementOrders;
}
@Override
public Comparator<Value> getComparator() {
Comparator<Value> comparator1 = dataset1.getComparator();
Comparator<Value> comparator2 = dataset2.getComparator();
assert (comparator1 == null && comparator2 == null) || (comparator1 != null && comparator2 != null);
return comparator1;
}
}