org.openrdf.sesame.query.rql.model.Intersection Maven / Gradle / Ivy
Go to download
Sesame is an open source Java framework for storing, querying and reasoning with RDF.
The newest version!
/* Sesame - Storage and Querying architecture for RDF and RDF Schema
* Copyright (C) 2001-2006 Aduna
*
* Contact:
* Aduna
* Prinses Julianaplein 14 b
* 3817 CS Amersfoort
* The Netherlands
* tel. +33 (0)33 465 99 87
* fax. +33 (0)33 465 99 87
*
* http://aduna-software.com/
* http://www.openrdf.org/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.openrdf.sesame.query.rql.model;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.openrdf.model.GraphException;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.Value;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.sesame.query.rql.model.iterators.StatementSubjectIterator;
import org.openrdf.sesame.sail.RdfSchemaSource;
import org.openrdf.sesame.sail.StatementIterator;
import org.openrdf.sesame.sail.ValueIterator;
import org.openrdf.sesame.sail.util.ValueCollectionIterator;
/**
* An intersection of classes.
**/
public class Intersection implements Resource {
/** The members (classes) of this intersection. **/
private TreeSet _memberSet;
/**
* Creates a new, empty Intersection.
**/
public Intersection() {
_memberSet = new TreeSet();
}
/**
* Creates a new Intersection that is initialized with the objects
* of the statements from the supplied StatementIterator. The
* StatementIterator will be closed when all its elements have been
* read.
**/
public Intersection(StatementIterator statIter) {
this();
while (statIter.hasNext()) {
Statement stat = statIter.next();
Value v = stat.getObject();
if (v instanceof Resource) {
this.add((Resource)v);
}
}
statIter.close();
}
/**
* Gets the members of this intersection.
*
* @return a Set of Resource objects.
**/
public Set getMembers() {
return _memberSet;
}
public Resource getFirstMember() {
if (_memberSet.size() > 0) {
return (Resource)_memberSet.iterator().next();
}
return null;
}
/**
* Adds a resource to this intersection. The resource will be ignored
* if it is already in the intersection.
*
* @param resource A Resource representing a class.
**/
public void add(Resource resource) {
_memberSet.add(resource);
}
/**
* Minimizes the set of classes in this intersection by filtering out
* any superclasses for which there are also subclasseses in this
* intersection.
*
* @param rss The RdfSchemaSource to use for checking the sub-superclass
* relations.
**/
public Value minimize(RdfSchemaSource rss) {
// Intersections of size 0 cannot be further minimized:
if (_memberSet.size() == 0) {
return this;
}
if (_memberSet.size() == 1) {
return getFirstMember();
}
Resource member, superClass;
org.openrdf.sesame.sail.StatementIterator superClasses;
Iterator memberIter = _memberSet.iterator();
TreeSet resultSet = new TreeSet(_memberSet);
while (memberIter.hasNext()) {
member = (Resource)memberIter.next();
superClasses = rss.getDirectSubClassOf(member, null);
/*
* A superclass of member in the iterator is member itself,
* because every superclass is a superclass of itself. You
* don 't want to remove member from resultSet.
* It is skipped with equals(Object).
*/
while (superClasses.hasNext()) {
superClass = (Resource)superClasses.next().getObject();
if (!member.equals(superClass)) {
resultSet.remove(superClass);
}
}
}
_memberSet = resultSet;
if (_memberSet.size() == 1) {
return getFirstMember();
}
else {
return this;
}
}
/**
* Gets the size (number of resources) of this intersection.
**/
public int size() {
return _memberSet.size();
}
/**
* Checks if the supplied resource is an instance of all classes
* of this intersection, using the supplied RdfSchemaSource to check
* the instance relations.
**/
public boolean containsInstance(Resource instance, RdfSchemaSource rss) {
boolean result = true;
Iterator iter = _memberSet.iterator();
while (iter.hasNext()) {
Resource clazz = (Resource)iter.next();
if (!rss.isType(instance, clazz)) {
result = false;
break;
}
}
return result;
}
/**
* Gets all resources that are instances of all classes of this
* intersection.
**/
public ValueIterator getInstances(RdfSchemaSource rss) {
if (size() == 0) {
// return all resources
return new StatementSubjectIterator(
rss.getType(null, URIImpl.RDFS_RESOURCE));
}
Iterator iter = _memberSet.iterator();
// Initialize result with all instances of the first class
Resource clazz = (Resource)iter.next();
Set result = _getInstances(clazz, rss);
// Retain only the instances that are also returned for the
// other classes
while (iter.hasNext()) {
clazz = (Resource)iter.next();
Set instances = _getInstances(clazz, rss);
result.retainAll(instances);
}
return new ValueCollectionIterator(result);
}
private Set _getInstances(Resource clazz, RdfSchemaSource rss) {
Set result = new HashSet();
StatementIterator statIter = rss.getType(null, clazz);
while (statIter.hasNext()) {
result.add(statIter.next().getSubject());
}
statIter.close();
return result;
}
/**
* Compares this intersection to another object.
*
* @param other The Object to compare ths intersection to.
* @return true if this intersection is equal to the supplied object,
* false otherwise.
**/
public boolean equals(Object other) {
if (other instanceof Intersection) {
return _memberSet.equals(((Intersection)other).getMembers());
}
return false;
}
public boolean lowerEqualThan(Intersection other, RdfSchemaSource rss) {
Set set2 = other.getMembers();
// if set2 is a subset of (or equal to) _memberSet, then
// _memberSet is more (or equally) constrained and therefore a
// larger (or equal) domain/range.
if (_memberSet.containsAll(set2)) {
return true;
}
// we need to check all classes that are in set2 but not in _memberSet;
// possibly _memberSet contains subclasses of these classes.
TreeSet difference = new TreeSet(set2);
difference.removeAll(_memberSet);
Resource classResource, subClass;
org.openrdf.sesame.sail.StatementIterator subClassIter;
boolean subClassInSet;
Iterator diffIter = difference.iterator();
// for each class in the difference, a subclass has to be present
// in _memberSet.
while (diffIter.hasNext()) {
subClassInSet = false;
classResource = (Resource)diffIter.next();
subClassIter = rss.getSubClassOf(null, classResource);
// while we have not found a subclass of this class in _memberSet,
// we keep on checking.
while (!subClassInSet && subClassIter.hasNext()) {
subClass = subClassIter.next().getSubject();
if (_memberSet.contains(subClass)) {
subClassInSet = true;
}
}
if (! subClassInSet) {
// there is a class in set2 that has no subclass in _memberSet.
return false;
}
}
// all classes in set2 are also in _memberSet, or a subclass of them is
// in _memberSet.
return true;
}
public boolean greaterThan(Intersection other, RdfSchemaSource rss) {
return ! this.lowerEqualThan(other, rss);
}
public boolean greaterEqualThan(Intersection other, RdfSchemaSource rss) {
return (this.equals(other) || this.greaterThan(other, rss));
}
public boolean lowerThan(Intersection other, RdfSchemaSource rss) {
return (! this.equals(other)) && this.lowerEqualThan(other, rss);
}
/**
* Returns a hashcode for use in hash tables.
**/
public int hashCode() {
return _memberSet.hashCode();
}
public int compareTo(Object o) {
Intersection other = (Intersection)o;
int result = size() - other.size();
if (result == 0) {
// equal size
Iterator thisIter = getMembers().iterator();
Iterator otherIter = other.getMembers().iterator();
while (result == 0 && thisIter.hasNext()) {
Resource thisRes = (Resource)thisIter.next();
Resource otherRes = (Resource)otherIter.next();
result = thisRes.compareTo(otherRes);
}
}
return result;
}
/**
* Gives a String-representation of this Intersection that can be used
* for debugging.
**/
public String toString() {
return _memberSet.toString();
}
/* (non-Javadoc)
* @see org.openrdf.model.Resource#addProperty(org.openrdf.model.URI, org.openrdf.model.Value)
*/
public void addProperty(org.openrdf.model.URI property, Value value) throws GraphException {
throw new GraphException("no backing store associated");
}
/* (non-Javadoc)
* @see org.openrdf.model.Resource#getSubjectStatements()
*/
public StatementIterator getSubjectStatements() throws GraphException {
throw new GraphException("no backing store associated");
}
/* (non-Javadoc)
* @see org.openrdf.model.Value#getObjectStatements()
*/
public StatementIterator getObjectStatements() throws GraphException {
throw new GraphException("no backing store associated");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy