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