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