/* * 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.graph; import java.util.HashSet ; import java.util.Iterator ; import java.util.Locale ; import java.util.Set ; import java.util.function.Predicate; import org.apache.jena.graph.Capabilities ; import org.apache.jena.graph.Node ; import org.apache.jena.graph.NodeFactory ; import org.apache.jena.graph.Triple ; import org.apache.jena.graph.impl.GraphBase ; import org.apache.jena.graph.impl.SimpleEventManager ; import org.apache.jena.util.iterator.ClosableIterator ; import org.apache.jena.util.iterator.ExtendedIterator ; /** * A version of Graph that does term equality only */ public class GraphMemPlain extends GraphBase { private Set<Triple> triples = new HashSet<>() ; public GraphMemPlain() {} @Override public Capabilities getCapabilities() { return gmpCapabilities; } @Override public void performAdd( Triple t ) { triples.add(t) ; } @Override public void performDelete( Triple t ) { triples.remove(t) ; } @Override public boolean graphBaseContains( Triple t ) { if ( t.isConcrete() ) return triples.contains( t ) ; ClosableIterator<Triple> it = find( t ); try { for ( ; it.hasNext() ; ) { Triple t2 = it.next() ; if ( tripleContained(t, t2) ) return true ; } } finally { it.close(); } return false ; } @Override protected ExtendedIterator<Triple> graphBaseFind(Triple m) { Iterator<Triple> iter = triples.iterator() ; return SimpleEventManager.notifyingRemove( this, iter ) .filterKeep ( new TripleMatchFilterEquality( m ) ); } static boolean tripleContained(Triple patternTriple, Triple dataTriple) { return equalNode(patternTriple.getSubject(), dataTriple.getSubject()) && equalNode(patternTriple.getPredicate(), dataTriple.getPredicate()) && equalNode(patternTriple.getObject(), dataTriple.getObject()) ; } private static boolean equalNode(Node m, Node n) { // m should not be null unless .getMatchXXXX used to get the node. // Language tag canonicalization n = fixupNode(n) ; m = fixupNode(m) ; return (m==null) || (m == Node.ANY) || m.equals(n) ; } private static Node fixupNode(Node node) { if ( node == null || node == Node.ANY ) return node ; // RDF says ... language tags should be canonicalized to lower case. if ( node.isLiteral() ) { String lang = node.getLiteralLanguage() ; if ( lang != null && ! lang.equals("") ) node = NodeFactory.createLiteral(node.getLiteralLexicalForm(), lang.toLowerCase(Locale.ROOT)) ; } return node ; } static class TripleMatchFilterEquality implements Predicate<Triple> { final protected Triple tMatch; /** Creates new TripleMatchFilter */ public TripleMatchFilterEquality(Triple tMatch) { this.tMatch = tMatch; } @Override public boolean test(Triple t) { return tripleContained(tMatch, t) ; } } private static Capabilities gmpCapabilities = new Capabilities() { @Override public boolean sizeAccurate() { return true; } @Override public boolean addAllowed() { return true; } @Override public boolean addAllowed(boolean everyTriple) { return true; } @Override public boolean deleteAllowed() { return true; } @Override public boolean deleteAllowed(boolean everyTriple) { return true; } @Override public boolean iteratorRemoveAllowed() { return true; } @Override public boolean canBeEmpty() { return true; } @Override public boolean findContractSafe() { return true; } @Override public boolean handlesLiteralTyping() { return false; } }; }