1 package org.simantics.graph.compiler;
\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
8 import java.util.ArrayList;
\r
9 import java.util.Collection;
\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
32 public class GraphUnparser {
\r
35 StringBuilder b = new StringBuilder();
\r
37 GraphUnparser(IGraph graph, GraphStore store) {
\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
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
54 int SimanticsDomain;
\r
61 void handleIdentity(Identity id) {
\r
62 int resource = id.resource;
\r
65 if(id.definition instanceof External) {
\r
66 External def = (External)id.definition;
\r
67 parent = def.parent;
\r
70 else if(id.definition instanceof Internal) {
\r
71 Internal def = (Internal)id.definition;
\r
72 parent = def.parent;
\r
75 else if(id.definition instanceof Optional) {
\r
76 Optional def = (Optional)id.definition;
\r
77 parent = def.parent;
\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
90 refNames.put(resource, "<" + uris.get(resource) + ">");
\r
91 parentNames.put(resource, name);
\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
99 if(activeResources.remove(resource)) {
\r
103 if(name.equals("www.simantics.org"))
\r
104 SimanticsDomain = resource;
\r
106 else if(parent == SimanticsDomain) {
\r
107 if(name.equals("Layer0-1.0")) {
\r
109 parentNames.put(resource, "L0");
\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
125 final TIntIntHashMap refCount = new TIntIntHashMap();
\r
126 store.statements.forStatements(new IStatementProcedure() {
\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
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
142 Paths paths = new Paths("1.0");
\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
150 public int compare(Identity arg0, Identity arg1) {
\r
151 int diff = arg0.parent - arg1.parent;
\r
154 return arg0.name.compareTo(arg1.name);
\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
166 Datatype dt = (Datatype)value.value.getValue(b);
\r
167 literals.put(value.resource, "@" + DataTypePrinter.toString(dt, false));
\r
169 } catch (Exception e) {
\r
170 // TODO Auto-generated catch block
\r
171 e.printStackTrace();
\r
175 Datatype dt = graph.getDatatype(res);
\r
177 Binding b = Bindings.getBinding(dt);
\r
179 Object obj = value.value.getValue(b);
\r
180 literals.put(value.resource, b.toString(obj));
\r
182 } catch (Exception e) {
\r
183 // TODO Auto-generated catch block
\r
184 e.printStackTrace();
\r
188 literals.put(value.resource, "<" + value.value + ">");
\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
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
209 for(Identity uriRe : uriRes)
\r
210 describeResource(0, uriRe.resource);
\r
211 for(int id : otherResources.toArray())
\r
212 describeResource(0, id);
\r
215 private void indent(int indentation) {
\r
216 for(int i=0;i<indentation;++i)
\r
220 private void describeResource(int indentation, int resource) {
\r
221 if(parentNameUsed.contains(resource)) {
\r
222 b.append(parentNames.get(resource));
\r
225 if(literals.containsKey(resource)) {
\r
226 if(refNames.get(resource) != null) {
\r
227 refResource(resource);
\r
230 b.append(literals.get(resource));
\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
241 refPredicate(stat.predicate);
\r
243 refResource(stat.object);
\r
250 for(LocalStatement stat : others) {
\r
251 indent(indentation+1);
\r
252 refPredicate(stat.predicate);
\r
254 describeObject(indentation+1, stat.object);
\r
258 private void describeObject(int indentation, int resource) {
\r
259 if(blankResources.contains(resource))
\r
260 describeResource(indentation, resource);
\r
262 refResource(resource);
\r
267 private void refPredicate(int resource) {
\r
268 if(resource == InstanceOf)
\r
270 else if(resource == Inherits)
\r
272 else if(resource == SubrelationOf)
\r
275 refResource(resource);
\r
278 private void refResource(int resource) {
\r
279 String name = refNames.get(resource);
\r
287 public String toString() {
\r
288 return b.toString();
\r
291 static boolean isIdentifier(String name) {
\r
294 if(!Character.isJavaIdentifierStart(name.charAt(0)))
\r
296 for(int i=1;i<name.length();++i)
\r
297 if(!Character.isJavaIdentifierPart(name.charAt(i)))
\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
307 GraphUnparser gu = new GraphUnparser(cg, store);
\r
310 return gu.toString();
\r