]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
7b12325e14b17408ecf437ab3ba6e9d5fad37db7
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.handlers.exports;\r
13 \r
14 import java.io.File;\r
15 import java.io.IOException;\r
16 import java.util.ArrayList;\r
17 import java.util.Collection;\r
18 \r
19 import org.eclipse.core.commands.AbstractHandler;\r
20 import org.eclipse.core.commands.ExecutionEvent;\r
21 import org.eclipse.core.commands.ExecutionException;\r
22 import org.eclipse.core.runtime.Platform;\r
23 import org.eclipse.jface.viewers.ISelection;\r
24 import org.eclipse.swt.SWT;\r
25 import org.eclipse.swt.widgets.FileDialog;\r
26 import org.eclipse.swt.widgets.MessageBox;\r
27 import org.eclipse.swt.widgets.Shell;\r
28 import org.eclipse.ui.handlers.HandlerUtil;\r
29 import org.simantics.databoard.Bindings;\r
30 import org.simantics.databoard.Files;\r
31 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
32 import org.simantics.db.ReadGraph;\r
33 import org.simantics.db.Resource;\r
34 import org.simantics.db.WriteGraph;\r
35 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
36 import org.simantics.db.common.request.ObjectsWithType;\r
37 import org.simantics.db.common.request.ReadRequest;\r
38 import org.simantics.db.common.request.WriteRequest;\r
39 import org.simantics.db.common.utils.NameUtils;\r
40 import org.simantics.db.exception.DatabaseException;\r
41 import org.simantics.db.layer0.util.TransferableGraphRequest2;\r
42 import org.simantics.db.request.Read;\r
43 import org.simantics.graph.representation.TransferableGraph1;\r
44 import org.simantics.layer0.Layer0;\r
45 import org.simantics.modeling.ModelingResources;\r
46 import org.simantics.structural.stubs.StructuralResource2;\r
47 import org.simantics.sysdyn.SysdynResource;\r
48 import org.simantics.sysdyn.ui.Activator;\r
49 import org.simantics.sysdyn.ui.handlers.imports.ImportModuleHandler;\r
50 import org.simantics.ui.SimanticsUI;\r
51 import org.simantics.ui.utils.ResourceAdaptionUtils;\r
52 import org.simantics.utils.datastructures.Pair;\r
53 \r
54 /**\r
55  * Exports a selected module\r
56  * @author Teemu Lempinen\r
57  *\r
58  */\r
59 public class ExportModuleHandler extends AbstractHandler {\r
60 \r
61         /**\r
62          * Temporary exception. At this phase, the system will not support exporting modules\r
63          * that depend on other modules. \r
64          * \r
65          * @author Teemu Lempinen\r
66          *\r
67          */\r
68         class ContainsDependenciesException extends DatabaseException {\r
69                 private static final long serialVersionUID = -1533706136673146020L;\r
70                 \r
71                 private Collection<String> dependencies;\r
72                 \r
73                 ContainsDependenciesException(Collection<String> dependencies) {\r
74                         this.dependencies = dependencies;\r
75                 }\r
76                 \r
77                 public Collection<String> getDependencies() {\r
78                         return this.dependencies;\r
79                 }\r
80                 \r
81         }\r
82         \r
83         @Override\r
84         public Object execute(ExecutionEvent event) throws ExecutionException {\r
85 \r
86         ISelection sel = HandlerUtil.getCurrentSelection(event);\r
87         final Resource modulesymbol = ResourceAdaptionUtils.toSingleResource(sel);\r
88         if(modulesymbol == null) return null;\r
89                 \r
90                 String name = null;\r
91                 try {\r
92                         name = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
93 \r
94                                 @Override\r
95                                 public String perform(ReadGraph graph) throws DatabaseException {\r
96                                         ModelingResources mr = ModelingResources.getInstance(graph);\r
97                                         StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
98                                         SysdynResource sr = SysdynResource.getInstance(graph);\r
99                                         Layer0 l0 = Layer0.getInstance(graph);\r
100                                         \r
101                                         // Start checking for module dependencies\r
102                                         Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType);\r
103                                         if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
104                                                 return null;\r
105                                         \r
106                                         Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
107                                         if (configuration == null)\r
108                                                 return null;\r
109                                         \r
110                                         ArrayList<String> dependencies = null;\r
111                                         for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) {\r
112                                                 if(dependencies == null)\r
113                                                         dependencies = new ArrayList<String>();\r
114                                                 String name = NameUtils.getSafeName(graph, r);\r
115                                                 String instanceOf = NameUtils.getSafeName(graph, graph.getSingleObject(r, l0.InstanceOf));\r
116                                                 dependencies.add(name + " : " + instanceOf);\r
117                                         }\r
118                                         if(dependencies != null && !dependencies.isEmpty())\r
119                                                 throw new ContainsDependenciesException(dependencies);\r
120                                         // End checking for module dependencies. If dependencies were found, an exception was thrown\r
121                                         \r
122                                         String name = graph.getPossibleRelatedValue(component, l0.HasName, Bindings.STRING);\r
123                                         return name;\r
124                                         \r
125                                 }\r
126                                 \r
127                         });\r
128                 } catch (ContainsDependenciesException e1) {\r
129                         Shell shell = HandlerUtil.getActiveShellChecked(event);\r
130                         MessageBox mb = new MessageBox(shell, SWT.OK);\r
131                         StringBuilder sb = new StringBuilder();\r
132                         sb.append("This version does not support exporting modules with other module instances.\n\n");\r
133                         sb.append("Dependencies:\n");\r
134                         for(String s : e1.getDependencies())\r
135                                 sb.append("    " + s + "\n");\r
136                         mb.setMessage(sb.toString());\r
137                         mb.setText("Module contains dependencies.");\r
138                         mb.open();\r
139                         return null;\r
140                 } catch (DatabaseException e1) {\r
141                         e1.printStackTrace();\r
142                 }\r
143                 \r
144         // Do not export if the resource has no name\r
145                 if(name == null) return null;\r
146                 \r
147         // Find a location (and name) for the exported library using FileDialog\r
148                 Shell shell = HandlerUtil.getActiveShellChecked(event);\r
149                 FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
150                 fd.setText("Export Module");\r
151                 fd.setFileName(name);\r
152                 String path = Activator.getDefault().getPreferenceStore().getString(ImportModuleHandler.IMPORTMODULETPATH);\r
153                 if(path.isEmpty() || !(new File(path).exists()))\r
154                         path = Platform.getLocation().toOSString();\r
155                 fd.setFilterPath(path);\r
156                 String[] filterExt = {"*.tg"};\r
157                 fd.setFilterExtensions(filterExt);\r
158                 final String selected = fd.open();\r
159                 if(selected == null) return null;\r
160                 \r
161         // Save location to preference store\r
162                 Activator.getDefault().getPreferenceStore().setValue(ImportModuleHandler.IMPORTMODULETPATH, (new File(selected)).getParent());\r
163                 \r
164         // Asynchronously create the file using transferable graph\r
165                 SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
166                         \r
167                         @Override\r
168                         public void run(ReadGraph graph) throws DatabaseException {\r
169                                 Layer0 l0 = Layer0.getInstance(graph);\r
170                                 ModelingResources mr = ModelingResources.getInstance(graph);\r
171 \r
172                                 final Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType);\r
173                                 if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
174                                         return;\r
175                                 String name = graph.syncRequest(new PossibleRelatedValue<String>(component, l0.HasName, Bindings.STRING ));\r
176                                 final ArrayList<Pair<Resource, String>> roots = new ArrayList<Pair<Resource, String>>();\r
177                                 roots.add(Pair.make(component, name));\r
178 \r
179                                 graph.asyncRequest(new WriteRequest() {\r
180 \r
181                                         @Override\r
182                                         public void perform(WriteGraph graph) throws DatabaseException {\r
183                                                 Layer0 l0 = Layer0.getInstance(graph);\r
184                                                 StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
185 \r
186                                                 Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
187                                                 if (!graph.hasStatement(configuration, l0.PartOf, component)&& \r
188                                                                 !graph.hasStatement(modulesymbol, l0.PartOf, component)) {\r
189                                                         // Make sure that configuration and symbol are included.\r
190                                                         // In old versions, they were attached to model, not to module.\r
191                                                         Resource previousPartof = graph.getSingleObject(configuration, l0.PartOf);\r
192 \r
193                                                         graph.deny(configuration, l0.PartOf);\r
194                                                         graph.deny(modulesymbol, l0.PartOf);\r
195                                                         graph.claim(configuration, l0.PartOf, l0.ConsistsOf, component);\r
196                                                         graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, component);\r
197 \r
198                                                         export(graph, selected, roots, component);\r
199 \r
200                                                         graph.deny(configuration, l0.PartOf);\r
201                                                         graph.deny(modulesymbol, l0.PartOf);\r
202                                                         graph.claim(configuration, l0.PartOf, l0.ConsistsOf, previousPartof);\r
203                                                         graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, previousPartof);\r
204                                                 } else {\r
205                                                         // Normal export\r
206                                                         export(graph, selected, roots, component);\r
207                                                 }\r
208                                         }\r
209                                 });\r
210 \r
211                         }\r
212                 });\r
213 \r
214                 return null;\r
215         }\r
216         \r
217         /**\r
218          * Export module (without dependencies to other modules) and write it to file. \r
219          * Disable existing enumeration replacement for during export.  \r
220          *  \r
221          * @param graph WriteGraph\r
222          * @param path Path for the exported file\r
223          * @param roots\r
224          * @param component Module\r
225          */\r
226         private void export(WriteGraph graph, String path, ArrayList<Pair<Resource, String>> roots, Resource component) {\r
227                 \r
228                 // FIXME: Enumeration replacement handling like this is not suitable.\r
229                 try {\r
230                         Layer0 l0 = Layer0.getInstance(graph);\r
231                         SysdynResource sr = SysdynResource.getInstance(graph);\r
232                         StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
233 \r
234                         Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
235                         ArrayList<Pair<Resource, Resource>> replacements = new ArrayList<Pair<Resource, Resource>>();\r
236 \r
237                         for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
238                                 if(graph.hasStatement(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
239                                         for(Resource replacement : graph.getObjects(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
240                                                 replacements.add(new Pair<Resource, Resource>(enumeration, replacement));\r
241                                         }\r
242                                 }\r
243                         }\r
244                         \r
245                         for(Pair<Resource,Resource> replacement : replacements)\r
246                                 graph.deny(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
247                         \r
248                         TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, component));\r
249                         Files.createFile(new File(path), Bindings.getBindingUnchecked(TransferableGraph1.class), tg);\r
250                         \r
251                         for(Pair<Resource,Resource> replacement : replacements)\r
252                                 graph.claim(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
253 \r
254                 } catch (RuntimeBindingConstructionException e) {\r
255                         e.printStackTrace();\r
256                 } catch (IOException e) {\r
257                         e.printStackTrace();\r
258                 } catch (DatabaseException e) {\r
259                         e.printStackTrace();\r
260                 }\r
261         }\r
262 }