package org.semanticweb.owlapi.rdf.rdfxml.parser;
import static org.semanticweb.owlapi.util.OWLAPIPreconditions.verifyNotNull;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.semanticweb.owlapi.io.RDFTriple;
import org.semanticweb.owlapi.model.HasIRI;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.vocab.OWL2Datatype;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
class TripleIndex {
/**
* Subject, predicate, object
*/
private final TripleMapCollection<IRI> resTriples = new TripleMapCollection<>();
/**
* Predicate, subject, object
*/
private final TripleMap<IRI> singlePredicateResources = new TripleMap<>();
/**
* Literal triples
*/
private final TripleMapCollection<OWLLiteral> litTriples = new TripleMapCollection<>();
/**
* Predicate, subject, object
*/
private final TripleMap<OWLLiteral> singlePredicateLiterals = new TripleMap<>();
private final TripleLogger tripleLogger;
public TripleIndex(TripleLogger logger) {
singlePredicateResources.setupSinglePredicateMaps();
tripleLogger = logger;
}
public void dumpRemainingTriples() {
singlePredicateResources.dumpRemainingTriples();
singlePredicateLiterals.dumpRemainingTriples();
resTriples.dumpRemainingTriples();
litTriples.dumpRemainingTriples();
}
public void clear() {
resTriples.clear();
litTriples.clear();
singlePredicateLiterals.clear();
singlePredicateResources.clear();
}
@Nullable
protected IRI resource(IRI subject, HasIRI predicate, boolean consume) {
return resource(subject, predicate.getIRI(), consume);
}
protected Stream<IRI> getPredicatesBySubject(IRI subject) {
return Stream.concat(resTriples.keys(subject), litTriples.keys(subject)).distinct();
}
@Nullable
protected IRI resource(IRI subject, IRI predicate, boolean consume) {
IRI obj = singlePredicateResources.get(subject, predicate, consume);
if (obj != null) {
return obj;
}
return resTriples.get(subject, predicate, consume);
}
@Nullable
protected OWLLiteral literal(IRI subject, IRI predicate, boolean consume) {
OWLLiteral obj = singlePredicateLiterals.get(subject, predicate, consume);
if (obj != null) {
return obj;
}
return litTriples.get(subject, predicate, consume);
}
protected Stream<OWLLiteral> getLiteralObjects(IRI subject, IRI predicate) {
OWLLiteral obj = singlePredicateLiterals.get(subject, predicate, false);
return Stream.concat(obj == null ? Stream.empty() : Stream.of(obj),
litTriples.getAll(subject, predicate, false));
}
protected Stream<IRI> getResourceObjects(IRI subject, IRI predicate) {
IRI obj = singlePredicateResources.get(subject, predicate, false);
return Stream.concat(obj == null ? Stream.empty() : Stream.of(obj),
resTriples.getAll(subject, predicate, false));
}
protected boolean consumeIfPresent(IRI subject, IRI predicate, IRI object) {
return singlePredicateResources.consume(subject, predicate, object)
|| resTriples.consume(subject, predicate, object);
}
protected boolean consumeIfPresent(IRI subject, IRI predicate, OWLLiteral object) {
return singlePredicateLiterals.consume(subject, predicate, object)
|| litTriples.consume(subject, predicate, object);
}
protected boolean hasPredicate(IRI subject, IRI predicate) {
return singlePredicateResources.contains(subject, predicate)
|| singlePredicateLiterals.contains(subject, predicate)
|| resTriples.contains(subject, predicate)
|| litTriples.contains(subject, predicate);
}
protected boolean consumeTriple(IRI subject, IRI predicate, IRI object) {
tripleLogger.justLog(subject, predicate, object);
return consumeIfPresent(subject, predicate, object);
}
protected boolean consumeTriple(IRI subject, IRI predicate, OWLLiteral con) {
tripleLogger.justLog(subject, predicate, con);
return consumeIfPresent(subject, predicate, con);
}
protected void addTriple(IRI subject, IRI predicate, IRI object) {
if (!singlePredicateResources.add(subject, predicate, object)) {
resTriples.add(subject, predicate, object);
}
}
protected void addTriple(IRI subject, IRI predicate, OWLLiteral l) {
if (!singlePredicateLiterals.add(subject, predicate, l)) {
litTriples.add(subject, predicate, l);
}
}
protected boolean isLiteralPresent(IRI mainNode, OWLRDFVocabulary p) {
return literal(mainNode, p.getIRI(), false) != null;
}
protected boolean isNonNegativeIntegerStrict(IRI mainNode, OWLRDFVocabulary p) {
OWLLiteral literal = literal(mainNode, p.getIRI(), false);
if (literal == null) {
return false;
}
return OWL2Datatype.XSD_NON_NEGATIVE_INTEGER.matches(literal.getDatatype())
&& OWL2Datatype.XSD_NON_NEGATIVE_INTEGER
.isInLexicalSpace(literal.getLiteral());
}
protected boolean isNonNegativeIntegerLax(IRI mainNode, OWLRDFVocabulary p) {
OWLLiteral literal = literal(mainNode, p.getIRI(), false);
if (literal == null) {
return false;
}
return OWL2Datatype.XSD_INTEGER
.isInLexicalSpace(verifyNotNull(literal.getLiteral().trim()));
}
protected int integer(IRI mainNode, OWLRDFVocabulary p) {
OWLLiteral literal = literal(mainNode, p.getIRI(), true);
if (literal == null) {
return 0;
}
try {
return Integer.parseInt(literal.getLiteral().trim());
} catch (@SuppressWarnings("unused") NumberFormatException e) {
return 0;
}
}
protected boolean isResourcePresent(IRI mainNode, OWLRDFVocabulary p) {
return resource(mainNode, p, false) != null;
}
protected Set<RDFTriple> getRemainingTriples(Predicate<IRI> anon) {
Set<RDFTriple> remaining = new HashSet<>();
resTriples.iterate((s, p, o) -> remaining.add(new RDFTriple(s, anon.test(s), isAxiom(s), p,
o, anon.test(o), isAxiom(o))));
litTriples.iterate((s, p, o) -> remaining
.add(new RDFTriple(s, anon.test(s), isAxiom(s), p, o)));
return remaining;
}
protected boolean isAxiom(IRI s) {
return resTriples.contains(s, OWLRDFVocabulary.RDF_TYPE.getIRI(),
OWLRDFVocabulary.OWL_AXIOM.getIRI());
}
public void iterate(TripleIterator<IRI> t1) {
// Inverse property axioms
resTriples.iterate(t1);
}
public void iterate(TripleIterator<IRI> t1, TripleIterator<IRI> t2,
TripleIterator<OWLLiteral> t3, TripleIterator<IRI> t4, TripleIterator<IRI> t5,
TripleIterator<OWLLiteral> t6) {
resTriples.iterate(t1);
// Now handle non-reserved predicate triples
resTriples.iterate(t2);
litTriples.iterate(t3);
// Now axiom annotations
resTriples.iterate(t4);
resTriples.iterate(t5);
litTriples.iterate(t6);
}
}