]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java
3243b82bd1c3aeb6be8e424ac7b907845ddaa240
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / PrettyPrintTG.java
1 package org.simantics.graph.representation;
2
3 import java.io.BufferedInputStream;
4 import java.io.DataInput;
5 import java.io.DataInputStream;
6 import java.io.InputStream;
7 import java.nio.file.Files;
8 import java.nio.file.Path;
9 import java.nio.file.Paths;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.TreeMap;
15
16 import org.simantics.databoard.binding.Binding;
17 import org.simantics.databoard.binding.mutable.Variant;
18 import org.simantics.databoard.container.DataContainers;
19 import org.simantics.databoard.type.Datatype;
20
21 import gnu.trove.list.array.TIntArrayList;
22 import gnu.trove.map.hash.TIntObjectHashMap;
23 import gnu.trove.set.hash.TLongHashSet;
24
25 /**
26  * @author Antti Villberg
27  * @since 1.24.0
28  */
29 public class PrettyPrintTG extends TransferableGraphUtils {
30
31         int blankCounter = 0;
32         
33         final StringBuilder output;
34         
35         static class ResourceInfo {
36                 final boolean hasURI;
37                 final String name;
38                 final int resource;
39                 boolean newResource = false;
40                 int owner = 0;
41                 int ownerPredicate = 0;
42                 String aliasURI = null;
43                 TIntArrayList owned = new TIntArrayList();
44                 TIntArrayList statements = new TIntArrayList();
45                 public ResourceInfo(boolean hasURI, String name, int resource) {
46                         this.hasURI = hasURI;
47                         this.name = name;
48                         this.resource = resource;
49                 }
50         }
51         
52         public PrettyPrintTG(StringBuilder b) {
53                 output = b;
54         }
55         
56         public PrettyPrintTG() {
57                 this(new StringBuilder());
58         }
59
60         TIntObjectHashMap<ResourceInfo> infos = new TIntObjectHashMap<>();
61         
62         String tgNodeName(String name) {
63                 if(name.contains(" ")) return "\"" + name + "\"";
64                 else return name;
65         }
66         
67         ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) {
68                 String name = parentName + "." + tgNodeName(getName(parent));
69                 ResourceInfo info = new ResourceInfo(true, name, parent.resource); 
70                 infos.put(parent.resource, info);
71                 for(Identity child : getChildren(graph, parent)) {
72                         recurseURI(graph, child, name);
73                 }
74                 return info;
75         }
76         
77         void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) {
78                 TIntArrayList statements = getStatements(graph, resource);
79                 for(int i=0;i<statements.size();i+=2) {
80                         int object = statements.get(i+1);
81                         Identity objectId = getIdentity(graph, object);
82                         if(objectId != null) {
83                                 if(objectId.definition instanceof External) continue;
84                         }
85                         Value value = TransferableGraphUtils.findValue(graph, object);
86                         if(value != null) {
87                                 infos.put(object, new ResourceInfo(false, printValue(value), object));
88                                 continue;
89                         }
90                         
91                         ResourceInfo existing = infos.get(object);
92                         if(existing == null) {
93                                 existing = new ResourceInfo(false, "blank" + blankCounter++, object);
94                                 infos.put(object, existing);
95                                 todo.add(object);
96                         }
97                 }
98         }
99         
100         void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
101                 int resource = info.resource;
102                 TIntArrayList statements = getStatements(graph, resource);
103                 for(int i=0;i<statements.size();i+=2) {
104                         int predicate = statements.get(i);
105                         int object = statements.get(i+1);
106                         ResourceInfo existing = infos.get(object);
107                         if(existing == null) continue;
108                         if(existing.owner == 0) {
109                                 existing.owner = resource;
110                                 existing.ownerPredicate = predicate;
111                                 //System.err.println("First owner " + info.name + " => " + predicateURI + " " + existing.name);
112                         } else {
113                                 existing.owner = -1;
114                                 //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name);
115                         }
116                 }
117                 info.statements = statements;
118         }
119         
120         String printValue(Value value) {
121                 Variant variant = value.value;
122                 Datatype dt = variant.getBinding().type();
123                 return "\"" + variant.getValue() + "\"";
124         }
125         
126         void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) {
127                 Identity id = getIdentity(graph, info.resource);
128                 if(id == null) return;
129                 if(id.definition instanceof Internal) {
130                         Identity instanceOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/InstanceOf");
131                         Identity library = findExternal(graph, "http://www.simantics.org/Layer0-1.1/Library");
132                         info.statements.add(instanceOf.resource);
133                         info.statements.add(library.resource);
134                 }
135         }
136         
137         public static String getExternalURI(TransferableGraph1 tg, External ext) {
138                 String name = ext.name;
139                 if(name.contains(" ")) name = name.replace(" ", "_").replaceAll("@", "_");//name = "\"" + name + "\"";
140                 int parentId = ext.parent;
141                 //if(parentId == 0) return ext.name;
142 //              else {
143                         Identity id = getIdentity(tg, parentId);
144                         if(id.definition instanceof External) {
145                                 return getExternalURI(tg, (External)id.definition) + "/" + name;
146                         } else if(id.definition instanceof Root) {
147                                 Root root = (Root)id.definition;
148                                 return "http:/" + root.name + "/" + name; 
149                         } else {
150                                 return null;
151                         }
152 //              }
153         }
154
155         public static String getExternalURI(TransferableGraph1 tg, int resource) {
156                 Identity id = getIdentity(tg, resource);
157                 if(id == null) return null;
158                 if(id.definition instanceof External) {
159                         External ext = (External)id.definition;
160                         return getExternalURI(tg, ext);
161                 }
162                 return null;
163         }
164         
165         String rewritePredicateURI(TransferableGraph1 graph, int predicate) {
166                 String uri = getExternalURI(graph, predicate);
167                 if(uri == null) return null;
168                 uri = uri.replace("http://www.simantics.org/Modeling-1.2", "MOD");
169                 uri = uri.replace("http://www.simantics.org/Layer0-1.1", "L0");
170                 uri = uri.replace("http://www.simantics.org/Layer0X-1.1", "L0X");
171                 uri = uri.replace("http://www.simantics.org/Diagram-2.2", "DIA");
172                 uri = uri.replace("http://www.simantics.org/Structural-1.2", "STR");
173                 uri = uri.replace("http://www.simantics.org/Documentation-1.2", "DOCU");
174                 uri = uri.replace("http://www.simantics.org/Document-1.2", "DOC");
175                 uri = uri.replace("http://www.simantics.org/G2D-1.1", "G2D");
176                 uri = uri.replace("http://www.simantics.org/Image2-1.2", "IMAGE2");
177                 uri = uri.replace("http://www.simantics.org/SelectionView-1.2", "SEL");
178                 uri = uri.replace("http://www.simantics.org/Viewpoint-1.2", "VP");
179                 uri = uri.replace("http://www.simantics.org/GraphFile-0.1", "GRAPHFILE");
180                 uri = uri.replace("http://www.semantum.fi/Simupedia-1.0", "SIMUPEDIA");
181                 uri = uri.replace("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WB");
182                 uri = uri.replace("http://www.apros.fi/OperationUI-6.6", "APROS_OPER");
183                 uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk", "SIMUPEDIA_STD");
184                 uri = uri.replace("/", ".");
185                 return uri;
186         }
187         
188         void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info) {
189                 
190                 if(info.hasURI) return;
191                 output.append("  " + predicateURI2 + " " + info.name + "\n");
192                 
193                 Value value = findValue(graph, info.resource);
194                 if(value != null) {
195                         
196                 }
197                 
198 //              for(int i=0;i<info.owned.size();i+=2) {
199 //                      String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
200 //                      ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
201 //                      if(ownedInfo == null) {
202 //                              System.err.println("null owned");
203 //                              continue;
204 //                      }
205 //                      printBlank(graph, predicateURI, ownedInfo);
206 //              }
207                 
208         }
209         
210         long longStm(int predicate, int object) {
211         return (predicate<<32) | (object & 0xffffffffL); 
212         }
213
214         void addStatement(Map<String,List<String>> statements, String predicate, String object) {
215                 List<String> objects = statements.get(predicate);
216                 if(objects == null) {
217                         objects = new ArrayList<String>();
218                         statements.put(predicate, objects);
219                 }
220                 objects.add(object);
221         }
222         
223         void printURI(TransferableGraph1 graph, ResourceInfo info) {
224                 
225                 if(!info.hasURI) return;
226                 
227                 Map<String,List<String>> statements = new HashMap<>();
228                 Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
229                 TLongHashSet processed = new TLongHashSet();
230                 for(int i=0;i<info.owned.size();i+=2) {
231                         String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
232                         ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
233                         if(ownedInfo == null) {
234                                 System.err.println("null owned");
235                                 continue;
236                         }
237                         long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
238                         processed.add(stmId);
239                         printBlank(graph, predicateURI, ownedInfo);
240                 }
241                 for(int i=0;i<info.statements.size();i+=2) {
242                         long stmId = longStm(info.statements.get(i), info.statements.get(i+1));
243                         if(processed.contains(stmId)) continue;
244                         if(consistsOf.resource == info.statements.get(i)) continue;
245                         String predicateURI = rewritePredicateURI(graph, info.statements.get(i));
246                         ResourceInfo objectInfo = infos.get(info.statements.get(i+1));
247                         if(objectInfo == null) {
248                                 String objectURI = rewritePredicateURI(graph, info.statements.get(i+1));
249                                 //output.append("  " + predicateURI + " " + objectURI + "\n");
250                                 addStatement(statements, predicateURI, objectURI);
251                         } else {
252                                 //output.append("  " + predicateURI + " " + objectInfo.name + "\n");
253                                 addStatement(statements, predicateURI, objectInfo.name);
254                         }
255                 }
256                 
257                 if("ROOT".equals(info.name)) {
258                         output.append("ROOT=<http:/>");
259                 } else if (info.aliasURI != null) {
260                         output.append(info.name + " = <" + info.aliasURI + ">");
261                 } else {
262                         output.append(info.name);
263                 }
264                 
265                 List<String> instanceOfs = statements.get("L0.InstanceOf");
266                 if(instanceOfs != null) {
267                         for(String instanceOf : instanceOfs) {
268                                 output.append(" : " + instanceOf);              
269                         }
270                 }
271
272                 List<String> subrelationOfs = statements.get("L0.SubrelationOf");
273                 if(subrelationOfs != null) {
274                         for(String subrelationOf : subrelationOfs) {
275                                 output.append(" <R " + subrelationOf);          
276                         }
277                 }
278                 
279                 List<String> inherits = statements.get("L0.Inherits");
280                 if(inherits != null) {
281                         for(String inherit : inherits) {
282                                 output.append(" <T " + inherit);                
283                         }
284                 }
285
286                 output.append("\n");
287                 
288                 if(info.newResource)
289                         output.append("  @L0.new\n");
290                 
291                 for(Map.Entry<String, List<String>> entry : statements.entrySet()) {
292                         String predicate = entry.getKey();
293                         if("L0.InstanceOf".equals(predicate)) continue;
294                         if("L0.SubrelationOf".equals(predicate)) continue;
295                         if("L0.Inherits".equals(predicate)) continue;
296                         List<String> objects = entry.getValue();
297                         if(objects.size() == 1) {
298                                 output.append("  " + predicate + " " + objects.iterator().next() + "\n");       
299                         } else{
300                                 output.append("  " + predicate + "\n"); 
301                                 for(String object : objects) {
302                                         output.append("    " + object + "\n");  
303                                 }
304                         }
305                 }
306                 
307         }
308
309         void prettyPrint(Path input, Path output) throws Exception {
310
311                 System.out.format("Converting exported shared ontology%n\t" + input.toString() + "%nto bundle-compatible ontology%n\t" + output.toString());
312                 try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128*1024)) {
313                         
314                         DataInput dis = new DataInputStream(is);
315                         org.simantics.databoard.container.DataContainer container = 
316                                         DataContainers.readFile(dis); 
317                         Binding binding = TransferableGraph1.BINDING;
318                         TransferableGraph1 graph = (TransferableGraph1)container.content.getValue(binding);
319                         prettyPrint(graph);
320                         Files.write(output, this.output.toString().getBytes());
321                         
322                 }
323
324         }
325
326         void prettyPrint(TransferableGraph1 graph) {
327         
328                         // Discover resources with URI
329 //                      for(Identity id : TransferableGraphUtils.getRoots(graph)) {
330 //                              String name = "ROOT";
331 //                              ResourceInfo info = new ResourceInfo(true, name, id.resource); 
332 //                              infos.put(id.resource, info);
333 //                              for(Identity child : getChildren(graph, id)) {
334 //                                      ResourceInfo childInfo = recurseURI(graph, child, name);
335 //                                      childInfo.newResource = true;
336 //                              }
337 //                      }
338                         for(Identity id : graph.identities) {
339                                 if(id.definition instanceof Internal) {
340                                         Internal internal = (Internal)id.definition;
341                                         Identity parent = TransferableGraphUtils.getIdentity(graph, internal.parent);
342                                         if(parent.definition instanceof External) {
343                                                 String name = "BASE";
344                                                 ResourceInfo info = new ResourceInfo(true, name, id.resource);
345                                                 info.aliasURI = TransferableGraphUtils.getURI(graph, id.resource);
346                                                 info.newResource = true;
347                                                 infos.put(id.resource, info);
348                                                 for(Identity child : getChildren(graph, id)) {
349                                                         recurseURI(graph, child, name);
350                                                 }
351                                         }
352                                 }
353                         }
354                         // Discover other resources
355                         TIntArrayList todo = new TIntArrayList();
356                         for(ResourceInfo info : infos.valueCollection())
357                                 todo.add(info.resource);
358                         while(!todo.isEmpty()) {
359                                 int resource = todo.removeAt(todo.size()-1);
360                                 discoverBlank(graph, resource, todo);
361                         }
362                         for(ResourceInfo info : infos.valueCollection())
363                                 discoverOwners(graph, info);
364                         for(ResourceInfo info : infos.valueCollection())
365                                 fixInstanceOf(graph, info);
366                         for(ResourceInfo info : infos.valueCollection())
367                                 if(info.owner > 0) {
368                                         ResourceInfo ownerInfo = infos.get(info.owner);
369                                         ownerInfo.owned.add(info.ownerPredicate);
370                                         ownerInfo.owned.add(info.resource);
371                                 } else if (info.owner == 0) {
372                                         //System.err.println("faf1");
373                                 } else if (info.owner == -1) {
374                                         //System.err.println("faf2");
375                                 }
376                         
377                         TreeMap<String,ResourceInfo> order = new TreeMap<>();
378                         for(ResourceInfo info : infos.valueCollection())
379                                 order.put(info.name, info);
380                         
381                         this.output.append("MOD = <http://www.simantics.org/Modeling-1.2>\n");
382                         this.output.append("L0 = <http://www.simantics.org/Layer0-1.1>\n");
383                         this.output.append("L0X = <http://www.simantics.org/Layer0X-1.1>\n");
384                         this.output.append("DIA = <http://www.simantics.org/Diagram-2.2>\n");
385                         this.output.append("STR = <http://www.simantics.org/Structural-1.2>\n");
386                         this.output.append("DOCU = <http://www.simantics.org/Documentation-1.2>\n");
387                         this.output.append("DOC = <http://www.simantics.org/Document-1.2>\n");
388                         this.output.append("G2D = <http://www.simantics.org/G2D-1.1>\n");
389                         this.output.append("SEL = <http://www.simantics.org/SelectionView-1.2>\n");
390                         this.output.append("VP =  <http://www.simantics.org.Viewpoint-1.2>\n");
391                         this.output.append("IMAGE2 = <http://www.simantics.org/Image2-1.2>\n");
392                         this.output.append("GRAPHFILE = <http://www.simantics.org/GraphFile-0.1>\n");
393                         this.output.append("APROS_OPER = <http://www.apros.fi/OperationUI-6.6>\n");
394                         this.output.append("SIMUPEDIA = <http://www.semantum.fi/Simupedia-1.0>\n");
395                         this.output.append("SIMUPEDIA_WB = <http://www.semantum.fi/SimupediaWorkbench-1.0>\n");
396                         this.output.append("SIMUPEDIA_STD = <http://semantum.fi/SimupediaStandardLibrary@1.3-trunk>\n");
397                         
398                         for(ResourceInfo info : order.values())
399                                 printURI(graph, info);
400                         
401         }
402         
403         public static String print(TransferableGraph1 tg) {
404                 StringBuilder b = new StringBuilder();
405                 new PrettyPrintTG(b).prettyPrint(tg);
406                 return b.toString();
407         }
408
409         public static void main(String[] args) throws Exception {
410                 if (args.length < 1) {
411                         System.out.println("Required arguments: <input .sharedOntology file> [<output .tg file>]");
412                 } else if (args.length < 2) {
413                         Path input = Paths.get(args[0]);
414                         Path output = input.getParent().resolve(input.getName(input.getNameCount()-1) + ".fixed");
415                         new PrettyPrintTG().prettyPrint(input, output);
416                 } else {
417                         new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1]));
418                 }
419         }
420
421 }