X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Frepresentation%2FPrettyPrintTG.java;h=00d17100ec461bb5800a63e93e1b40175d90a204;hb=527940f032d9dd8ebd4c7bd202356115f1715120;hp=5968b6822e35a122fac68158119151783247c4d8;hpb=9acebe9584f8f2a78f0322b6e0e24438e7ceb984;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java index 5968b6822..00d17100e 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java @@ -4,13 +4,26 @@ import java.io.BufferedInputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.InputStream; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.container.DataContainers; +import org.simantics.databoard.type.Datatype; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntObjectHashMap; @@ -23,29 +36,51 @@ import gnu.trove.set.hash.TLongHashSet; public class PrettyPrintTG extends TransferableGraphUtils { int blankCounter = 0; - - StringBuilder output = new StringBuilder(); - + MessageDigest m; + + private final Pattern versionExtractPattern = Pattern.compile("^.*-(\\d+\\.\\d+)"); + + final StringBuilder output; + final Map ontologies = new HashMap<>(knownOntologies); + final Set referencedOntologies = new TreeSet<>(); + static class ResourceInfo { final boolean hasURI; final String name; final int resource; boolean newResource = false; - int owner = 0; + + // -1 = no owner, -2 = multiple owners + int owner = -1; int ownerPredicate = 0; + String aliasURI = null; TIntArrayList owned = new TIntArrayList(); - TIntArrayList statements = new TIntArrayList(); + //TIntObjectHashMap statements = new TIntObjectHashMap(); public ResourceInfo(boolean hasURI, String name, int resource) { this.hasURI = hasURI; this.name = name; this.resource = resource; } } - + + public PrettyPrintTG(StringBuilder b) throws NoSuchAlgorithmException { + output = b; + m = MessageDigest.getInstance("SHA-256"); + } + + public PrettyPrintTG() throws NoSuchAlgorithmException { + this(new StringBuilder()); + } + TIntObjectHashMap infos = new TIntObjectHashMap<>(); - + + String tgNodeName(String name) { + if(name.contains(" ")) return "\"" + name + "\""; + else return name; + } + ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) { - String name = parentName + ".\"" + getName(parent) + "\""; + String name = parentName + "." + tgNodeName(getName(parent)); ResourceInfo info = new ResourceInfo(true, name, parent.resource); infos.put(parent.resource, info); for(Identity child : getChildren(graph, parent)) { @@ -53,8 +88,8 @@ public class PrettyPrintTG extends TransferableGraphUtils { } return info; } - - void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) { + + void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) throws Exception { TIntArrayList statements = getStatements(graph, resource); for(int i=0;i " + predicateURI + " " + existing.name); } else { - existing.owner = -1; + existing.owner = -2; //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name); } } - info.statements = statements; + } - - void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) { - Identity id = getIdentity(graph, info.resource); - if(id == null) return; - if(id.definition instanceof Internal) { - Identity instanceOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/InstanceOf"); - Identity library = findExternal(graph, "http://www.simantics.org/Layer0-1.1/Library"); - info.statements.add(instanceOf.resource); - info.statements.add(library.resource); + + String printValue(Value value) throws Exception { + Variant variant = value.value; + Datatype dt = variant.getBinding().type(); + if(Datatypes.STRING.equals(dt)) { + String s = (String)variant.getValue(Bindings.STRING); + if(s.contains("\n")) { + return "\"\"\"" + s + "\"\"\""; + } else { + return "\"" + s + "\""; + } + } else if(Datatypes.BOOLEAN.equals(dt)) { + Boolean i = (Boolean)variant.getValue(Bindings.BOOLEAN); + return i ? "true" : "false"; + } else if(Datatypes.INTEGER.equals(dt)) { + Integer i = (Integer)variant.getValue(Bindings.INTEGER); + return i.toString(); + } else if(Datatypes.LONG.equals(dt)) { + Long i = (Long)variant.getValue(Bindings.LONG); + return i.toString(); + } else { + byte[] data = variant.getBinding().serializer().serialize(variant.getValue()); + m.reset(); + m.update(data, 0, data.length); + return "\"" + new BigInteger(1, m.digest()).toString(16) + "\""; } + } - + + // void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) { + // Identity id = getIdentity(graph, info.resource); + // if(id == null) return; + // if(id.definition instanceof Internal) { + // Identity instanceOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/InstanceOf"); + // Identity library = findExternal(graph, "http://www.simantics.org/Layer0-1.1/Library"); + // info.statements.add(instanceOf.resource); + // info.statements.add(library.resource); + // } + // } + public static String getExternalURI(TransferableGraph1 tg, External ext) { String name = ext.name; if(name.contains(" ")) name = name.replace(" ", "_").replaceAll("@", "_");//name = "\"" + name + "\""; int parentId = ext.parent; - if(parentId == 0) return ext.name; - else { - Identity id = getIdentity(tg, parentId); - if(id.definition instanceof External) { - return getExternalURI(tg, (External)id.definition) + "/" + name; - } else if(id.definition instanceof Root) { - Root root = (Root)id.definition; - return "http:/" + root.name + "/" + name; - } else { - return null; - } + //if(parentId == 0) return ext.name; + // else { + Identity id = getIdentity(tg, parentId); + if(id.definition instanceof External) { + return getExternalURI(tg, (External)id.definition) + "/" + name; + } else if(id.definition instanceof Root) { + Root root = (Root)id.definition; + return "http:/" + root.name + "/" + name; + } else { + return null; } + // } } public static String getExternalURI(TransferableGraph1 tg, int resource) { @@ -129,93 +197,148 @@ public class PrettyPrintTG extends TransferableGraphUtils { } return null; } - + String rewritePredicateURI(TransferableGraph1 graph, int predicate) { + String uri = getExternalURI(graph, predicate); - if(uri == null) return null; - uri = uri.replace("http://www.simantics.org/Modeling-1.2", "MOD"); - uri = uri.replace("http://www.simantics.org/Layer0-1.1", "L0"); - uri = uri.replace("http://www.simantics.org/Layer0X-1.1", "L0X"); - uri = uri.replace("http://www.simantics.org/Diagram-2.2", "DIA"); - uri = uri.replace("http://www.simantics.org/Structural-1.2", "STR"); - uri = uri.replace("http://www.simantics.org/Documentation-1.2", "DOCU"); - uri = uri.replace("http://www.simantics.org/Document-1.2", "DOC"); - uri = uri.replace("http://www.simantics.org/G2D-1.1", "G2D"); - uri = uri.replace("http://www.simantics.org/Image2-1.2", "IMAGE2"); - uri = uri.replace("http://www.simantics.org/SelectionView-1.2", "SEL"); - uri = uri.replace("http://www.simantics.org/GraphFile-0.1", "GRAPHFILE"); - uri = uri.replace("http://www.semantum.fi/Simupedia-1.0", "SIMUPEDIA"); - uri = uri.replace("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WB"); - uri = uri.replace("http://www.apros.fi/OperationUI-6.6", "APROS_OPER"); - uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk", "SIMUPEDIA_STD"); + if(uri == null) { + ResourceInfo info = infos.get(predicate); + if(info != null) return info.name; + return "_"; + } + + for(String ontology : ontologies.keySet()) { + if(uri.contains(ontology)) { + String key = ontologies.get(ontology); + uri = uri.replace(ontology, key); + referencedOntologies.add(ontology); + } + } + uri = uri.replace("/", "."); + return uri; + + } + + void indent(int indent) { + for(int i=0;i\n"); - } else { - output.append(info.name + "\n"); + + void addStatement(Map> statements, String predicate, String object) { + Set objects = statements.get(predicate); + if(objects == null) { + objects = new TreeSet<>(); + statements.put(predicate, objects); } - if(info.newResource) - output.append(" @L0.new\n"); + objects.add(object); + } + + void printURI(TransferableGraph1 graph, ResourceInfo info, boolean requireURI, int indent) { + + if(requireURI && !info.hasURI) return; + + Map> statements = new TreeMap<>(); + Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf"); TLongHashSet processed = new TLongHashSet(); for(int i=0;i"); + } else if (info.aliasURI != null) { + output.append(info.name + " = <" + info.aliasURI + ">"); } else { - output.append(" " + predicateURI + " " + objectInfo.name + "\n"); + output.append(info.name); + } + Set instanceOfs = statements.get("L0.InstanceOf"); + if(instanceOfs != null) { + for(String instanceOf : instanceOfs) { + output.append(" : " + instanceOf); + } } + Set subrelationOfs = statements.get("L0.SubrelationOf"); + if(subrelationOfs != null) { + for(String subrelationOf : subrelationOfs) { + output.append(" inherits = statements.get("L0.Inherits"); + if(inherits != null) { + for(String inherit : inherits) { + output.append(" > entry : statements.entrySet()) { + String predicate = entry.getKey(); + if("L0.InstanceOf".equals(predicate)) continue; + if("L0.SubrelationOf".equals(predicate)) continue; + if("L0.Inherits".equals(predicate)) continue; + if("L0.PartOf".equals(predicate)) continue; + Set objects = entry.getValue(); + if(objects.size() == 1) { + indent(indent+1); + output.append(predicate + " " + objects.iterator().next() + "\n"); + } else{ + indent(indent+1); + output.append(predicate + "\n"); + for(String object : objects) { + indent(indent+1); + output.append(" " + object + "\n"); + } + } + } + + for(int i=0;i knownOntologies = new HashMap<>(); + + static { + knownOntologies.put("http://www.simantics.org/Layer0-1.1", "L0"); + knownOntologies.put("http://www.simantics.org/Layer0X-1.1", "L0X"); + knownOntologies.put("http://www.simantics.org/Modeling-1.2", "MOD"); + knownOntologies.put("http://www.simantics.org/Diagram-2.2", "DIA"); + knownOntologies.put("http://www.simantics.org/Structural-1.2", "STR"); + knownOntologies.put("http://www.simantics.org/Document-1.2", "DOC"); + knownOntologies.put("http://www.simantics.org/Documentation-1.2", "DOCU"); + knownOntologies.put("http://www.simantics.org/G2D-1.1", "G2D"); + knownOntologies.put("http://www.simantics.org/SelectionView-1.2", "SEL"); + knownOntologies.put("http://www.simantics.org/Viewpoint-1.2", "VP"); + knownOntologies.put("http://www.simantics.org/Image2-1.2", "IMAGE2"); + knownOntologies.put("http://www.simantics.org/GraphFile-0.1", "GRAPHFILE"); + knownOntologies.put("http://www.simantics.org/Project-1.2", "PROJECT"); + knownOntologies.put("http://www.semantum.fi/Simupedia-1.0", "SIMUPEDIA"); + knownOntologies.put("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WORKBENCH"); + } + + + void prettyPrint(TransferableGraph1 graph) throws Exception { + + for(Identity id : graph.identities) { + if(id.definition instanceof Internal) { + Internal internal = (Internal)id.definition; + Identity parent = TransferableGraphUtils.getIdentity(graph, internal.parent); + if(parent.definition instanceof External) { + String name = "BASE"; + ResourceInfo info = new ResourceInfo(true, name, id.resource); + info.aliasURI = TransferableGraphUtils.getURI(graph, id.resource); + info.newResource = true; + infos.put(id.resource, info); + for(Identity child : getChildren(graph, id)) { + recurseURI(graph, child, name); + } } - } - // Discover other resources - TIntArrayList todo = new TIntArrayList(); - for(ResourceInfo info : infos.valueCollection()) - todo.add(info.resource); - while(!todo.isEmpty()) { - int resource = todo.removeAt(todo.size()-1); - discoverBlank(graph, resource, todo); - } - for(ResourceInfo info : infos.valueCollection()) - discoverOwners(graph, info); - for(ResourceInfo info : infos.valueCollection()) - fixInstanceOf(graph, info); - for(ResourceInfo info : infos.valueCollection()) - if(info.owner > 0) { - ResourceInfo ownerInfo = infos.get(info.owner); - ownerInfo.owned.add(info.ownerPredicate); - ownerInfo.owned.add(info.resource); - } else if (info.owner == 0) { - //System.err.println("faf1"); - } else if (info.owner == -1) { - //System.err.println("faf2"); + } else if (id.definition instanceof External) { + External ext = (External)id.definition; + // Try to detect shared libraries + if(ext.name.contains("@")) { + + int index = ext.name.indexOf('@'); + String prefix = ext.name.substring(0, index); + int index2 = ext.name.indexOf('/', index); + String ontology = index2 == -1 ? ext.name : ext.name.substring(0, index2); + String uri = TransferableGraphUtils.getURI(graph, id.resource); + ontologies.put(uri, prefix); + + } else if (ext.name.contains("-")) { + + String uri = TransferableGraphUtils.getURI(graph, id.resource); + Matcher m = versionExtractPattern.matcher(uri); + if (m.matches()) { + if(!ontologies.containsKey(uri)) { + int index = ext.name.indexOf('-'); + String prefix = ext.name.substring(0, index); + ontologies.put(uri, prefix); + } + } + } - - TreeMap order = new TreeMap<>(); - for(ResourceInfo info : infos.valueCollection()) - order.put(info.name, info); - - this.output.append("MOD = \n"); - this.output.append("L0 = \n"); - this.output.append("L0X = \n"); - this.output.append("DIA = \n"); - this.output.append("STR = \n"); - this.output.append("DOCU = \n"); - this.output.append("DOC = \n"); - this.output.append("G2D = \n"); - this.output.append("SEL = \n"); - this.output.append("IMAGE2 = \n"); - this.output.append("GRAPHFILE = \n"); - this.output.append("APROS_OPER = \n"); - this.output.append("SIMUPEDIA = \n"); - this.output.append("SIMUPEDIA_WB = \n"); - this.output.append("SIMUPEDIA_STD = \n"); - -// uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk/", "SIMUPEDIA_STD."); - - - for(ResourceInfo info : order.values()) - printURI(graph, info); - - Files.write(output, this.output.toString().getBytes()); + + + } + } + // Discover other resources + TIntArrayList todo = new TIntArrayList(); + for(ResourceInfo info : infos.valueCollection()) + todo.add(info.resource); + while(!todo.isEmpty()) { + int resource = todo.removeAt(todo.size()-1); + discoverBlank(graph, resource, todo); } + for(ResourceInfo info : infos.valueCollection()) + discoverOwners(graph, info); + // for(ResourceInfo info : infos.valueCollection()) + // fixInstanceOf(graph, info); + for(ResourceInfo info : infos.valueCollection()) + if(info.owner >= 0) { + ResourceInfo ownerInfo = infos.get(info.owner); + ownerInfo.owned.add(info.ownerPredicate); + ownerInfo.owned.add(info.resource); + } + + TreeMap order = new TreeMap<>(); + for(ResourceInfo info : infos.valueCollection()) + order.put(info.name, info); + + for(ResourceInfo info : order.values()) + printURI(graph, info, true, 0); + + for(ResourceInfo info : order.values()) + if(!info.hasURI && info.owner < 0) + printURI(graph, info, false, 0); + + StringBuilder refs = new StringBuilder(); + for(String ontology : referencedOntologies) { + String key = ontologies.get(ontology); + refs.append(key + " = <" + ontology + ">\n"); + } + output.insert(0, refs.toString()); + + } + + public static String print(TransferableGraph1 tg) throws Exception { + StringBuilder b = new StringBuilder(); + new PrettyPrintTG(b).prettyPrint(tg); + return b.toString(); } public static void main(String[] args) throws Exception {