]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphCompiler.java
Merge commit 'bf75fd9'
[simantics/platform.git] / bundles / org.simantics.graph.compiler / src / org / simantics / graph / compiler / GraphCompiler.java
1 package org.simantics.graph.compiler;\r
2 \r
3 import java.io.ByteArrayInputStream;\r
4 import java.io.ByteArrayOutputStream;\r
5 import java.io.DataInputStream;\r
6 import java.io.File;\r
7 import java.io.IOException;\r
8 import java.io.InputStream;\r
9 import java.io.PrintStream;\r
10 import java.util.ArrayList;\r
11 import java.util.Collection;\r
12 import java.util.Formatter;\r
13 import java.util.Locale;\r
14 \r
15 import org.simantics.databoard.Bindings;\r
16 import org.simantics.databoard.Files;\r
17 import org.simantics.databoard.adapter.AdaptException;\r
18 import org.simantics.databoard.binding.error.BindingException;\r
19 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
20 import org.simantics.databoard.binding.mutable.Variant;\r
21 import org.simantics.databoard.container.DataContainer;\r
22 import org.simantics.databoard.container.DataContainers;\r
23 import org.simantics.databoard.serialization.SerializationException;\r
24 import org.simantics.graph.compiler.internal.parsing.Parsing;\r
25 import org.simantics.graph.compiler.internal.procedures.AddConsistsOf;\r
26 import org.simantics.graph.compiler.internal.procedures.ApplyTemplates;\r
27 import org.simantics.graph.compiler.internal.procedures.Compactify;\r
28 import org.simantics.graph.compiler.internal.procedures.ConvertPreValues;\r
29 import org.simantics.graph.compiler.internal.procedures.CreateInverseRelations;\r
30 import org.simantics.graph.compiler.internal.procedures.CreateTemplates;\r
31 import org.simantics.graph.compiler.internal.procedures.DefaultValueTyping;\r
32 import org.simantics.graph.compiler.internal.procedures.MergeEqualResources;\r
33 import org.simantics.graph.compiler.internal.procedures.PropagateNewMarks;\r
34 import org.simantics.graph.compiler.internal.resourceFiles.ResourceFileGenerator;\r
35 import org.simantics.graph.compiler.internal.store.LocationStore;\r
36 import org.simantics.graph.compiler.internal.store.VariableStore;\r
37 import org.simantics.graph.compiler.internal.validation.ReportCollisions;\r
38 import org.simantics.graph.compiler.internal.validation.ValidateGraph;\r
39 import org.simantics.graph.query.CompositeGraph;\r
40 import org.simantics.graph.query.Paths;\r
41 import org.simantics.graph.query.TransferableGraphConversion;\r
42 import org.simantics.graph.representation.TransferableGraph1;\r
43 import org.simantics.graph.store.GraphStore;\r
44 import org.simantics.ltk.FileSource;\r
45 import org.simantics.ltk.ISource;\r
46 import org.simantics.ltk.Location;\r
47 import org.simantics.ltk.Problem;\r
48 \r
49 public class GraphCompiler {\r
50         \r
51         public static PrintStream out = System.out;\r
52         \r
53         public static TransferableGraph1 read(File file) throws Exception {\r
54                 DataContainer container = DataContainers.readFile(file);\r
55                 return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING);\r
56         }\r
57         \r
58         public static TransferableGraph1 read(InputStream stream) throws AdaptException, IOException {\r
59                 DataContainer container = DataContainers.readFile(new DataInputStream(stream));\r
60                 stream.close();\r
61                 return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING);\r
62         }\r
63         \r
64         public static InputStream write(TransferableGraph1 tg) throws BindingException, IOException {\r
65                 byte[] buffer = DataContainers.writeFile(\r
66                                 new DataContainer("graph", 1, new Variant(TransferableGraph1.BINDING, tg))\r
67                                 );\r
68                 return new ByteArrayInputStream(buffer);\r
69         }\r
70         \r
71         public static CompilationResult compile(\r
72                 String Layer0Version,\r
73                         Collection<ISource> sources, \r
74                         Collection<TransferableGraph1> dependencies,\r
75                         ExternalFileLoader fileLoader,\r
76                         GraphCompilerPreferences preferences) {\r
77             out.println(preferences);\r
78             \r
79                 Collection<Problem> errors = new ArrayList<Problem>();\r
80                 GraphStore store = new GraphStore();            \r
81                 \r
82                 CompilationResult compilationResult = new CompilationResult();\r
83                 compilationResult.errors = errors;\r
84                 compilationResult.warnings = new ArrayList<Problem>();\r
85                 \r
86                 Paths paths = new Paths(Layer0Version);\r
87                 \r
88                 try {                   \r
89                         run(new Parsing(paths, sources, errors, store));\r
90                         \r
91                         if(!errors.isEmpty())\r
92                                 return compilationResult;\r
93         \r
94                         // Create composite graph of the new statements and dependencies\r
95                         CompositeGraph graph;\r
96                         {\r
97                                 long beginTime = System.nanoTime();\r
98                                 graph = TransferableGraphConversion.convert(paths, dependencies);\r
99                                 graph.addFragment(store);               \r
100                                 long endTime = System.nanoTime();\r
101                                 reportTime("Composition", beginTime, endTime);\r
102                         }\r
103         \r
104                         // Procedures\r
105                         run(new MergeEqualResources(paths, store));\r
106                         {\r
107                             int[] unfoundedIdentitities = store.identities.getUnfoundedIdentities();\r
108                             if(unfoundedIdentitities.length > 0) {\r
109                                 LocationStore locations = store.getStore(LocationStore.class);\r
110                                 for(int id : unfoundedIdentitities) {\r
111                                     errors.add(new Problem(\r
112                                             locations.getLocation(id), \r
113                                             "URIless resource used as a parent."));\r
114                                 }\r
115                                 return compilationResult;\r
116                             }\r
117                         }                           \r
118                         store.identities.createPathToId(paths.ConsistsOf);\r
119                         run(new CreateTemplates(graph, store, errors));\r
120                         run(new ApplyTemplates(graph, store, errors, fileLoader));\r
121                         run(new DefaultValueTyping(paths, store));              \r
122                         run(new Compactify(store));                        \r
123                         run(new PropagateNewMarks(store));                      \r
124                         run(new CreateInverseRelations(graph, store));\r
125                         run(new AddConsistsOf(paths, store));\r
126                         run(new ConvertPreValues(graph, store, errors));\r
127                         run(new ReportCollisions(preferences, errors, store));\r
128                         if(preferences.validate)\r
129                                 run(new ValidateGraph(graph, errors, store, preferences));\r
130                         \r
131                         // Create the result\r
132                         {\r
133                                 long beginTime = System.nanoTime();\r
134                                 compilationResult.graph = TransferableGraphConversion.convert(graph, store);                            \r
135                                 long endTime = System.nanoTime();\r
136                                 reportTime("Generate TG", beginTime, endTime);\r
137                         }\r
138                         \r
139                         // Create resource files        \r
140                         {\r
141                                 long beginTime = System.nanoTime();\r
142                                 compilationResult.resourceFiles = ResourceFileGenerator.generate(paths, store);         \r
143                                 long endTime = System.nanoTime();\r
144                                 reportTime("Generate resources", beginTime, endTime);\r
145                         }\r
146                         \r
147                         // Create source info\r
148                         {\r
149                                 VariableStore variableStore = store.getStore(VariableStore.class);\r
150                                 compilationResult.sourceInfo = variableStore.getSourceInfo();\r
151                         }\r
152                         \r
153                         // Fix source location of problems whose location is null at this point\r
154 \r
155                         for(Problem problem : compilationResult.errors) {\r
156                                 if(problem.getLocation() == null)\r
157                                         for(ISource source : sources) {\r
158                                                 problem.setLocation(new Location(source));\r
159                                                 break;\r
160                                         }\r
161                                 else if(problem.getLocation().getSource() == null)\r
162                                         for(ISource source : sources) {\r
163                                                 problem.getLocation().setSource(source);\r
164                                                 break;\r
165                                         }\r
166                         }\r
167                         for(Problem problem : compilationResult.warnings) {\r
168                                 if(problem.getLocation() == null)\r
169                                         for(ISource source : sources) {\r
170                                                 problem.setLocation(new Location(source));\r
171                                                 break;\r
172                                         }\r
173                                 else if(problem.getLocation().getSource() == null)\r
174                                         for(ISource source : sources) {\r
175                                                 problem.getLocation().setSource(source);\r
176                                                 break;\r
177                                         }\r
178                         }\r
179                         \r
180                 } catch(Exception e) {\r
181                         e.printStackTrace();\r
182                         ByteArrayOutputStream stream = new ByteArrayOutputStream();\r
183                         e.printStackTrace(new PrintStream(stream));\r
184                         String description = "Internal error: " +\r
185                                 new String(stream.toByteArray());\r
186                         for(ISource source : sources)           \r
187                                 errors.add(new Problem(new Location(source), description));\r
188                 }\r
189                 \r
190                 return compilationResult;\r
191         }\r
192         \r
193         private static void run(Runnable runnable) {\r
194                 long beginTime = System.nanoTime();\r
195                 runnable.run();\r
196                 long endTime = System.nanoTime();\r
197                 \r
198                 reportTime(runnable.getClass().getSimpleName(), beginTime, endTime);\r
199         }\r
200         \r
201         public static void reportTime(String taskName, long beginTime, long endTime) {\r
202                 StringBuilder sb = new StringBuilder();\r
203             Formatter formatter = new Formatter(sb, Locale.US);\r
204             formatter.format("%-25s %8.4f ms", taskName, (endTime - beginTime)*1e-6);\r
205                    \r
206                 out.println(sb.toString());\r
207         }\r
208         \r
209         public static void reportTime(String taskName, long beginTime) {\r
210                 reportTime(taskName, beginTime, System.nanoTime());\r
211         }\r
212         \r
213         public static void main(String[] args) {\r
214                 Collection<ISource> sources = new ArrayList<ISource>();\r
215                 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();\r
216                 String outputFile = null;\r
217                 \r
218                 for(int i=0;i<args.length;++i) {\r
219                         String arg = args[i];\r
220                         if(arg.equals("-o")) {\r
221                                 if(++i < args.length)\r
222                                         outputFile = args[i];\r
223                         }\r
224                         else {\r
225                                 if(arg.endsWith(".tg")) {\r
226                                         try {\r
227                                                 dependencies.add(read(new File(arg)));\r
228                                         } catch (Exception e) {\r
229                                                 e.printStackTrace();\r
230                                                 return;\r
231                                         }\r
232                                 }\r
233                                 else if(arg.endsWith(".graph") || arg.endsWith(".pgraph")) {\r
234                                         sources.add(new FileSource(arg));\r
235                                 }\r
236                                 else {\r
237                                         System.err.println("Invalid input file extension " + arg);\r
238                                         return;\r
239                                 }\r
240                         }\r
241                 }\r
242                 \r
243                 if(sources.isEmpty()) {\r
244                         System.err.println("No source files");\r
245                         return;\r
246                 }\r
247                 \r
248                 if(outputFile == null) {\r
249                         System.err.println("Name of the output file is not given (use -o flag).");\r
250                         return;\r
251                 }\r
252                 \r
253                 CompilationResult result = compile("1.0", sources, dependencies, null, new GraphCompilerPreferences());\r
254                 for(Problem problem : result.getErrors())\r
255                         out.println(problem.getLocation() + ": " + problem.getDescription());\r
256                 \r
257                 if(result.getGraph() != null)\r
258                         try {\r
259                                 Files.createFile(new File(outputFile), TransferableGraph1.BINDING, result.getGraph());\r
260                         } catch (Exception e) {\r
261                                 e.printStackTrace();\r
262                                 return;\r
263                         }\r
264         }\r
265         \r
266 }\r