1 package org.simantics.modeling.ui.actions;
\r
3 import static org.simantics.db.common.utils.Transaction.endTransaction;
\r
5 import java.io.ByteArrayInputStream;
\r
6 import java.io.Closeable;
\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
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
77 * @author Antti Villberg
\r
79 public class CompilePGraphs implements ActionFactory {
\r
82 public Runnable create(Object target) {
\r
84 if (!(target instanceof Resource))
\r
87 final Resource r = (Resource)target;
\r
89 return new Runnable() {
\r
91 private void uncheckedClose(Closeable closeable) {
\r
93 if (closeable != null)
\r
95 } catch (IOException e) {
\r
100 private File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {
\r
101 FileOutputStream os = null;
\r
102 InputStream is = null;
\r
104 if (targetFile.exists())
\r
105 targetFile.delete();
\r
107 is = url.openStream();
\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
119 uncheckedClose(os);
\r
120 uncheckedClose(is);
\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
133 private File url2file(URL url, String fileName) {
\r
134 if ("file".equals(url.getProtocol())) {
\r
136 File path = new File(URLDecoder.decode(url.getPath(), "UTF-8"));
\r
138 } catch (UnsupportedEncodingException e) {
\r
139 Logger.defaultLogError(e);
\r
141 } else if ("jar".equals(url.getProtocol())) {
\r
143 File libFile = extractLib(url, fileName);
\r
145 } catch (FileNotFoundException e) {
\r
146 Logger.defaultLogError(e);
\r
147 } catch (IOException e) {
\r
148 Logger.defaultLogError(e);
\r
151 System.err.println("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName);
\r
156 public void run() {
\r
160 final Collection<ISource> sources = new ArrayList<ISource>();
\r
161 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();
\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
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
187 final TransferableGraph1 thisOntology = Simantics.sync(new UniqueRead<TransferableGraph1>() {
\r
190 public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {
\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
196 CopyHandler ch = new DefaultCopyHandler(r) {
\r
198 protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {
\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
205 return new TransferableGraphConfiguration2(null, Collections.emptyList(), preStatus, true, true);
\r
209 protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException {
\r
210 return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf) {
\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
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
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
238 dependencies.add(thisOntology);
\r
240 Simantics.sync(new ReadRequest() {
\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
247 final String src = graph.getRelatedValue(file, L0.PGraph_definition, Bindings.STRING);
\r
249 final ByteArrayInputStream baos = new ByteArrayInputStream(src.getBytes());
\r
251 sources.add(new ISource() {
\r
254 public int startPos() {
\r
259 public int startLine() {
\r
264 public InputStream open() throws IOException {
\r
269 public int length() throws IOException {
\r
270 return src.length();
\r
274 public String getName() {
\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
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
299 if(!result.getErrors().isEmpty() || !result.getWarnings().isEmpty()) {
\r
301 class ErrorMessageDialog extends MessageDialog {
\r
303 public ErrorMessageDialog(Shell 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
311 protected Control createCustomArea(Composite composite) {
\r
313 GridLayoutFactory.fillDefaults().applyTo(composite);
\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
328 ErrorMessageDialog md = new ErrorMessageDialog(Display.getCurrent().getActiveShell());
\r
335 final Pair<TransferableGraph1, long[]> existing = Simantics.sync(new UniqueRead<Pair<TransferableGraph1, long[]>>() {
\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
349 if(existing != null) {
\r
353 Simantics.sync(new WriteRequest() {
\r
356 public void perform(WriteGraph graph) throws DatabaseException {
\r
358 TransferableGraphDelta1 delta = new Diff(existing.first, result.getGraph()).diff();
\r
359 long[] resourceArray = TransferableGraphs.applyDelta(graph, existing.second, delta);
\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
365 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
\r
371 } catch (Throwable t) {
\r
372 throw new PlatformException(t);
\r
379 final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(r);
\r
381 // final ImportAdvisor advisor = new ImportAdvisor(r, modelName);
\r
382 DefaultPasteHandler.defaultExecute(result.getGraph(), r, advisor);
\r
384 Simantics.sync(new WriteRequest() {
\r
387 public void perform(WriteGraph graph) throws DatabaseException {
\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
393 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
\r
404 } catch (Exception e) {
\r
405 Logger.defaultLogError(e);
\r