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