--- /dev/null
+package org.simantics.modeling.ui.actions;\r
+\r
+import static org.simantics.db.common.utils.Transaction.endTransaction;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.Closeable;\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.UnsupportedEncodingException;\r
+import java.net.URL;\r
+import java.net.URLDecoder;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.FileLocator;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.simantics.PlatformException;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.db.layer0.adapter.CopyHandler;\r
+import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;\r
+import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;\r
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
+import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
+import org.simantics.db.layer0.util.ClipboardUtils;\r
+import org.simantics.db.layer0.util.DomainProcessorState;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSource;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
+import org.simantics.db.layer0.util.SimanticsClipboardImpl;\r
+import org.simantics.db.layer0.util.SimanticsKeys;\r
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.graph.compiler.CompilationResult;\r
+import org.simantics.graph.compiler.GraphCompiler;\r
+import org.simantics.graph.compiler.GraphCompilerPreferences;\r
+import org.simantics.graph.compiler.ValidationMode;\r
+import org.simantics.graph.db.TransferableGraphSource;\r
+import org.simantics.graph.db.TransferableGraphs;\r
+import org.simantics.graph.diff.Diff;\r
+import org.simantics.graph.diff.TransferableGraphDelta1;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.Root;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ltk.ISource;\r
+import org.simantics.ltk.Problem;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * @author Antti Villberg\r
+ */\r
+public class CompilePGraphs implements ActionFactory {\r
+\r
+ @Override\r
+ public Runnable create(Object target) {\r
+ \r
+ if (!(target instanceof Resource))\r
+ return null;\r
+ \r
+ final Resource r = (Resource)target;\r
+\r
+ return new Runnable() {\r
+ \r
+ private void uncheckedClose(Closeable closeable) {\r
+ try {\r
+ if (closeable != null)\r
+ closeable.close();\r
+ } catch (IOException e) {\r
+ //ignore\r
+ }\r
+ }\r
+ \r
+ private File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {\r
+ FileOutputStream os = null;\r
+ InputStream is = null;\r
+ try {\r
+ if (targetFile.exists())\r
+ targetFile.delete();\r
+\r
+ is = url.openStream();\r
+ int read;\r
+ byte [] buffer = new byte [16384];\r
+ os = new FileOutputStream (targetFile);\r
+ while ((read = is.read (buffer)) != -1) {\r
+ os.write(buffer, 0, read);\r
+ }\r
+ os.close ();\r
+ is.close ();\r
+\r
+ return targetFile;\r
+ } finally {\r
+ uncheckedClose(os);\r
+ uncheckedClose(is);\r
+ }\r
+ }\r
+ \r
+ private File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {\r
+ String tmpDirStr = System.getProperty("java.io.tmpdir");\r
+ if (tmpDirStr == null)\r
+ throw new NullPointerException("java.io.tmpdir property is null");\r
+ File tmpDir = new File(tmpDirStr);\r
+ File libFile = new File(tmpDir, libName);\r
+ return copyResource(libURL, libFile);\r
+ }\r
+ \r
+ private File url2file(URL url, String fileName) {\r
+ if ("file".equals(url.getProtocol())) {\r
+ try {\r
+ File path = new File(URLDecoder.decode(url.getPath(), "UTF-8"));\r
+ return path;\r
+ } catch (UnsupportedEncodingException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ } else if ("jar".equals(url.getProtocol())) {\r
+ try {\r
+ File libFile = extractLib(url, fileName);\r
+ return libFile;\r
+ } catch (FileNotFoundException e) {\r
+ Logger.defaultLogError(e);\r
+ } catch (IOException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ } else {\r
+ System.err.println("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName);\r
+ } \r
+ return null;\r
+ }\r
+ @Override\r
+ public void run() {\r
+ \r
+ try {\r
+ \r
+ final Collection<ISource> sources = new ArrayList<ISource>();\r
+ Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();\r
+\r
+ File L0GraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.layer0").getEntry("/graph.tg")), "L0_graph.tg");\r
+ File L0XGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.layer0x.ontology").getEntry("/graph.tg")), "L0X_graph.tg");\r
+ File DiagramGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.diagram.ontology").getEntry("/graph.tg")), "DIA_graph.tg");\r
+ File G2DGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.g2d.ontology").getEntry("/graph.tg")), "G2D_graph.tg");\r
+ File StructuralGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.structural.ontology").getEntry("/graph.tg")), "ST_graph.tg");\r
+ File ModelingGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.modeling.ontology").getEntry("/graph.tg")), "MOD_graph.tg");\r
+ File SimulationGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.simulation.ontology").getEntry("/graph.tg")), "SIMU_graph.tg");\r
+ File DocumentGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.document.ontology").getEntry("/graph.tg")), "DOC_graph.tg");\r
+ File SpreadsheetGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.spreadsheet.ontology").getEntry("/graph.tg")), "SHEET_graph.tg");\r
+ File ProjectGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.project.ontology").getEntry("/graph.tg")), "PROJ_graph.tg");\r
+ File SelectionViewGraphFile = url2file(FileLocator.resolve(Platform.getBundle("org.simantics.selectionview.ontology").getEntry("/graph.tg")), "SEL_graph.tg");\r
+ \r
+ dependencies.add(GraphCompiler.read(L0GraphFile));\r
+ dependencies.add(GraphCompiler.read(L0XGraphFile));\r
+ dependencies.add(GraphCompiler.read(DiagramGraphFile));\r
+ dependencies.add(GraphCompiler.read(G2DGraphFile));\r
+ dependencies.add(GraphCompiler.read(StructuralGraphFile));\r
+ dependencies.add(GraphCompiler.read(ModelingGraphFile));\r
+ dependencies.add(GraphCompiler.read(SimulationGraphFile));\r
+ dependencies.add(GraphCompiler.read(DocumentGraphFile));\r
+ dependencies.add(GraphCompiler.read(SpreadsheetGraphFile));\r
+ dependencies.add(GraphCompiler.read(ProjectGraphFile));\r
+ dependencies.add(GraphCompiler.read(SelectionViewGraphFile));\r
+\r
+ final TransferableGraph1 thisOntology = Simantics.sync(new UniqueRead<TransferableGraph1>() {\r
+\r
+ @Override\r
+ public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {\r
+ \r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Resource parent = graph.getSingleObject(r, L0.PartOf);\r
+ String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);\r
+ \r
+ CopyHandler ch = new DefaultCopyHandler(r) {\r
+ \r
+ protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {\r
+\r
+ Map<Resource, ExtentStatus> preStatus = new HashMap<Resource, ExtentStatus>();\r
+ preStatus.put(r, ExtentStatus.EXTERNAL);\r
+ if(!parent.equals(graph.getRootLibrary()))\r
+ preStatus.put(parent, ExtentStatus.EXTERNAL);\r
+ \r
+ return new TransferableGraphConfiguration2(null, Collections.emptyList(), preStatus, true, true);\r
+ \r
+ }\r
+\r
+ protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException {\r
+ return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf) {\r
+\r
+ protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {\r
+ return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile) {\r
+\r
+ @Override\r
+ protected Identity getRootIdentity(DomainProcessorState state, SerialisationSupport support, Resource rootLibrary) throws DatabaseException {\r
+ return new Identity(state.ids.get(support.getTransientId(rootLibrary)), new Root("", ""));\r
+ }\r
+\r
+ };\r
+ }\r
+\r
+ });\r
+ }\r
+ \r
+ };\r
+ SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
+ ch.copyToClipboard(graph, clipboard);\r
+ for (Set<Representation> object : clipboard.getContents()) {\r
+ TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
+ if(tg != null) return tg;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ });\r
+\r
+ dependencies.add(thisOntology);\r
+ \r
+ Simantics.sync(new ReadRequest() {\r
+\r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ for(Resource file : graph.syncRequest(new ObjectsWithType(r, L0.ConsistsOf, L0.PGraph))) {\r
+ \r
+ final String src = graph.getRelatedValue(file, L0.PGraph_definition, Bindings.STRING);\r
+\r
+ final ByteArrayInputStream baos = new ByteArrayInputStream(src.getBytes()); \r
+ \r
+ sources.add(new ISource() {\r
+ \r
+ @Override\r
+ public int startPos() {\r
+ return 0;\r
+ }\r
+ \r
+ @Override\r
+ public int startLine() {\r
+ return 0;\r
+ }\r
+ \r
+ @Override\r
+ public InputStream open() throws IOException {\r
+ return baos;\r
+ }\r
+ \r
+ @Override\r
+ public int length() throws IOException {\r
+ return src.length();\r
+ }\r
+ \r
+ @Override\r
+ public String getName() {\r
+ return "Source";\r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ }\r
+ \r
+ });\r
+ \r
+\r
+ \r
+ final StringBuilder errorStringBuilder = new StringBuilder();\r
+ GraphCompilerPreferences prefs = new GraphCompilerPreferences();\r
+ prefs.validate = true;\r
+ prefs.validateRelationRestrictions = ValidationMode.ERROR;\r
+ prefs.validateResourceHasType = ValidationMode.IGNORE;\r
+ final CompilationResult result = GraphCompiler.compile("1.1", sources, dependencies, null, prefs);\r
+ \r
+ for(Problem problem : result.getErrors())\r
+ errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
+ for(Problem problem : result.getWarnings())\r
+ errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
+ \r
+ if(!result.getErrors().isEmpty() || !result.getWarnings().isEmpty()) {\r
+\r
+ class ErrorMessageDialog extends MessageDialog {\r
+\r
+ public ErrorMessageDialog(Shell shell) {\r
+ super(shell, \r
+ "Unsatisfied dependencies", null, \r
+ "The following dependencies were missing. Please import the dependencies and try again.", \r
+ MessageDialog.ERROR, new String[] { "Continue" }, 0);\r
+ }\r
+\r
+ @Override\r
+ protected Control createCustomArea(Composite composite) {\r
+ \r
+ GridLayoutFactory.fillDefaults().applyTo(composite);\r
+ \r
+ org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(list);\r
+ for(Problem problem : result.getErrors())\r
+ list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
+ for(Problem problem : result.getWarnings())\r
+ list.add(problem.getLocation() + ": " + problem.getDescription() + "\n");\r
+\r
+ return composite;\r
+ \r
+ }\r
+\r
+ }\r
+\r
+ ErrorMessageDialog md = new ErrorMessageDialog(Display.getCurrent().getActiveShell());\r
+ md.open();\r
+\r
+ return;\r
+ }\r
+ \r
+ \r
+ final Pair<TransferableGraph1, long[]> existing = Simantics.sync(new UniqueRead<Pair<TransferableGraph1, long[]>>() {\r
+\r
+ @Override\r
+ public Pair<TransferableGraph1, long[]> perform(ReadGraph graph) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ TransferableGraph1 tg = graph.getPossibleRelatedValue(r, L0.SharedOntology_tg, Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
+ if(tg == null) return null;\r
+ long[] tgResources = graph.getPossibleRelatedValue(r, L0.SharedOntology_tgResources, Bindings.LONG_ARRAY);\r
+ if(tgResources == null) return null;\r
+ return Pair.make(tg, tgResources);\r
+ }\r
+ \r
+ });\r
+ \r
+ if(existing != null) {\r
+ \r
+ try {\r
+ \r
+ Simantics.sync(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+\r
+ TransferableGraphDelta1 delta = new Diff(existing.first, result.getGraph()).diff();\r
+ long[] resourceArray = TransferableGraphs.applyDelta(graph, existing.second, delta);\r
+\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
+ graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, resourceArray, Bindings.LONG_ARRAY);\r
+ \r
+ Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));\r
+\r
+ }\r
+ \r
+ });\r
+\r
+ } catch (Throwable t) {\r
+ throw new PlatformException(t);\r
+ } finally {\r
+ endTransaction();\r
+ }\r
+ \r
+ } else {\r
+ \r
+ final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(r);\r
+ \r
+ // final ImportAdvisor advisor = new ImportAdvisor(r, modelName);\r
+ DefaultPasteHandler.defaultExecute(result.getGraph(), r, advisor);\r
+ \r
+ Simantics.sync(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ \r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ graph.claimLiteral(r, L0.SharedOntology_tg, result.getGraph(), Bindings.getBindingUnchecked( TransferableGraph1.class ));\r
+ graph.claimLiteral(r, L0.SharedOntology_tgResources, L0.ResourceIdArray, advisor.getResourceIds(), Bindings.LONG_ARRAY);\r
+\r
+ Layer0Utils.addCommentMetadata(graph, "Compiled ontology " + graph.getURI(r));\r
+\r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ \r
+\r
+ \r
+ } catch (Exception e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ \r
+ }\r
+ \r
+ };\r
+ \r
+ }\r
+\r
+}\r