package org.openprovenance.prov.notation; import java.net.URI; import java.util.LinkedList; import java.util.List; import javax.xml.datatype.XMLGregorianCalendar; import org.antlr.runtime.tree.Tree; import org.antlr.runtime.tree.CommonTree; import org.openprovenance.prov.model.Entry; import org.openprovenance.prov.model.LangString; import org.openprovenance.prov.model.Key; import org.openprovenance.prov.model.Attribute; import org.openprovenance.prov.model.ModelConstructor; import org.openprovenance.prov.model.Name; import org.openprovenance.prov.model.Bundle; import org.openprovenance.prov.model.Namespace; import org.openprovenance.prov.model.ProvUtilities; import org.openprovenance.prov.model.ProvFactory; import org.openprovenance.prov.model.QualifiedName; import org.openprovenance.prov.model.Statement; import org.openprovenance.prov.model.ValueConverter; /* Class to traverse the syntax tree generated by antl parser, invoking constructor methods in TreeConstructor interface. */ public class TreeTraversal { final private ModelConstructor c; final private ProvFactory pFactory; final private Name name; final private ValueConverter vconv; public TreeTraversal(ModelConstructor c, ProvFactory pFactory) { this.c=c; this.pFactory=pFactory; this.name=pFactory.getName(); this.namespace=pFactory.newNamespace(); this.namespace.addKnownNamespaces(); this.vconv=new ValueConverter(pFactory); } public String getTokenString(Tree t) { if (t==null) return null; if (((CommonTree)t).getToken()==null) return null; return ((CommonTree)t).getToken().getText(); } public String convertToken(String token) { return token; } public int convertInt(String token) { return Integer.valueOf(token); } public String stripAmpersand(String token) { return token.substring(1); } public String unquoteTwice(String token) { return token.substring(2,token.length()-2); } public String unquoteTrice(String token) { return token.substring(3,token.length()-3); } public Object convert(Tree ast) { switch(ast.getType()) { /* Component 1 */ case PROV_NParser.ENTITY: QualifiedName id=(QualifiedName)convert(ast.getChild(0)); List<Attribute> eAttrs=(List<Attribute>) convert(ast.getChild(1)); return c.newEntity(id,eAttrs); case PROV_NParser.ACTIVITY: id=(QualifiedName)convert(ast.getChild(0)); XMLGregorianCalendar startTime=(XMLGregorianCalendar)convert(ast.getChild(1)); XMLGregorianCalendar endTime=(XMLGregorianCalendar)convert(ast.getChild(2)); List<Attribute> aAttrs=(List<Attribute>) convert(ast.getChild(3)); return c.newActivity(id,startTime,endTime,aAttrs); case PROV_NParser.START: case PROV_NParser.END: if (ast.getChildCount()==0) return null; if (ast.getChild(0)==null) return null; return convert (ast.getChild(0)); case PROV_NParser.USED: Tree uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } QualifiedName uid=(QualifiedName) convert(uidTree); QualifiedName id2=(QualifiedName) convert(ast.getChild(1)); QualifiedName id1=(QualifiedName) convert(ast.getChild(2)); XMLGregorianCalendar time=(XMLGregorianCalendar) convert(ast.getChild(3)); List<Attribute> rAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newUsed(uid, id2, id1,time,rAttrs); case PROV_NParser.WGB: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName) convert(uidTree); id2=(QualifiedName) convert(ast.getChild(1)); id1=(QualifiedName) convert(ast.getChild(2)); time=(XMLGregorianCalendar) convert(ast.getChild(3)); rAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newWasGeneratedBy(uid,id2,id1,time,rAttrs); case PROV_NParser.WSB: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); QualifiedName id3=(QualifiedName)convert(ast.getChild(3)); time=(XMLGregorianCalendar) convert(ast.getChild(4)); rAttrs=(List<Attribute>) convert(ast.getChild(5)); return c.newWasStartedBy(uid,id2,id1,id3,time,rAttrs); case PROV_NParser.WEB: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); id3=(QualifiedName) convert(ast.getChild(3)); time=(XMLGregorianCalendar) convert(ast.getChild(4)); rAttrs=(List<Attribute>) convert(ast.getChild(5)); return c.newWasEndedBy(uid,id2,id1,id3,time,rAttrs); case PROV_NParser.TIME: if (ast.getChildCount()==0) return null; if (ast.getChild(0)==null) return null; return pFactory.newISOTime(getTokenString(ast.getChild(0))); case PROV_NParser.WINVB: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); time=(XMLGregorianCalendar) convert(ast.getChild(3)); rAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newWasInvalidatedBy(uid,id2,id1,time,rAttrs); case PROV_NParser.WIB: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); rAttrs=(List<Attribute>) convert(ast.getChild(3)); return c.newWasInformedBy(uid,id2,id1,rAttrs); /* Component 2 */ case PROV_NParser.AGENT: id=(QualifiedName) convert(ast.getChild(0)); List<Attribute> agAttrs=(List<Attribute>) convert(ast.getChild(1)); return c.newAgent(id,agAttrs); case PROV_NParser.WAT: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); rAttrs=(List<Attribute>) convert(ast.getChild(3)); return c.newWasAttributedTo(uid,id2,id1,rAttrs); case PROV_NParser.WAW: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName) ((ast.getChild(2)==null)?null : convert(ast.getChild(2))); QualifiedName pl=(QualifiedName) ((ast.getChild(3)==null)?null : convert(ast.getChild(3))); rAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newWasAssociatedWith(uid,id2,id1,pl,rAttrs); case PROV_NParser.AOBO: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); QualifiedName a=(QualifiedName) ((ast.getChild(3)==null)?null : convert(ast.getChild(3))); rAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newActedOnBehalfOf(uid,id2,id1,a,rAttrs); /* Component 3 */ case PROV_NParser.WDF: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); QualifiedName pe=(QualifiedName) convert(ast.getChild(3)); QualifiedName q2=(QualifiedName) convert(ast.getChild(4)); QualifiedName q1=(QualifiedName) convert(ast.getChild(5)); List<Attribute> dAttrs=(List<Attribute>) convert(ast.getChild(6)); return c.newWasDerivedFrom(uid,id2,id1,pe,q2,q1,dAttrs); /* case PROV_NParser.WRO: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); pe=convert(ast.getChild(3)); q2=convert(ast.getChild(4)); q1=convert(ast.getChild(5)); dAttrs=convert(ast.getChild(6)); return c.newWasRevisionOf(uid,id2,id1,pe,q2,q1,dAttrs); case PROV_NParser.WQF: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); pe=convert(ast.getChild(3)); q2=convert(ast.getChild(4)); q1=convert(ast.getChild(5)); dAttrs=convert(ast.getChild(6)); return c.newWasQuotedFrom(uid,id2,id1,pe,q2,q1,dAttrs); case PROV_NParser.PRIMARYSOURCE: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); pe=convert(ast.getChild(3)); q2=convert(ast.getChild(4)); q1=convert(ast.getChild(5)); dAttrs=convert(ast.getChild(6)); return c.newHadPrimarySource(uid,id2,id1,pe,q2,q1,dAttrs); */ case PROV_NParser.INFL: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); dAttrs=(List<Attribute>) convert(ast.getChild(3)); return c.newWasInfluencedBy(uid,id2,id1,dAttrs); /* Component 4 */ /* Component 5 */ case PROV_NParser.ALTERNATE: id2=(QualifiedName)convert(ast.getChild(0)); id1=(QualifiedName)convert(ast.getChild(1)); return c.newAlternateOf(id2,id1); case PROV_NParser.SPECIALIZATION: id2=(QualifiedName)convert(ast.getChild(0)); id1=(QualifiedName)convert(ast.getChild(1)); return c.newSpecializationOf(id2,id1); case PROV_NParser.MEM: id2=(QualifiedName)convert(ast.getChild(0)); id1=(QualifiedName)convert(ast.getChild(1)); List<QualifiedName> ll=new LinkedList<QualifiedName>(); if (id1!=null) ll.add(id1); return c.newHadMember(id2,ll); case PROV_NParser.CTX: QualifiedName su=(QualifiedName)convert(ast.getChild(0)); QualifiedName bu=(QualifiedName)convert(ast.getChild(1)); QualifiedName ta=(QualifiedName)convert(ast.getChild(2)); return c.newMentionOf(su,bu,ta); /* Component 6 */ case PROV_NParser.DBIF: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); List<Entry> keymap=(List<Entry>)convert(ast.getChild(3)); dAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newDerivedByInsertionFrom(uid,id2,id1,keymap,dAttrs); case PROV_NParser.DBRF: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); id1=(QualifiedName)convert(ast.getChild(2)); Object keyset=convert(ast.getChild(3)); dAttrs=(List<Attribute>)convert(ast.getChild(4)); return c.newDerivedByRemovalFrom(uid,id2,id1,(List<org.openprovenance.prov.model.Key>)keyset,dAttrs); case PROV_NParser.DMEM: //uidTree=ast.getChild(0); //if (uidTree.getChildCount()>0) { // uidTree=uidTree.getChild(0); //} //uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); keymap=(List<Entry>) convert(ast.getChild(2)); //dAttrs=(List<Attribute>) convert(ast.getChild(4)); return c.newDictionaryMembership(id2,keymap); case PROV_NParser.CMEM: uidTree=ast.getChild(0); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); id2=(QualifiedName)convert(ast.getChild(1)); Object cmemEntities=convert(ast.getChild(2)); //complete=convert(ast.getChild(3)); dAttrs=(List<Attribute>) convert(ast.getChild(4)); //return c.newCollectionMemberOf(uid,id2,cmemEntities,complete,dAttrs); return null; case PROV_NParser.KEYS: List<Key> keys=new LinkedList<Key>(); for (int i=0; i< ast.getChildCount(); i++) { Object o=convert(ast.getChild(i)); if (o instanceof LangString) { keys.add(pFactory.newKey(o, name.PROV_LANG_STRING)); } else { Object [] pair=(Object[]) o; keys.add(pFactory.newKey(pair[0], (QualifiedName)pair[1])); } } return keys; case PROV_NParser.VALUES: List<Object> values=new LinkedList<Object>(); for (int i=0; i< ast.getChildCount(); i++) { Object o=convert(ast.getChild(i)); values.add(o); } return values; case PROV_NParser.KES: Object keys1=convert(ast.getChild(0)); Object entities=convert(ast.getChild(1)); @SuppressWarnings("unchecked") List<Object> keys2 = (List<Object>)keys1; @SuppressWarnings("unchecked") List<QualifiedName> qualifiedNames = (List<QualifiedName>)entities; List<Entry> entries=new LinkedList<Entry>(); int ii=0; for (Object o : keys2) { QualifiedName value=qualifiedNames.get(ii); Entry p=pFactory.newEntry((org.openprovenance.prov.model.Key)o, value); entries.add(p); ii++; } return entries; case PROV_NParser.ES: List<Object> listOfEntities=new LinkedList<Object>(); for (int i=0; i< ast.getChildCount(); i++) { Object o=convert(ast.getChild(i)); listOfEntities.add(o); } return listOfEntities; /* Component 6 */ case PROV_NParser.EXT: System.out.println("FOUND Extension " + ast); Object extName=convert(ast.getChild(0)); uidTree=ast.getChild(1); if (uidTree.getChildCount()>0) { uidTree=uidTree.getChild(0); } uid=(QualifiedName)convert(uidTree); Object optionalAttributes=convert(ast.getChild(ast.getChildCount()-1)); List<Object> args=new LinkedList<Object>(); for (int i=2; i< ast.getChildCount()-1; i++) { Object o=convert(ast.getChild(i)); args.add(o); } //return c.newExtension(extName, uid, args, optionalAttributes); return null; /* Miscellaneous Constructs */ case PROV_NParser.EXPRESSIONS: case PROV_NParser.BUNDLES: List<Object> records=new LinkedList<Object>(); for (int i=0; i< ast.getChildCount(); i++) { Object o=convert(ast.getChild(i)); records.add(o); } return records; case PROV_NParser.DOCUMENT: Namespace nss=(Namespace)convert(ast.getChild(0)); //System.out.println("+++ namespace" + nss); @SuppressWarnings("unchecked") List<Statement> records2=(List<Statement>)convert(ast.getChild(1)); List<Bundle> bundles=null; if (ast.getChild(2)!=null) { @SuppressWarnings("unchecked") List<Bundle> tmp = (List<Bundle>)convert(ast.getChild(2)); bundles=tmp; } return c.newDocument(nss,records2, bundles); case PROV_NParser.BUNDLE: Namespace localNamespace=pFactory.newNamespace(); localNamespace.addKnownNamespaces(); localNamespace.setParent(namespace); // make the local namespace to become the current namespace namespace=localNamespace; convert(ast.getChild(1)); // parse bundleId after namespace declarations QualifiedName bundleId=(QualifiedName) convert(ast.getChild(0)); //c.startBundle(bundleId); @SuppressWarnings("unchecked") List<Statement> records3=(List<Statement>)convert(ast.getChild(2)); //restore the parent namespace namespace=localNamespace.getParent(); return c.newNamedBundle(bundleId,localNamespace,records3); case PROV_NParser.ATTRIBUTES: List<Attribute> attributes=new LinkedList<Attribute>(); for (int i=0; i< ast.getChildCount(); i++) { attributes.add((Attribute)convert(ast.getChild(i))); } return attributes; case PROV_NParser.ID: return stringToQualifiedName(convertToken(getTokenString(ast.getChild(0)))); case PROV_NParser.ATTRIBUTE: String attr1=convertToken(getTokenString(ast.getChild(0))); Object val1=convert(ast.getChild(1)); if (val1 instanceof Object[]) { Object [] values2=(Object[])val1; Object theValue=values2[0]; QualifiedName theType=(QualifiedName)values2[1]; return pFactory.newAttribute(stringToQualifiedName(attr1), theValue, theType); } else if (val1 instanceof LangString) { return pFactory.newAttribute(stringToQualifiedName(attr1), val1, name.PROV_LANG_STRING); } else if (val1 instanceof Integer) { return pFactory.newAttribute(stringToQualifiedName(attr1), val1, name.XSD_INT); } else if (val1 instanceof String) { return pFactory.newAttribute(stringToQualifiedName(attr1), val1, name.XSD_STRING); } else { System.out.println("****** " + val1); // TODO what case is it? System.out.println("****** " + val1.getClass()); return pFactory.newAttribute(stringToQualifiedName(attr1), val1, name.XSD_STRING); } case PROV_NParser.STRING: if (ast.getChildCount()==1) { return unescape(unwrap(convertToken(getTokenString(ast.getChild(0))))); } else { return pFactory.newInternationalizedString(unescape(unwrap(convertToken(getTokenString(ast.getChild(0))))), stripAmpersand(convertToken(getTokenString(ast.getChild(1))))); } case PROV_NParser.STRING_LONG: if (ast.getChildCount()==1) { return unescape(unquoteTrice(convertToken(getTokenString(ast.getChild(0))))); } else { return pFactory.newInternationalizedString(unescape(unquoteTrice(convertToken(getTokenString(ast.getChild(0))))), stripAmpersand(convertToken(getTokenString(ast.getChild(1))))); } case PROV_NParser.INT: return convertInt(getTokenString(ast.getChild(0))); case PROV_NParser.QNAM: return stringToQualifiedName(convertToken(getTokenString(ast.getChild(0)))); case PROV_NParser.IRI: String iri=convertToken(getTokenString(ast.getChild(0))); return URI.create(unwrap(iri)); case PROV_NParser.TYPEDLITERAL: String typedLiteral_string=convertToken(getTokenString(ast.getChild(0))); QualifiedName typedLiteral_datatype; Tree tree_datatype=ast.getChild(1); if (tree_datatype==null) { typedLiteral_datatype=name.PROV_QUALIFIED_NAME; return convertTypedLiteral(typedLiteral_string,typedLiteral_datatype); } else { typedLiteral_datatype=(QualifiedName)convert(tree_datatype); Tree tree_langtag=ast.getChild(2); if (tree_langtag!=null) { LangString lstring=pFactory.newInternationalizedString(unescape(unwrap(typedLiteral_string)), stripAmpersand(convertToken(getTokenString(tree_langtag)))); return convertTypedLiteral(lstring,name.PROV_LANG_STRING); } else { typedLiteral_string=unescape(unwrap(typedLiteral_string)); return convertTypedLiteral(typedLiteral_string,typedLiteral_datatype); } } case PROV_NParser.NAMESPACE: String pre=(String)convert(ast.getChild(0)); String iri1=unwrap(getTokenString(ast.getChild(1))); if (pre!=null) { // should not occur namespace.register(pre, iri1); } return null; case PROV_NParser.DEFAULTNAMESPACE: iri1=unwrap(getTokenString(ast.getChild(0))); namespace.registerDefault(iri1); return null; case PROV_NParser.PREFIX: String prefix=getTokenString(ast.getChild(0)); return prefix; case PROV_NParser.NAMESPACES: for (int i=0; i< ast.getChildCount(); i++) { Object o=convert(ast.getChild(i)); } return namespace; case PROV_NParser.TRUE: return true; case PROV_NParser.FALSE: return false; case PROV_NParser.UNKNOWN: return null; } return null; } private QualifiedName stringToQualifiedName(String attr1) { return namespace.stringToQualifiedName(attr1,pFactory); } private String unescape(String s) { return ProvUtilities.unescape(s); } Namespace namespace; public Object convertTypedLiteral(String literal, QualifiedName datatype) { Object value=literal; if (datatype.equals(name.PROV_QUALIFIED_NAME)) value = stringToQualifiedName(literal); Object [] valueTypePair=new Object[] {value,datatype}; return valueTypePair; } public Object convertTypedLiteral(LangString literal, QualifiedName datatype) { Object value=literal; if (datatype.equals(name.PROV_QUALIFIED_NAME)) { // I could throw an exception since this doesn't make sense, LangString literal cannot go with QUALIFIED_NAME datatype } Object [] valueTypePair=new Object[] {value,datatype}; return valueTypePair; } public String unwrap (String s) { return s.substring(1,s.length()-1); } }