]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph.compiler / src / org / simantics / graph / compiler / GraphUnparser.java
1 package org.simantics.graph.compiler;\r
2 \r
3 import gnu.trove.list.array.TIntArrayList;\r
4 import gnu.trove.map.hash.TIntIntHashMap;\r
5 import gnu.trove.map.hash.TIntObjectHashMap;\r
6 import gnu.trove.set.hash.TIntHashSet;\r
7 \r
8 import java.util.ArrayList;\r
9 import java.util.Collection;\r
10 \r
11 import org.simantics.databoard.Bindings;\r
12 import org.simantics.databoard.binding.Binding;\r
13 import org.simantics.databoard.parser.unparsing.DataTypePrinter;\r
14 import org.simantics.databoard.type.Datatype;\r
15 import org.simantics.graph.query.CompositeGraph;\r
16 import org.simantics.graph.query.IGraph;\r
17 import org.simantics.graph.query.Path;\r
18 import org.simantics.graph.query.Paths;\r
19 import org.simantics.graph.query.Res;\r
20 import org.simantics.graph.query.TransferableGraphConversion;\r
21 import org.simantics.graph.query.UriUtils;\r
22 import org.simantics.graph.representation.External;\r
23 import org.simantics.graph.representation.Identity;\r
24 import org.simantics.graph.representation.Internal;\r
25 import org.simantics.graph.representation.LocalStatement;\r
26 import org.simantics.graph.representation.Optional;\r
27 import org.simantics.graph.representation.TransferableGraph1;\r
28 import org.simantics.graph.representation.Value;\r
29 import org.simantics.graph.store.GraphStore;\r
30 import org.simantics.graph.store.IStatementProcedure;\r
31 \r
32 public class GraphUnparser {\r
33         IGraph graph;\r
34         GraphStore store;\r
35         StringBuilder b = new StringBuilder();  \r
36         \r
37         GraphUnparser(IGraph graph, GraphStore store) {\r
38                 this.graph = graph;\r
39                 this.store = store;\r
40         }\r
41         \r
42         ArrayList<Identity> uriRes = new ArrayList<Identity>();\r
43         TIntHashSet blankResources = new TIntHashSet(); \r
44         TIntObjectHashMap<String> refNames = new TIntObjectHashMap<String>();\r
45         TIntHashSet parentNameUsed = new TIntHashSet();\r
46         TIntObjectHashMap<String> parentNames = new TIntObjectHashMap<String>();\r
47         \r
48         TIntHashSet activeResources = new TIntHashSet(); // Resources that have statements      \r
49         TIntObjectHashMap<ArrayList<LocalStatement>> localStatements = \r
50                 new TIntObjectHashMap<ArrayList<LocalStatement>>();\r
51         TIntObjectHashMap<String> uris = new TIntObjectHashMap<String>();               \r
52         TIntObjectHashMap<String> literals = new TIntObjectHashMap<String>();\r
53         \r
54         int SimanticsDomain;\r
55         int Layer0;\r
56         int Inherits;\r
57         int InstanceOf;\r
58         int DataType;\r
59         int SubrelationOf;\r
60         \r
61         void handleIdentity(Identity id) {\r
62                 int resource = id.resource;\r
63                 int parent;\r
64                 String name;\r
65                 if(id.definition instanceof External) {\r
66                         External def = (External)id.definition;\r
67                         parent = def.parent;\r
68                         name = def.name;\r
69                 }\r
70                 else if(id.definition instanceof Internal) {\r
71                         Internal def = (Internal)id.definition;\r
72                         parent = def.parent;\r
73                         name = def.name;\r
74                 }\r
75                 else if(id.definition instanceof Optional) {\r
76                         Optional def = (Optional)id.definition;\r
77                         parent = def.parent;\r
78                         name = def.name;\r
79                 }\r
80                 else\r
81                         return;\r
82                 \r
83                 uris.put(id.resource, uris.get(parent) + "/" + name);           \r
84                 if(isIdentifier(name)) {\r
85                         if(parentNames.containsKey(parent)) {\r
86                                 refNames.put(resource, parentNames.get(parent) + "." + name);\r
87                                 parentNameUsed.add(parent);\r
88                         }\r
89                         else\r
90                                 refNames.put(resource, "<" + uris.get(resource) + ">");\r
91                         parentNames.put(resource, name);\r
92                 }\r
93                 else {\r
94                         refNames.put(resource, "<" + uris.get(resource) + ">");\r
95                         String[] parts = name.split("-");\r
96                         if(isIdentifier(parts[0]))\r
97                                 parentNames.put(resource, parts[0]);\r
98                 }\r
99                 if(activeResources.remove(resource)) {  \r
100                         uriRes.add(id);         \r
101                 }\r
102                 if(parent == 0) {\r
103                         if(name.equals("www.simantics.org"))\r
104                                 SimanticsDomain = resource;\r
105                 }\r
106                 else if(parent == SimanticsDomain) {\r
107                         if(name.equals("Layer0-1.0")) {\r
108                                 Layer0 = resource;\r
109                                 parentNames.put(resource, "L0");\r
110                         }\r
111                 }\r
112                 else if(parent == Layer0) {\r
113                         if(name.equals("InstanceOf"))\r
114                                 InstanceOf = resource;\r
115                         else if(name.equals("Inherits"))\r
116                                 Inherits = resource;\r
117                         else if(name.equals("SubrelationOf"))\r
118                                 SubrelationOf = resource;\r
119                         else if(name.equals("DataType"))\r
120                                 DataType = resource;\r
121                 }\r
122         }\r
123         \r
124         void run() {\r
125                 final TIntIntHashMap refCount = new TIntIntHashMap(); \r
126                 store.statements.forStatements(new IStatementProcedure() {                      \r
127                         @Override\r
128                         public void execute(int s, int p, int o) {\r
129                                 ArrayList<LocalStatement> localStatement;\r
130                                 if(activeResources.add(s)) {\r
131                                         localStatement = new ArrayList<LocalStatement>(2);\r
132                                         localStatements.put(s, localStatement);\r
133                                 }\r
134                                 else\r
135                                         localStatement = localStatements.get(s);\r
136                                 refCount.adjustOrPutValue(p, 1, 1);\r
137                                 refCount.adjustOrPutValue(o, 1, 1);\r
138                                 localStatement.add(new LocalStatement(p, o));   \r
139                         }\r
140                 });     \r
141                 \r
142                 Paths paths = new Paths("1.0");\r
143                                 \r
144                 // Uris\r
145                 uris.put(0, "http:/");\r
146                 for(Identity id : store.identities.toArray())\r
147                         handleIdentity(id);\r
148                 /*Collections.sort(uriRes, new Comparator<Identity>() {\r
149                         @Override\r
150                         public int compare(Identity arg0, Identity arg1) {\r
151                                 int diff = arg0.parent - arg1.parent;\r
152                                 if(diff != 0)\r
153                                         return diff;\r
154                                 return arg0.name.compareTo(arg1.name);                          \r
155                         }                       \r
156                 });*/\r
157                 \r
158                 // Literals             \r
159                 Path dataTypeRes = UriUtils.uriToPath("http://www.simantics.org/Layer0-1.0/DataType");\r
160                 for(Value value : store.values.toArray()) {\r
161                         if(graph != null) {\r
162                                 Res res = store.idToRes(value.resource);\r
163                                 if(graph.rawGetObjects(res, paths.InstanceOf).contains(dataTypeRes)) {\r
164                                         Binding b = Bindings.getBindingUnchecked(Datatype.class);\r
165                                         try {\r
166                                                 Datatype dt = (Datatype)value.value.getValue(b);\r
167                                                 literals.put(value.resource, "@" + DataTypePrinter.toString(dt, false));\r
168                                                 continue;\r
169                                         } catch (Exception e) {\r
170                                                 // TODO Auto-generated catch block\r
171                                                 e.printStackTrace();\r
172                                         }                                       \r
173                                 }\r
174                                 else {\r
175                                         Datatype dt = graph.getDatatype(res);\r
176                                         if(dt != null) {\r
177                                                 Binding b = Bindings.getBinding(dt);\r
178                                                 try {\r
179                                                         Object obj = value.value.getValue(b);                           \r
180                                                         literals.put(value.resource, b.toString(obj));\r
181                                                         continue;\r
182                                                 } catch (Exception e) {\r
183                                                         // TODO Auto-generated catch block\r
184                                                         e.printStackTrace();\r
185                                                 }                                       \r
186                                         }\r
187                                         else {\r
188                                                 literals.put(value.resource, "<" + value.value + ">");\r
189                                         }\r
190                                                 \r
191                                 }\r
192                         }\r
193                 }       \r
194                 \r
195                 // Blank resources\r
196                 for(int id : activeResources.toArray())\r
197                         if(refCount.get(id) == 1) {\r
198                                 activeResources.remove(id);\r
199                                 blankResources.add(id);\r
200                         }       \r
201                 \r
202                 int tempId = 0;\r
203                 TIntArrayList otherResources = new TIntArrayList(); \r
204                 for(int id : activeResources.toArray()) {\r
205                         refNames.put(id, "r" + (++tempId));\r
206                         otherResources.add(id);\r
207                 }\r
208                 \r
209                 for(Identity uriRe : uriRes)\r
210                         describeResource(0, uriRe.resource);\r
211                 for(int id : otherResources.toArray())\r
212                         describeResource(0, id);\r
213         }\r
214         \r
215         private void indent(int indentation) {\r
216                 for(int i=0;i<indentation;++i)\r
217                         b.append("    ");\r
218         }\r
219         \r
220         private void describeResource(int indentation, int resource) {\r
221                 if(parentNameUsed.contains(resource)) {\r
222                         b.append(parentNames.get(resource));\r
223                         b.append(" = ");\r
224                 }               \r
225                 if(literals.containsKey(resource)) {                    \r
226                         if(refNames.get(resource) != null) {\r
227                                 refResource(resource);                  \r
228                                 b.append(" = ");\r
229                         }\r
230                         b.append(literals.get(resource));\r
231                 }\r
232                 else\r
233                         refResource(resource);\r
234                 ArrayList<LocalStatement> others = new ArrayList<LocalStatement>();\r
235                 for(LocalStatement stat : localStatements.get(resource)) {\r
236                         if(!blankResources.contains(stat.object) &&\r
237                                         (stat.predicate == InstanceOf ||\r
238                                                         stat.predicate == Inherits ||\r
239                                                         stat.predicate == SubrelationOf)) {\r
240                                 b.append(' ');\r
241                                 refPredicate(stat.predicate);\r
242                                 b.append(' ');\r
243                                 refResource(stat.object);\r
244                         }\r
245                         else\r
246                                 others.add(stat);\r
247                 }\r
248                 b.append('\n');\r
249                 \r
250                 for(LocalStatement stat : others) {\r
251                         indent(indentation+1);\r
252                         refPredicate(stat.predicate);\r
253                         b.append(" ");\r
254                         describeObject(indentation+1, stat.object);\r
255                 }\r
256         }\r
257         \r
258         private void describeObject(int indentation, int resource) {\r
259                 if(blankResources.contains(resource))\r
260                         describeResource(indentation, resource);\r
261                 else {\r
262                         refResource(resource);\r
263                         b.append('\n');\r
264                 }\r
265         }\r
266         \r
267         private void refPredicate(int resource) {\r
268                 if(resource == InstanceOf)\r
269                         b.append(":");\r
270                 else if(resource == Inherits)\r
271                         b.append("<T");\r
272                 else if(resource == SubrelationOf)\r
273                         b.append("<R");\r
274                 else\r
275                         refResource(resource);\r
276         }\r
277         \r
278         private void refResource(int resource) {\r
279                 String name = refNames.get(resource);\r
280                 if(name == null)\r
281                         b.append("_");\r
282                 else\r
283                         b.append(name);\r
284         }\r
285         \r
286         @Override\r
287         public String toString() {\r
288                 return b.toString();\r
289         }\r
290         \r
291         static boolean isIdentifier(String name) {\r
292                 if(name.isEmpty())\r
293                         return false;\r
294                 if(!Character.isJavaIdentifierStart(name.charAt(0)))\r
295                         return false;\r
296                 for(int i=1;i<name.length();++i)\r
297                         if(!Character.isJavaIdentifierPart(name.charAt(i)))\r
298                                 return false;\r
299                 return true;\r
300         }\r
301         \r
302         public static String unparse(Paths paths, TransferableGraph1 tg, Collection<TransferableGraph1> dependencies) {\r
303                 CompositeGraph cg = TransferableGraphConversion.convert(paths, dependencies);                   \r
304                 GraphStore store = TransferableGraphConversion.convert(tg);\r
305                 cg.addFragment(store);  \r
306                 \r
307                 GraphUnparser gu = new GraphUnparser(cg, store);\r
308                 gu.run();\r
309                 \r
310                 return gu.toString();\r
311         }\r
312 }\r