com.bigdata.gom.gpo.LinkSet Maven / Gradle / Ivy
package com.bigdata.gom.gpo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.query.BindingSet;
import com.bigdata.gom.om.IObjectManager;
import com.bigdata.gom.om.ObjectMgrModel;
import cutthecrap.utils.striterators.EmptyIterator;
import cutthecrap.utils.striterators.ICloseableIterator;
/**
* A (forward or reverse) link set.
*
* @author Martyn
* Cutcher
* @author Bryan Thompson
*
* FIXME We should materialize the link set unless the cardinality is
* excessive. This applies in both the forward and reverse direction. We
* will need a means to obtain a "DESCRIBE" of a resource (complete set
* of attributes, forward, and reverse links) and a "SKETCH" of a
* resource (cardinality counts only when a forward or reverse link set
* is large and otherwise they are inlined as well into the sketch).
*/
public class LinkSet implements ILinkSet {
/**
* The {@link IGPO} that is the head of the link set.
*/
private final IGPO m_owner;
/**
* The predicate that collects this link set.
*/
private final URI m_linkProperty;
/**
* true
iff this is a reverse link set.
*/
private final boolean m_linksIn;
/**
*
* @param owner
* The {@link IGPO} that is the head of the link set.
* @param linkProperty
* The predicate that collects this link set.
* @param linksIn
* true
iff this is a reverse link set.
*/
public LinkSet(final IGPO owner, final URI linkProperty,
final boolean linksIn) {
if (owner == null)
throw new IllegalArgumentException();
if (linkProperty == null)
throw new IllegalArgumentException();
m_owner = owner;
m_linkProperty = linkProperty;
m_linksIn = linksIn;
}
@Override
public URI getLinkProperty() {
return m_linkProperty;
}
@Override
public IGPO getOwner() {
return m_owner;
}
@Override
public boolean isLinkSetIn() {
return m_linksIn;
}
@Override
public Iterator iterator(Class theClassOrInterface) {
// TODO Auto-generated method stub
return null;
}
@Override
public int size() {
final GPO.GPOEntry entry;
if (m_linksIn) {
entry = ((GPO) m_owner).getLinkEntry(m_linkProperty);
} else {
entry = ((GPO) m_owner).getEntry(m_linkProperty);
}
return entry == null ? 0 : entry.size();
}
@Override
public long sizeLong() {
return size();
}
@Override
public boolean add(IGPO arg) {
if (arg == null) {
throw new IllegalArgumentException();
}
if (m_linksIn) {
arg.addValue(m_linkProperty, m_owner.getId());
} else {
m_owner.addValue(m_linkProperty, arg.getId());
}
return true;
}
@Override
public boolean addAll(Collection extends IGPO> arg) {
if (arg == null) {
throw new IllegalArgumentException();
}
for (IGPO mem : arg)
add(mem);
return true;
}
@Override
public void clear() {
// TODO Auto-generated method stub
}
@Override
public boolean contains(Object arg) {
if (!(arg instanceof IGPO)) {
throw new IllegalArgumentException("IGPO required");
}
IGPO gpo = (IGPO) arg;
// since linkSet is fully materialized, just run through it
Iterator values = iterator();
while (values.hasNext()) {
if (values.next() == gpo)
return true;
}
return false;
}
@Override
public boolean containsAll(Collection> arg0) {
// TODO Auto-generated method stub
return false;
}
/*
* @see #size()
*/
@Override
public boolean isEmpty() {
// Not sufficient to check for null GPOEntry - items could have been removed
return size() == 0;
}
/**
* Encode a URL, Literal, or blank node for inclusion in a SPARQL query to
* be sent to the remote service.
*
* @param v
* The resource.
*
* @return The encoded representation of the resource.
*
* @see ObjectMgrModel#encode(Resource)
*/
public String encode(final Resource v) {
return ((GPO) m_owner).encode(v);
}
@Override
public Iterator iterator() {
if (false) {
/*
* Links in is not materialized.
*
* TODO It should be fully materialized when the cardinality is not
* excessive.
*/
final IObjectManager om = m_owner.getObjectManager();
final String query = "SELECT ?x\n" //
+ "WHERE {\n"//
+ " ?x <"+ encode(m_linkProperty) + "> <" + encode(m_owner.getId())+ ">\n"//
+"}";//
final ICloseableIterator res = om.evaluate(query);
return new Iterator() {
@Override
public boolean hasNext() {
return res != null && res.hasNext();
}
@Override
public IGPO next() {
final BindingSet bs = res.next();
return om.getGPO((Resource) bs.getBinding("x").getValue());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
} else {
/*
* Both Links in AND Links out are fully materialized on the gpo with DESCRIBE.
*/
final GPO.GPOEntry entry;
if (m_linksIn) {
entry = ((GPO) m_owner).getLinkEntry(m_linkProperty);
} else {
entry = ((GPO) m_owner).getEntry(m_linkProperty);
}
if (entry == null) {
return new EmptyIterator();
}
return new Iterator() {
final Iterator m_values = entry.values();
IGPO nextGPO = nextGPO();
private IGPO nextGPO() {
while (m_values.hasNext()) {
final Value val = m_values.next();
if (val instanceof Resource) {
return m_owner.getObjectManager().getGPO((Resource) val);
}
}
return null;
}
@Override
public boolean hasNext() {
return nextGPO != null;
}
@Override
public IGPO next() {
if (nextGPO == null)
throw new NoSuchElementException();
final IGPO ret = nextGPO;
nextGPO = nextGPO();
return ret;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
@Override
public boolean remove(Object obj) {
if (!(obj instanceof IGPO)) {
throw new IllegalArgumentException("Expected an instance of IGPO");
}
final IGPO gpo = (IGPO) obj;
final boolean ret;
if (m_linksIn) {
gpo.removeValue(m_linkProperty, m_owner.getId());
} else {
m_owner.removeValue(m_linkProperty, gpo.getId());
}
return true;
}
@Override
public boolean removeAll(Collection> arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean retainAll(Collection> arg0) {
// TODO Auto-generated method stub
return false;
}
/**
* Eagerly streams materialized objects into an array
*/
@Override
public Object[] toArray() {
final ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy