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