1 package org.simantics.graph.compiler;
3 import gnu.trove.list.array.TIntArrayList;
4 import gnu.trove.map.hash.TIntIntHashMap;
5 import gnu.trove.map.hash.TIntObjectHashMap;
6 import gnu.trove.set.hash.TIntHashSet;
8 import java.util.ArrayList;
9 import java.util.Collection;
11 import org.simantics.databoard.Bindings;
12 import org.simantics.databoard.binding.Binding;
13 import org.simantics.databoard.parser.unparsing.DataTypePrinter;
14 import org.simantics.databoard.type.Datatype;
15 import org.simantics.graph.query.CompositeGraph;
16 import org.simantics.graph.query.IGraph;
17 import org.simantics.graph.query.Path;
18 import org.simantics.graph.query.Paths;
19 import org.simantics.graph.query.Res;
20 import org.simantics.graph.query.TransferableGraphConversion;
21 import org.simantics.graph.query.UriUtils;
22 import org.simantics.graph.representation.External;
23 import org.simantics.graph.representation.Identity;
24 import org.simantics.graph.representation.Internal;
25 import org.simantics.graph.representation.LocalStatement;
26 import org.simantics.graph.representation.Optional;
27 import org.simantics.graph.representation.TransferableGraph1;
28 import org.simantics.graph.representation.Value;
29 import org.simantics.graph.store.GraphStore;
30 import org.simantics.graph.store.IStatementProcedure;
32 public class GraphUnparser {
35 StringBuilder b = new StringBuilder();
37 GraphUnparser(IGraph graph, GraphStore store) {
42 ArrayList<Identity> uriRes = new ArrayList<Identity>();
43 TIntHashSet blankResources = new TIntHashSet();
44 TIntObjectHashMap<String> refNames = new TIntObjectHashMap<String>();
45 TIntHashSet parentNameUsed = new TIntHashSet();
46 TIntObjectHashMap<String> parentNames = new TIntObjectHashMap<String>();
48 TIntHashSet activeResources = new TIntHashSet(); // Resources that have statements
49 TIntObjectHashMap<ArrayList<LocalStatement>> localStatements =
50 new TIntObjectHashMap<ArrayList<LocalStatement>>();
51 TIntObjectHashMap<String> uris = new TIntObjectHashMap<String>();
52 TIntObjectHashMap<String> literals = new TIntObjectHashMap<String>();
61 void handleIdentity(Identity id) {
62 int resource = id.resource;
65 if(id.definition instanceof External) {
66 External def = (External)id.definition;
70 else if(id.definition instanceof Internal) {
71 Internal def = (Internal)id.definition;
75 else if(id.definition instanceof Optional) {
76 Optional def = (Optional)id.definition;
83 uris.put(id.resource, uris.get(parent) + "/" + name);
84 if(isIdentifier(name)) {
85 if(parentNames.containsKey(parent)) {
86 refNames.put(resource, parentNames.get(parent) + "." + name);
87 parentNameUsed.add(parent);
90 refNames.put(resource, "<" + uris.get(resource) + ">");
91 parentNames.put(resource, name);
94 refNames.put(resource, "<" + uris.get(resource) + ">");
95 String[] parts = name.split("-");
96 if(isIdentifier(parts[0]))
97 parentNames.put(resource, parts[0]);
99 if(activeResources.remove(resource)) {
103 if(name.equals("www.simantics.org"))
104 SimanticsDomain = resource;
106 else if(parent == SimanticsDomain) {
107 if(name.equals("Layer0-1.0")) {
109 parentNames.put(resource, "L0");
112 else if(parent == Layer0) {
113 if(name.equals("InstanceOf"))
114 InstanceOf = resource;
115 else if(name.equals("Inherits"))
117 else if(name.equals("SubrelationOf"))
118 SubrelationOf = resource;
119 else if(name.equals("DataType"))
125 final TIntIntHashMap refCount = new TIntIntHashMap();
126 store.statements.forStatements(new IStatementProcedure() {
128 public void execute(int s, int p, int o) {
129 ArrayList<LocalStatement> localStatement;
130 if(activeResources.add(s)) {
131 localStatement = new ArrayList<LocalStatement>(2);
132 localStatements.put(s, localStatement);
135 localStatement = localStatements.get(s);
136 refCount.adjustOrPutValue(p, 1, 1);
137 refCount.adjustOrPutValue(o, 1, 1);
138 localStatement.add(new LocalStatement(p, o));
142 Paths paths = new Paths("1.0");
145 uris.put(0, "http:/");
146 for(Identity id : store.identities.toArray())
148 /*Collections.sort(uriRes, new Comparator<Identity>() {
150 public int compare(Identity arg0, Identity arg1) {
151 int diff = arg0.parent - arg1.parent;
154 return arg0.name.compareTo(arg1.name);
159 Path dataTypeRes = UriUtils.uriToPath("http://www.simantics.org/Layer0-1.0/DataType");
160 for(Value value : store.values.toArray()) {
162 Res res = store.idToRes(value.resource);
163 if(graph.rawGetObjects(res, paths.InstanceOf).contains(dataTypeRes)) {
164 Binding b = Bindings.getBindingUnchecked(Datatype.class);
166 Datatype dt = (Datatype)value.value.getValue(b);
167 literals.put(value.resource, "@" + DataTypePrinter.toString(dt, false));
169 } catch (Exception e) {
170 // TODO Auto-generated catch block
175 Datatype dt = graph.getDatatype(res);
177 Binding b = Bindings.getBinding(dt);
179 Object obj = value.value.getValue(b);
180 literals.put(value.resource, b.toString(obj));
182 } catch (Exception e) {
183 // TODO Auto-generated catch block
188 literals.put(value.resource, "<" + value.value + ">");
196 for(int id : activeResources.toArray())
197 if(refCount.get(id) == 1) {
198 activeResources.remove(id);
199 blankResources.add(id);
203 TIntArrayList otherResources = new TIntArrayList();
204 for(int id : activeResources.toArray()) {
205 refNames.put(id, "r" + (++tempId));
206 otherResources.add(id);
209 for(Identity uriRe : uriRes)
210 describeResource(0, uriRe.resource);
211 for(int id : otherResources.toArray())
212 describeResource(0, id);
215 private void indent(int indentation) {
216 for(int i=0;i<indentation;++i)
220 private void describeResource(int indentation, int resource) {
221 if(parentNameUsed.contains(resource)) {
222 b.append(parentNames.get(resource));
225 if(literals.containsKey(resource)) {
226 if(refNames.get(resource) != null) {
227 refResource(resource);
230 b.append(literals.get(resource));
233 refResource(resource);
234 ArrayList<LocalStatement> others = new ArrayList<LocalStatement>();
235 for(LocalStatement stat : localStatements.get(resource)) {
236 if(!blankResources.contains(stat.object) &&
237 (stat.predicate == InstanceOf ||
238 stat.predicate == Inherits ||
239 stat.predicate == SubrelationOf)) {
241 refPredicate(stat.predicate);
243 refResource(stat.object);
250 for(LocalStatement stat : others) {
251 indent(indentation+1);
252 refPredicate(stat.predicate);
254 describeObject(indentation+1, stat.object);
258 private void describeObject(int indentation, int resource) {
259 if(blankResources.contains(resource))
260 describeResource(indentation, resource);
262 refResource(resource);
267 private void refPredicate(int resource) {
268 if(resource == InstanceOf)
270 else if(resource == Inherits)
272 else if(resource == SubrelationOf)
275 refResource(resource);
278 private void refResource(int resource) {
279 String name = refNames.get(resource);
287 public String toString() {
291 static boolean isIdentifier(String name) {
294 if(!Character.isJavaIdentifierStart(name.charAt(0)))
296 for(int i=1;i<name.length();++i)
297 if(!Character.isJavaIdentifierPart(name.charAt(i)))
302 public static String unparse(Paths paths, TransferableGraph1 tg, Collection<TransferableGraph1> dependencies) {
303 CompositeGraph cg = TransferableGraphConversion.convert(paths, dependencies);
304 GraphStore store = TransferableGraphConversion.convert(tg);
305 cg.addFragment(store);
307 GraphUnparser gu = new GraphUnparser(cg, store);
310 return gu.toString();