]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
diff --git a/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphUnparser.java
new file mode 100644 (file)
index 0000000..07bdd61
--- /dev/null
@@ -0,0 +1,312 @@
+package org.simantics.graph.compiler;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.map.hash.TIntIntHashMap;\r
+import gnu.trove.map.hash.TIntObjectHashMap;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.parser.unparsing.DataTypePrinter;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.graph.query.CompositeGraph;\r
+import org.simantics.graph.query.IGraph;\r
+import org.simantics.graph.query.Path;\r
+import org.simantics.graph.query.Paths;\r
+import org.simantics.graph.query.Res;\r
+import org.simantics.graph.query.TransferableGraphConversion;\r
+import org.simantics.graph.query.UriUtils;\r
+import org.simantics.graph.representation.External;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.Internal;\r
+import org.simantics.graph.representation.LocalStatement;\r
+import org.simantics.graph.representation.Optional;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.graph.representation.Value;\r
+import org.simantics.graph.store.GraphStore;\r
+import org.simantics.graph.store.IStatementProcedure;\r
+\r
+public class GraphUnparser {\r
+       IGraph graph;\r
+       GraphStore store;\r
+       StringBuilder b = new StringBuilder();  \r
+       \r
+       GraphUnparser(IGraph graph, GraphStore store) {\r
+               this.graph = graph;\r
+               this.store = store;\r
+       }\r
+       \r
+       ArrayList<Identity> uriRes = new ArrayList<Identity>();\r
+       TIntHashSet blankResources = new TIntHashSet(); \r
+       TIntObjectHashMap<String> refNames = new TIntObjectHashMap<String>();\r
+       TIntHashSet parentNameUsed = new TIntHashSet();\r
+       TIntObjectHashMap<String> parentNames = new TIntObjectHashMap<String>();\r
+       \r
+       TIntHashSet activeResources = new TIntHashSet(); // Resources that have statements      \r
+       TIntObjectHashMap<ArrayList<LocalStatement>> localStatements = \r
+               new TIntObjectHashMap<ArrayList<LocalStatement>>();\r
+       TIntObjectHashMap<String> uris = new TIntObjectHashMap<String>();               \r
+       TIntObjectHashMap<String> literals = new TIntObjectHashMap<String>();\r
+       \r
+       int SimanticsDomain;\r
+       int Layer0;\r
+       int Inherits;\r
+       int InstanceOf;\r
+       int DataType;\r
+       int SubrelationOf;\r
+       \r
+       void handleIdentity(Identity id) {\r
+               int resource = id.resource;\r
+               int parent;\r
+               String name;\r
+               if(id.definition instanceof External) {\r
+                       External def = (External)id.definition;\r
+                       parent = def.parent;\r
+                       name = def.name;\r
+               }\r
+               else if(id.definition instanceof Internal) {\r
+                       Internal def = (Internal)id.definition;\r
+                       parent = def.parent;\r
+                       name = def.name;\r
+               }\r
+               else if(id.definition instanceof Optional) {\r
+                       Optional def = (Optional)id.definition;\r
+                       parent = def.parent;\r
+                       name = def.name;\r
+               }\r
+               else\r
+                       return;\r
+               \r
+               uris.put(id.resource, uris.get(parent) + "/" + name);           \r
+               if(isIdentifier(name)) {\r
+                       if(parentNames.containsKey(parent)) {\r
+                               refNames.put(resource, parentNames.get(parent) + "." + name);\r
+                               parentNameUsed.add(parent);\r
+                       }\r
+                       else\r
+                               refNames.put(resource, "<" + uris.get(resource) + ">");\r
+                       parentNames.put(resource, name);\r
+               }\r
+               else {\r
+                       refNames.put(resource, "<" + uris.get(resource) + ">");\r
+                       String[] parts = name.split("-");\r
+                       if(isIdentifier(parts[0]))\r
+                               parentNames.put(resource, parts[0]);\r
+               }\r
+               if(activeResources.remove(resource)) {  \r
+                       uriRes.add(id);         \r
+               }\r
+               if(parent == 0) {\r
+                       if(name.equals("www.simantics.org"))\r
+                               SimanticsDomain = resource;\r
+               }\r
+               else if(parent == SimanticsDomain) {\r
+                       if(name.equals("Layer0-1.0")) {\r
+                               Layer0 = resource;\r
+                               parentNames.put(resource, "L0");\r
+                       }\r
+               }\r
+               else if(parent == Layer0) {\r
+                       if(name.equals("InstanceOf"))\r
+                               InstanceOf = resource;\r
+                       else if(name.equals("Inherits"))\r
+                               Inherits = resource;\r
+                       else if(name.equals("SubrelationOf"))\r
+                               SubrelationOf = resource;\r
+                       else if(name.equals("DataType"))\r
+                               DataType = resource;\r
+               }\r
+       }\r
+       \r
+       void run() {\r
+               final TIntIntHashMap refCount = new TIntIntHashMap(); \r
+               store.statements.forStatements(new IStatementProcedure() {                      \r
+                       @Override\r
+                       public void execute(int s, int p, int o) {\r
+                               ArrayList<LocalStatement> localStatement;\r
+                               if(activeResources.add(s)) {\r
+                                       localStatement = new ArrayList<LocalStatement>(2);\r
+                                       localStatements.put(s, localStatement);\r
+                               }\r
+                               else\r
+                                       localStatement = localStatements.get(s);\r
+                               refCount.adjustOrPutValue(p, 1, 1);\r
+                               refCount.adjustOrPutValue(o, 1, 1);\r
+                               localStatement.add(new LocalStatement(p, o));   \r
+                       }\r
+               });     \r
+               \r
+               Paths paths = new Paths("1.0");\r
+                               \r
+               // Uris\r
+               uris.put(0, "http:/");\r
+               for(Identity id : store.identities.toArray())\r
+                       handleIdentity(id);\r
+               /*Collections.sort(uriRes, new Comparator<Identity>() {\r
+                       @Override\r
+                       public int compare(Identity arg0, Identity arg1) {\r
+                               int diff = arg0.parent - arg1.parent;\r
+                               if(diff != 0)\r
+                                       return diff;\r
+                               return arg0.name.compareTo(arg1.name);                          \r
+                       }                       \r
+               });*/\r
+               \r
+               // Literals             \r
+               Path dataTypeRes = UriUtils.uriToPath("http://www.simantics.org/Layer0-1.0/DataType");\r
+               for(Value value : store.values.toArray()) {\r
+                       if(graph != null) {\r
+                               Res res = store.idToRes(value.resource);\r
+                               if(graph.rawGetObjects(res, paths.InstanceOf).contains(dataTypeRes)) {\r
+                                       Binding b = Bindings.getBindingUnchecked(Datatype.class);\r
+                                       try {\r
+                                               Datatype dt = (Datatype)value.value.getValue(b);\r
+                                               literals.put(value.resource, "@" + DataTypePrinter.toString(dt, false));\r
+                                               continue;\r
+                                       } catch (Exception e) {\r
+                                               // TODO Auto-generated catch block\r
+                                               e.printStackTrace();\r
+                                       }                                       \r
+                               }\r
+                               else {\r
+                                       Datatype dt = graph.getDatatype(res);\r
+                                       if(dt != null) {\r
+                                               Binding b = Bindings.getBinding(dt);\r
+                                               try {\r
+                                                       Object obj = value.value.getValue(b);                           \r
+                                                       literals.put(value.resource, b.toString(obj));\r
+                                                       continue;\r
+                                               } catch (Exception e) {\r
+                                                       // TODO Auto-generated catch block\r
+                                                       e.printStackTrace();\r
+                                               }                                       \r
+                                       }\r
+                                       else {\r
+                                               literals.put(value.resource, "<" + value.value + ">");\r
+                                       }\r
+                                               \r
+                               }\r
+                       }\r
+               }       \r
+               \r
+               // Blank resources\r
+               for(int id : activeResources.toArray())\r
+                       if(refCount.get(id) == 1) {\r
+                               activeResources.remove(id);\r
+                               blankResources.add(id);\r
+                       }       \r
+               \r
+               int tempId = 0;\r
+               TIntArrayList otherResources = new TIntArrayList(); \r
+               for(int id : activeResources.toArray()) {\r
+                       refNames.put(id, "r" + (++tempId));\r
+                       otherResources.add(id);\r
+               }\r
+               \r
+               for(Identity uriRe : uriRes)\r
+                       describeResource(0, uriRe.resource);\r
+               for(int id : otherResources.toArray())\r
+                       describeResource(0, id);\r
+       }\r
+       \r
+       private void indent(int indentation) {\r
+               for(int i=0;i<indentation;++i)\r
+                       b.append("    ");\r
+       }\r
+       \r
+       private void describeResource(int indentation, int resource) {\r
+               if(parentNameUsed.contains(resource)) {\r
+                       b.append(parentNames.get(resource));\r
+                       b.append(" = ");\r
+               }               \r
+               if(literals.containsKey(resource)) {                    \r
+                       if(refNames.get(resource) != null) {\r
+                               refResource(resource);                  \r
+                               b.append(" = ");\r
+                       }\r
+                       b.append(literals.get(resource));\r
+               }\r
+               else\r
+                       refResource(resource);\r
+               ArrayList<LocalStatement> others = new ArrayList<LocalStatement>();\r
+               for(LocalStatement stat : localStatements.get(resource)) {\r
+                       if(!blankResources.contains(stat.object) &&\r
+                                       (stat.predicate == InstanceOf ||\r
+                                                       stat.predicate == Inherits ||\r
+                                                       stat.predicate == SubrelationOf)) {\r
+                               b.append(' ');\r
+                               refPredicate(stat.predicate);\r
+                               b.append(' ');\r
+                               refResource(stat.object);\r
+                       }\r
+                       else\r
+                               others.add(stat);\r
+               }\r
+               b.append('\n');\r
+               \r
+               for(LocalStatement stat : others) {\r
+                       indent(indentation+1);\r
+                       refPredicate(stat.predicate);\r
+                       b.append(" ");\r
+                       describeObject(indentation+1, stat.object);\r
+               }\r
+       }\r
+       \r
+       private void describeObject(int indentation, int resource) {\r
+               if(blankResources.contains(resource))\r
+                       describeResource(indentation, resource);\r
+               else {\r
+                       refResource(resource);\r
+                       b.append('\n');\r
+               }\r
+       }\r
+       \r
+       private void refPredicate(int resource) {\r
+               if(resource == InstanceOf)\r
+                       b.append(":");\r
+               else if(resource == Inherits)\r
+                       b.append("<T");\r
+               else if(resource == SubrelationOf)\r
+                       b.append("<R");\r
+               else\r
+                       refResource(resource);\r
+       }\r
+       \r
+       private void refResource(int resource) {\r
+               String name = refNames.get(resource);\r
+               if(name == null)\r
+                       b.append("_");\r
+               else\r
+                       b.append(name);\r
+       }\r
+       \r
+       @Override\r
+       public String toString() {\r
+               return b.toString();\r
+       }\r
+       \r
+       static boolean isIdentifier(String name) {\r
+               if(name.isEmpty())\r
+                       return false;\r
+               if(!Character.isJavaIdentifierStart(name.charAt(0)))\r
+                       return false;\r
+               for(int i=1;i<name.length();++i)\r
+                       if(!Character.isJavaIdentifierPart(name.charAt(i)))\r
+                               return false;\r
+               return true;\r
+       }\r
+       \r
+       public static String unparse(Paths paths, TransferableGraph1 tg, Collection<TransferableGraph1> dependencies) {\r
+               CompositeGraph cg = TransferableGraphConversion.convert(paths, dependencies);                   \r
+               GraphStore store = TransferableGraphConversion.convert(tg);\r
+               cg.addFragment(store);  \r
+               \r
+               GraphUnparser gu = new GraphUnparser(cg, store);\r
+               gu.run();\r
+               \r
+               return gu.toString();\r
+       }\r
+}\r