X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2FGraphUnparser.java;fp=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2FGraphUnparser.java;h=07bdd61a1d230d3ae2413b06c52929a0e07d83b6;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java new file mode 100644 index 000000000..07bdd61a1 --- /dev/null +++ b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java @@ -0,0 +1,312 @@ +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(); + } +}