1 package org.simantics.graph.representation;
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;
12 import org.simantics.databoard.binding.Binding;
13 import org.simantics.databoard.container.DataContainers;
15 import gnu.trove.list.array.TIntArrayList;
16 import gnu.trove.map.hash.TIntObjectHashMap;
17 import gnu.trove.set.hash.TLongHashSet;
20 * @author Antti Villberg
23 public class PrettyPrintTG extends TransferableGraphUtils {
27 StringBuilder output = new StringBuilder();
29 static class ResourceInfo {
33 boolean newResource = false;
35 int ownerPredicate = 0;
36 TIntArrayList owned = new TIntArrayList();
37 TIntArrayList statements = new TIntArrayList();
38 public ResourceInfo(boolean hasURI, String name, int resource) {
41 this.resource = resource;
45 TIntObjectHashMap<ResourceInfo> infos = new TIntObjectHashMap<>();
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);
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;
65 ResourceInfo existing = infos.get(object);
66 if(existing == null) {
67 existing = new ResourceInfo(false, "blank" + blankCounter++, object);
68 infos.put(object, existing);
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);
88 //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name);
91 info.statements = statements;
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);
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;
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;
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);
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("/", ".");
155 void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info) {
157 if(info.hasURI) return;
158 output.append(" " + predicateURI2 + " " + info.name + "\n");
160 Value value = findValue(graph, info.resource);
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");
172 // printBlank(graph, predicateURI, ownedInfo);
177 long longStm(int predicate, int object) {
178 return (predicate<<32) | (object & 0xffffffffL);
181 void printURI(TransferableGraph1 graph, ResourceInfo info) {
182 if(!info.hasURI) return;
183 if("ROOT".equals(info.name)) {
184 output.append("ROOT=<http:/>\n");
186 output.append(info.name + "\n");
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");
198 long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
199 processed.add(stmId);
200 printBlank(graph, predicateURI, ownedInfo);
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");
213 output.append(" " + predicateURI + " " + objectInfo.name + "\n");
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;
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);
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())
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");
259 TreeMap<String,ResourceInfo> order = new TreeMap<>();
260 for(ResourceInfo info : infos.valueCollection())
261 order.put(info.name, info);
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");
279 // uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk/", "SIMUPEDIA_STD.");
282 for(ResourceInfo info : order.values())
283 printURI(graph, info);
285 Files.write(output, this.output.toString().getBytes());
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);
298 new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1]));