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