package edu.mit.simile.fresnel.results;
import java.util.HashMap;
import java.util.Iterator;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import edu.mit.simile.fresnel.util.WrappedVector;
/**
* Set of PropertyResults.
*
* @author ryanlee
*/
public class PropertyResultSet extends WrappedVector<PropertyResult> {
/**
* Maps property URIs to their corresponding PropertyResults
*/
private HashMap<InvertableURI, PropertyResult> _used;
/**
* Initialize a set.
*/
public PropertyResultSet() {
super();
this._used = new HashMap<InvertableURI, PropertyResult>();
}
/**
* Returns a PropertyResultIterator instead of a normal iterator.
*
* @return A <code>PropertyResultIterator</code>
*/
public Iterator<PropertyResult> propertyResultIterator() {
return this._base.iterator();
}
/**
* Adds a property result to the existing set.
*
* @param property A <code>PropertyResult</code>
* @return Success or failure
*/
public boolean addPropertyResult(PropertyResult property, Result parent) {
this._used.put(new InvertableURI(property.getOrigin(), property.isInverse()), property);
return this._base.add(property);
}
/**
* Removes a property result from the existing set.
*
* @param property A <code>PropertyResult</code>
* @return Success or failure
*/
public boolean removePropertyResult(PropertyResult property) {
this._used.remove(property);
return this._base.remove(property);
}
/**
* Add all elements from a property result set into this one.
*
* @param arg0 A <code>PropertyResultSet</code>
* @return Success or failure
*/
public boolean addPropertyResultSet(PropertyResultSet arg0) {
for(Iterator<PropertyResult> it = arg0.propertyResultIterator(); it.hasNext() ;) {
PropertyResult pr = it.next();
this._used.put(new InvertableURI(pr.getOrigin(), pr.isInverse()), pr);
}
return this._base.addAll(arg0._base);
}
/**
* Replace WrappedVector contains method to do specific <code>PropertyResult</code>
* equality checking.
*
* @param property The <code>PropertyResult</code> component to check
* @return True if contained in set, false if not.
*/
public boolean contains(PropertyResult property) {
for (Iterator<PropertyResult> it = this.propertyResultIterator(); it.hasNext(); ) {
if (property.equals(it.next())) return true;
}
return false;
}
/**
* Checks if this set contains a property URI and return its PropertyResult if so.
*
* @param prop The property <code>URI</code> to lookup
* @return Corresponding <code>PropertyResult</code> or null if non-existent.
*
* @author Christian Becker
*/
public PropertyResult lookup(URI prop, boolean inverse) {
if (this._used.containsKey(new InvertableURI(prop, inverse))) {
return (PropertyResult) this._used.get(new InvertableURI(prop, inverse));
} else {
return null;
}
}
/**
* Checks if this set contains a property URI and return its PropertyResult if so.
*
* @param prop The property <code>URI</code> to lookup
* @return Corresponding <code>PropertyResult</code> or null if non-existent.
*
* @author Christian Becker
*/
public PropertyResult lookup(URI prop) {
return lookup(prop, false);
}
/**
* Permits properties to be inverted. An inverse property where the focal resource acts as the RDF object.
* @author Christian Becker
*/
private class InvertableURI {
private Resource uri;
private boolean inverse;
public InvertableURI(Resource uri, boolean inverse) {
this.uri = uri;
this.inverse = inverse;
}
@Override
public boolean equals(Object obj) {
return (obj instanceof InvertableURI
&& ((InvertableURI)obj).getUri().equals(getUri())
&& ((InvertableURI)obj).isInverse() == isInverse());
}
public Resource getUri() {
return uri;
}
public boolean isInverse() {
return inverse;
}
@Override
public int hashCode() {
return uri.toString().hashCode() * (inverse ? -1 : 1);
}
}
}