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