package org.simantics.graph.compiler; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntIntHashMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.set.hash.TIntHashSet; import java.util.ArrayList; import java.util.Collection; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.parser.unparsing.DataTypePrinter; import org.simantics.databoard.type.Datatype; import org.simantics.graph.query.CompositeGraph; import org.simantics.graph.query.IGraph; import org.simantics.graph.query.Path; import org.simantics.graph.query.Paths; import org.simantics.graph.query.Res; import org.simantics.graph.query.TransferableGraphConversion; import org.simantics.graph.query.UriUtils; import org.simantics.graph.representation.External; import org.simantics.graph.representation.Identity; import org.simantics.graph.representation.Internal; import org.simantics.graph.representation.LocalStatement; import org.simantics.graph.representation.Optional; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.graph.representation.Value; import org.simantics.graph.store.GraphStore; import org.simantics.graph.store.IStatementProcedure; public class GraphUnparser { IGraph graph; GraphStore store; StringBuilder b = new StringBuilder(); GraphUnparser(IGraph graph, GraphStore store) { this.graph = graph; this.store = store; } ArrayList uriRes = new ArrayList(); TIntHashSet blankResources = new TIntHashSet(); TIntObjectHashMap refNames = new TIntObjectHashMap(); TIntHashSet parentNameUsed = new TIntHashSet(); TIntObjectHashMap parentNames = new TIntObjectHashMap(); TIntHashSet activeResources = new TIntHashSet(); // Resources that have statements TIntObjectHashMap> localStatements = new TIntObjectHashMap>(); TIntObjectHashMap uris = new TIntObjectHashMap(); TIntObjectHashMap literals = new TIntObjectHashMap(); int SimanticsDomain; int Layer0; int Inherits; int InstanceOf; int DataType; int SubrelationOf; void handleIdentity(Identity id) { int resource = id.resource; int parent; String name; if(id.definition instanceof External) { External def = (External)id.definition; parent = def.parent; name = def.name; } else if(id.definition instanceof Internal) { Internal def = (Internal)id.definition; parent = def.parent; name = def.name; } else if(id.definition instanceof Optional) { Optional def = (Optional)id.definition; parent = def.parent; name = def.name; } else return; uris.put(id.resource, uris.get(parent) + "/" + name); if(isIdentifier(name)) { if(parentNames.containsKey(parent)) { refNames.put(resource, parentNames.get(parent) + "." + name); parentNameUsed.add(parent); } else refNames.put(resource, "<" + uris.get(resource) + ">"); parentNames.put(resource, name); } else { refNames.put(resource, "<" + uris.get(resource) + ">"); String[] parts = name.split("-"); if(isIdentifier(parts[0])) parentNames.put(resource, parts[0]); } if(activeResources.remove(resource)) { uriRes.add(id); } if(parent == 0) { if(name.equals("www.simantics.org")) SimanticsDomain = resource; } else if(parent == SimanticsDomain) { if(name.equals("Layer0-1.0")) { Layer0 = resource; parentNames.put(resource, "L0"); } } else if(parent == Layer0) { if(name.equals("InstanceOf")) InstanceOf = resource; else if(name.equals("Inherits")) Inherits = resource; else if(name.equals("SubrelationOf")) SubrelationOf = resource; else if(name.equals("DataType")) DataType = resource; } } void run() { final TIntIntHashMap refCount = new TIntIntHashMap(); store.statements.forStatements(new IStatementProcedure() { @Override public void execute(int s, int p, int o) { ArrayList localStatement; if(activeResources.add(s)) { localStatement = new ArrayList(2); localStatements.put(s, localStatement); } else localStatement = localStatements.get(s); refCount.adjustOrPutValue(p, 1, 1); refCount.adjustOrPutValue(o, 1, 1); localStatement.add(new LocalStatement(p, o)); } }); Paths paths = new Paths("1.0"); // Uris uris.put(0, "http:/"); for(Identity id : store.identities.toArray()) handleIdentity(id); /*Collections.sort(uriRes, new Comparator() { @Override public int compare(Identity arg0, Identity arg1) { int diff = arg0.parent - arg1.parent; if(diff != 0) return diff; return arg0.name.compareTo(arg1.name); } });*/ // Literals Path dataTypeRes = UriUtils.uriToPath("http://www.simantics.org/Layer0-1.0/DataType"); for(Value value : store.values.toArray()) { if(graph != null) { Res res = store.idToRes(value.resource); if(graph.rawGetObjects(res, paths.InstanceOf).contains(dataTypeRes)) { Binding b = Bindings.getBindingUnchecked(Datatype.class); try { Datatype dt = (Datatype)value.value.getValue(b); literals.put(value.resource, "@" + DataTypePrinter.toString(dt, false)); continue; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { Datatype dt = graph.getDatatype(res); if(dt != null) { Binding b = Bindings.getBinding(dt); try { Object obj = value.value.getValue(b); literals.put(value.resource, b.toString(obj)); continue; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { literals.put(value.resource, "<" + value.value + ">"); } } } } // Blank resources for(int id : activeResources.toArray()) if(refCount.get(id) == 1) { activeResources.remove(id); blankResources.add(id); } int tempId = 0; TIntArrayList otherResources = new TIntArrayList(); for(int id : activeResources.toArray()) { refNames.put(id, "r" + (++tempId)); otherResources.add(id); } for(Identity uriRe : uriRes) describeResource(0, uriRe.resource); for(int id : otherResources.toArray()) describeResource(0, id); } private void indent(int indentation) { for(int i=0;i others = new ArrayList(); for(LocalStatement stat : localStatements.get(resource)) { if(!blankResources.contains(stat.object) && (stat.predicate == InstanceOf || stat.predicate == Inherits || stat.predicate == SubrelationOf)) { b.append(' '); refPredicate(stat.predicate); b.append(' '); refResource(stat.object); } else others.add(stat); } b.append('\n'); for(LocalStatement stat : others) { indent(indentation+1); refPredicate(stat.predicate); b.append(" "); describeObject(indentation+1, stat.object); } } private void describeObject(int indentation, int resource) { if(blankResources.contains(resource)) describeResource(indentation, resource); else { refResource(resource); b.append('\n'); } } private void refPredicate(int resource) { if(resource == InstanceOf) b.append(":"); else if(resource == Inherits) b.append(" dependencies) { CompositeGraph cg = TransferableGraphConversion.convert(paths, dependencies); GraphStore store = TransferableGraphConversion.convert(tg); cg.addFragment(store); GraphUnparser gu = new GraphUnparser(cg, store); gu.run(); return gu.toString(); } }