package org.openprovenance.prov.template;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.openprovenance.prov.model.Attribute;
import org.openprovenance.prov.model.Bundle;
import org.openprovenance.prov.model.ProvFactory;
import org.openprovenance.prov.model.QualifiedName;
import org.openprovenance.prov.model.Statement;
import org.openprovenance.prov.model.StatementOrBundle.Kind;
import org.openprovenance.prov.model.TypedValue;
import org.openprovenance.prov.model.exception.InvalidCaseException;
import org.openprovenance.prov.model.ProvUtilities;
public class ExpandUtil {
static Logger logger = Logger.getLogger(ExpandUtil.class);
public static final String VAR_NS = "http://openprovenance.org/var#";
public static final String VARGEN_NS = "http://openprovenance.org/vargen#";
public static final String TMPL_NS = "http://openprovenance.org/tmpl#";
public static final String TMPL_PREFIX = "tmpl";
public static final String VAR_PREFIX = "var";
public static final String VARGEN_PREFIX = "vargen";
public static final String LINKED = "linked";
public static final String LINKED_URI = TMPL_NS + LINKED;
public static final String LABEL = "label";
public static final String TIME = "time";
public static final String STARTTIME = "startTime";
public static final String ENDTIME = "endTime";
public static final String LABEL_URI = TMPL_NS + LABEL;
public static final String TIME_URI = TMPL_NS + TIME;
public static final String STARTTIME_URI = TMPL_NS + STARTTIME;
public static final String ENDTIME_URI = TMPL_NS + ENDTIME;
//private final ProvFactory pf;
static ProvUtilities u = new ProvUtilities();
static public int getFirstTimeIndex(Statement s) {
final Kind kind = s.getKind();
switch (kind) {
case PROV_ACTIVITY: return 1;
case PROV_AGENT: return 1;
case PROV_ALTERNATE: return 2;
case PROV_ASSOCIATION: return 4;
case PROV_ATTRIBUTION: return 3;
case PROV_BUNDLE:
throw new InvalidCaseException("ProvUtilities.getFirstTimeIndex() for " + kind);
case PROV_COMMUNICATION: return 3;
case PROV_DELEGATION: return 4;
case PROV_DERIVATION: return 6;
case PROV_DICTIONARY_INSERTION:
throw new InvalidCaseException("ProvUtilities.getFirstTimeIndex() for " + kind);
case PROV_DICTIONARY_MEMBERSHIP:
throw new InvalidCaseException("ProvUtilities.getFirstTimeIndex() for " + kind);
case PROV_DICTIONARY_REMOVAL:
throw new InvalidCaseException("ProvUtilities.getFirstTimeIndex() for " + kind);
case PROV_END: return 4;
case PROV_ENTITY: return 1;
case PROV_GENERATION: return 3;
case PROV_INFLUENCE: return 3;
case PROV_INVALIDATION: return 3;
case PROV_MEMBERSHIP: return 2;
case PROV_MENTION: return 3;
case PROV_SPECIALIZATION: return 2;
case PROV_START: return 4;
case PROV_USAGE: return 3;
default:
throw new InvalidCaseException("ProvUtilities.getFirstTimeIndex() for " + kind);
}
}
static public Set<QualifiedName> freeVariables(Statement statement) {
HashSet<QualifiedName> result = new HashSet<QualifiedName>();
for (int i = 0; i < getFirstTimeIndex(statement); i++) {
Object o = u.getter(statement, i);
if (o instanceof QualifiedName) {
QualifiedName name = (QualifiedName) o;
if (name != null && isVariable(name))
result.add(name);
} else {
if (o instanceof List) {
List<QualifiedName> ll = (List<QualifiedName>) o;
for (QualifiedName name : ll) {
if (name != null && isVariable(name))
result.add(name);
}
}
}
}
return result;
}
static public Set<QualifiedName> freeVariables(Bundle statement) {
HashSet<QualifiedName> result = new HashSet<QualifiedName>();
QualifiedName name = statement.getId();
if (name != null && isVariable(name)) {
result.add(name);
}
return result;
}
static public HashSet<QualifiedName> freeAttributeVariables(Statement statement, ProvFactory pf) {
HashSet<QualifiedName> result = new HashSet<QualifiedName>();
Collection<Attribute> ll = pf.getAttributes(statement);
for (Attribute attr : ll) {
if (pf.getName().PROV_QUALIFIED_NAME.equals(attr.getType())) {
Object o = attr.getValue();
if (o instanceof QualifiedName) { // if attribute is constructed
// properly, this test should
// always return true
QualifiedName qn = (QualifiedName) o;
if (isVariable(qn))
result.add(qn);
}
}
}
return result;
}
public static Using usedGroups(Statement statement, Groupings groupings, Bindings bindings) {
Set<QualifiedName> vars = freeVariables(statement);
Set<Integer> groups = new HashSet<Integer>();
for (QualifiedName var : vars) {
for (int grp = 0; grp < groupings.size(); grp++) {
List<QualifiedName> names = groupings.get(grp);
if (names.contains(var)) {
groups.add(grp);
}
}
}
Using u = new Using();
Integer[] sorted = groups.toArray(new Integer[0]);
Arrays.sort(sorted);
for (Integer g : sorted) {
List<QualifiedName> vs = groupings.get(g);
QualifiedName qn = vs.get(0);
List<QualifiedName> vals = bindings.getVariables().get(qn);
if (vals != null) {
u.addGroup(g, vals.size());
} else {
if (isGensymVariable(qn)) {
u.addGroup(g, 1); // uuid to be generated for this gensym
// variable
} else {
List<List<TypedValue>> attrs = bindings.getAttributes().get(vs.get(0));
if (attrs != null) {
u.addGroup(g, attrs.size());
}
}
}
}
return u;
}
static public boolean isVariable(QualifiedName id) {
if (id == null)
return false;
final String namespaceURI = id.getNamespaceURI();
return (VAR_NS.equals(namespaceURI) || VARGEN_NS.equals(namespaceURI));
}
static public boolean isGensymVariable(QualifiedName id) {
if (id == null)
return false;
final String namespaceURI = id.getNamespaceURI();
return VARGEN_NS.equals(namespaceURI);
}
}