]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java
Merge branch 'feature/funcwrite'
[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.TreeMap;
11
12 import org.simantics.databoard.binding.Binding;
13 import org.simantics.databoard.container.DataContainers;
14
15 import gnu.trove.list.array.TIntArrayList;
16 import gnu.trove.map.hash.TIntObjectHashMap;
17 import gnu.trove.set.hash.TLongHashSet;
18
19 /**
20  * @author Antti Villberg
21  * @since 1.24.0
22  */
23 public class PrettyPrintTG extends TransferableGraphUtils {
24
25         int blankCounter = 0;
26         
27         StringBuilder output = new StringBuilder();
28         
29         static class ResourceInfo {
30                 final boolean hasURI;
31                 final String name;
32                 final int resource;
33                 boolean newResource = false;
34                 int owner = 0;
35                 int ownerPredicate = 0;
36                 TIntArrayList owned = new TIntArrayList();
37                 TIntArrayList statements = new TIntArrayList();
38                 public ResourceInfo(boolean hasURI, String name, int resource) {
39                         this.hasURI = hasURI;
40                         this.name = name;
41                         this.resource = resource;
42                 }
43         }
44         
45         TIntObjectHashMap<ResourceInfo> infos = new TIntObjectHashMap<>();
46         
47         ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) {
48                 String name = parentName + ".\"" + getName(parent) + "\"";
49                 ResourceInfo info = new ResourceInfo(true, name, parent.resource); 
50                 infos.put(parent.resource, info);
51                 for(Identity child : getChildren(graph, parent)) {
52                         recurseURI(graph, child, name);
53                 }
54                 return info;
55         }
56         
57         void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) {
58                 TIntArrayList statements = getStatements(graph, resource);
59                 for(int i=0;i<statements.size();i+=2) {
60                         int object = statements.get(i+1);
61                         Identity objectId = getIdentity(graph, object);
62                         if(objectId != null) {
63                                 if(objectId.definition instanceof External) continue;
64                         }
65                         ResourceInfo existing = infos.get(object);
66                         if(existing == null) {
67                                 existing = new ResourceInfo(false, "blank" + blankCounter++, object);
68                                 infos.put(object, existing);
69                                 todo.add(object);
70                         }
71                 }
72         }
73         
74         void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
75                 int resource = info.resource;
76                 TIntArrayList statements = getStatements(graph, resource);
77                 for(int i=0;i<statements.size();i+=2) {
78                         int predicate = statements.get(i);
79                         int object = statements.get(i+1);
80                         ResourceInfo existing = infos.get(object);
81                         if(existing == null) continue;
82                         if(existing.owner == 0) {
83                                 existing.owner = resource;
84                                 existing.ownerPredicate = predicate;
85                                 //System.err.println("First owner " + info.name + " => " + predicateURI + " " + existing.name);
86                         } else {
87                                 existing.owner = -1;
88                                 //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name);
89                         }
90                 }
91                 info.statements = statements;
92         }
93         
94         void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) {
95                 Identity id = getIdentity(graph, info.resource);
96                 if(id == null) return;
97                 if(id.definition instanceof Internal) {
98                         Identity instanceOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/InstanceOf");
99                         Identity library = findExternal(graph, "http://www.simantics.org/Layer0-1.1/Library");
100                         info.statements.add(instanceOf.resource);
101                         info.statements.add(library.resource);
102                 }
103         }
104         
105         public static String getExternalURI(TransferableGraph1 tg, External ext) {
106                 String name = ext.name;
107                 if(name.contains(" ")) name = name.replace(" ", "_").replaceAll("@", "_");//name = "\"" + name + "\"";
108                 int parentId = ext.parent;
109                 if(parentId == 0) return ext.name;
110                 else {
111                         Identity id = getIdentity(tg, parentId);
112                         if(id.definition instanceof External) {
113                                 return getExternalURI(tg, (External)id.definition) + "/" + name;
114                         } else if(id.definition instanceof Root) {
115                                 Root root = (Root)id.definition;
116                                 return "http:/" + root.name + "/" + name; 
117                         } else {
118                                 return null;
119                         }
120                 }
121         }
122
123         public static String getExternalURI(TransferableGraph1 tg, int resource) {
124                 Identity id = getIdentity(tg, resource);
125                 if(id == null) return null;
126                 if(id.definition instanceof External) {
127                         External ext = (External)id.definition;
128                         return getExternalURI(tg, ext);
129                 }
130                 return null;
131         }
132         
133         String rewritePredicateURI(TransferableGraph1 graph, int predicate) {
134                 String uri = getExternalURI(graph, predicate);
135                 if(uri == null) return null;
136                 uri = uri.replace("http://www.simantics.org/Modeling-1.2", "MOD");
137                 uri = uri.replace("http://www.simantics.org/Layer0-1.1", "L0");
138                 uri = uri.replace("http://www.simantics.org/Layer0X-1.1", "L0X");
139                 uri = uri.replace("http://www.simantics.org/Diagram-2.2", "DIA");
140                 uri = uri.replace("http://www.simantics.org/Structural-1.2", "STR");
141                 uri = uri.replace("http://www.simantics.org/Documentation-1.2", "DOCU");
142                 uri = uri.replace("http://www.simantics.org/Document-1.2", "DOC");
143                 uri = uri.replace("http://www.simantics.org/G2D-1.1", "G2D");
144                 uri = uri.replace("http://www.simantics.org/Image2-1.2", "IMAGE2");
145                 uri = uri.replace("http://www.simantics.org/SelectionView-1.2", "SEL");
146                 uri = uri.replace("http://www.simantics.org/GraphFile-0.1", "GRAPHFILE");
147                 uri = uri.replace("http://www.semantum.fi/Simupedia-1.0", "SIMUPEDIA");
148                 uri = uri.replace("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WB");
149                 uri = uri.replace("http://www.apros.fi/OperationUI-6.6", "APROS_OPER");
150                 uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk", "SIMUPEDIA_STD");
151                 uri = uri.replace("/", ".");
152                 return uri;
153         }
154         
155         void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info) {
156                 
157                 if(info.hasURI) return;
158                 output.append("  " + predicateURI2 + " " + info.name + "\n");
159                 
160                 Value value = findValue(graph, info.resource);
161                 if(value != null) {
162                         
163                 }
164                 
165 //              for(int i=0;i<info.owned.size();i+=2) {
166 //                      String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
167 //                      ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
168 //                      if(ownedInfo == null) {
169 //                              System.err.println("null owned");
170 //                              continue;
171 //                      }
172 //                      printBlank(graph, predicateURI, ownedInfo);
173 //              }
174                 
175         }
176         
177         long longStm(int predicate, int object) {
178         return (predicate<<32) | (object & 0xffffffffL); 
179         }
180         
181         void printURI(TransferableGraph1 graph, ResourceInfo info) {
182                 if(!info.hasURI) return;
183                 if("ROOT".equals(info.name)) {
184                         output.append("ROOT=<http:/>\n");
185                 } else {
186                         output.append(info.name + "\n");
187                 }
188                 if(info.newResource)
189                         output.append("  @L0.new\n");
190                 TLongHashSet processed = new TLongHashSet();
191                 for(int i=0;i<info.owned.size();i+=2) {
192                         String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
193                         ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
194                         if(ownedInfo == null) {
195                                 System.err.println("null owned");
196                                 continue;
197                         }
198                         long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
199                         processed.add(stmId);
200                         printBlank(graph, predicateURI, ownedInfo);
201                 }
202                 Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
203                 for(int i=0;i<info.statements.size();i+=2) {
204                         long stmId = longStm(info.statements.get(i), info.statements.get(i+1));
205                         if(processed.contains(stmId)) continue;
206                         if(consistsOf.resource == info.statements.get(i)) continue;
207                         String predicateURI = rewritePredicateURI(graph, info.statements.get(i));
208                         ResourceInfo objectInfo = infos.get(info.statements.get(i+1));
209                         if(objectInfo == null) {
210                                 String objectURI = rewritePredicateURI(graph, info.statements.get(i+1));
211                                 output.append("  " + predicateURI + " " + objectURI + "\n");
212                         } else {
213                                 output.append("  " + predicateURI + " " + objectInfo.name + "\n");
214                         }
215                 }
216         }
217
218         void prettyPrint(Path input, Path output) throws Exception {
219                 System.out.format("Converting exported shared ontology%n\t" + input.toString() + "%nto bundle-compatible ontology%n\t" + output.toString());
220                 try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128*1024)) {
221                         DataInput dis = new DataInputStream(is);
222                         org.simantics.databoard.container.DataContainer container = 
223                                         DataContainers.readFile(dis); 
224                         Binding binding = TransferableGraph1.BINDING;
225                         TransferableGraph1 graph = (TransferableGraph1)container.content.getValue(binding);
226                         // Discover resources with URI
227                         for(Identity id : TransferableGraphUtils.getRoots(graph)) {
228                                 String name = "ROOT";
229                                 ResourceInfo info = new ResourceInfo(true, name, id.resource); 
230                                 infos.put(id.resource, info);
231                                 for(Identity child : getChildren(graph, id)) {
232                                         ResourceInfo childInfo = recurseURI(graph, child, name);
233                                         childInfo.newResource = true;
234                                 }
235                         }
236                         // Discover other resources
237                         TIntArrayList todo = new TIntArrayList();
238                         for(ResourceInfo info : infos.valueCollection())
239                                 todo.add(info.resource);
240                         while(!todo.isEmpty()) {
241                                 int resource = todo.removeAt(todo.size()-1);
242                                 discoverBlank(graph, resource, todo);
243                         }
244                         for(ResourceInfo info : infos.valueCollection())
245                                 discoverOwners(graph, info);
246                         for(ResourceInfo info : infos.valueCollection())
247                                 fixInstanceOf(graph, info);
248                         for(ResourceInfo info : infos.valueCollection())
249                                 if(info.owner > 0) {
250                                         ResourceInfo ownerInfo = infos.get(info.owner);
251                                         ownerInfo.owned.add(info.ownerPredicate);
252                                         ownerInfo.owned.add(info.resource);
253                                 } else if (info.owner == 0) {
254                                         //System.err.println("faf1");
255                                 } else if (info.owner == -1) {
256                                         //System.err.println("faf2");
257                                 }
258                         
259                         TreeMap<String,ResourceInfo> order = new TreeMap<>();
260                         for(ResourceInfo info : infos.valueCollection())
261                                 order.put(info.name, info);
262                         
263                         this.output.append("MOD = <http://www.simantics.org/Modeling-1.2>\n");
264                         this.output.append("L0 = <http://www.simantics.org/Layer0-1.1>\n");
265                         this.output.append("L0X = <http://www.simantics.org/Layer0X-1.1>\n");
266                         this.output.append("DIA = <http://www.simantics.org/Diagram-2.2>\n");
267                         this.output.append("STR = <http://www.simantics.org/Structural-1.2>\n");
268                         this.output.append("DOCU = <http://www.simantics.org/Documentation-1.2>\n");
269                         this.output.append("DOC = <http://www.simantics.org/Document-1.2>\n");
270                         this.output.append("G2D = <http://www.simantics.org/G2D-1.1>\n");
271                         this.output.append("SEL = <http://www.simantics.org/SelectionView-1.2>\n");
272                         this.output.append("IMAGE2 = <http://www.simantics.org/Image2-1.2>\n");
273                         this.output.append("GRAPHFILE = <http://www.simantics.org/GraphFile-0.1>\n");
274                         this.output.append("APROS_OPER = <http://www.apros.fi/OperationUI-6.6>\n");
275                         this.output.append("SIMUPEDIA = <http://www.semantum.fi/Simupedia-1.0>\n");
276                         this.output.append("SIMUPEDIA_WB = <http://www.semantum.fi/SimupediaWorkbench-1.0>\n");
277                         this.output.append("SIMUPEDIA_STD = <http://semantum.fi/SimupediaStandardLibrary@1.3-trunk>\n");
278                         
279 //                      uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk/", "SIMUPEDIA_STD.");
280
281                         
282                         for(ResourceInfo info : order.values())
283                                 printURI(graph, info);
284                         
285                         Files.write(output, this.output.toString().getBytes());
286                                 
287                 }
288         }
289
290         public static void main(String[] args) throws Exception {
291                 if (args.length < 1) {
292                         System.out.println("Required arguments: <input .sharedOntology file> [<output .tg file>]");
293                 } else if (args.length < 2) {
294                         Path input = Paths.get(args[0]);
295                         Path output = input.getParent().resolve(input.getName(input.getNameCount()-1) + ".fixed");
296                         new PrettyPrintTG().prettyPrint(input, output);
297                 } else {
298                         new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1]));
299                 }
300         }
301
302 }