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