package org.openprovenance.prov.template; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; import java.util.HashMap; import java.util.List; import java.util.LinkedList; import java.util.Map.Entry; import org.openprovenance.prov.model.Namespace; import org.openprovenance.prov.model.ProvFactory; import org.openprovenance.prov.model.QualifiedName; import org.openprovenance.prov.model.LangString; import org.openprovenance.prov.model.NamespacePrefixMapper; import org.openprovenance.prov.model.TypedValue; import org.openprovenance.prov.model.exception.UncheckedException; import com.fasterxml.jackson.databind.ObjectMapper; public class BindingsJson { // public static ProvFactory pf=new org.openprovenance.prov.scala.immutable.ProvFactory(); public static class BindingsBean { public Hashtable<String, List<Object>> var; public Hashtable<String, List<Object>> vargen; public Hashtable<String, String> context; } public static Object convertValueToBean(Object o, QualifiedName type, Hashtable<String, String> context) { if (o instanceof Integer) return o; if (o instanceof Float) return o; if (o instanceof QualifiedName) { QualifiedName qn=(QualifiedName)o; Hashtable<String,String> table=new Hashtable<String,String>(); table.put("@id",qn.getPrefix() + ":" + qn.getLocalPart()); context.put(qn.getPrefix(),qn.getNamespaceURI()); return table; } if (o instanceof LangString) { LangString qn=(LangString)o; Hashtable<String,String> table=new Hashtable<String,String>(); table.put("@language",qn.getLang()); table.put("@value",qn.getValue()); return table; } if (o instanceof String) { if ((type==null) || (type.getUri().equals(NamespacePrefixMapper.XSD_NS+"string"))) { return o; } else { Hashtable<String,String> table=new Hashtable<String,String>(); table.put("@type",type.toString()); table.put("@value",o.toString()); return table; } } throw new UnsupportedOperationException("type is " + o); } public static Object[] convertBeanToValue(Object v, Hashtable<String, String> context, Namespace ns, ProvFactory pf) { if (v instanceof Integer) return new Object[] {v , pf.getName().XSD_INT}; if (v instanceof Float) return new Object[] {v , pf.getName().XSD_FLOAT}; if (v instanceof QualifiedName) return new Object[] {v , pf.getName().PROV_QUALIFIED_NAME}; if (v instanceof String) { String s=(String)v; if (s.startsWith("{")) { ObjectMapper mapper = new ObjectMapper(); try { v=mapper.readValue((String)v,Hashtable.class); } catch (Exception e) { e.printStackTrace(); } } else { return new Object[] {v , pf.getName().XSD_STRING}; } } if (v instanceof HashMap) { HashMap<String,String> table=(HashMap<String,String>)v; String lang =table.get("@language"); String value=table.get("@value"); String type =table.get("@type"); String id =table.get("@id"); if (lang!=null) { return new Object[]{pf.newInternationalizedString(value,lang),pf.getName().XSD_STRING}; } if (id!=null) { return new Object[]{ns.stringToQualifiedName(id,pf),pf.getName().PROV_QUALIFIED_NAME}; } return new Object[] {value , pf.newQualifiedName("xa","xb","cx")}; } throw new UnsupportedOperationException("bean is " + v.getClass()); } public static BindingsBean toBean(Bindings bindings) { BindingsBean bean=new BindingsBean(); bean.var=new Hashtable<String,List<Object>>(); bean.vargen=new Hashtable<String,List<Object>>(); bean.context=new Hashtable<String,String>(); for (Entry<QualifiedName,List<List<TypedValue>>> entry: bindings.getAttributes().entrySet()) { List<Object> l1=new LinkedList<Object>(); for (List<TypedValue> ll: entry.getValue()) { if (ll.size()==1) { l1.add(convertValueToBean(ll.get(0).getValue(), ll.get(0).getType(), bean.context)); } else { List<Object> l2=new LinkedList<Object>(); for (TypedValue tv:ll) { l2.add(convertValueToBean(tv.getValue(), tv.getType(), bean.context)); } l1.add(l2); } } if (entry.getKey().getNamespaceURI().startsWith(ExpandUtil.VARGEN_NS)) { bean.vargen.put(entry.getKey().getLocalPart(),l1); } else { bean.var.put(entry.getKey().getLocalPart(),l1); } } return bean; } public static Bindings fromBean(BindingsBean bean, ProvFactory pf) { Bindings result=new Bindings(pf); Namespace ns=new Namespace(bean.context); for (Entry<String,List<Object>> bindings: bean.var.entrySet()) { String var=bindings.getKey(); int i=0; List<List<TypedValue>> allvalues= new LinkedList<List<TypedValue>>(); boolean single_value=true; for (Object value: bindings.getValue()) { List<Object> wrapped; if (!(value instanceof List)) { wrapped=new LinkedList<Object>(); wrapped.add(value); } else { wrapped=(List<Object>) value; single_value=false; } int count=0; List<TypedValue> values= new LinkedList<TypedValue>(); for (Object o: wrapped) { Object[] conversion=convertBeanToValue(o,bean.context, ns, pf); Object theValue=conversion[0]; QualifiedName type=(QualifiedName)conversion[1]; if (!(type.equals(pf.getName().PROV_QUALIFIED_NAME))) single_value=false; // interested only in qualified names values.add(pf.newAttribute(ExpandUtil.TMPL_NS, Bindings.VALUE2+i+"_"+count, ExpandUtil.TMPL_PREFIX, theValue, type)); count++; } //System.out.println("Adding values " + values + " to allvalues " + allvalues); allvalues.add(values); i++; } QualifiedName myvar=pf.newQualifiedName(ExpandUtil.VAR_NS,var,"var"); result.getAttributes().put(myvar,allvalues); if (single_value) { List<QualifiedName> ll=new LinkedList<QualifiedName>(); for (Object o: bindings.getValue()) { Object[] conversion=convertBeanToValue(o,bean.context, ns, pf); Object theValue=conversion[0]; Object type=conversion[1]; //System.out.println("Found " + theValue + " " + type); ll.add((QualifiedName) theValue); } result.getVariables().put(myvar,ll); } } return result; } public static void exportBean(String output_file1, BindingsBean bean, boolean pretty) { ObjectMapper mapper = new ObjectMapper(); try { if (pretty) { mapper.writerWithDefaultPrettyPrinter().writeValue(new File(output_file1), bean); } else { mapper.writeValue(new File(output_file1), bean); } } catch (IOException e) { e.printStackTrace(); throw new UncheckedException("JSON serialization failed", e); } } public static BindingsBean importBean(File input_file1) { ObjectMapper mapper = new ObjectMapper(); try { BindingsBean bean=mapper.readValue(input_file1,BindingsBean.class); return bean; } catch (IOException e) { e.printStackTrace(); throw new UncheckedException("JSON serialization failed", e); } } public static BindingsBean importBean(InputStream input_file1) { ObjectMapper mapper = new ObjectMapper(); try { BindingsBean bean=mapper.readValue(input_file1,BindingsBean.class); return bean; } catch (IOException e) { e.printStackTrace(); throw new UncheckedException("JSON serialization failed", e); } } }