]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java
Merge "Testing SonarQube with Simantics Platform SDK"
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / ModelingUtils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.modeling;\r
13 \r
14 import java.io.File;\r
15 import java.io.IOException;\r
16 import java.text.DateFormat;\r
17 import java.util.ArrayList;\r
18 import java.util.Collection;\r
19 import java.util.Collections;\r
20 import java.util.Date;\r
21 import java.util.HashMap;\r
22 import java.util.HashSet;\r
23 import java.util.List;\r
24 import java.util.Map;\r
25 import java.util.Set;\r
26 import java.util.TreeMap;\r
27 \r
28 import org.eclipse.core.runtime.CoreException;\r
29 import org.eclipse.core.runtime.IProgressMonitor;\r
30 import org.eclipse.core.runtime.NullProgressMonitor;\r
31 import org.eclipse.core.runtime.Path;\r
32 import org.eclipse.jface.dialogs.Dialog;\r
33 import org.eclipse.jface.dialogs.IDialogConstants;\r
34 import org.eclipse.jface.dialogs.MessageDialog;\r
35 import org.eclipse.jface.layout.GridDataFactory;\r
36 import org.eclipse.jface.layout.GridLayoutFactory;\r
37 import org.eclipse.jface.resource.ImageDescriptor;\r
38 import org.eclipse.jface.viewers.IStructuredSelection;\r
39 import org.eclipse.jface.viewers.StructuredSelection;\r
40 import org.eclipse.jface.window.Window;\r
41 import org.eclipse.jface.wizard.WizardDialog;\r
42 import org.eclipse.swt.SWT;\r
43 import org.eclipse.swt.widgets.Composite;\r
44 import org.eclipse.swt.widgets.Control;\r
45 import org.eclipse.swt.widgets.Display;\r
46 import org.eclipse.swt.widgets.FileDialog;\r
47 import org.eclipse.swt.widgets.Shell;\r
48 import org.eclipse.ui.IWorkbenchWizard;\r
49 import org.eclipse.ui.PlatformUI;\r
50 import org.eclipse.ui.wizards.IWizardDescriptor;\r
51 import org.simantics.Simantics;\r
52 import org.simantics.annotation.ontology.AnnotationResource;\r
53 import org.simantics.databoard.Bindings;\r
54 import org.simantics.databoard.binding.Binding;\r
55 import org.simantics.databoard.binding.mutable.Variant;\r
56 import org.simantics.databoard.container.DataContainer;\r
57 import org.simantics.databoard.container.DataContainers;\r
58 import org.simantics.databoard.container.DataFormatException;\r
59 import org.simantics.databoard.container.FormatHandler;\r
60 import org.simantics.databoard.serialization.SerializationException;\r
61 import org.simantics.databoard.type.Datatype;\r
62 import org.simantics.databoard.util.URIStringUtils;\r
63 import org.simantics.datatypes.literal.GUID;\r
64 import org.simantics.db.ReadGraph;\r
65 import org.simantics.db.RequestProcessor;\r
66 import org.simantics.db.Resource;\r
67 import org.simantics.db.Statement;\r
68 import org.simantics.db.WriteGraph;\r
69 import org.simantics.db.common.NamedResource;\r
70 import org.simantics.db.common.QueryMemoryWatcher;\r
71 import org.simantics.db.common.primitiverequest.IsInstanceOf;\r
72 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
73 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
74 import org.simantics.db.common.request.IndexRoot;\r
75 import org.simantics.db.common.request.ObjectsWithType;\r
76 import org.simantics.db.common.request.PossibleIndexRoot;\r
77 import org.simantics.db.common.request.ReadRequest;\r
78 import org.simantics.db.common.request.ResourceRead2;\r
79 import org.simantics.db.common.request.WriteRequest;\r
80 import org.simantics.db.common.request.WriteResultRequest;\r
81 import org.simantics.db.common.utils.ListUtils;\r
82 import org.simantics.db.common.utils.Logger;\r
83 import org.simantics.db.common.utils.NameUtils;\r
84 import org.simantics.db.common.utils.OrderedSetUtils;\r
85 import org.simantics.db.common.utils.VersionInfo;\r
86 import org.simantics.db.common.utils.VersionInfoRequest;\r
87 import org.simantics.db.common.utils.Versions;\r
88 import org.simantics.db.exception.DatabaseException;\r
89 import org.simantics.db.layer0.SelectionHints;\r
90 import org.simantics.db.layer0.adapter.CopyHandler;\r
91 import org.simantics.db.layer0.adapter.GenericRelationIndex;\r
92 import org.simantics.db.layer0.adapter.Instances;\r
93 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
94 import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;\r
95 import org.simantics.db.layer0.genericrelation.IndexedRelations;\r
96 import org.simantics.db.layer0.migration.MigrationUtils;\r
97 import org.simantics.db.layer0.request.ActivateModel;\r
98 import org.simantics.db.layer0.request.ActiveModels;\r
99 import org.simantics.db.layer0.request.Configuration;\r
100 import org.simantics.db.layer0.request.IsLinkedTo;\r
101 import org.simantics.db.layer0.request.PossibleModel;\r
102 import org.simantics.db.layer0.util.ClipboardUtils;\r
103 import org.simantics.db.layer0.util.DraftStatusBean;\r
104 import org.simantics.db.layer0.util.Layer0Utils;\r
105 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
106 import org.simantics.db.layer0.util.PasteEventHandler;\r
107 import org.simantics.db.layer0.util.RemoverUtil;\r
108 import org.simantics.db.layer0.util.SimanticsClipboard;\r
109 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
110 import org.simantics.db.layer0.util.SimanticsClipboardImpl;\r
111 import org.simantics.db.layer0.util.SimanticsKeys;\r
112 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
113 import org.simantics.db.layer0.variable.Variable;\r
114 import org.simantics.db.layer0.variable.Variables;\r
115 import org.simantics.db.request.Read;\r
116 import org.simantics.db.service.ClusterControl;\r
117 import org.simantics.db.service.CollectionSupport;\r
118 import org.simantics.db.service.QueryControl;\r
119 import org.simantics.db.service.VirtualGraphSupport;\r
120 import org.simantics.diagram.stubs.DiagramResource;\r
121 import org.simantics.diagram.stubs.G2DResource;\r
122 import org.simantics.diagram.synchronization.graph.AddElement;\r
123 import org.simantics.graph.db.IImportAdvisor2;\r
124 import org.simantics.graph.db.ImportAdvisors;\r
125 import org.simantics.graph.db.MissingDependencyException;\r
126 import org.simantics.graph.db.StreamingTransferableGraphFileReader;\r
127 import org.simantics.graph.db.TransferableGraphException;\r
128 import org.simantics.graph.db.TransferableGraphSource;\r
129 import org.simantics.graph.db.TransferableGraphs;\r
130 import org.simantics.graph.representation.Identity;\r
131 import org.simantics.graph.representation.Root;\r
132 import org.simantics.graph.representation.TransferableGraph1;\r
133 import org.simantics.graph.representation.TransferableGraphUtils;\r
134 import org.simantics.issues.common.IssueSourceUtils;\r
135 import org.simantics.issues.ontology.IssueResource;\r
136 import org.simantics.layer0.Layer0;\r
137 import org.simantics.layer0.utils.direct.GraphUtils;\r
138 import org.simantics.modeling.adapters.ChangeInformation;\r
139 import org.simantics.modeling.template2d.ontology.Template2dResource;\r
140 import org.simantics.operation.Layer0X;\r
141 import org.simantics.project.ontology.ProjectResource;\r
142 import org.simantics.scenegraph.profile.ProfileUtils;\r
143 import org.simantics.scl.runtime.function.Function1;\r
144 import org.simantics.scl.runtime.tuple.Tuple;\r
145 import org.simantics.simulation.ontology.SimulationResource;\r
146 import org.simantics.structural.stubs.StructuralResource2;\r
147 import org.simantics.structural2.scl.StructuralComponent;\r
148 import org.simantics.structural2.utils.StructuralUtils;\r
149 import org.simantics.ui.SimanticsUI;\r
150 import org.simantics.utils.ObjectUtils;\r
151 import org.simantics.utils.datastructures.Pair;\r
152 import org.simantics.utils.datastructures.Triple;\r
153 import org.simantics.utils.datastructures.hints.HintContext;\r
154 import org.simantics.utils.ui.dialogs.ListDialog;\r
155 \r
156 /**\r
157  * @author Hannu Niemistö\r
158  */\r
159 public class ModelingUtils {\r
160 \r
161         private ReadGraph g;\r
162         private WriteGraph wg;\r
163         public Layer0 b;\r
164         private StructuralResource2 sr;\r
165         private DiagramResource dr;\r
166         public ModelingResources mr;\r
167         public SimulationResource SIMU;\r
168 \r
169         public ModelingUtils(WriteGraph g) {\r
170                 wg = g;\r
171                 this.g = g;\r
172                 b = Layer0.getInstance(g);\r
173                 sr = StructuralResource2.getInstance(g);\r
174                 dr = DiagramResource.getInstance(g);\r
175                 mr = ModelingResources.getInstance(g);\r
176                 SIMU = SimulationResource.getInstance(g);\r
177         }\r
178 \r
179         @Deprecated\r
180         public Resource createSymbol2(String name) throws DatabaseException {\r
181                 return createSymbol2(name, dr.Composite);\r
182         }\r
183 \r
184         @Deprecated\r
185         public Resource createSymbol2(String name, Resource type) throws DatabaseException {\r
186                 G2DResource g2d = G2DResource.getInstance(g);\r
187 \r
188 //              Resource visibleTag = wg.newResource();\r
189 //              wg.claim(visibleTag, b.SubrelationOf, null, dr.IsVisible);\r
190 //              Resource focusableTag = wg.newResource();\r
191 //              wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable);\r
192 \r
193                 Double boxDimension = 6.0;\r
194                 Collection<Statement> grid = g.getAssertedStatements(type, dr.HasGridSize);\r
195                 if(grid.size() == 1) {\r
196                         Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE);\r
197                         if(d != null) boxDimension = 2*d;\r
198                 }\r
199 \r
200 \r
201                 Resource element  = GraphUtils.create(wg,\r
202                                 b.InstanceOf, dr.SVGElement,\r
203                                 g2d.HasSVGDocument,\r
204                                 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +\r
205                                                 // REMOVED by Tuukka, because This will cause\r
206                                                 // parsers to get on the net and get the doctype\r
207                                                 // definitions which can stall the UI for a long time.\r
208                                                 // Besides, we're not using the validation for anything\r
209                                                 // so it's useless to us.\r
210                                                 //"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" +\r
211                                                 "<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">" +\r
212                                                 "<rect x=\"-" + boxDimension + "\" y=\"-" + boxDimension + "\" width=\"" + (2*boxDimension) + "\" height=\"" + (2*boxDimension) + "\" fill=\"none\" stroke=\"rgb(0,0,0)\" stroke-width=\"0.1\"/>" +\r
213                                                 "</svg>"\r
214                                 );\r
215 \r
216 //              wg.claim(element, visibleTag, element);\r
217 //              wg.claim(element, focusableTag, element);\r
218 \r
219                 Resource orderedSet = OrderedSetUtils.create(wg, type, element);\r
220 \r
221 //              wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer,\r
222 //                              b.HasName, "Default",\r
223 //                              dr.IsActive, Boolean.TRUE,\r
224 //                              dr.HasVisibleTag, visibleTag,\r
225 //                              dr.HasFocusableTag, focusableTag));\r
226 \r
227                 Resource result = GraphUtils.create(wg,\r
228                                 b.HasName, name,\r
229                                 b.HasLabel, "",\r
230                                 sr.IsDefinedBy, orderedSet);\r
231 \r
232                 wg.claim(result, b.ConsistsOf, orderedSet);\r
233                 wg.claimLiteral(orderedSet, b.HasName, "__DIAGRAM__", Bindings.STRING);\r
234                 AddElement.claimFreshElementName(wg, orderedSet, element);\r
235                 wg.claim(orderedSet, b.ConsistsOf, element);\r
236 \r
237                 wg.claim(result, b.Inherits, null, dr.DefinedElement);\r
238                 return result;\r
239         }\r
240 \r
241         public static Collection<Resource> getElementCorrespondendences(ReadGraph g, Resource element) throws DatabaseException {\r
242                 DiagramResource dr = DiagramResource.getInstance(g);\r
243                 ModelingResources mr = ModelingResources.getInstance(g);\r
244                 if(g.isInstanceOf(element, dr.Connection)) {\r
245                         Resource mappedComponent = g.getPossibleObject(element, mr.ElementToComponent);\r
246                         if(mappedComponent != null) return Collections.singletonList(mappedComponent);\r
247                         Resource mappedConnection = g.getPossibleObject(element, mr.DiagramConnectionToConnection);\r
248                         if(mappedConnection == null)\r
249                                 return Collections.emptyList();\r
250                         ArrayList<Resource> result = new ArrayList<Resource>();\r
251                         Collection<Resource> relatedMappedConnections = StructuralUtils.getRelatedConnections(g, mappedConnection);\r
252                         for(Resource relatedMappedConnection : relatedMappedConnections)\r
253                                 for(Resource relatedConnection : g.getObjects(relatedMappedConnection, mr.ConnectionToDiagramConnection))\r
254                                         result.addAll(g.getObjects(relatedConnection, mr.ElementToComponent));\r
255                         return result;\r
256                 }\r
257                 else\r
258                         return g.getObjects(element, mr.ElementToComponent);\r
259         }\r
260 \r
261         public static Resource getPossibleElement(ReadGraph g, Resource component) throws DatabaseException {\r
262                 ModelingResources mr = ModelingResources.getInstance(g);\r
263                 return g.getPossibleObject(component, mr.ComponentToElement);\r
264         }\r
265 \r
266         public static Resource getPossibleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {\r
267                 Collection<Resource> corrs = getElementCorrespondendences(g, element);\r
268                 if(corrs.size() != 1) return null;\r
269                 else return corrs.iterator().next();\r
270         }\r
271 \r
272         public static Resource getSingleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {\r
273                 Collection<Resource> corrs = getElementCorrespondendences(g, element);\r
274                 if(corrs.size() != 1) throw new DatabaseException("Expected 1 element correspondence, got " + corrs.size());\r
275                 else return corrs.iterator().next();\r
276         }\r
277 \r
278         public static Resource createExperiment(WriteGraph graph, Resource model) throws DatabaseException {\r
279 \r
280                 Layer0 L0 = Layer0.getInstance(graph);\r
281                 SimulationResource SIMU = SimulationResource.getInstance(graph);\r
282                 Resource experiment = graph.newResource();\r
283                 graph.claim(experiment, L0.InstanceOf, SIMU.Experiment);\r
284                 graph.claimLiteral(experiment, L0.HasName, "Experiment");\r
285                 graph.claim(model, L0.ConsistsOf, experiment);\r
286                 return experiment;\r
287 \r
288         }\r
289 \r
290         public static Resource createModel(WriteGraph graph, Resource type) throws DatabaseException {\r
291                 return createModel(graph, type, Simantics.getProjectResource(), null);\r
292         }\r
293                 \r
294         public static Resource createModel(WriteGraph graph, Resource type, String name) throws DatabaseException {\r
295                 return createModel(graph, type, Simantics.getProjectResource(), name);\r
296         }\r
297 \r
298         public static Resource createModel(WriteGraph graph, Resource type, final Resource target, String name) throws DatabaseException {\r
299 \r
300                 Layer0 L0 = Layer0.getInstance(graph);\r
301                 SimulationResource SIMU = SimulationResource.getInstance(graph);\r
302                 StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
303                 ModelingResources MOD = ModelingResources.getInstance(graph);\r
304 \r
305                 if(name == null)\r
306                         name = NameUtils.findFreshName(graph, "Model", target, L0.ConsistsOf, "%s%d");\r
307 \r
308                 final Resource model = graph.newResource();\r
309                 graph.newClusterSet(model);\r
310                 graph.claim(model, L0.InstanceOf, null, type);\r
311                 graph.claimLiteral(model, L0.HasName, name);\r
312 \r
313                 graph.claim(target, L0.ConsistsOf, model);\r
314 \r
315                 Resource configurationType = graph.getPossibleObject(model, MOD.StructuralModel_HasConfigurationType);\r
316                 if(configurationType == null) configurationType = STR.Composite;\r
317 \r
318                 Resource configuration = graph.newResource();\r
319                 graph.claimLiteral(configuration, L0.HasName, "Configuration", Bindings.STRING);\r
320                 graph.claim(configuration, L0.InstanceOf, null, configurationType);\r
321                 graph.claim(model, L0.ConsistsOf, configuration);\r
322                 graph.claim(model, SIMU.HasConfiguration, configuration);\r
323 \r
324                 Resource joinClusterSet = graph.newResource();\r
325                 graph.newClusterSet(joinClusterSet);\r
326                 graph.claim(joinClusterSet, L0.InstanceOf, L0.ClusterSet);\r
327                 graph.claim(model, STR.HasJoinClusterSet, joinClusterSet);\r
328 \r
329                 linkOntologyDependenciesToModel(graph, model, target);\r
330                 \r
331                 Resource ontology = graph.syncRequest(new PossibleIndexRoot(type));\r
332                 if(ontology != null) {\r
333                         graph.claim(model, L0.IsLinkedTo, ontology);\r
334                 }\r
335 \r
336                 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
337                 graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("activations")) {\r
338 \r
339                         @Override\r
340                         public void perform(WriteGraph graph) throws DatabaseException {\r
341                                 Layer0X L0X = Layer0X.getInstance(graph);\r
342                                 Collection<Resource> actives = graph.syncRequest(new ActiveModels(target));\r
343                                 if(actives.isEmpty()) {\r
344                                         graph.claim(model,  L0X.IsActivatedBy, target);\r
345                                 }\r
346                         }\r
347 \r
348                 });\r
349 \r
350                 return model;\r
351 \r
352         }\r
353         \r
354         public static void linkOntologyDependenciesToModel(WriteGraph graph, Resource model, Resource target) \r
355                         throws DatabaseException {\r
356                 Layer0 L0 = Layer0.getInstance(graph);\r
357                 ProjectResource PROJ = ProjectResource.getInstance(graph);\r
358                 for(Resource dep : graph.getObjects(target, L0.IsLinkedTo)) {\r
359                         if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {\r
360                                 for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {\r
361                                         String uri = graph.getPossibleValue(req, Bindings.STRING);\r
362                                         if(uri != null) {\r
363                                                 Resource ns = graph.getResource(uri);\r
364                                                 if(ns != null) {\r
365                                                         graph.claim(model, L0.IsLinkedTo, null, ns);\r
366                                                 }\r
367                                         }\r
368                                 }\r
369                         }\r
370                 }\r
371         }\r
372         \r
373         public static void addSCLMainToModel(WriteGraph graph, Resource model) \r
374                         throws DatabaseException {\r
375                 addSCLMainToModel(graph, model, "SCLMain", "include \"Simantics/All\"\n");\r
376         }\r
377         \r
378         public static void addSCLMainToModel(WriteGraph graph, Resource model, String name, String contents) \r
379                         throws DatabaseException {\r
380                 Layer0 L0 = Layer0.getInstance(graph);\r
381         Resource sclmain = GraphUtils.create2(graph, L0.SCLModule, L0.PartOf, model, L0.HasName, name);\r
382         graph.claimLiteral(sclmain, L0.SCLModule_definition, contents, Bindings.STRING);\r
383         }\r
384 \r
385     public static Resource createLocalLibrary(WriteGraph graph, Resource container, String name) throws DatabaseException {\r
386         Layer0 L0 = Layer0.getInstance(graph);\r
387         ModelingResources MOD = ModelingResources.getInstance(graph);\r
388         Resource library = graph.newResource();\r
389         graph.claim(library, L0.InstanceOf, null, L0.Library);\r
390         graph.addLiteral(library, L0.HasName, L0.NameOf, "Library", Bindings.STRING);\r
391         if (container != null) {\r
392             graph.claim(container, L0.ConsistsOf, L0.PartOf, library);\r
393             graph.claim(container, MOD.HasLocalLibrary, MOD.IsLocalLibraryOf, library);\r
394         }\r
395         return library;\r
396     }\r
397 \r
398         public static void importModel(String fileName) {\r
399 \r
400                 Resource project = SimanticsUI.getProject().get();\r
401 \r
402                 try {\r
403 \r
404                         StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName));\r
405                         TransferableGraphSource tg = importer.readTG();\r
406 \r
407                         final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(project) {\r
408                                 @Override\r
409                                 public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {\r
410                                 }\r
411                                 @Override\r
412                                 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {\r
413                                         library = Simantics.getProjectResource();\r
414                                         String newName = newName(graph, library, root.name);\r
415                                         nameMappings.put(root.name, newName);\r
416                                         return null;\r
417                                 }\r
418                         };\r
419                         TransferableGraphs.importGraph1(Simantics.getSession(), tg, advisor);\r
420 \r
421                 } catch (MissingDependencyException e) {\r
422 \r
423                         final Set<String> missingURIs = e.getMissingURIs();\r
424 \r
425                         class ErrorMessageDialog extends MessageDialog {\r
426 \r
427                                 public ErrorMessageDialog(Shell shell) {\r
428                                         super(shell, \r
429                                                         "Unsatisfied dependencies", null, \r
430                                                         "The following dependencies were missing. Please import the dependencies and try again.", \r
431                                                         MessageDialog.ERROR, new String[] { "Continue" }, 0);\r
432                                 }\r
433 \r
434                                 @Override\r
435                                 protected Control createCustomArea(Composite composite) {\r
436                                         GridLayoutFactory.fillDefaults().applyTo(composite);\r
437                                         \r
438                                         org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);\r
439                                         GridDataFactory.fillDefaults().grab(true, true).applyTo(list);\r
440                                         for(String s : missingURIs) list.add(s);\r
441                                         return composite;\r
442                                 }\r
443 \r
444                         }\r
445 \r
446                         Display display = Display.getCurrent();\r
447                         if(display != null) {\r
448                                 ErrorMessageDialog md = new ErrorMessageDialog(display.getActiveShell());\r
449                                 md.open();\r
450                         } else {\r
451                                 Display.getDefault().asyncExec(new Runnable() {\r
452 \r
453                                         @Override\r
454                                         public void run() {\r
455                                                 Shell shell = Display.getCurrent().getActiveShell();\r
456                                                 ErrorMessageDialog md = new ErrorMessageDialog(shell);\r
457                                                 md.open();\r
458                                         }\r
459                                         \r
460                                 });\r
461                         }\r
462                         \r
463 \r
464                 } catch (Exception e) {\r
465                         Logger.defaultLogError(e);\r
466                 }\r
467 \r
468         }\r
469 \r
470         public static void primeVirtualGraphs() {\r
471                 VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
472                 support.getWorkspacePersistent("activations");\r
473                 support.getWorkspacePersistent("experiments");\r
474                 support.getWorkspacePersistent("issues");\r
475                 support.getWorkspacePersistent("preferences");\r
476         }\r
477 \r
478         public static Resource createProfileEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException {\r
479 \r
480                 Layer0 L0 = Layer0.getInstance(graph);\r
481                 DiagramResource DIA = DiagramResource.getInstance(graph);\r
482 \r
483                 Resource entry = graph.newResource();\r
484                 graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);\r
485                 graph.claimLiteral(entry, L0.HasName, name);\r
486                 graph.claimLiteral(entry, L0.HasLabel, name);\r
487                 graph.claim(entry, DIA.ProfileEntry_HasStyle, style);\r
488                 graph.claim(entry, DIA.ProfileEntry_HasGroup, group);\r
489 \r
490                 return entry;\r
491 \r
492         }\r
493 \r
494         public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException {\r
495 \r
496                 Layer0 L0 = Layer0.getInstance(graph);\r
497                 DiagramResource DIA = DiagramResource.getInstance(graph);\r
498 \r
499                 Resource list = ListUtils.create(graph, DIA.Profile, entries);\r
500 \r
501                 Resource profile = graph.newResource();\r
502                 graph.claim(profile, L0.InstanceOf, null, DIA.Profile);\r
503                 graph.claimLiteral(profile, L0.HasName, profileName);\r
504                 graph.claim(profile, DIA.HasEntries, null, list);\r
505 \r
506                 return profile;\r
507 \r
508         }\r
509         \r
510         public static Resource createProfile(WriteGraph graph, String profileName, Collection<Resource> entries) throws DatabaseException {\r
511             return createProfile(graph, profileName, entries.toArray(new Resource[entries.size()]));\r
512         }\r
513 \r
514         public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Resource ... profiles) throws DatabaseException {\r
515 \r
516                 Resource work = createProfile(graph, name, profiles);\r
517 \r
518                 Layer0 L0 = Layer0.getInstance(graph);\r
519                 DiagramResource DIA = DiagramResource.getInstance(graph);\r
520 \r
521                 graph.deny(model, DIA.HasActiveProfile);\r
522                 graph.claim(model, DIA.HasActiveProfile, work);\r
523                 graph.claim(model, L0.ConsistsOf, L0.PartOf, work);\r
524 \r
525                 return work;\r
526 \r
527         }\r
528         \r
529         public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Collection<Resource> profiles) throws DatabaseException {\r
530             return createToplevelProfile(graph, model, name, profiles.toArray(new Resource[profiles.size()]));\r
531         }\r
532 \r
533         public static void activateProfileEntries(WriteGraph graph, final Resource profile, final Resource ... entries) {\r
534 \r
535                 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
536                 graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
537 \r
538                         @Override\r
539                         public void perform(WriteGraph graph) throws DatabaseException {\r
540                                 SimulationResource SIMU = SimulationResource.getInstance(graph);\r
541                                 for(Resource entry : entries)\r
542                                         graph.claim(profile, SIMU.IsActive, entry);\r
543                         }\r
544 \r
545                 });\r
546 \r
547         }\r
548         \r
549         public static void activateProfileEntries(WriteGraph graph, Resource profile, Collection<Resource> entries) {\r
550             activateProfileEntries(graph, profile, entries.toArray(new Resource[entries.size()]));\r
551         }\r
552         \r
553         public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, String groupName, boolean enabled) throws DatabaseException {\r
554                 Layer0 L0 = Layer0.getInstance(graph);\r
555                 for (Resource group : ProfileUtils.getProfileChildren(graph, runtimeProfile)) {\r
556                         String name = graph.getRelatedValue2(group, L0.HasName);\r
557                         if (name.equals(groupName)) {\r
558                                 toggleProfileGroup(graph, runtimeProfile, group, enabled);\r
559                                 return;\r
560                         }\r
561                 }\r
562         }\r
563         \r
564         public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, Resource group, boolean enabled) throws DatabaseException {\r
565         DiagramResource DIA = DiagramResource.getInstance(graph);\r
566                 \r
567         if(graph.isInstanceOf(group, DIA.Profile)) {\r
568                 \r
569                 for(Resource child : ProfileUtils.getProfileChildren(graph, group)) {\r
570                         toggleProfileGroup(graph, runtimeProfile, child, enabled);\r
571                 }\r
572                 \r
573         } else if(graph.isInstanceOf(group, DIA.ProfileEntry)) {\r
574 \r
575             if(enabled) {\r
576                 graph.claim(runtimeProfile, SimulationResource.getInstance(graph).IsActive, null, group);\r
577             } else {\r
578                 graph.denyStatement(runtimeProfile, SimulationResource.getInstance(graph).IsActive, group);\r
579             }\r
580 \r
581                 }\r
582         }\r
583 \r
584     public static void untrackDependencies() {\r
585         untrackDependencies(Simantics.getSession());\r
586     }\r
587 \r
588         public static void untrackDependencies(RequestProcessor processor) {\r
589         \r
590         try {\r
591             processor.syncRequest(new ReadRequest() {\r
592 \r
593                 @Override\r
594                 public void run(ReadGraph graph) throws DatabaseException {\r
595                     Layer0X L0X = Layer0X.getInstance(graph);\r
596                     GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
597                     index.untrack(graph.getSession(), graph.getRootLibrary());\r
598                 }\r
599                 \r
600             });\r
601         } catch (DatabaseException e) {\r
602             Logger.defaultLogError(e);\r
603         }\r
604 \r
605     }\r
606 \r
607     public static void trackDependencies() {\r
608         trackDependencies(Simantics.getSession());\r
609     }\r
610 \r
611         public static void trackDependencies(RequestProcessor processor) {\r
612             \r
613             try {\r
614             processor.syncRequest(new ReadRequest() {\r
615 \r
616                 @Override\r
617                 public void run(ReadGraph graph) throws DatabaseException {\r
618                     Layer0X L0X = Layer0X.getInstance(graph);\r
619                     GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
620                     index.trackAndIndex(graph.getSession(), graph.getRootLibrary());\r
621                 }\r
622                 \r
623             });\r
624         } catch (DatabaseException e) {\r
625             Logger.defaultLogError(e);\r
626         }\r
627 \r
628         }\r
629 \r
630     public static void removeIndex(WriteGraph graph, Resource model) throws DatabaseException {\r
631         Layer0X L0X = Layer0X.getInstance(graph);\r
632         IndexedRelations ir = graph.getService(IndexedRelations.class);\r
633         // Deletes index files\r
634         ir.reset(null, graph, L0X.DependenciesRelation, model);\r
635     }\r
636     \r
637     public static void resetIssueSources(WriteGraph graph, Resource model) throws DatabaseException {\r
638         Layer0 L0 = Layer0.getInstance(graph);\r
639         IssueResource ISSUE = IssueResource.getInstance(graph);\r
640         for(Resource source : graph.sync(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.ContinuousIssueSource))) {\r
641             IssueSourceUtils.update(graph, source);\r
642         }\r
643     }\r
644     \r
645     public static void copyAnnotationTypes(WriteGraph graph, Resource sourceModel, Resource targetModel) throws DatabaseException {\r
646 \r
647         Layer0 L0 = Layer0.getInstance(graph);\r
648         AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
649 \r
650         Instances query = graph.adapt(ANNO.AnnotationType, Instances.class);\r
651 \r
652         Resource library = graph.getPossibleObject(targetModel, ANNO.HasAnnotationTypeRoot);\r
653         // HAXX:\r
654         if(library == null) {\r
655             library = graph.newResource();\r
656             graph.claim(library, L0.InstanceOf, null, ANNO.AnnotationTypeLibrary);\r
657             graph.claimLiteral(library, L0.HasName, L0.NameOf, L0.String, "Annotation types", Bindings.STRING);\r
658             graph.claim(library, L0.PartOf, L0.ConsistsOf, targetModel);\r
659             graph.claim(targetModel, ANNO.HasAnnotationTypeRoot, library);\r
660         }\r
661 \r
662         for(Resource type : query.find(graph, sourceModel)) {\r
663             String name = graph.getRelatedValue(type, L0.HasName);\r
664             Resource existing = Layer0Utils.getPossibleChild(graph, library, name);\r
665             if(existing != null) {\r
666                 RemoverUtil.remove(graph, existing);\r
667             }\r
668             Layer0Utils.copyTo(graph, library, type);\r
669         }\r
670 \r
671     }\r
672     \r
673         public static void deleteIndex(WriteGraph graph, Resource model) throws DatabaseException {\r
674                 Layer0X L0X = Layer0X.getInstance(graph);\r
675                 IndexedRelations ir = graph.getService(IndexedRelations.class);\r
676                 // Deletes index files\r
677                 ir.reset(null, graph, L0X.DependenciesRelation, model);\r
678         }\r
679     \r
680         public static void disableDependencies(WriteGraph graph, Resource dummy) {\r
681                 Layer0Utils.setDependenciesIndexingDisabled(graph, true);               \r
682         }\r
683 \r
684     public static void releaseMemory(WriteGraph graph) {\r
685         \r
686                 QueryControl qc = graph.getService(QueryControl.class);\r
687                 ClusterControl cc = graph.getService(ClusterControl.class);\r
688                 cc.flushClusters();\r
689                 qc.flush(graph);\r
690         \r
691     }\r
692 \r
693     public static List<Resource> filterByIndexRoot(ReadGraph graph, Resource indexRoot, List<Resource> resources) throws DatabaseException {\r
694         ArrayList<Resource> result =  new ArrayList<Resource>(resources.size());\r
695         for (Resource r : resources) {\r
696             Resource root = graph.syncRequest(new PossibleIndexRoot(r));\r
697             if (indexRoot.equals(root))\r
698                 result.add(r);\r
699         }\r
700         return result;\r
701     }\r
702 \r
703     public static List<Resource> searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException {\r
704         return filterByIndexRoot(graph, model, searchByType(graph, model, type));\r
705     }\r
706 \r
707     public static List<Resource> searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {\r
708         Instances query = graph.adapt(type, Instances.class);\r
709         return Layer0Utils.sortByCluster(graph, query.find(graph, model));\r
710     }\r
711 \r
712     public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, GUID guid) throws DatabaseException {\r
713         return searchByGUID(graph, indexRoot, guid.indexString());\r
714     }\r
715     \r
716     public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException {\r
717         return searchByQueryShallow(graph, indexRoot, "GUID:" + indexString);\r
718     }\r
719 \r
720     public static List<Resource> searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException {\r
721         return filterByIndexRoot(graph, model, searchByQuery(graph, model, query));\r
722     }\r
723 \r
724     public static List<Resource> searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException {\r
725         Instances instances = graph.adapt(Layer0.getInstance(graph).Entity, Instances.class);\r
726         Collection<Resource> queryResult = instances.find(graph, model, query);\r
727         return Layer0Utils.sortByCluster(graph, queryResult);\r
728     }\r
729 \r
730     public static List<Resource> searchByTypeAndFilter(ReadGraph graph, Resource model, Resource type, Function1<Resource,Boolean> filter) throws DatabaseException {\r
731         Instances query = graph.adapt(type, Instances.class);\r
732         ArrayList<Resource> result =  new ArrayList<Resource>();\r
733         for(Resource r : query.find(graph, model)) {\r
734                 if(filter.apply(r))\r
735                         result.add(r);\r
736         }\r
737         return result;\r
738     }\r
739 \r
740     public static List<Triple<Resource, Resource, String>> getIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {\r
741         Layer0 L0 = Layer0.getInstance(graph);\r
742         List<Resource> entries = searchByQuery(graph, model, filter);\r
743         List<Triple<Resource, Resource, String>> listOfTriples = new ArrayList<Triple<Resource,Resource,String>>();\r
744         for (Resource entry : entries) {\r
745                 Resource type = graph.getPossibleObject(entry, L0.InstanceOf);\r
746                 String name = NameUtils.getSafeName(graph, entry);\r
747                 listOfTriples.add(new Triple<Resource, Resource, String>(entry, type, name));\r
748         }\r
749                 return listOfTriples;\r
750     }\r
751     \r
752     public static String listIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {\r
753         List<Triple<Resource, Resource, String>> listOfTriples = getIndexEntries(graph, model, filter);\r
754         StringBuilder sb = new StringBuilder();\r
755         sb.append("== LISTING INDEX ENTRIES OF INDEX: " + NameUtils.getSafeName(graph, model) + ". AMOUNT OF ENTRIES: " + listOfTriples.size() + " ==\n");\r
756         for (Triple<Resource, Resource, String> entry : listOfTriples) {\r
757                 String instanceOf = NameUtils.getSafeName(graph, entry.second);\r
758                 sb.append("Name: " + entry.third + " instanceOf: " + instanceOf + " Resource: " + entry.first.toString() + "\n");\r
759         }\r
760                 return sb.toString();\r
761     }\r
762 \r
763     public static List<Resource> searchByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {\r
764         Instances query = graph.adapt(type, Instances.class);\r
765         ArrayList<Resource> result =  new ArrayList<Resource>();\r
766         for(Resource r : query.findByName(graph, model, name)) {\r
767                 if(graph.isInstanceOf(r, type))\r
768                         result.add(r);\r
769         }\r
770         return result;\r
771     }\r
772 \r
773     public static List<Resource> searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {\r
774         return filterByIndexRoot(graph, model, searchByTypeAndName(graph, model, type, name));\r
775     }\r
776 \r
777         /**\r
778          * @param graph\r
779          *            database write access\r
780          * @param sourceContainer\r
781          *            the source container to look for annotationProperty from to be\r
782          *            used as the copy source\r
783          * @param targetContainer\r
784          *            the target container for the copied annotationProperty\r
785          *            annotation\r
786          * @param annotationProperty\r
787          *            the annotation property relation\r
788          * @return created copy of the original annotation or <code>null</code> if\r
789          *         there was nothing to copy\r
790          * @throws DatabaseException\r
791          */\r
792         public static Resource copyPossibleAnnotation(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty) throws DatabaseException {\r
793                 return copyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, null);\r
794         }\r
795 \r
796         public static List<String> getPossibleNamePath(ReadGraph graph, Resource resource) throws DatabaseException {\r
797                 return getPossibleNamePath(graph, resource, null);\r
798         }\r
799          \r
800         private static List<String> getPossibleNamePath(ReadGraph graph, Resource resource, List<String> result) throws DatabaseException {\r
801                 \r
802                 Layer0 L0 = Layer0.getInstance(graph);\r
803                 String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);\r
804                 if(name == null) return null;\r
805 \r
806                 if(result == null) result = new ArrayList<String>();\r
807                 \r
808                 SimulationResource SIMU = SimulationResource.getInstance(graph);\r
809                 if(graph.isInstanceOf(resource, SIMU.Model)) return result;\r
810                 \r
811                 Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
812                 if(parent != null) {\r
813                         getPossibleNamePath(graph, parent, result);\r
814                 } else {\r
815                         return null;\r
816                 }\r
817 \r
818                 result.add(name);\r
819                 \r
820                 return result;\r
821 \r
822         }\r
823         \r
824         public static Resource claimLibraryPath(WriteGraph graph, Resource resource, List<String> path) throws DatabaseException {\r
825                 Layer0 L0 = Layer0.getInstance(graph);\r
826                 for(int i=0;i<path.size()-1;i++) {\r
827                         String p = path.get(i);\r
828                         Resource child = Layer0Utils.getPossibleChild(graph, resource, p);\r
829                         if(child == null) {\r
830                                 child = graph.newResource();\r
831                                 graph.claim(child, L0.InstanceOf, L0.Library);\r
832                                 graph.addLiteral(child, L0.HasName, L0.NameOf, L0.String, p, Bindings.STRING);\r
833                                 graph.claim(resource, L0.ConsistsOf, L0.PartOf, child);\r
834                         }\r
835                         resource = child;\r
836                 }\r
837                 return resource;\r
838         }\r
839         \r
840         /**\r
841          * @param graph\r
842          *            database write access\r
843          * @param sourceContainer\r
844          *            the source container to look for annotationProperty from to be\r
845          *            used as the copy source\r
846          * @param targetContainer\r
847          *            the target container for the copied annotationProperty\r
848          *            annotation\r
849          * @param annotationProperty\r
850          *            the annotation property relation\r
851          * @param annotationProperty\r
852          *            the 2nd level annotation property relation or\r
853          *            <code>null</code> if no 2nd level annotation exists\r
854          * @return created copy of the original annotation or <code>null</code> if\r
855          *         there was nothing to copy\r
856          * @throws DatabaseException\r
857          */\r
858         public static Resource copyPossibleAnnotation2(WriteGraph graph,\r
859                         Resource sourceContainer, Resource targetContainer,\r
860                         Resource annotationProperty, Resource entryType) throws DatabaseException {\r
861 \r
862                 // Delete existing target value first\r
863                 Layer0 L0 = Layer0.getInstance(graph);\r
864                 Resource targetValue = graph.getPossibleObject(targetContainer, annotationProperty);\r
865                 if (targetValue != null) {\r
866                         if(!graph.hasStatement(targetValue, L0.PartOf))\r
867                                 RemoverUtil.remove(graph, targetValue);\r
868                         graph.deny(targetContainer, annotationProperty);\r
869                 }\r
870 \r
871                 Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);\r
872                 if (sourceValue == null)\r
873                         return null;\r
874                 \r
875                 List<String> sourceValuePath = getPossibleNamePath(graph, sourceValue);\r
876                 if(sourceValuePath != null) {\r
877                         Resource targetModel = graph.sync(new PossibleModel(targetContainer));\r
878                         if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);\r
879                         Resource library = claimLibraryPath(graph, targetModel, sourceValuePath);\r
880                         Resource existing = Layer0Utils.getPossibleChild(graph, library, sourceValuePath.get(sourceValuePath.size()-1));\r
881                         if(existing == null) {\r
882                                 existing = doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);\r
883                                 graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);\r
884                         }\r
885                         graph.claim(targetContainer, annotationProperty, existing);\r
886                         return existing;\r
887                 } else {\r
888                         return doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);\r
889                 }\r
890 \r
891         }\r
892 \r
893         private static Resource doCopyPossibleAnnotation2(WriteGraph graph,\r
894                         Resource sourceContainer, Resource targetContainer,\r
895                         Resource annotationProperty, Resource entryType) throws DatabaseException {\r
896 \r
897                 Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);\r
898                 if (sourceValue == null)\r
899                         return null;\r
900                 \r
901                 // Copy 1st level annotation\r
902                 Resource targetValue = createAnnotation(graph, targetContainer, annotationProperty, sourceValue);\r
903 \r
904                 // Copy possible 2nd level annotations and attach to 1st if entry\r
905                 // property is defined.\r
906                 Layer0 L0 = Layer0.getInstance(graph);\r
907                 if (entryType != null) {\r
908                         \r
909                         AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
910                         for (Resource entry : graph.getObjects(sourceValue, ANNO.Annotation_HasEntry)) {\r
911 \r
912                                 String name = graph.getRelatedValue(entry, L0.HasName, Bindings.STRING);\r
913 \r
914                                 List<String> entryPath = getPossibleNamePath(graph, entry);\r
915                                 if(entryPath != null) {\r
916                                         Resource targetModel = graph.sync(new PossibleModel(targetContainer));\r
917                                         if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);\r
918                                         Resource library = claimLibraryPath(graph, targetModel, entryPath);\r
919                                         Resource existing = Layer0Utils.getPossibleChild(graph, library, entryPath.get(entryPath.size()-1));\r
920                                         if(existing == null) {\r
921                                                 existing = createTypedAnnotation(graph, null, null, entry, entryType, name);\r
922                                                 graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);\r
923                                         }\r
924                                         graph.claim(targetValue, ANNO.Annotation_HasEntry, existing);\r
925                                 } else {\r
926                                         Resource result = createTypedAnnotation(graph, null, null, entry, entryType, name);\r
927                                         graph.claim(targetValue, ANNO.Annotation_HasEntry, result);\r
928                                 }\r
929                                 \r
930                         }\r
931                 }\r
932 \r
933                 return targetValue;\r
934 \r
935         }\r
936 \r
937         /**\r
938          * @param graph\r
939          *            database write access\r
940          * @param container\r
941          *            the container resource to attach the new annotation to\r
942          * @param property\r
943          *            the annotation property relation. The type of the created\r
944          *            annotation is decided from this property relation's range\r
945          * @param sourceAnnotation\r
946          *            the annotation to copy data from or <code>null</code> if\r
947          *            nothing shall be copied\r
948          * @return the newly created annotation resource or <code>null</code> if the\r
949          *         annotation property relation didn't have a single range type\r
950          * @throws DatabaseException\r
951          */\r
952         public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation) throws DatabaseException {\r
953                 return createAnnotation(graph, container, property, sourceAnnotation, null);\r
954         }\r
955 \r
956         /**\r
957          * @param graph\r
958          *            database write access\r
959          * @param container\r
960          *            the container resource to attach the new annotation to\r
961          * @param property\r
962          *            the annotation property relation. The type of the created\r
963          *            annotation is decided from this property relation's range\r
964          * @param sourceAnnotation\r
965          *            the annotation to copy data from or <code>null</code> if\r
966          *            nothing shall be copied\r
967          * @param name\r
968          *            name for newly created annotation or <code>null</code> to copy\r
969          *            name from source if available\r
970          * @return the newly created annotation resource or <code>null</code> if the\r
971          *         annotation property relation didn't have a single range type\r
972          * @throws DatabaseException\r
973          */\r
974         public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, String name) throws DatabaseException {\r
975 \r
976                 Layer0 L0 = Layer0.getInstance(graph);\r
977                 Resource annotationType = graph.getSingleObject(property, L0.HasRange);\r
978                 if (annotationType == null)\r
979                         return null;\r
980 \r
981                 return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, name);\r
982 \r
983         }\r
984 \r
985         /**\r
986          * @param graph\r
987          *            database write access\r
988          * @param container\r
989          *            the container resource to attach the new annotation to\r
990          * @param property\r
991          *            the annotation property relation\r
992          * @param sourceAnnotation\r
993          *            the annotation to copy data from or <code>null</code> if\r
994          *            nothing shall be copied\r
995          * @param annotationType\r
996          *            the type of the new annotation\r
997          * @return the newly created annotation resource\r
998          * @throws DatabaseException\r
999          */\r
1000         public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType) throws DatabaseException {\r
1001                 return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, null);\r
1002         }\r
1003 \r
1004         /**\r
1005          * @param graph\r
1006          *            database write access\r
1007          * @param container\r
1008          *            the container resource to attach the new annotation to\r
1009          * @param property\r
1010          *            the annotation property relation\r
1011          * @param sourceAnnotation\r
1012          *            the annotation to copy data from or <code>null</code> if\r
1013          *            nothing shall be copied\r
1014          * @param annotationType\r
1015          *            the type of the new annotation\r
1016          * @param name\r
1017          *            name for newly created annotation or <code>null</code> to copy\r
1018          *            name from source if available\r
1019          * @return the newly created annotation resource\r
1020          * @throws DatabaseException\r
1021          */\r
1022         public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType, String name) throws DatabaseException {\r
1023 \r
1024                 Layer0 L0 = Layer0.getInstance(graph);\r
1025 \r
1026                 Resource anno = graph.newResource();\r
1027 \r
1028                 graph.claim(anno, L0.InstanceOf, null, annotationType);\r
1029 \r
1030                 if (name != null)\r
1031                         graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
1032 \r
1033                 if (sourceAnnotation != null) {\r
1034 \r
1035                         if (name == null) {\r
1036                                 String sourceName = graph.getPossibleRelatedValue(sourceAnnotation, L0.HasName, Bindings.STRING);\r
1037                                 if(sourceName != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, sourceName, Bindings.STRING);\r
1038                         }\r
1039 \r
1040                         Resource sourceType = graph.getSingleType(sourceAnnotation);\r
1041                         List<AnnotationMap> am = getAnnotationMap(graph, annotationType, sourceType);\r
1042                         for (AnnotationMap a : am) {\r
1043                                 Resource object = graph.getSingleObject(sourceAnnotation, a.sourcePredicate);\r
1044                                 Collection<Resource> objectTypes = graph.getTypes(object);\r
1045                                 if (objectTypes.contains(L0.Literal)) {\r
1046                                         Object value = graph.getValue(object, a.defaultValueBinding);\r
1047                                         if (!ObjectUtils.objectEquals(value, a.defaultValue)) {\r
1048                                                 graph.addLiteral(anno, a.annotationPredicate, a.annotationPredicateInverse, a.defaultValueType, value, a.defaultValueBinding);\r
1049                                         }\r
1050                                 }\r
1051                         }\r
1052                 }\r
1053 \r
1054                 if (container != null && property != null) {\r
1055                         graph.claim(container, property, anno);\r
1056                 }\r
1057 \r
1058                 return anno;\r
1059 \r
1060         }\r
1061 \r
1062         private static class AnnotationMap {\r
1063 \r
1064                 final public Resource sourcePredicate;\r
1065                 final public Resource sourcePredicateInverse;\r
1066 \r
1067                 final public Resource annotationPredicate;\r
1068                 final public Resource annotationPredicateInverse;\r
1069 \r
1070                 final public Resource defaultValueType;\r
1071                 final public Object defaultValue;\r
1072                 final public Binding defaultValueBinding;\r
1073 \r
1074                 public AnnotationMap(Resource sp, Resource spi, Resource tp, Resource tpi, Resource defaultValueType, Object defaultValue, Binding defaultValueBinding) {\r
1075                         sourcePredicate = sp;\r
1076                         sourcePredicateInverse = spi;\r
1077                         annotationPredicate = tp;\r
1078                         annotationPredicateInverse = tpi;\r
1079                         this.defaultValueType = defaultValueType;\r
1080                         this.defaultValue = defaultValue;\r
1081                         this.defaultValueBinding = defaultValueBinding;\r
1082                 }\r
1083 \r
1084         }\r
1085 \r
1086         public static List<AnnotationMap> getAnnotationMap(ReadGraph graph, Resource annotationType, Resource sourceType) throws DatabaseException {\r
1087                 return graph.syncRequest(new AnnotationMapRequest(annotationType, sourceType), TransientCacheListener.<List<AnnotationMap>>instance());\r
1088         }\r
1089 \r
1090         static class AnnotationMapRequest extends ResourceRead2<List<AnnotationMap>> {\r
1091 \r
1092                 public AnnotationMapRequest(Resource annotationType, Resource sourceType) {\r
1093                         super(annotationType, sourceType);\r
1094                 }\r
1095 \r
1096                 @Override\r
1097                 public List<AnnotationMap> perform(ReadGraph graph) throws DatabaseException {\r
1098 \r
1099                         Layer0 L0 = Layer0.getInstance(graph);\r
1100 \r
1101                         ArrayList<AnnotationMap> result = new ArrayList<AnnotationMap>(); \r
1102 \r
1103                         Map<String, Resource> annotationPredicates = new HashMap<String, Resource>();\r
1104                         for(Resource predicate : graph.getObjects(resource, L0.DomainOf)) {\r
1105                                 String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);\r
1106                                 annotationPredicates.put(name, predicate);\r
1107                         }\r
1108                         Map<String, Resource> sourcePredicates = new HashMap<String, Resource>();\r
1109                         for(Resource predicate : graph.getObjects(resource2, L0.DomainOf)) {\r
1110                                 String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);\r
1111                                 sourcePredicates.put(name, predicate);\r
1112                         }\r
1113 \r
1114                         for(String key : sourcePredicates.keySet()) {\r
1115                                 Resource sourcePredicate = sourcePredicates.get(key);\r
1116                                 Resource anno = annotationPredicates.get(key);\r
1117                                 if(sourcePredicate != null && anno != null) {\r
1118                                         Resource defaultValueType = graph.getSingleObject(anno, L0.HasRange);\r
1119                                         Binding defaultValueBinding = null;\r
1120                                         Object defaultValue = null;\r
1121                                         Resource assertion = graph.getPossibleObject(anno, L0.HasPredicateInverse);\r
1122                                         if (assertion != null) {\r
1123                                                 Resource object = graph.getPossibleObject(assertion, L0.HasObject);\r
1124                                                 if (object != null) {\r
1125                                                         if(graph.isInstanceOf(object, L0.Literal)) {\r
1126                                                                 Datatype dt = graph.getDataType(object);\r
1127                                                                 defaultValueBinding = Bindings.getBeanBinding(dt);\r
1128                                                                 defaultValue = graph.getPossibleValue(object);\r
1129                                                         }\r
1130                                                 }\r
1131                                         }\r
1132                                         result.add(new AnnotationMap(\r
1133                                                         sourcePredicate, graph.getInverse(sourcePredicate),\r
1134                                                         anno, graph.getInverse(anno),\r
1135                                                         defaultValueType, defaultValue, defaultValueBinding));\r
1136                                 }\r
1137                         }\r
1138 \r
1139                         return result;\r
1140 \r
1141                 }\r
1142 \r
1143         }\r
1144 \r
1145         public static final String DRAWING_TEMPLATE_FORMAT    = "drawingTemplate";\r
1146     public static final String DRAWING_TEMPLATE_FORMAT_V1 = DRAWING_TEMPLATE_FORMAT + ":1";\r
1147     public static final String DRAWING_TEMPLATE_FORMAT_V2 = DRAWING_TEMPLATE_FORMAT + ":2";\r
1148 \r
1149     public static Resource importDrawingTemplate(final Resource model, final File file) throws IOException, SerializationException, DatabaseException, TransferableGraphException {\r
1150 \r
1151                 try {\r
1152 \r
1153                         final Resource library = Simantics.sync(new WriteResultRequest<Resource>() {\r
1154 \r
1155                                 @Override\r
1156                                 public Resource perform(WriteGraph graph) throws DatabaseException {\r
1157                                         \r
1158                                         Layer0 L0 = Layer0.getInstance(graph);\r
1159                                         Template2dResource TEMPLATE = Template2dResource.getInstance(graph);\r
1160                                         Resource root = graph.getPossibleObject(model, TEMPLATE.HasDrawingTemplateRoot);\r
1161                                         if(root == null) {\r
1162                                                 Template2dResource TEMPLATE2D = Template2dResource.getInstance(graph);\r
1163                                                 root = graph.newResource();\r
1164                                                 graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibrary);\r
1165                                                 graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibraryUI);\r
1166                                                 graph.claimLiteral(root, L0.HasName, L0.NameOf, L0.String, "Diagram Templates", Bindings.STRING);\r
1167                                                 graph.claim(root, L0.PartOf, L0.ConsistsOf, model);\r
1168                                                 graph.claim(model, TEMPLATE2D.HasDrawingTemplateRoot, root);\r
1169                                         }\r
1170                                         \r
1171                                         String name = new Path(file.getAbsolutePath()).removeFileExtension().lastSegment();\r
1172                                         if(name != null) {\r
1173                                                 Resource existing = Layer0Utils.getPossibleChild(graph, root, name);\r
1174                                                 if(existing != null)\r
1175                                                         graph.deny(root, L0.ConsistsOf, existing);\r
1176                                         }\r
1177                                         \r
1178                                         return root;\r
1179                                         \r
1180                                 }\r
1181 \r
1182                         });\r
1183 \r
1184                         final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(library);\r
1185 \r
1186                         try {\r
1187                                 HashMap<String, FormatHandler<Object>> handlers = new HashMap<String, FormatHandler<Object>>();\r
1188                                 FormatHandler<Object> handler = new FormatHandler<Object>() {\r
1189                                         @Override\r
1190                                         public Binding getBinding() {\r
1191                                                 return TransferableGraph1.BINDING;\r
1192                                         }\r
1193 \r
1194                                         @Override\r
1195                                         public Object process(DataContainer container) throws Exception {\r
1196                                                 TransferableGraphs.importGraph1(Simantics.getSession(), (TransferableGraph1)container.content.getValue(), \r
1197                                                                 advisor, null);\r
1198                                                 return null;\r
1199                                         }\r
1200                                 };\r
1201                                 handlers.put(DRAWING_TEMPLATE_FORMAT_V1, handler);\r
1202                                 handlers.put(DRAWING_TEMPLATE_FORMAT_V2, handler);\r
1203                                 try {\r
1204                                         DataContainers.readFile(file, handlers);\r
1205                                 } catch(DataFormatException e) {\r
1206                                         throw new IOException(e);\r
1207                                 } catch(IOException e) {\r
1208                                         throw e;\r
1209                                 } catch(Exception e) {\r
1210                                         if(e instanceof RuntimeException)\r
1211                                                 throw (RuntimeException)e;\r
1212                                         else\r
1213                                                 throw new RuntimeException(e);\r
1214                                 }\r
1215 \r
1216                         } catch(IOException e) {\r
1217                         }\r
1218 \r
1219                         return advisor.getRoot();\r
1220 \r
1221                 } catch (Throwable t) {\r
1222                         Logger.defaultLogError("Unexpected exception while importing diagram template.", t);\r
1223                 } finally {\r
1224                 }\r
1225 \r
1226                 return null;\r
1227 \r
1228         }\r
1229     \r
1230     public static Collection<Variable> getMappedVariables(ReadGraph graph, Variable source) throws DatabaseException {\r
1231         \r
1232         ArrayList<Variable> result = new ArrayList<Variable>();\r
1233         Resource represents = source.getPossibleRepresents(graph);\r
1234         if(represents == null) return Collections.emptyList();\r
1235         ModelingResources MOD = ModelingResources.getInstance(graph);\r
1236         for(Resource r : getElementCorrespondendences(graph, represents)) {\r
1237             result.add(Variables.getVariable(graph, r));\r
1238         }\r
1239         for(Resource r : graph.getObjects(represents, MOD.ComponentToElement)) {\r
1240             result.add(Variables.getVariable(graph, r));\r
1241         }\r
1242         for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite)) {\r
1243             result.add(Variables.getVariable(graph, r));\r
1244         }\r
1245         for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram)) {\r
1246             result.add(Variables.getVariable(graph, r));\r
1247         }\r
1248         return result;\r
1249         \r
1250     }\r
1251     \r
1252     public static Resource getPossibleModel(ReadGraph graph, Resource resource) throws DatabaseException {\r
1253         \r
1254         PossibleModel pm = new PossibleModel(resource);\r
1255         Resource model = pm.perform(graph);\r
1256         return model;\r
1257     }\r
1258     \r
1259     public static Resource possibleIndexRoot(ReadGraph graph, Resource resource) throws DatabaseException {\r
1260         return graph.syncRequest(new PossibleIndexRoot(resource));\r
1261     }\r
1262 \r
1263     public static Object getMonitorValue(StructuralComponent _variable, ReadGraph graph, String path) throws DatabaseException {\r
1264         Variable variable = ((VariableStructuralContext)_variable).variable;\r
1265         Variable var = variable.browse(graph, path);\r
1266         return var.getValue(graph);\r
1267     }\r
1268     \r
1269     public static void createSharedOntologyWithUI(ReadGraph graph, Variable variable, Resource baseType) throws DatabaseException {\r
1270         createSharedOntologyWithUI(graph, baseType);\r
1271     }\r
1272 \r
1273     public static void createSharedOntologyWithUI(ReadGraph graph, Resource baseType) throws DatabaseException {\r
1274         \r
1275 //      Resource indexRoot_ = variable.getPossibleRepresents(graph);\r
1276 //      if(indexRoot_ == null) return;\r
1277 \r
1278             final Map<Resource, Pair<String,ImageDescriptor>> map = new HashMap<Resource, Pair<String,ImageDescriptor>>();\r
1279 \r
1280         Layer0 L0 = Layer0.getInstance(graph);\r
1281         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
1282         Instances query = graph.adapt(L0.IndexRootType, Instances.class);\r
1283         for(Resource ontology : Layer0Utils.listOntologies(graph)) {\r
1284                 for(Resource type : query.find(graph, ontology)) {\r
1285                         if(graph.isInheritedFrom(type, SIMU.Model)) continue;\r
1286                         if(graph.hasStatement(type, L0.Abstract)) continue;\r
1287                         if(!graph.isInheritedFrom(type, baseType)) continue;\r
1288                         String name = graph.getPossibleRelatedValue(type, L0.HasLabel, Bindings.STRING);\r
1289                         if(name == null) name = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);\r
1290                         map.put(type, new Pair<String,ImageDescriptor>(name, null));\r
1291                 }\r
1292         }\r
1293         \r
1294         Display.getDefault().asyncExec(new Runnable() {\r
1295                         @Override\r
1296                         public void run() {\r
1297                                 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
1298                                 CreateSharedOntologyDialog page = new CreateSharedOntologyDialog(shell, map, "Select type and name of new shared library");\r
1299                                 if (page.open() == Window.OK) {\r
1300                                         Object[] result = page.getResult();\r
1301                                         if (result != null && result.length == 1) {\r
1302                                                 final Resource res = (Resource)result[0];\r
1303                                                 final String name = "http://" + page.getName();\r
1304                                                 Simantics.getSession().asyncRequest(new WriteRequest() {\r
1305 \r
1306                                                         @Override\r
1307                                                         public void perform(WriteGraph graph) throws DatabaseException {\r
1308                                                                 graph.markUndoPoint();\r
1309                                                                 Resource target = Simantics.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, name+"@A", res);\r
1310                                                                 \r
1311                                                                 ProjectResource PROJ = ProjectResource.getInstance(graph);\r
1312                                                                 Layer0 L0 = Layer0.getInstance(graph);\r
1313                                                                 for(Resource dep : graph.getObjects(Simantics.getProjectResource(), L0.IsLinkedTo)) {\r
1314                                                                         if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {\r
1315                                                                                 for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {\r
1316                                                                                         String uri = graph.getPossibleValue(req, Bindings.STRING);\r
1317                                                                                         if(uri != null) {\r
1318                                                                                                 Resource ns = graph.getResource(uri);\r
1319                                                                                                 if(ns != null) {\r
1320                                                                                                         graph.claim(target, L0.IsLinkedTo, null, ns);\r
1321                                                                                                 }\r
1322                                                                                         }\r
1323                                                                                 }\r
1324                                                                         }\r
1325                                                                 }\r
1326                                                                 \r
1327                                                         }\r
1328                                                         \r
1329                                                 });\r
1330                                         }\r
1331                                 }\r
1332                         }\r
1333                 });\r
1334         \r
1335     }\r
1336 \r
1337     public static void unlinkSharedOntologyWithUI(ReadGraph graph, Variable variable, final List<Resource> libraries) throws DatabaseException {\r
1338         \r
1339         final Resource indexRoot = variable.getPossibleRepresents(graph);\r
1340         if(indexRoot == null) return;\r
1341         \r
1342         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
1343 \r
1344         final List<String> instances = new ArrayList<String>();\r
1345         \r
1346         DiagramResource DIA = DiagramResource.getInstance(graph);\r
1347         \r
1348         for(Resource library : libraries) {\r
1349                 for(Resource type : ModelingUtils.searchByTypeShallow(graph, library, STR.ComponentType)) {\r
1350                         for(Resource instance : ModelingUtils.searchByTypeShallow(graph, indexRoot, type)) {\r
1351                                 // TODO: haxx\r
1352                                 if(graph.isInstanceOf(instance, DIA.Element)) continue;\r
1353                                 String name = Versions.getStandardPathNameString(graph, instance);\r
1354                                 instances.add(name);\r
1355                         }\r
1356                 }\r
1357         }\r
1358         \r
1359         if(instances.isEmpty()) {\r
1360                 graph.getSession().asyncRequest(new WriteRequest() {\r
1361                         \r
1362                                 @Override\r
1363                                 public void perform(WriteGraph graph) throws DatabaseException {\r
1364                                 Layer0 L0 = Layer0.getInstance(graph);\r
1365                                 for(Resource library : libraries)\r
1366                                         graph.deny(indexRoot, L0.IsLinkedTo, library);\r
1367                                 }\r
1368                         \r
1369                 });\r
1370                 return;\r
1371         }\r
1372         \r
1373         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
1374             @Override\r
1375             public void run() {\r
1376                 \r
1377                 if (!PlatformUI.isWorkbenchRunning())\r
1378                     return;\r
1379 \r
1380                 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
1381                 ListDialog<String> dialog = new ListDialog<String>(\r
1382                         shell,\r
1383                         instances,\r
1384                         "Cannot unlink selected libraries",\r
1385                         "Libraries cannot be unlinked since the following instances are referring to them.") {\r
1386 \r
1387                         protected void createButtonsForButtonBar(Composite parent) {\r
1388                                 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
1389                         }\r
1390                         \r
1391                 };\r
1392                 int result = dialog.open();\r
1393                 if (result != Dialog.OK)\r
1394                     return;\r
1395 \r
1396             }\r
1397         });\r
1398         \r
1399     }\r
1400     \r
1401     public static void importSharedOntology(String fileName) throws Exception {\r
1402         try {\r
1403                 DataContainer dc = DataContainers.readFile(new File(fileName));\r
1404                 TransferableGraph1 tg = (TransferableGraph1)dc.content.getValue(TransferableGraph1.BINDING);\r
1405                 Variant draftStatus = dc.metadata.get(DraftStatusBean.EXTENSION_KEY);\r
1406                 MigrationUtils.importSharedOntology(Simantics.getSession(), tg, draftStatus == null);\r
1407         } catch (Exception e) {\r
1408                 Logger.defaultLogError(e);\r
1409                 throw e;\r
1410         }\r
1411     }\r
1412     \r
1413     public static void importSharedOntologyWithUI(ReadGraph graph, final Variable variable) throws DatabaseException {\r
1414         \r
1415         Display.getDefault().asyncExec(new Runnable() {\r
1416 \r
1417                         @Override\r
1418                         public void run() {\r
1419                                 IStructuredSelection sel = new StructuredSelection(variable);\r
1420                         openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyImportWizard");\r
1421                         }\r
1422                         \r
1423                 });\r
1424         \r
1425     }\r
1426     \r
1427         public static class LibraryInfo implements Comparable<LibraryInfo> {\r
1428                 public NamedResource library;\r
1429                 public DraftStatusBean draft;\r
1430                 public LibraryInfo(String name, Resource r, DraftStatusBean draft) {\r
1431                         library = new NamedResource(name, r);\r
1432                         this.draft = draft;\r
1433                 }\r
1434                 @Override\r
1435                 public int compareTo(LibraryInfo o) {\r
1436                         return library.compareTo(o.library);\r
1437                 }\r
1438                 @Override\r
1439                 public int hashCode() {\r
1440                         return library.hashCode();\r
1441                 }\r
1442                 @Override\r
1443                 public boolean equals(Object object) {\r
1444                 if (this == object)\r
1445                     return true;\r
1446                 else if (object == null)\r
1447                     return false;\r
1448                 else if (!(object instanceof LibraryInfo))\r
1449                     return false;\r
1450                 LibraryInfo info = (LibraryInfo)object;\r
1451                 return info.library.equals(library);\r
1452                 }\r
1453                 \r
1454         }\r
1455         \r
1456     public static void exportSharedOntologyWithUI(final Resource sharedOntology) {\r
1457 \r
1458         Display.getDefault().asyncExec(new Runnable() {\r
1459 \r
1460                 @Override\r
1461                 public void run() {\r
1462                         HintContext hc = new HintContext();\r
1463                         hc.setHint(SelectionHints.KEY_MAIN, sharedOntology);\r
1464                         IStructuredSelection sel = new StructuredSelection(hc);\r
1465                 openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyExportWizard");\r
1466                 }\r
1467                 \r
1468         });\r
1469         \r
1470     }\r
1471         \r
1472     public static void exportSharedOntology(IProgressMonitor monitor, RequestProcessor processor, File location, String format, int version, final LibraryInfo info) throws DatabaseException, IOException {\r
1473         \r
1474         if(monitor == null) monitor = new NullProgressMonitor();\r
1475         \r
1476         // TODO: figure out a way to make the TG go directly into a file\r
1477         // instead of having it all in memory at once.\r
1478 \r
1479         monitor.beginTask("Exporting shared library...", 100);\r
1480         SimanticsClipboard clipboard = processor.syncRequest(new Read<SimanticsClipboard>() {\r
1481             @Override\r
1482             public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException {\r
1483                 CopyHandler ch = graph.adapt(info.library.getResource(), CopyHandler.class);\r
1484                 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
1485                 ch.copyToClipboard(graph, clipboard);\r
1486                 return clipboard;\r
1487             }\r
1488         });\r
1489         \r
1490         TreeMap<String,Variant> metadata = getExportMetadata();\r
1491         DraftStatusBean draft = info.draft;\r
1492         if(draft != null) {\r
1493                 metadata.put(DraftStatusBean.EXTENSION_KEY, new Variant(DraftStatusBean.BINDING ,draft));\r
1494         }\r
1495         \r
1496         for (Set<Representation> object : clipboard.getContents()) {\r
1497                 \r
1498             TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
1499             monitor.worked(95);\r
1500 \r
1501             monitor.setTaskName("Writing transferable graph...");\r
1502             DataContainers.writeFile(location, new DataContainer(\r
1503                     format, version,\r
1504                     metadata, new Variant(TransferableGraph1.BINDING, tg)));\r
1505 \r
1506             monitor.worked(5);\r
1507         }\r
1508     }\r
1509 \r
1510     public static TreeMap<String, Variant> getExportMetadata() {\r
1511 \r
1512         TreeMap<String,Variant> metadata = new TreeMap<String,Variant>();\r
1513         metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())));\r
1514         metadata.put("author", Variant.ofInstance(System.getProperty("user.name", "")));\r
1515 \r
1516         return metadata;\r
1517         \r
1518     }\r
1519     \r
1520     public static void createNewVersionWithoutUI(WriteGraph graph, Resource resource) throws DatabaseException {\r
1521         VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));\r
1522         int currentVersion = Integer.parseInt(info.version);\r
1523         String result = Integer.toString(currentVersion + 1);\r
1524         createNewVersion(graph, resource, info, result);\r
1525     }\r
1526     \r
1527     public static void createNewVersionWithUI(ReadGraph graph, final Resource resource) throws DatabaseException {\r
1528         \r
1529         final VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));\r
1530         \r
1531         Display.getDefault().asyncExec(new Runnable() {\r
1532                         @Override\r
1533                         public void run() {\r
1534                                 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
1535                                 CreateVersionDialog dialog = new CreateVersionDialog(shell, info);\r
1536                                 if (dialog.open() == Window.OK) {\r
1537                                         final String result = dialog.getResult();\r
1538                                         Simantics.getSession().asyncRequest(new WriteRequest() {\r
1539                                                 @Override\r
1540                                                 public void perform(WriteGraph graph) throws DatabaseException {\r
1541                                                     createNewVersion(graph, resource, info, result);\r
1542                                                 }\r
1543                                         });\r
1544                                 }\r
1545                         }\r
1546                 });\r
1547         \r
1548     }\r
1549     \r
1550     public static void createNewVersion(WriteGraph graph, Resource resource, final VersionInfo info, final String result) throws DatabaseException {\r
1551         graph.markUndoPoint();\r
1552         Layer0 L0 = Layer0.getInstance(graph);\r
1553         Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
1554         if(parent == null) return;\r
1555         final String parentURI = graph.getPossibleURI(parent);\r
1556         if(parentURI == null) return;\r
1557         Layer0Utils.copyTo(graph, parent, resource, new PasteEventHandler() {\r
1558 \r
1559             @Override\r
1560             public void postProcess(WriteGraph graph, Resource root) throws DatabaseException {\r
1561                 Layer0 L0 = Layer0.getInstance(graph);\r
1562                 graph.deny(root, L0.Entity_published);\r
1563             }\r
1564             \r
1565             @Override\r
1566             public IImportAdvisor2 createAdvisor(ReadGraph graph, ImportAdvisorFactory factory, Resource target) throws DatabaseException {\r
1567                 Map<String,Object> context = new HashMap<String,Object>();\r
1568                 String base = parentURI + "/" + URIStringUtils.escape( info.baseName ) + "@";\r
1569                 Map<String,String> renameMap = new HashMap<String,String>();\r
1570                 renameMap.put(base + info.version, base + result);\r
1571                 renameMap.put(info.baseName + "@" + info.version, info.baseName + "@" + result);\r
1572                 context.put(ImportAdvisors.RENAME_MAP, renameMap);\r
1573                 return factory.create(graph, target, context);\r
1574             }\r
1575             \r
1576         });\r
1577         Layer0Utils.addCommentMetadata(graph, "Created new version of " + info.baseName);\r
1578     }\r
1579     \r
1580     public static boolean isUserComponent(ReadGraph graph, Resource type) throws DatabaseException {\r
1581         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
1582         if(graph.isInstanceOf(type, STR.ProceduralComponentType)) return true;\r
1583         else if (graph.hasStatement(type, STR.IsDefinedBy)) return true;\r
1584         return false;\r
1585     }\r
1586     \r
1587     public static void publishComponentTypeWithUI(WriteGraph graph, final Resource componentType) throws DatabaseException {\r
1588 \r
1589         Layer0 L0 = Layer0.getInstance(graph);\r
1590         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
1591         Resource composite = graph.getPossibleObject(componentType, STR.IsDefinedBy);\r
1592         final List<String> instances = new ArrayList<String>();\r
1593         if(composite != null) {\r
1594                 for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {\r
1595                 Resource type = graph.getPossibleType(component, STR.Component);\r
1596                         if(type != null && isUserComponent(graph, type)) {\r
1597                                 if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, component));\r
1598                         }\r
1599                 }\r
1600         }\r
1601 \r
1602         if(instances.isEmpty()) {\r
1603                 graph.getSession().asyncRequest(new WriteRequest() {\r
1604                         \r
1605                                 @Override\r
1606                                 public void perform(WriteGraph graph) throws DatabaseException {\r
1607                                 graph.markUndoPoint();\r
1608                                 publish(graph, componentType);\r
1609                                 }\r
1610                         \r
1611                 });\r
1612                 return;\r
1613         }\r
1614         \r
1615         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
1616             @Override\r
1617             public void run() {\r
1618                 \r
1619                 if (!PlatformUI.isWorkbenchRunning())\r
1620                     return;\r
1621 \r
1622                 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
1623                 ListDialog<String> dialog = new ListDialog<String>(\r
1624                         shell,\r
1625                         instances,\r
1626                         "Cannot publish user component",\r
1627                         "The following instances are referring to unpublished user components.") {\r
1628 \r
1629                         protected void createButtonsForButtonBar(Composite parent) {\r
1630                                 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
1631                         }\r
1632                         \r
1633                 };\r
1634                 int result = dialog.open();\r
1635                 if (result != Dialog.OK)\r
1636                     return;\r
1637 \r
1638             }\r
1639         });\r
1640         \r
1641     }\r
1642 \r
1643     public static void publishSharedOntologyWithUI(WriteGraph graph, final Resource sharedOntology) throws DatabaseException {\r
1644         \r
1645         Layer0 L0 = Layer0.getInstance(graph);\r
1646         DiagramResource DIA = DiagramResource.getInstance(graph);\r
1647         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
1648         final List<String> instances = new ArrayList<String>();\r
1649         for(Resource type : searchByTypeShallow(graph, sharedOntology, STR.ComponentType)) {\r
1650                         // TODO: haxx\r
1651                         if(graph.isInheritedFrom(type, DIA.Element)) continue;\r
1652                 if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, type));\r
1653         }\r
1654         for(Resource dep : graph.syncRequest(new ObjectsWithType(sharedOntology, L0.IsLinkedTo, L0.SharedOntology))) {\r
1655                 if(!Layer0Utils.isPublished(graph, dep)) instances.add(Versions.getStandardPathNameString(graph, dep));\r
1656         }\r
1657         \r
1658         if(instances.isEmpty()) {\r
1659                 graph.getSession().asyncRequest(new WriteRequest() {\r
1660                         \r
1661                                 @Override\r
1662                                 public void perform(WriteGraph graph) throws DatabaseException {\r
1663                                 graph.markUndoPoint();\r
1664                                 publish(graph, sharedOntology);\r
1665                                 }\r
1666                         \r
1667                 });\r
1668                 return;\r
1669         }\r
1670         \r
1671         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
1672             @Override\r
1673             public void run() {\r
1674                 \r
1675                 if (!PlatformUI.isWorkbenchRunning())\r
1676                     return;\r
1677 \r
1678                 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
1679                 ListDialog<String> dialog = new ListDialog<String>(\r
1680                         shell,\r
1681                         instances,\r
1682                         "Cannot publish shared library",\r
1683                         "The following dependencies are unpublished.") {\r
1684 \r
1685                         protected void createButtonsForButtonBar(Composite parent) {\r
1686                                 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
1687                         }\r
1688                         \r
1689                 };\r
1690                 int result = dialog.open();\r
1691                 if (result != Dialog.OK)\r
1692                     return;\r
1693 \r
1694             }\r
1695         });\r
1696         \r
1697     }\r
1698 \r
1699     \r
1700     public static void createSCLModuleDefault(WriteGraph graph, Resource target) throws DatabaseException {\r
1701         String name = NameUtils.findFreshEscapedName(graph, "SCLModule", target);\r
1702         createSCLModule(graph, target, name);\r
1703     }\r
1704 \r
1705     public static void createSCLModule(WriteGraph graph, Resource target, String name) throws DatabaseException {\r
1706         graph.markUndoPoint();\r
1707         Layer0 L0 = Layer0.getInstance(graph);\r
1708         Resource sclModule = GraphUtils.create2(graph, L0.SCLModule,\r
1709                 L0.HasName, name,\r
1710                 L0.PartOf, target,\r
1711                 L0.SCLModule_definition, "");\r
1712         Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString());\r
1713     }\r
1714 \r
1715     public static void createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException {\r
1716         String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target);\r
1717         createPGraph(graph, target, name);\r
1718     }\r
1719 \r
1720     public static void createPGraph(WriteGraph graph, Resource target, String name) throws DatabaseException {\r
1721         graph.markUndoPoint();\r
1722         Layer0 L0 = Layer0.getInstance(graph);\r
1723         Resource file = GraphUtils.create2(graph, L0.PGraph,\r
1724                 L0.HasName, name,\r
1725                 L0.PartOf, target,\r
1726                 L0.PGraph_definition, "");\r
1727         Layer0Utils.addCommentMetadata(graph, "Created Ontology Definition File " + name + " " + file.toString());\r
1728     }\r
1729     \r
1730     public static void publish(WriteGraph graph, Resource target) throws DatabaseException {\r
1731         Layer0 L0 = Layer0.getInstance(graph);\r
1732         graph.claimLiteral(target, L0.Entity_published, true, Bindings.BOOLEAN);\r
1733         Layer0Utils.addCommentMetadata(graph, "Published " + graph.getPossibleRelatedValue2(target, L0.HasName, Bindings.STRING) + " " + target.toString());\r
1734     }\r
1735 \r
1736     public static boolean isLinkedToDeep(ReadGraph graph, Resource r1, Resource r2) throws DatabaseException {\r
1737         return graph.syncRequest(new IsLinkedTo(r1, r2));\r
1738     }\r
1739     \r
1740     public static void openWizard(Display display, IStructuredSelection selection, String id) {\r
1741         // First see if this is a "new wizard".\r
1742         IWizardDescriptor descriptor = PlatformUI.getWorkbench()\r
1743                         .getNewWizardRegistry().findWizard(id);\r
1744         // If not check if it is an "import wizard".\r
1745         if  (descriptor == null) {\r
1746                 descriptor = PlatformUI.getWorkbench().getImportWizardRegistry()\r
1747                                 .findWizard(id);\r
1748         }\r
1749         // Or maybe an export wizard\r
1750         if  (descriptor == null) {\r
1751                 descriptor = PlatformUI.getWorkbench().getExportWizardRegistry()\r
1752                                 .findWizard(id);\r
1753         }\r
1754         try  {\r
1755                 // Then if we have a wizard, open it.\r
1756                 if  (descriptor != null) {\r
1757                         IWorkbenchWizard wizard = descriptor.createWizard();\r
1758                         wizard.init(PlatformUI.getWorkbench(), selection);\r
1759                         WizardDialog wd = new  WizardDialog(display.getActiveShell(), wizard);\r
1760                         wd.setTitle(wizard.getWindowTitle());\r
1761                         wd.open();\r
1762                 }\r
1763         } catch  (CoreException e) {\r
1764                 e.printStackTrace();\r
1765         }\r
1766     }\r
1767     \r
1768     public static String withinEpsilon(double value, double reference, double epsilon) {\r
1769         if(Math.abs(value-reference) < epsilon) return "True";\r
1770         else return "Not within epsilon value=" + value + ", reference=" + reference + " , epsilon=" + epsilon; \r
1771     }\r
1772     \r
1773     public static boolean needsIdentifier(ReadGraph graph, Resource r) throws DatabaseException {\r
1774         Layer0 L0 = Layer0.getInstance(graph);\r
1775         Collection<Resource> types = graph.getPrincipalTypes(r);\r
1776         for(Resource type : types)\r
1777                 if(graph.syncRequest(new IsInstanceOf(type, L0.TypeWithIdentifier), TransientCacheAsyncListener.<Boolean>instance()))\r
1778                                 return true;\r
1779         return false;\r
1780     }\r
1781 \r
1782     public static boolean needsModificationInfo(ReadGraph graph, Resource r) throws DatabaseException {\r
1783         ModelingResources MOD = ModelingResources.getInstance(graph);\r
1784         Collection<Resource> types = graph.getPrincipalTypes(r);\r
1785         for(Resource type : types)\r
1786                 if(graph.syncRequest(new IsInstanceOf(type, MOD.TypeWithChangeInformation), TransientCacheAsyncListener.<Boolean>instance()))\r
1787                                 return true;\r
1788         return false;\r
1789     }\r
1790 \r
1791     public static void attachCreationInformation(IProgressMonitor monitor, WriteGraph graph, Resource model) throws DatabaseException {\r
1792         \r
1793         if(monitor == null) monitor = new NullProgressMonitor();\r
1794         \r
1795         final String author = System.getProperty("user.name", "");\r
1796         final long time = System.currentTimeMillis();\r
1797         \r
1798         monitor.setTaskName("Attach creation information");\r
1799 \r
1800         ModelingResources MOD = ModelingResources.getInstance(graph);\r
1801         Collection<Resource> rs = ModelingUtils.searchByType(graph, model, MOD.TypeWithChangeInformation);\r
1802         Collection<Resource> supers = ModelingUtils.getMostUnspecificTypes(graph, rs);\r
1803         \r
1804         CollectionSupport cs = graph.getService(CollectionSupport.class);\r
1805         Collection<Resource> set = cs.createSet();\r
1806         for(Resource type : supers) {\r
1807                 set.addAll(ModelingUtils.searchByTypeShallow(graph, model, type));\r
1808         }\r
1809         Collection<Resource> instances = Layer0Utils.sortByCluster(graph, set);\r
1810 \r
1811         int pc = instances.size() / 100;\r
1812         int done = 0;\r
1813         int stint = pc;\r
1814 \r
1815         for(Resource instance : instances) {\r
1816                 ChangeInformation info = graph.getPossibleRelatedValue(instance, MOD.changeInformation, ChangeInformation.BINDING);\r
1817                 if(info == null) {\r
1818                         info = new ChangeInformation();\r
1819                         info.createdAt = time;\r
1820                         info.createdBy = author;\r
1821                         info.modifiedAt = time;\r
1822                         info.modifiedBy = author;\r
1823                         graph.claimLiteral(instance, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING);\r
1824                 }\r
1825                 done++;\r
1826                 stint--;\r
1827                 if(stint == 0) {\r
1828                         Double d = (100.0*done)/instances.size();\r
1829                         monitor.setTaskName("Attach creation information " +  d.intValue() + "%");\r
1830                         stint = pc;\r
1831                 }\r
1832         }\r
1833         \r
1834                 monitor.setTaskName("Attach creation information - commit");\r
1835         \r
1836     }\r
1837 \r
1838     public static class DiagramComponentInfo {\r
1839 \r
1840         private static String CHILD_PREFIX             = "child:";\r
1841 \r
1842                 final private String compositePathAndName;\r
1843                 final private String componentName;\r
1844                 final private GUID guid;\r
1845                 \r
1846                 public DiagramComponentInfo(String compositePathAndName, String componentName, GUID guid) {\r
1847                         this.compositePathAndName = compositePathAndName;\r
1848                         this.componentName = componentName;\r
1849                         this.guid = guid;\r
1850                 }\r
1851                 \r
1852                 public static boolean isDiagramComponent(String tgName) {\r
1853                         return tgName.startsWith(CHILD_PREFIX);\r
1854                 }\r
1855 \r
1856                 public String getTGName(CompositeInfo info) {\r
1857                         return CHILD_PREFIX + info.getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + info.getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedComponentName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();\r
1858                 }\r
1859                 \r
1860                 public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
1861                         Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);\r
1862                         return !res.isEmpty();\r
1863                 }\r
1864 \r
1865                 public static DiagramComponentInfo fromResource(ReadGraph graph, CompositeInfo info, Resource resource) throws DatabaseException {\r
1866                         Layer0 L0 = Layer0.getInstance(graph);\r
1867                 GUID childId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);\r
1868             String childName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);\r
1869             return new DiagramComponentInfo(info.getStateKey(), URIStringUtils.escape(childName), childId);\r
1870                 }\r
1871                 \r
1872                 public GUID getGUID() {\r
1873                         return guid;\r
1874                 }\r
1875                 \r
1876                 public String getEscapedCompositePathAndName() {\r
1877                         return compositePathAndName;\r
1878                 }\r
1879                 \r
1880                 public String getEscapedComponentName() {\r
1881                         return componentName;\r
1882                 }\r
1883                 \r
1884                 public String getUnescapedComponentName() {\r
1885                         return URIStringUtils.unescape(getEscapedComponentName());\r
1886                 }\r
1887                 \r
1888                 // "child:path#compositeName#componentName#guid"\r
1889                 public static DiagramComponentInfo parse(String tgName) {\r
1890                         \r
1891             String name = tgName.substring(CHILD_PREFIX.length());\r
1892             String compositePathAndName = "";\r
1893             String moduleName = name;\r
1894             GUID guid = GUID.invalid();\r
1895             int lastHash = name.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);\r
1896             if(lastHash >= 0) {\r
1897                 String first = name.substring(0, lastHash);\r
1898                 String second = name.substring(lastHash+1);\r
1899                 lastHash = first.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);\r
1900                 if(lastHash >= 0) {\r
1901                         compositePathAndName = first.substring(0, lastHash);\r
1902                         moduleName = first.substring(lastHash+1);\r
1903                         guid = GUID.parseIndexString(second);\r
1904                 } else {\r
1905                         compositePathAndName = first;\r
1906                         moduleName = second;\r
1907                 }\r
1908             }\r
1909             return new DiagramComponentInfo(compositePathAndName, moduleName, guid); \r
1910                         \r
1911                 }\r
1912 \r
1913 \r
1914         @Override\r
1915                 public int hashCode() {\r
1916                         final int prime = 31;\r
1917                         int result = 1;\r
1918                         result = prime * result + ((compositePathAndName == null) ? 0 : compositePathAndName.hashCode());\r
1919                         result = prime * result + ((componentName == null) ? 0 : componentName.hashCode());\r
1920                         return result;\r
1921                 }\r
1922 \r
1923                 @Override\r
1924                 public boolean equals(Object obj) {\r
1925                         if (this == obj)\r
1926                                 return true;\r
1927                         if (obj == null)\r
1928                                 return false;\r
1929                         if (getClass() != obj.getClass())\r
1930                                 return false;\r
1931                         DiagramComponentInfo other = (DiagramComponentInfo) obj;\r
1932                         if (compositePathAndName == null) {\r
1933                                 if (other.compositePathAndName != null)\r
1934                                         return false;\r
1935                         } else if (!compositePathAndName.equals(other.compositePathAndName))\r
1936                                 return false;\r
1937                         if (componentName == null) {\r
1938                                 if (other.componentName != null)\r
1939                                         return false;\r
1940                         } else if (!componentName.equals(other.componentName))\r
1941                                 return false;\r
1942                         return true;\r
1943                 }\r
1944                 \r
1945     }\r
1946     \r
1947         public static class CompositeInfo {\r
1948 \r
1949             public static String COMPOSITE_PREFIX         = "composite:";\r
1950 \r
1951                 final private boolean useGuids;\r
1952                 final private boolean applyPaths;\r
1953                 final private String path;\r
1954                 final private String name;\r
1955                 final private GUID guid;\r
1956                 \r
1957                 private CompositeInfo(boolean useGuids, boolean applyPaths, String path, String name, GUID guid) {\r
1958                         this.useGuids = useGuids;\r
1959                         this.applyPaths = applyPaths;\r
1960                         this.path = path;\r
1961                         this.name = name;\r
1962                         this.guid = guid;\r
1963                 }\r
1964 \r
1965                 @Override\r
1966                 public String toString() {\r
1967                         return "CompositeInfo[useGuids=" + useGuids + ", applyPaths=" + applyPaths + ", path=" + path + ", name=" + name + ", guid=" + guid.indexString() + "]";\r
1968                 }\r
1969 \r
1970                 public static boolean isComposite(String tgName) {\r
1971                         return tgName.startsWith(COMPOSITE_PREFIX);\r
1972                 }\r
1973 \r
1974                 public String getTGName() {\r
1975                         return COMPOSITE_PREFIX + getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();\r
1976                 }\r
1977                 \r
1978                 public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
1979                         Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);\r
1980                         return !res.isEmpty();\r
1981                 }\r
1982 \r
1983                 public static CompositeInfo fromResource(ReadGraph graph, Resource resource) throws DatabaseException {\r
1984                         \r
1985                         Layer0 L0 = Layer0.getInstance(graph);\r
1986             GUID rootId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);\r
1987             String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);\r
1988             String escapedRootName = URIStringUtils.escape(rootName);\r
1989             String escapedPath = ModelingUtils.getDiagramCompositePath(graph, resource);\r
1990             return new CompositeInfo(true, true, escapedPath, escapedRootName, rootId);\r
1991                         \r
1992                 }\r
1993 \r
1994             public static CompositeInfo parse(String tgName) {\r
1995                 return parse(tgName, true, true);\r
1996             }\r
1997 \r
1998             /*\r
1999              * Index 0 is root-relative folder path separated with '/' or null if target-relative positioning is used\r
2000              * Index 1 is diagram name\r
2001              */\r
2002             public static CompositeInfo parse(String tgName, boolean applyPaths, boolean useGuids) {\r
2003                 if(!tgName.startsWith(COMPOSITE_PREFIX)) return null;\r
2004                 tgName = tgName.substring(COMPOSITE_PREFIX.length());\r
2005                 if(!tgName.contains(COMPOSITE_SEPARATOR)) {\r
2006                         if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");\r
2007                         return new CompositeInfo(useGuids, applyPaths, null, tgName, null);\r
2008                 }\r
2009                 String[] parts = tgName.split(COMPOSITE_SEPARATOR);\r
2010                 if(parts.length == 2) {\r
2011                         String name = parts[1];\r
2012                         String path = applyPaths ? parts[0] : null;\r
2013                         if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");\r
2014                         return new CompositeInfo(useGuids, applyPaths, path, name, null);\r
2015                 } else if(parts.length == 3) {\r
2016                         String path = parts[0];\r
2017                         String name = parts[1];\r
2018                         GUID guid = GUID.parseIndexString(parts[2]);\r
2019                         return new CompositeInfo(useGuids, applyPaths, path, name, guid);\r
2020                 } else {\r
2021                         return null;\r
2022                 }\r
2023             }\r
2024 \r
2025                 public GUID getGUID() {\r
2026                         return guid;\r
2027                 }\r
2028 \r
2029                 public String getEscapedName() {\r
2030                         return name;\r
2031                 }\r
2032                 \r
2033                 public String getUnescapedName() {\r
2034                         return URIStringUtils.unescape(name);\r
2035                 }\r
2036                 \r
2037                 public String getOriginalPath() {\r
2038                         return path;\r
2039                 }\r
2040                 \r
2041                 public String getFinalPath() {\r
2042                         if(applyPaths) return path;\r
2043                         else return null;\r
2044                 }\r
2045                 \r
2046                 public CompositeInfo renamed(String newName) {\r
2047                         return new CompositeInfo(useGuids, applyPaths, path, newName, guid);\r
2048                 }\r
2049                 \r
2050                 public String getStateKey() {\r
2051                         return path + "#" + getEscapedName();\r
2052                 }\r
2053                 \r
2054                 private Resource getFromFolder(ReadGraph graph, Resource target) throws DatabaseException {\r
2055             Resource diagram = Layer0Utils.getPossibleChild(graph, target, URIStringUtils.unescape(name));\r
2056             if(diagram == null) return null;\r
2057             StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
2058             return graph.isInstanceOf(diagram, STR.Composite) ? diagram : null;\r
2059                 }\r
2060                 \r
2061                 public Resource resolve(ReadGraph graph, Resource target) throws DatabaseException {\r
2062 \r
2063                         if(useGuids && guid != null) {\r
2064                                 Resource indexRoot = graph.syncRequest(new IndexRoot(target));\r
2065                                 Collection<Resource> queryResult = searchByGUID(graph, indexRoot, guid);\r
2066                                 if(queryResult.size() == 1) {\r
2067                                         Resource composite = queryResult.iterator().next(); \r
2068                             StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
2069                             if(!graph.isInstanceOf(composite, STR.Composite)) return null;\r
2070                             return composite;\r
2071                                 }\r
2072                         }\r
2073                         \r
2074                         if(applyPaths) {\r
2075                                 Resource folder = resolveFolder(graph, target);\r
2076                                 if(folder == null) return null;\r
2077                         return getFromFolder(graph, folder);\r
2078                         } else {\r
2079                         return getFromFolder(graph, target);\r
2080                         }\r
2081                         \r
2082                 }\r
2083                 \r
2084                 public Resource resolveFolder(ReadGraph graph, Resource target) throws DatabaseException {\r
2085                         \r
2086                         String path = getFinalPath();\r
2087                         if(path == null) return target;\r
2088                         \r
2089                 Resource folder = graph.syncRequest(new Configuration(target));\r
2090                 String[] segments = path.split("/");\r
2091                 for(int i=0;i<segments.length;i++) {\r
2092                         if(segments[i].isEmpty()) continue;\r
2093                         folder = Layer0Utils.getPossibleChild(graph, folder, URIStringUtils.unescape(segments[i]));\r
2094                         if(folder == null) return null;\r
2095                 }\r
2096                 \r
2097                 return folder;\r
2098                         \r
2099                 }\r
2100                 \r
2101                 \r
2102                 @Override\r
2103                 public int hashCode() {\r
2104                         \r
2105                         if(useGuids) return guid.hashCode();\r
2106                         \r
2107                         final int prime = 31;\r
2108                         int result = name.hashCode();\r
2109                         result = prime * result + ((path == null) ? 0 : path.hashCode());\r
2110                         return result;\r
2111                         \r
2112                 }\r
2113 \r
2114                 @Override\r
2115                 public boolean equals(Object obj) {\r
2116                         \r
2117                         if (this == obj)\r
2118                                 return true;\r
2119                         if (obj == null)\r
2120                                 return false;\r
2121                         if (getClass() != obj.getClass())\r
2122                                 return false;\r
2123                         \r
2124                         CompositeInfo other = (CompositeInfo) obj;\r
2125                         \r
2126                         if(useGuids) return guid.equals(other.guid);\r
2127                         \r
2128                         if (!name.equals(other.name))\r
2129                                 return false;\r
2130                         \r
2131                         if(applyPaths)\r
2132                                 if (!path.equals(other.path))\r
2133                                         return false;\r
2134                         \r
2135                         return true;\r
2136                         \r
2137                 }\r
2138                 \r
2139         }\r
2140         \r
2141     public static char   COMPOSITE_SEPARATOR_CHAR = '#';\r
2142     public static String COMPOSITE_SEPARATOR      = String.valueOf(COMPOSITE_SEPARATOR_CHAR);\r
2143     \r
2144     public static CompositeInfo parseCompositeNameFromRoot(Root root, boolean applyPaths, boolean useGuids) {\r
2145         return CompositeInfo.parse(root.name, applyPaths, useGuids);\r
2146     }\r
2147 \r
2148     public static CompositeInfo parseCompositeNameFromRoot(Identity root, boolean applyPaths, boolean useGuids) {\r
2149         String coded = TransferableGraphUtils.getName(root);\r
2150         return CompositeInfo.parse(coded, applyPaths, useGuids);\r
2151     }\r
2152     \r
2153         private static StringBuilder getDiagramCompositePathInternal(ReadGraph graph, Resource folder, StringBuilder builder) throws DatabaseException {\r
2154                 SimulationResource SIMU = SimulationResource.getInstance(graph);\r
2155                 Resource model = graph.getPossibleObject(folder, SIMU.IsConfigurationOf);\r
2156                 if (model != null) return builder;\r
2157 \r
2158                 Layer0 L0 = Layer0.getInstance(graph);\r
2159                 String name = graph.getPossibleRelatedValue(folder, L0.HasName, Bindings.STRING);\r
2160                 if (name == null) return null;\r
2161                 Resource parent = graph.getPossibleObject(folder, L0.PartOf);\r
2162                 if (parent == null) return null;\r
2163 \r
2164                 StringBuilder sb = getDiagramCompositePathInternal(graph, parent, builder);\r
2165                 if (sb == null) return null;\r
2166                 if (sb.length() > 0)\r
2167                         sb.append(URIStringUtils.NAMESPACE_PATH_SEPARATOR);\r
2168                 sb.append( URIStringUtils.escape(name) );\r
2169                 return sb;\r
2170         }\r
2171 \r
2172         /**\r
2173          * @param graph\r
2174          * @param diagram\r
2175          * @return diagram/folder path up until model configuration root with each\r
2176          *         segment escaped using {@link URIStringUtils#escape(String)} and\r
2177          *         {@value URIStringUtils#NAMESPACE_PATH_SEPARATOR} between each\r
2178          *         segment or <code>null</code> if the specified diagram composite\r
2179          *         is not part of any model configuration structure.\r
2180          * @throws DatabaseException\r
2181          */\r
2182         public static String getDiagramCompositePath(ReadGraph graph, Resource diagram) throws DatabaseException {\r
2183                 Layer0 L0 = Layer0.getInstance(graph);\r
2184                 Resource parent = graph.getPossibleObject(diagram, L0.PartOf);\r
2185                 if(parent == null) return null;\r
2186                 StringBuilder sb = getDiagramCompositePathInternal(graph, parent, new StringBuilder());\r
2187                 return sb != null ? sb.toString() : null;\r
2188         }\r
2189         \r
2190         public static void exportModel(ReadGraph graph, Resource model, String fileName, String format, int version) throws DatabaseException {\r
2191         \r
2192                 try {\r
2193                         TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model, true, false);\r
2194                 TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
2195                         TransferableGraphs.writeTransferableGraph(graph, format, version, s, new File(fileName));\r
2196                 } catch (Exception e) {\r
2197                         throw new DatabaseException(e);\r
2198                 }\r
2199 \r
2200         }\r
2201 \r
2202         public static void exportSharedOntology(ReadGraph graph, Resource library, String fileName, String format, int version) throws DatabaseException {\r
2203                 \r
2204         Layer0 L0 = Layer0.getInstance(graph);\r
2205         String name = graph.getRelatedValue(library, L0.HasName, Bindings.STRING);\r
2206 \r
2207         DraftStatusBean draft = null;\r
2208         boolean published = Layer0Utils.isPublished(graph, library);\r
2209         if(!published) draft = new DraftStatusBean(new String[0]);\r
2210         \r
2211         LibraryInfo info = new LibraryInfo(name, library, draft);\r
2212                 \r
2213         try {\r
2214                         exportSharedOntology(new NullProgressMonitor(), graph, new File(fileName), format, version, info);\r
2215                 } catch (IOException e) {\r
2216                         throw new DatabaseException(e);\r
2217                 }\r
2218 \r
2219         }\r
2220 \r
2221     public static DraftStatusBean getDependencyDraftStatus(ReadGraph graph, Resource library) throws DatabaseException {\r
2222         Layer0 L0 = Layer0.getInstance(graph);\r
2223         List<String> drafts = new ArrayList<>();\r
2224         for (Resource shared : graph.syncRequest(new ObjectsWithType(library, L0.IsLinkedTo, L0.SharedOntology))) {\r
2225             boolean published = Layer0Utils.isPublished(graph, shared);\r
2226             if (!published)\r
2227                 drafts.add(graph.getURI(shared));\r
2228         }\r
2229         return drafts.isEmpty() ? null : new DraftStatusBean(drafts);\r
2230     }\r
2231 \r
2232         public static Set<Resource> getMostUnspecificTypes(final ReadGraph graph, Collection<Resource> types) throws DatabaseException {\r
2233                 \r
2234                 final Set<Resource> work = new HashSet<Resource>(types);\r
2235                 for(Resource type : types) {\r
2236                         Set<Resource> supers = graph.getSupertypes(type);\r
2237                         if(!Collections.disjoint(supers, work)) work.remove(type);\r
2238                 }\r
2239 \r
2240                 return work;\r
2241                 \r
2242         }\r
2243         \r
2244         public static void rewriteGUIDS(WriteGraph graph, Resource root, boolean deep) throws DatabaseException {\r
2245                 List<Resource> todo = new ArrayList<Resource>();\r
2246                 todo.add(root);\r
2247                 Layer0 L0 = Layer0.getInstance(graph);\r
2248                 while(!todo.isEmpty()) {\r
2249                         Resource resource = todo.remove(todo.size()-1);\r
2250             graph.claimLiteral(resource, L0.identifier, L0.GUID, GUID.random(), GUID.BINDING);\r
2251             if(deep)\r
2252                 todo.addAll(graph.getObjects(resource, L0.ConsistsOf));\r
2253                 }\r
2254         }\r
2255         \r
2256         public static void createMissingGUIDs(IProgressMonitor monitor, WriteGraph graph, Collection<Resource> roots) throws DatabaseException {\r
2257                 \r
2258         if(monitor == null) monitor = new NullProgressMonitor();\r
2259         \r
2260                 Layer0 L0 = Layer0.getInstance(graph);\r
2261                 \r
2262         // Allow this process to make 50k queries\r
2263         QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000);\r
2264 \r
2265                 for(Resource root : roots) {\r
2266                         \r
2267                         boolean madeChanges = false;\r
2268                         \r
2269                 monitor.setTaskName("Creating missing GUID identifiers " + NameUtils.getSafeName(graph, root));\r
2270                         Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(root));\r
2271                         for(Resource r : searchByType(graph, indexRoot, L0.Entity)) {\r
2272 \r
2273                                 memory.maintain();\r
2274 \r
2275                                 if(graph.isImmutable(r)) continue;\r
2276 \r
2277                                 if(!ModelingUtils.needsIdentifier(graph, r)) continue;\r
2278                                 \r
2279                                 GUID existing = graph.getPossibleRelatedValue(r, L0.identifier, GUID.BINDING);\r
2280                                 if(existing == null) {\r
2281                                         graph.addLiteral(r, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING);\r
2282                                         madeChanges = true;\r
2283                                 }\r
2284                                 \r
2285                         }\r
2286                         \r
2287                         if(madeChanges)\r
2288                                 ModelingUtils.deleteIndex(graph, root);\r
2289                         \r
2290                 }\r
2291                 \r
2292                 \r
2293         }\r
2294         \r
2295         public static boolean activateModel(WriteGraph graph, Resource model) throws DatabaseException {\r
2296                 return graph.syncRequest(new ActivateModel(Simantics.getProjectResource(), model));\r
2297         }\r
2298         \r
2299         public static File fileDialog(String title, List<Tuple> namesAndExtensions) {\r
2300                 \r
2301                 Display display = Display.getCurrent();\r
2302                 Shell shell = display.getActiveShell();\r
2303                 \r
2304         FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
2305         dialog.setText(title);\r
2306         \r
2307         String[] extensions = new String[namesAndExtensions.size()];\r
2308         String[] filterNames = new String[namesAndExtensions.size()];\r
2309         int index = 0;\r
2310         for(Tuple t : namesAndExtensions) {\r
2311                 String filterName = (String)t.get(0);\r
2312                 String extension = (String)t.get(1);\r
2313                 filterNames[index] = filterName;\r
2314                 extensions[index] = extension;\r
2315         }\r
2316         \r
2317         dialog.setFilterExtensions(extensions);\r
2318         dialog.setFilterNames(filterNames);\r
2319         final String fileName = dialog.open();\r
2320         if (fileName == null) return null;\r
2321         \r
2322         return new File(fileName);\r
2323 \r
2324         }\r
2325         \r
2326         public static Resource createLibrary(WriteGraph graph, Resource parent) throws DatabaseException {\r
2327         Layer0 l0 = Layer0.getInstance(graph);\r
2328         return createLibrary(graph, parent, NameUtils.findFreshName(graph, "Library", parent, l0.ConsistsOf));\r
2329     }\r
2330     \r
2331     public static Resource createLibrary(WriteGraph graph, Resource parent, String name) throws DatabaseException {\r
2332         graph.markUndoPoint();\r
2333         Layer0 l0 = Layer0.getInstance(graph);\r
2334 \r
2335         Resource library = graph.newResource();\r
2336         graph.claim(library, l0.InstanceOf, null, l0.Library);\r
2337         graph.addLiteral(library, l0.HasName, l0.NameOf, l0.String, name, Bindings.STRING);\r
2338         graph.claim(library, l0.PartOf, parent);\r
2339 \r
2340         Layer0Utils.addCommentMetadata(graph, "Created new Library named " + name + ", resource " + library);\r
2341 \r
2342         return library;\r
2343     }\r
2344 \r
2345 \r
2346 }\r