1 package org.simantics.modeling.ui.actions;
3 import static org.simantics.db.common.utils.Transaction.endTransaction;
5 import java.io.ByteArrayInputStream;
6 import java.io.Closeable;
8 import java.io.FileNotFoundException;
9 import java.io.FileOutputStream;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.UnsupportedEncodingException;
14 import java.net.URLDecoder;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
22 import org.eclipse.core.runtime.FileLocator;
23 import org.eclipse.jface.dialogs.MessageDialog;
24 import org.eclipse.jface.layout.GridDataFactory;
25 import org.eclipse.jface.layout.GridLayoutFactory;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Display;
30 import org.eclipse.swt.widgets.Shell;
31 import org.osgi.framework.Bundle;
32 import org.simantics.PlatformException;
33 import org.simantics.Simantics;
34 import org.simantics.databoard.Bindings;
35 import org.simantics.db.ReadGraph;
36 import org.simantics.db.Resource;
37 import org.simantics.db.WriteGraph;
38 import org.simantics.db.common.request.IndexRoot;
39 import org.simantics.db.common.request.ObjectsWithType;
40 import org.simantics.db.common.request.ReadRequest;
41 import org.simantics.db.common.request.UniqueRead;
42 import org.simantics.db.common.request.WriteRequest;
43 import org.simantics.db.common.utils.Logger;
44 import org.simantics.db.exception.DatabaseException;
45 import org.simantics.db.layer0.adapter.ActionFactory;
46 import org.simantics.db.layer0.adapter.CopyHandler;
47 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
48 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
49 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
50 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
51 import org.simantics.db.layer0.util.ClipboardUtils;
52 import org.simantics.db.layer0.util.DomainProcessorState;
53 import org.simantics.db.layer0.util.Layer0Utils;
54 import org.simantics.db.layer0.util.ModelTransferableGraphSource;
55 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
56 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
57 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
58 import org.simantics.db.layer0.util.SimanticsKeys;
59 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
60 import org.simantics.db.service.SerialisationSupport;
61 import org.simantics.graph.compiler.CompilationResult;
62 import org.simantics.graph.compiler.ExternalFileLoader;
63 import org.simantics.graph.compiler.GraphCompiler;
64 import org.simantics.graph.compiler.GraphCompilerPreferences;
65 import org.simantics.graph.compiler.ValidationMode;
66 import org.simantics.graph.db.TransferableGraphSource;
67 import org.simantics.graph.db.TransferableGraphs;
68 import org.simantics.graph.diff.Diff;
69 import org.simantics.graph.diff.TransferableGraphDelta1;
70 import org.simantics.graph.representation.Identity;
71 import org.simantics.graph.representation.Root;
72 import org.simantics.graph.representation.TransferableGraph1;
73 import org.simantics.graphfile.ontology.GraphFileResource;
74 import org.simantics.layer0.Layer0;
75 import org.simantics.ltk.ISource;
76 import org.simantics.ltk.Problem;
77 import org.simantics.modeling.ui.Activator;
78 import org.simantics.utils.datastructures.Pair;
81 * @author Antti Villberg
83 public class CompilePGraphs implements ActionFactory {
86 public Runnable create(Object target) {
88 if (!(target instanceof Resource))
91 final Resource r = (Resource)target;
93 return new Runnable() {
95 private void uncheckedClose(Closeable closeable) {
97 if (closeable != null)
99 } catch (IOException e) {
104 private File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {
105 FileOutputStream os = null;
106 InputStream is = null;
108 if (targetFile.exists())
111 is = url.openStream();
113 byte [] buffer = new byte [16384];
114 os = new FileOutputStream (targetFile);
115 while ((read = is.read (buffer)) != -1) {
116 os.write(buffer, 0, read);
128 private File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {
129 String tmpDirStr = System.getProperty("java.io.tmpdir");
130 if (tmpDirStr == null)
131 throw new NullPointerException("java.io.tmpdir property is null");
132 File tmpDir = new File(tmpDirStr);
133 File libFile = new File(tmpDir, libName);
134 return copyResource(libURL, libFile);
137 private File url2file(URL url, String fileName) {
138 if ("file".equals(url.getProtocol())) {
140 File path = new File(URLDecoder.decode(url.getPath(), "UTF-8"));
142 } catch (UnsupportedEncodingException e) {
143 Logger.defaultLogError(e);
145 } else if ("jar".equals(url.getProtocol())) {
147 File libFile = extractLib(url, fileName);
149 } catch (FileNotFoundException e) {
150 Logger.defaultLogError(e);
151 } catch (IOException e) {
152 Logger.defaultLogError(e);
155 System.err.println("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName);
164 final Collection<ISource> sources = new ArrayList<ISource>();
165 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();
167 for(Bundle b : Activator.getContext().getBundles()) {
168 URL tg = b.getEntry("/graph.tg");
169 if(tg == null) continue;
170 File f = url2file(FileLocator.resolve(tg), b.getSymbolicName());
171 dependencies.add(GraphCompiler.read(f));
174 final TransferableGraph1 thisOntology = Simantics.sync(new UniqueRead<TransferableGraph1>() {
177 public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {
179 Layer0 L0 = Layer0.getInstance(graph);
180 Resource parent = graph.getSingleObject(r, L0.PartOf);
182 CopyHandler ch = new DefaultCopyHandler(r) {
184 protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {
186 Map<Resource, ExtentStatus> preStatus = new HashMap<Resource, ExtentStatus>();
187 preStatus.put(r, ExtentStatus.EXTERNAL);
188 if(!parent.equals(graph.getRootLibrary()))
189 preStatus.put(parent, ExtentStatus.EXTERNAL);
191 return new TransferableGraphConfiguration2(null, Collections.emptyList(), preStatus, true, true);
195 protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException {
196 return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf) {
198 protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {
199 return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile) {
202 protected Identity getRootIdentity(DomainProcessorState state, SerialisationSupport support, Resource rootLibrary) throws DatabaseException {
203 return new Identity(state.ids.get(support.getTransientId(rootLibrary)), new Root("", ""));
213 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
214 ch.copyToClipboard(graph, clipboard);
215 for (Set<Representation> object : clipboard.getContents()) {
216 TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
217 if(tg != null) return tg;
224 dependencies.add(thisOntology);
226 Simantics.sync(new ReadRequest() {
229 public void run(ReadGraph graph) throws DatabaseException {
230 Layer0 L0 = Layer0.getInstance(graph);
231 for(Resource file : graph.syncRequest(new ObjectsWithType(r, L0.ConsistsOf, L0.PGraph))) {
233 final String src = graph.getRelatedValue(file, L0.PGraph_definition, Bindings.STRING);
235 final ByteArrayInputStream baos = new ByteArrayInputStream(src.getBytes());
237 sources.add(new ISource() {
240 public int startPos() {
245 public int startLine() {
250 public InputStream open() throws IOException {
255 public int length() throws IOException {
260 public String getName() {
271 final StringBuilder errorStringBuilder = new StringBuilder();
272 GraphCompilerPreferences prefs = new GraphCompilerPreferences();
273 prefs.validate = true;
274 prefs.validateRelationRestrictions = ValidationMode.ERROR;
275 prefs.validateResourceHasType = ValidationMode.IGNORE;
277 final CompilationResult result = Simantics.sync(new UniqueRead<CompilationResult>() {
280 public CompilationResult perform(ReadGraph graph) throws DatabaseException {
282 final Resource root = graph.syncRequest(new IndexRoot(r));
283 final String baseURI = graph.getURI(root);
285 ExternalFileLoader fileLoader = new ExternalFileLoader() {
287 public byte[] load(String fileName) throws IOException {
289 GraphFileResource GF = GraphFileResource.getInstance(graph);
290 Resource file = graph.getResource(baseURI + "/" + fileName);
291 return graph.getRelatedValue(file, GF.HasFiledata, Bindings.BYTE_ARRAY);
292 } catch (DatabaseException e) {
293 throw new IOException(e);
298 return GraphCompiler.compile("1.1", sources, dependencies, fileLoader, prefs);
304 for(Problem problem : result.getErrors())
305 errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");
306 for(Problem problem : result.getWarnings())
307 errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");
309 if(!result.getErrors().isEmpty() || !result.getWarnings().isEmpty()) {
311 class ErrorMessageDialog extends MessageDialog {
313 public ErrorMessageDialog(Shell shell) {
315 "Unsatisfied dependencies", null,
316 "The following dependencies were missing. Please import the dependencies and try again.",
317 MessageDialog.ERROR, new String[] { "Continue" }, 0);
321 protected Control createCustomArea(Composite composite) {
323 GridLayoutFactory.fillDefaults().applyTo(composite);
325 org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);
326 GridDataFactory.fillDefaults().grab(true, true).applyTo(list);
327 for(Problem problem : result.getErrors())
328 list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");
329 for(Problem problem : result.getWarnings())
330 list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");
338 ErrorMessageDialog md = new ErrorMessageDialog(Display.getCurrent().getActiveShell());
345 final Pair<TransferableGraph1, long[]> existing = Simantics.sync(new UniqueRead<Pair<TransferableGraph1, long[]>>() {
348 public Pair<TransferableGraph1, long[]> perform(ReadGraph graph) throws DatabaseException {
349 Layer0 L0 = Layer0.getInstance(graph);
350 TransferableGraph1 tg = graph.getPossibleRelatedValue(r, L0.SharedOntology_tg, Bindings.getBindingUnchecked( TransferableGraph1.class ));
351 if(tg == null) return null;
352 long[] tgResources = graph.getPossibleRelatedValue(r, L0.SharedOntology_tgResources, Bindings.LONG_ARRAY);
353 if(tgResources == null) return null;
354 return Pair.make(tg, tgResources);
359 if(existing != null) {
363 Simantics.sync(new WriteRequest() {
366 public void perform(WriteGraph graph) throws DatabaseException {
368 TransferableGraphDelta1 delta = new Diff(existing.first, result.getGraph()).diff();
369 long[] resourceArray = TransferableGraphs.applyDelta(graph, existing.second, delta);
371 Layer0 L0 = Layer0.getInstance(graph);
372 graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));
373 graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, resourceArray, Bindings.LONG_ARRAY);
375 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
381 } catch (Throwable t) {
382 throw new PlatformException(t);
389 final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(r);
391 DefaultPasteHandler.defaultExecute(result.getGraph(), r, advisor);
393 Simantics.sync(new WriteRequest() {
396 public void perform(WriteGraph graph) throws DatabaseException {
398 Layer0 L0 = Layer0.getInstance(graph);
399 graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));
400 graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, advisor.getResourceIds(), Bindings.LONG_ARRAY);
402 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
410 } catch (Exception e) {
411 Logger.defaultLogError(e);