--- /dev/null
+package org.simantics.graph.representation;
+
+import java.io.BufferedInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.TreeMap;
+
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.container.DataContainers;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.hash.TLongHashSet;
+
+/**
+ * @author Antti Villberg
+ * @since 1.24.0
+ */
+public class PrettyPrintTG extends TransferableGraphUtils {
+
+ int blankCounter = 0;
+
+ StringBuilder output = new StringBuilder();
+
+ static class ResourceInfo {
+ final boolean hasURI;
+ final String name;
+ final int resource;
+ boolean newResource = false;
+ int owner = 0;
+ int ownerPredicate = 0;
+ TIntArrayList owned = new TIntArrayList();
+ TIntArrayList statements = new TIntArrayList();
+ public ResourceInfo(boolean hasURI, String name, int resource) {
+ this.hasURI = hasURI;
+ this.name = name;
+ this.resource = resource;
+ }
+ }
+
+ TIntObjectHashMap<ResourceInfo> infos = new TIntObjectHashMap<>();
+
+ ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) {
+ String name = parentName + ".\"" + getName(parent) + "\"";
+ ResourceInfo info = new ResourceInfo(true, name, parent.resource);
+ infos.put(parent.resource, info);
+ for(Identity child : getChildren(graph, parent)) {
+ recurseURI(graph, child, name);
+ }
+ return info;
+ }
+
+ void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) {
+ TIntArrayList statements = getStatements(graph, resource);
+ for(int i=0;i<statements.size();i+=2) {
+ int object = statements.get(i+1);
+ Identity objectId = getIdentity(graph, object);
+ if(objectId != null) {
+ if(objectId.definition instanceof External) continue;
+ }
+ ResourceInfo existing = infos.get(object);
+ if(existing == null) {
+ existing = new ResourceInfo(false, "blank" + blankCounter++, object);
+ infos.put(object, existing);
+ todo.add(object);
+ }
+ }
+ }
+
+ void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
+ int resource = info.resource;
+ TIntArrayList statements = getStatements(graph, resource);
+ for(int i=0;i<statements.size();i+=2) {
+ int predicate = statements.get(i);
+ int object = statements.get(i+1);
+ ResourceInfo existing = infos.get(object);
+ if(existing == null) continue;
+ if(existing.owner == 0) {
+ existing.owner = resource;
+ existing.ownerPredicate = predicate;
+ //System.err.println("First owner " + info.name + " => " + predicateURI + " " + existing.name);
+ } else {
+ existing.owner = -1;
+ //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);
+ }
+ }
+
+ 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;
+ }
+ }
+ }
+
+ public static String getExternalURI(TransferableGraph1 tg, int resource) {
+ Identity id = getIdentity(tg, resource);
+ if(id == null) return null;
+ if(id.definition instanceof External) {
+ External ext = (External)id.definition;
+ return getExternalURI(tg, ext);
+ }
+ 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");
+ uri = uri.replace("/", ".");
+ return uri;
+ }
+
+ void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info) {
+
+ if(info.hasURI) return;
+ output.append(" " + predicateURI2 + " " + info.name + "\n");
+
+ Value value = findValue(graph, info.resource);
+ if(value != null) {
+
+ }
+
+// for(int i=0;i<info.owned.size();i+=2) {
+// String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
+// ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
+// if(ownedInfo == null) {
+// System.err.println("null owned");
+// continue;
+// }
+// printBlank(graph, predicateURI, ownedInfo);
+// }
+
+ }
+
+ long longStm(int predicate, int object) {
+ return (predicate<<32) | (object & 0xffffffffL);
+ }
+
+ void printURI(TransferableGraph1 graph, ResourceInfo info) {
+ if(!info.hasURI) return;
+ if("ROOT".equals(info.name)) {
+ output.append("ROOT=<http:/>\n");
+ } else {
+ output.append(info.name + "\n");
+ }
+ if(info.newResource)
+ output.append(" @L0.new\n");
+ TLongHashSet processed = new TLongHashSet();
+ for(int i=0;i<info.owned.size();i+=2) {
+ String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
+ ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
+ if(ownedInfo == null) {
+ System.err.println("null owned");
+ continue;
+ }
+ long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
+ processed.add(stmId);
+ printBlank(graph, predicateURI, ownedInfo);
+ }
+ Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ for(int i=0;i<info.statements.size();i+=2) {
+ long stmId = longStm(info.statements.get(i), info.statements.get(i+1));
+ if(processed.contains(stmId)) continue;
+ if(consistsOf.resource == info.statements.get(i)) continue;
+ String predicateURI = rewritePredicateURI(graph, info.statements.get(i));
+ ResourceInfo objectInfo = infos.get(info.statements.get(i+1));
+ if(objectInfo == null) {
+ String objectURI = rewritePredicateURI(graph, info.statements.get(i+1));
+ output.append(" " + predicateURI + " " + objectURI + "\n");
+ } else {
+ output.append(" " + predicateURI + " " + objectInfo.name + "\n");
+ }
+ }
+ }
+
+ void prettyPrint(Path input, Path output) throws Exception {
+ System.out.format("Converting exported shared ontology%n\t" + input.toString() + "%nto bundle-compatible ontology%n\t" + output.toString());
+ try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128*1024)) {
+ DataInput dis = new DataInputStream(is);
+ org.simantics.databoard.container.DataContainer container =
+ DataContainers.readFile(dis);
+ Binding binding = TransferableGraph1.BINDING;
+ TransferableGraph1 graph = (TransferableGraph1)container.content.getValue(binding);
+ // Discover resources with URI
+ for(Identity id : TransferableGraphUtils.getRoots(graph)) {
+ String name = "ROOT";
+ ResourceInfo info = new ResourceInfo(true, name, id.resource);
+ infos.put(id.resource, info);
+ for(Identity child : getChildren(graph, id)) {
+ ResourceInfo childInfo = recurseURI(graph, child, name);
+ childInfo.newResource = true;
+ }
+ }
+ // 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");
+ }
+
+ TreeMap<String,ResourceInfo> order = new TreeMap<>();
+ for(ResourceInfo info : infos.valueCollection())
+ order.put(info.name, info);
+
+ this.output.append("MOD = <http://www.simantics.org/Modeling-1.2>\n");
+ this.output.append("L0 = <http://www.simantics.org/Layer0-1.1>\n");
+ this.output.append("L0X = <http://www.simantics.org/Layer0X-1.1>\n");
+ this.output.append("DIA = <http://www.simantics.org/Diagram-2.2>\n");
+ this.output.append("STR = <http://www.simantics.org/Structural-1.2>\n");
+ this.output.append("DOCU = <http://www.simantics.org/Documentation-1.2>\n");
+ this.output.append("DOC = <http://www.simantics.org/Document-1.2>\n");
+ this.output.append("G2D = <http://www.simantics.org/G2D-1.1>\n");
+ this.output.append("SEL = <http://www.simantics.org/SelectionView-1.2>\n");
+ this.output.append("IMAGE2 = <http://www.simantics.org/Image2-1.2>\n");
+ this.output.append("GRAPHFILE = <http://www.simantics.org/GraphFile-0.1>\n");
+ this.output.append("APROS_OPER = <http://www.apros.fi/OperationUI-6.6>\n");
+ this.output.append("SIMUPEDIA = <http://www.semantum.fi/Simupedia-1.0>\n");
+ this.output.append("SIMUPEDIA_WB = <http://www.semantum.fi/SimupediaWorkbench-1.0>\n");
+ this.output.append("SIMUPEDIA_STD = <http://semantum.fi/SimupediaStandardLibrary@1.3-trunk>\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());
+
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ System.out.println("Required arguments: <input .sharedOntology file> [<output .tg file>]");
+ } else if (args.length < 2) {
+ Path input = Paths.get(args[0]);
+ Path output = input.getParent().resolve(input.getName(input.getNameCount()-1) + ".fixed");
+ new PrettyPrintTG().prettyPrint(input, output);
+ } else {
+ new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1]));
+ }
+ }
+
+}