]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/CompilePGraphs.java
Sync git svn branch with SVN repository r33382.
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / actions / CompilePGraphs.java
1 package org.simantics.modeling.ui.actions;\r
2 \r
3 import static org.simantics.db.common.utils.Transaction.endTransaction;\r
4 \r
5 import java.io.ByteArrayInputStream;\r
6 import java.io.Closeable;\r
7 import java.io.File;\r
8 import java.io.FileNotFoundException;\r
9 import java.io.FileOutputStream;\r
10 import java.io.IOException;\r
11 import java.io.InputStream;\r
12 import java.io.UnsupportedEncodingException;\r
13 import java.net.URL;\r
14 import java.net.URLDecoder;\r
15 import java.util.ArrayList;\r
16 import java.util.Collection;\r
17 import java.util.Collections;\r
18 import java.util.HashMap;\r
19 import java.util.Map;\r
20 import java.util.Set;\r
21 \r
22 import org.eclipse.core.runtime.FileLocator;\r
23 import org.eclipse.core.runtime.Platform;\r
24 import org.eclipse.jface.dialogs.MessageDialog;\r
25 import org.eclipse.jface.layout.GridDataFactory;\r
26 import org.eclipse.jface.layout.GridLayoutFactory;\r
27 import org.eclipse.swt.SWT;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.eclipse.swt.widgets.Control;\r
30 import org.eclipse.swt.widgets.Display;\r
31 import org.eclipse.swt.widgets.Shell;\r
32 import org.simantics.PlatformException;\r
33 import org.simantics.Simantics;\r
34 import org.simantics.databoard.Bindings;\r
35 import org.simantics.db.ReadGraph;\r
36 import org.simantics.db.Resource;\r
37 import org.simantics.db.WriteGraph;\r
38 import org.simantics.db.common.request.ObjectsWithType;\r
39 import org.simantics.db.common.request.ReadRequest;\r
40 import org.simantics.db.common.request.UniqueRead;\r
41 import org.simantics.db.common.request.WriteRequest;\r
42 import org.simantics.db.common.utils.Logger;\r
43 import org.simantics.db.exception.DatabaseException;\r
44 import org.simantics.db.layer0.adapter.ActionFactory;\r
45 import org.simantics.db.layer0.adapter.CopyHandler;\r
46 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;\r
47 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;\r
48 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
49 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
50 import org.simantics.db.layer0.util.ClipboardUtils;\r
51 import org.simantics.db.layer0.util.DomainProcessorState;\r
52 import org.simantics.db.layer0.util.Layer0Utils;\r
53 import org.simantics.db.layer0.util.ModelTransferableGraphSource;\r
54 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
55 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
56 import org.simantics.db.layer0.util.SimanticsClipboardImpl;\r
57 import org.simantics.db.layer0.util.SimanticsKeys;\r
58 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
59 import org.simantics.db.service.SerialisationSupport;\r
60 import org.simantics.graph.compiler.CompilationResult;\r
61 import org.simantics.graph.compiler.GraphCompiler;\r
62 import org.simantics.graph.compiler.GraphCompilerPreferences;\r
63 import org.simantics.graph.compiler.ValidationMode;\r
64 import org.simantics.graph.db.TransferableGraphSource;\r
65 import org.simantics.graph.db.TransferableGraphs;\r
66 import org.simantics.graph.diff.Diff;\r
67 import org.simantics.graph.diff.TransferableGraphDelta1;\r
68 import org.simantics.graph.representation.Identity;\r
69 import org.simantics.graph.representation.Root;\r
70 import org.simantics.graph.representation.TransferableGraph1;\r
71 import org.simantics.layer0.Layer0;\r
72 import org.simantics.ltk.ISource;\r
73 import org.simantics.ltk.Problem;\r
74 import org.simantics.utils.datastructures.Pair;\r
75 \r
76 /**\r
77  * @author Antti Villberg\r
78  */\r
79 public class CompilePGraphs implements ActionFactory {\r
80 \r
81     @Override\r
82     public Runnable create(Object target) {\r
83         \r
84         if (!(target instanceof Resource))\r
85             return null;\r
86         \r
87         final Resource r = (Resource)target;\r
88 \r
89         return new Runnable() {\r
90                 \r
91             private void uncheckedClose(Closeable closeable) {\r
92                 try {\r
93                     if (closeable != null)\r
94                         closeable.close();\r
95                 } catch (IOException e) {\r
96                     //ignore\r
97                 }\r
98             }\r
99                 \r
100             private File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {\r
101                 FileOutputStream os = null;\r
102                 InputStream is = null;\r
103                 try {\r
104                     if (targetFile.exists())\r
105                         targetFile.delete();\r
106 \r
107                     is = url.openStream();\r
108                     int read;\r
109                     byte [] buffer = new byte [16384];\r
110                     os = new FileOutputStream (targetFile);\r
111                     while ((read = is.read (buffer)) != -1) {\r
112                         os.write(buffer, 0, read);\r
113                     }\r
114                     os.close ();\r
115                     is.close ();\r
116 \r
117                     return targetFile;\r
118                 } finally {\r
119                     uncheckedClose(os);\r
120                     uncheckedClose(is);\r
121                 }\r
122             }\r
123                 \r
124             private File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {\r
125                 String tmpDirStr = System.getProperty("java.io.tmpdir");\r
126                 if (tmpDirStr == null)\r
127                     throw new NullPointerException("java.io.tmpdir property is null");\r
128                 File tmpDir = new File(tmpDirStr);\r
129                 File libFile = new File(tmpDir, libName);\r
130                 return copyResource(libURL, libFile);\r
131             }\r
132                 \r
133                 private File url2file(URL url, String fileName) {\r
134                         if ("file".equals(url.getProtocol())) {\r
135                                 try {\r
136                                         File path = new File(URLDecoder.decode(url.getPath(), "UTF-8"));\r
137                                         return path;\r
138                                 } catch (UnsupportedEncodingException e) {\r
139                                         Logger.defaultLogError(e);\r
140                                 }\r
141                         } else if ("jar".equals(url.getProtocol())) {\r
142                                 try {\r
143                                         File libFile = extractLib(url, fileName);\r
144                                         return libFile;\r
145                                 } catch (FileNotFoundException e) {\r
146                                         Logger.defaultLogError(e);\r
147                                 } catch (IOException e) {\r
148                                         Logger.defaultLogError(e);\r
149                                 }\r
150                         } else {\r
151                                 System.err.println("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName);\r
152                         }       \r
153                         return null;\r
154                 }\r
155                         @Override\r
156                         public void run() {\r
157                                 \r
158                                 try {\r
159                                         \r
160                                 final Collection<ISource> sources = new ArrayList<ISource>();\r
161                                 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();\r
162 \r
163                         File L0GraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.layer0").getEntry("/graph.tg")), "L0_graph.tg");\r
164                         File L0XGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.layer0x.ontology").getEntry("/graph.tg")), "L0X_graph.tg");\r
165                         File DiagramGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.diagram.ontology").getEntry("/graph.tg")), "DIA_graph.tg");\r
166                         File G2DGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.g2d.ontology").getEntry("/graph.tg")), "G2D_graph.tg");\r
167                         File StructuralGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.structural.ontology").getEntry("/graph.tg")), "ST_graph.tg");\r
168                         File ModelingGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.modeling.ontology").getEntry("/graph.tg")), "MOD_graph.tg");\r
169                         File SimulationGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.simulation.ontology").getEntry("/graph.tg")), "SIMU_graph.tg");\r
170                         File DocumentGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.document.ontology").getEntry("/graph.tg")), "DOC_graph.tg");\r
171                         File SpreadsheetGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.spreadsheet.ontology").getEntry("/graph.tg")), "SHEET_graph.tg");\r
172                         File ProjectGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.project.ontology").getEntry("/graph.tg")), "PROJ_graph.tg");\r
173                         File SelectionViewGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.selectionview.ontology").getEntry("/graph.tg")), "SEL_graph.tg");\r
174                         \r
175                                 dependencies.add(GraphCompiler.read(L0GraphFile));\r
176                                 dependencies.add(GraphCompiler.read(L0XGraphFile));\r
177                                 dependencies.add(GraphCompiler.read(DiagramGraphFile));\r
178                                 dependencies.add(GraphCompiler.read(G2DGraphFile));\r
179                                 dependencies.add(GraphCompiler.read(StructuralGraphFile));\r
180                                 dependencies.add(GraphCompiler.read(ModelingGraphFile));\r
181                                 dependencies.add(GraphCompiler.read(SimulationGraphFile));\r
182                                 dependencies.add(GraphCompiler.read(DocumentGraphFile));\r
183                                 dependencies.add(GraphCompiler.read(SpreadsheetGraphFile));\r
184                                 dependencies.add(GraphCompiler.read(ProjectGraphFile));\r
185                                 dependencies.add(GraphCompiler.read(SelectionViewGraphFile));\r
186 \r
187                                 final TransferableGraph1 thisOntology = Simantics.sync(new UniqueRead<TransferableGraph1>() {\r
188 \r
189                                                 @Override\r
190                                                 public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {\r
191                                                         \r
192                                                         Layer0 L0 = Layer0.getInstance(graph);\r
193                                                         Resource parent = graph.getSingleObject(r, L0.PartOf);\r
194                                                         String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);\r
195                                                         \r
196                                     CopyHandler ch = new DefaultCopyHandler(r) {\r
197                                         \r
198                                         protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {\r
199 \r
200                                                 Map<Resource, ExtentStatus> preStatus = new HashMap<Resource, ExtentStatus>();\r
201                                                 preStatus.put(r, ExtentStatus.EXTERNAL);\r
202                                                 if(!parent.equals(graph.getRootLibrary()))\r
203                                                         preStatus.put(parent, ExtentStatus.EXTERNAL);\r
204                                                 \r
205                                                 return new TransferableGraphConfiguration2(null, Collections.emptyList(), preStatus, true, true);\r
206                                                 \r
207                                         }\r
208 \r
209                                         protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException {\r
210                                                 return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf) {\r
211 \r
212                                                         protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {\r
213                                                         return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile) {\r
214 \r
215                                                                         @Override\r
216                                                                         protected Identity getRootIdentity(DomainProcessorState state, SerialisationSupport support, Resource rootLibrary) throws DatabaseException {\r
217                                                                                 return new Identity(state.ids.get(support.getTransientId(rootLibrary)), new Root("", ""));\r
218                                                                         }\r
219 \r
220                                                         };\r
221                                                         }\r
222 \r
223                                                 });\r
224                                         }\r
225                                         \r
226                                     };\r
227                                     SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
228                                     ch.copyToClipboard(graph, clipboard);\r
229                                     for (Set<Representation> object : clipboard.getContents()) {\r
230                                         TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
231                                         if(tg != null) return tg;\r
232                                     }\r
233                                                         return null;\r
234                                                 }\r
235                                         \r
236                                 });\r
237 \r
238                                 dependencies.add(thisOntology);\r
239                                 \r
240                                         Simantics.sync(new ReadRequest() {\r
241 \r
242                                                 @Override\r
243                                                 public void run(ReadGraph graph) throws DatabaseException {\r
244                                                         Layer0 L0 = Layer0.getInstance(graph);\r
245                                                         for(Resource file : graph.syncRequest(new ObjectsWithType(r, L0.ConsistsOf, L0.PGraph))) {\r
246                                                                 \r
247                                                                 final String src = graph.getRelatedValue(file, L0.PGraph_definition, Bindings.STRING);\r
248 \r
249                                                                 final ByteArrayInputStream baos = new ByteArrayInputStream(src.getBytes()); \r
250                                                         \r
251                                                         sources.add(new ISource() {\r
252                                                                         \r
253                                                                         @Override\r
254                                                                         public int startPos() {\r
255                                                                                 return 0;\r
256                                                                         }\r
257                                                                         \r
258                                                                         @Override\r
259                                                                         public int startLine() {\r
260                                                                                 return 0;\r
261                                                                         }\r
262                                                                         \r
263                                                                         @Override\r
264                                                                         public InputStream open() throws IOException {\r
265                                                                                 return baos;\r
266                                                                         }\r
267                                                                         \r
268                                                                         @Override\r
269                                                                         public int length() throws IOException {\r
270                                                                                 return src.length();\r
271                                                                         }\r
272                                                                         \r
273                                                                         @Override\r
274                                                                         public String getName() {\r
275                                                                                 return "Source";\r
276                                                                         }\r
277                                                                         \r
278                                                                 });\r
279                                                                 \r
280                                                         }\r
281                                                 }\r
282                                                 \r
283                                         });\r
284                                 \r
285 \r
286                                 \r
287                                 final StringBuilder errorStringBuilder = new StringBuilder();\r
288                                 GraphCompilerPreferences prefs = new GraphCompilerPreferences();\r
289                                 prefs.validate = true;\r
290                                 prefs.validateRelationRestrictions = ValidationMode.ERROR;\r
291                                 prefs.validateResourceHasType = ValidationMode.IGNORE;\r
292                                 final CompilationResult result = GraphCompiler.compile("1.1", sources, dependencies, null, prefs);\r
293                                 \r
294                                 for(Problem problem : result.getErrors())\r
295                                         errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
296                                 for(Problem problem : result.getWarnings())\r
297                                         errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
298                                 \r
299                                 if(!result.getErrors().isEmpty() || !result.getWarnings().isEmpty()) {\r
300 \r
301                                         class ErrorMessageDialog extends MessageDialog {\r
302 \r
303                                                 public ErrorMessageDialog(Shell shell) {\r
304                                                         super(shell, \r
305                                                                         "Unsatisfied dependencies", null, \r
306                                                                         "The following dependencies were missing. Please import the dependencies and try again.", \r
307                                                                         MessageDialog.ERROR, new String[] { "Continue" }, 0);\r
308                                                 }\r
309 \r
310                                                 @Override\r
311                                                 protected Control createCustomArea(Composite composite) {\r
312                                                         \r
313                                                         GridLayoutFactory.fillDefaults().applyTo(composite);\r
314                                                         \r
315                                                         org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);\r
316                                                         GridDataFactory.fillDefaults().grab(true, true).applyTo(list);\r
317                                                 for(Problem problem : result.getErrors())\r
318                                                         list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
319                                                 for(Problem problem : result.getWarnings())\r
320                                                         list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
321 \r
322                                                         return composite;\r
323                                                         \r
324                                                 }\r
325 \r
326                                         }\r
327 \r
328                                         ErrorMessageDialog md = new ErrorMessageDialog(Display.getCurrent().getActiveShell());\r
329                                         md.open();\r
330 \r
331                                         return;\r
332                                 }\r
333                                 \r
334                                 \r
335                                 final Pair<TransferableGraph1, long[]> existing = Simantics.sync(new UniqueRead<Pair<TransferableGraph1, long[]>>() {\r
336 \r
337                                                 @Override\r
338                                                 public Pair<TransferableGraph1, long[]> perform(ReadGraph graph) throws DatabaseException {\r
339                                                         Layer0 L0 = Layer0.getInstance(graph);\r
340                                                         TransferableGraph1 tg = graph.getPossibleRelatedValue(r, L0.SharedOntology_tg, Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
341                                                         if(tg == null) return null;\r
342                                                         long[] tgResources = graph.getPossibleRelatedValue(r, L0.SharedOntology_tgResources, Bindings.LONG_ARRAY);\r
343                                                         if(tgResources == null) return null;\r
344                                                         return Pair.make(tg,  tgResources);\r
345                                                 }\r
346                                         \r
347                                 });\r
348                                 \r
349                                 if(existing != null) {\r
350                                         \r
351                             try {\r
352                                 \r
353                                                         Simantics.sync(new WriteRequest() {\r
354                                                                 \r
355                                                                 @Override\r
356                                                                 public void perform(WriteGraph graph) throws DatabaseException {\r
357 \r
358                                                     TransferableGraphDelta1 delta = new Diff(existing.first, result.getGraph()).diff();\r
359                                                 long[] resourceArray = TransferableGraphs.applyDelta(graph, existing.second, delta);\r
360 \r
361                                                                         Layer0 L0 = Layer0.getInstance(graph);\r
362                                                                         graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
363                                                                         graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, resourceArray, Bindings.LONG_ARRAY);\r
364                                                                         \r
365                                                         Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));\r
366 \r
367                                                                 }\r
368                                                                 \r
369                                                         });\r
370 \r
371                             } catch (Throwable t) {\r
372                                 throw new PlatformException(t);\r
373                             } finally {\r
374                                 endTransaction();\r
375                             }\r
376                                         \r
377                                 } else {\r
378                                 \r
379                                         final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(r);\r
380                                         \r
381         //                              final ImportAdvisor advisor = new ImportAdvisor(r, modelName);\r
382                                         DefaultPasteHandler.defaultExecute(result.getGraph(), r, advisor);\r
383                                         \r
384                                                 Simantics.sync(new WriteRequest() {\r
385         \r
386                                                         @Override\r
387                                                         public void perform(WriteGraph graph) throws DatabaseException {\r
388         \r
389                                                                 Layer0 L0 = Layer0.getInstance(graph);\r
390                                                                 graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
391                                                                 graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, advisor.getResourceIds(), Bindings.LONG_ARRAY);\r
392 \r
393                                                 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));\r
394 \r
395                                                         }\r
396                                                         \r
397                                                 });\r
398                                                 \r
399                                 }\r
400                                         \r
401                                         \r
402 \r
403                                         \r
404                                 } catch (Exception e) {\r
405                                         Logger.defaultLogError(e);\r
406                                 }\r
407                                 \r
408                         }\r
409                 \r
410         };\r
411         \r
412     }\r
413 \r
414 }\r