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.ObjectsWithType;
39 import org.simantics.db.common.request.ReadRequest;
40 import org.simantics.db.common.request.UniqueRead;
41 import org.simantics.db.common.request.WriteRequest;
42 import org.simantics.db.common.utils.Logger;
43 import org.simantics.db.exception.DatabaseException;
44 import org.simantics.db.layer0.adapter.ActionFactory;
45 import org.simantics.db.layer0.adapter.CopyHandler;
46 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
47 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
48 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
49 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
50 import org.simantics.db.layer0.util.ClipboardUtils;
51 import org.simantics.db.layer0.util.DomainProcessorState;
52 import org.simantics.db.layer0.util.Layer0Utils;
53 import org.simantics.db.layer0.util.ModelTransferableGraphSource;
54 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
55 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
56 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
57 import org.simantics.db.layer0.util.SimanticsKeys;
58 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
59 import org.simantics.db.service.SerialisationSupport;
60 import org.simantics.graph.compiler.CompilationResult;
61 import org.simantics.graph.compiler.GraphCompiler;
62 import org.simantics.graph.compiler.GraphCompilerPreferences;
63 import org.simantics.graph.compiler.ValidationMode;
64 import org.simantics.graph.db.TransferableGraphSource;
65 import org.simantics.graph.db.TransferableGraphs;
66 import org.simantics.graph.diff.Diff;
67 import org.simantics.graph.diff.TransferableGraphDelta1;
68 import org.simantics.graph.representation.Identity;
69 import org.simantics.graph.representation.Root;
70 import org.simantics.graph.representation.TransferableGraph1;
71 import org.simantics.layer0.Layer0;
72 import org.simantics.ltk.ISource;
73 import org.simantics.ltk.Problem;
74 import org.simantics.modeling.ui.Activator;
75 import org.simantics.utils.datastructures.Pair;
78 * @author Antti Villberg
80 public class CompilePGraphs implements ActionFactory {
83 public Runnable create(Object target) {
85 if (!(target instanceof Resource))
88 final Resource r = (Resource)target;
90 return new Runnable() {
92 private void uncheckedClose(Closeable closeable) {
94 if (closeable != null)
96 } catch (IOException e) {
101 private File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {
102 FileOutputStream os = null;
103 InputStream is = null;
105 if (targetFile.exists())
108 is = url.openStream();
110 byte [] buffer = new byte [16384];
111 os = new FileOutputStream (targetFile);
112 while ((read = is.read (buffer)) != -1) {
113 os.write(buffer, 0, read);
125 private File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {
126 String tmpDirStr = System.getProperty("java.io.tmpdir");
127 if (tmpDirStr == null)
128 throw new NullPointerException("java.io.tmpdir property is null");
129 File tmpDir = new File(tmpDirStr);
130 File libFile = new File(tmpDir, libName);
131 return copyResource(libURL, libFile);
134 private File url2file(URL url, String fileName) {
135 if ("file".equals(url.getProtocol())) {
137 File path = new File(URLDecoder.decode(url.getPath(), "UTF-8"));
139 } catch (UnsupportedEncodingException e) {
140 Logger.defaultLogError(e);
142 } else if ("jar".equals(url.getProtocol())) {
144 File libFile = extractLib(url, fileName);
146 } catch (FileNotFoundException e) {
147 Logger.defaultLogError(e);
148 } catch (IOException e) {
149 Logger.defaultLogError(e);
152 System.err.println("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName);
161 final Collection<ISource> sources = new ArrayList<ISource>();
162 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();
164 for(Bundle b : Activator.getContext().getBundles()) {
165 URL tg = b.getEntry("/graph.tg");
166 if(tg == null) continue;
167 File f = url2file(FileLocator.resolve(tg), b.getSymbolicName());
168 dependencies.add(GraphCompiler.read(f));
171 final TransferableGraph1 thisOntology = Simantics.sync(new UniqueRead<TransferableGraph1>() {
174 public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {
176 Layer0 L0 = Layer0.getInstance(graph);
177 Resource parent = graph.getSingleObject(r, L0.PartOf);
179 CopyHandler ch = new DefaultCopyHandler(r) {
181 protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {
183 Map<Resource, ExtentStatus> preStatus = new HashMap<Resource, ExtentStatus>();
184 preStatus.put(r, ExtentStatus.EXTERNAL);
185 if(!parent.equals(graph.getRootLibrary()))
186 preStatus.put(parent, ExtentStatus.EXTERNAL);
188 return new TransferableGraphConfiguration2(null, Collections.emptyList(), preStatus, true, true);
192 protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException {
193 return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf) {
195 protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {
196 return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile) {
199 protected Identity getRootIdentity(DomainProcessorState state, SerialisationSupport support, Resource rootLibrary) throws DatabaseException {
200 return new Identity(state.ids.get(support.getTransientId(rootLibrary)), new Root("", ""));
210 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
211 ch.copyToClipboard(graph, clipboard);
212 for (Set<Representation> object : clipboard.getContents()) {
213 TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
214 if(tg != null) return tg;
221 dependencies.add(thisOntology);
223 Simantics.sync(new ReadRequest() {
226 public void run(ReadGraph graph) throws DatabaseException {
227 Layer0 L0 = Layer0.getInstance(graph);
228 for(Resource file : graph.syncRequest(new ObjectsWithType(r, L0.ConsistsOf, L0.PGraph))) {
230 final String src = graph.getRelatedValue(file, L0.PGraph_definition, Bindings.STRING);
232 final ByteArrayInputStream baos = new ByteArrayInputStream(src.getBytes());
234 sources.add(new ISource() {
237 public int startPos() {
242 public int startLine() {
247 public InputStream open() throws IOException {
252 public int length() throws IOException {
257 public String getName() {
268 final StringBuilder errorStringBuilder = new StringBuilder();
269 GraphCompilerPreferences prefs = new GraphCompilerPreferences();
270 prefs.validate = true;
271 prefs.validateRelationRestrictions = ValidationMode.ERROR;
272 prefs.validateResourceHasType = ValidationMode.IGNORE;
273 final CompilationResult result = GraphCompiler.compile("1.1", sources, dependencies, null, prefs);
275 for(Problem problem : result.getErrors())
276 errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");
277 for(Problem problem : result.getWarnings())
278 errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");
280 if(!result.getErrors().isEmpty() || !result.getWarnings().isEmpty()) {
282 class ErrorMessageDialog extends MessageDialog {
284 public ErrorMessageDialog(Shell shell) {
286 "Unsatisfied dependencies", null,
287 "The following dependencies were missing. Please import the dependencies and try again.",
288 MessageDialog.ERROR, new String[] { "Continue" }, 0);
292 protected Control createCustomArea(Composite composite) {
294 GridLayoutFactory.fillDefaults().applyTo(composite);
296 org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);
297 GridDataFactory.fillDefaults().grab(true, true).applyTo(list);
298 for(Problem problem : result.getErrors())
299 list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");
300 for(Problem problem : result.getWarnings())
301 list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");
309 ErrorMessageDialog md = new ErrorMessageDialog(Display.getCurrent().getActiveShell());
316 final Pair<TransferableGraph1, long[]> existing = Simantics.sync(new UniqueRead<Pair<TransferableGraph1, long[]>>() {
319 public Pair<TransferableGraph1, long[]> perform(ReadGraph graph) throws DatabaseException {
320 Layer0 L0 = Layer0.getInstance(graph);
321 TransferableGraph1 tg = graph.getPossibleRelatedValue(r, L0.SharedOntology_tg, Bindings.getBindingUnchecked( TransferableGraph1.class ));
322 if(tg == null) return null;
323 long[] tgResources = graph.getPossibleRelatedValue(r, L0.SharedOntology_tgResources, Bindings.LONG_ARRAY);
324 if(tgResources == null) return null;
325 return Pair.make(tg, tgResources);
330 if(existing != null) {
334 Simantics.sync(new WriteRequest() {
337 public void perform(WriteGraph graph) throws DatabaseException {
339 TransferableGraphDelta1 delta = new Diff(existing.first, result.getGraph()).diff();
340 long[] resourceArray = TransferableGraphs.applyDelta(graph, existing.second, delta);
342 Layer0 L0 = Layer0.getInstance(graph);
343 graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));
344 graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, resourceArray, Bindings.LONG_ARRAY);
346 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
352 } catch (Throwable t) {
353 throw new PlatformException(t);
360 final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(r);
362 DefaultPasteHandler.defaultExecute(result.getGraph(), r, advisor);
364 Simantics.sync(new WriteRequest() {
367 public void perform(WriteGraph graph) throws DatabaseException {
369 Layer0 L0 = Layer0.getInstance(graph);
370 graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));
371 graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, advisor.getResourceIds(), Bindings.LONG_ARRAY);
373 Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));
381 } catch (Exception e) {
382 Logger.defaultLogError(e);