1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling;
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;
26 import java.util.TreeMap;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.NullProgressMonitor;
31 import org.eclipse.core.runtime.Path;
32 import org.eclipse.jface.dialogs.Dialog;
33 import org.eclipse.jface.dialogs.IDialogConstants;
34 import org.eclipse.jface.dialogs.MessageDialog;
35 import org.eclipse.jface.layout.GridDataFactory;
36 import org.eclipse.jface.layout.GridLayoutFactory;
37 import org.eclipse.jface.resource.ImageDescriptor;
38 import org.eclipse.jface.viewers.IStructuredSelection;
39 import org.eclipse.jface.viewers.StructuredSelection;
40 import org.eclipse.jface.window.Window;
41 import org.eclipse.jface.wizard.WizardDialog;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Control;
45 import org.eclipse.swt.widgets.Display;
46 import org.eclipse.swt.widgets.FileDialog;
47 import org.eclipse.swt.widgets.Shell;
48 import org.eclipse.ui.IWorkbenchWizard;
49 import org.eclipse.ui.PlatformUI;
50 import org.eclipse.ui.wizards.IWizardDescriptor;
51 import org.simantics.Simantics;
52 import org.simantics.annotation.ontology.AnnotationResource;
53 import org.simantics.databoard.Bindings;
54 import org.simantics.databoard.binding.Binding;
55 import org.simantics.databoard.binding.mutable.Variant;
56 import org.simantics.databoard.container.DataContainer;
57 import org.simantics.databoard.container.DataContainers;
58 import org.simantics.databoard.container.DataFormatException;
59 import org.simantics.databoard.container.FormatHandler;
60 import org.simantics.databoard.serialization.SerializationException;
61 import org.simantics.databoard.type.Datatype;
62 import org.simantics.databoard.util.URIStringUtils;
63 import org.simantics.datatypes.literal.GUID;
64 import org.simantics.db.ReadGraph;
65 import org.simantics.db.RequestProcessor;
66 import org.simantics.db.Resource;
67 import org.simantics.db.Statement;
68 import org.simantics.db.WriteGraph;
69 import org.simantics.db.common.NamedResource;
70 import org.simantics.db.common.QueryMemoryWatcher;
71 import org.simantics.db.common.primitiverequest.IsInstanceOf;
72 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
73 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
74 import org.simantics.db.common.request.IndexRoot;
75 import org.simantics.db.common.request.ObjectsWithType;
76 import org.simantics.db.common.request.PossibleIndexRoot;
77 import org.simantics.db.common.request.ReadRequest;
78 import org.simantics.db.common.request.ResourceRead2;
79 import org.simantics.db.common.request.WriteRequest;
80 import org.simantics.db.common.request.WriteResultRequest;
81 import org.simantics.db.common.utils.ListUtils;
82 import org.simantics.db.common.utils.Logger;
83 import org.simantics.db.common.utils.NameUtils;
84 import org.simantics.db.common.utils.OrderedSetUtils;
85 import org.simantics.db.common.utils.VersionInfo;
86 import org.simantics.db.common.utils.VersionInfoRequest;
87 import org.simantics.db.common.utils.Versions;
88 import org.simantics.db.exception.DatabaseException;
89 import org.simantics.db.layer0.SelectionHints;
90 import org.simantics.db.layer0.adapter.CopyHandler;
91 import org.simantics.db.layer0.adapter.GenericRelationIndex;
92 import org.simantics.db.layer0.adapter.Instances;
93 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
94 import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;
95 import org.simantics.db.layer0.genericrelation.IndexedRelations;
96 import org.simantics.db.layer0.migration.MigrationUtils;
97 import org.simantics.db.layer0.request.ActivateModel;
98 import org.simantics.db.layer0.request.ActiveModels;
99 import org.simantics.db.layer0.request.Configuration;
100 import org.simantics.db.layer0.request.IsLinkedTo;
101 import org.simantics.db.layer0.request.PossibleModel;
102 import org.simantics.db.layer0.util.ClipboardUtils;
103 import org.simantics.db.layer0.util.DraftStatusBean;
104 import org.simantics.db.layer0.util.ExternalDownloadBean;
105 import org.simantics.db.layer0.util.Layer0Utils;
106 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
107 import org.simantics.db.layer0.util.PasteEventHandler;
108 import org.simantics.db.layer0.util.RemoverUtil;
109 import org.simantics.db.layer0.util.SimanticsClipboard;
110 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
111 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
112 import org.simantics.db.layer0.util.SimanticsKeys;
113 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
114 import org.simantics.db.layer0.variable.Variable;
115 import org.simantics.db.layer0.variable.Variables;
116 import org.simantics.db.request.Read;
117 import org.simantics.db.service.ClusterControl;
118 import org.simantics.db.service.CollectionSupport;
119 import org.simantics.db.service.QueryControl;
120 import org.simantics.db.service.VirtualGraphSupport;
121 import org.simantics.diagram.stubs.DiagramResource;
122 import org.simantics.diagram.stubs.G2DResource;
123 import org.simantics.diagram.synchronization.graph.AddElement;
124 import org.simantics.graph.db.IImportAdvisor2;
125 import org.simantics.graph.db.ImportAdvisors;
126 import org.simantics.graph.db.MissingDependencyException;
127 import org.simantics.graph.db.StreamingTransferableGraphFileReader;
128 import org.simantics.graph.db.TransferableGraphException;
129 import org.simantics.graph.db.TransferableGraphSource;
130 import org.simantics.graph.db.TransferableGraphs;
131 import org.simantics.graph.representation.Identity;
132 import org.simantics.graph.representation.Root;
133 import org.simantics.graph.representation.TransferableGraph1;
134 import org.simantics.graph.representation.TransferableGraphUtils;
135 import org.simantics.issues.common.IssueSourceUtils;
136 import org.simantics.issues.ontology.IssueResource;
137 import org.simantics.layer0.Layer0;
138 import org.simantics.layer0.utils.direct.GraphUtils;
139 import org.simantics.modeling.adapters.ChangeInformation;
140 import org.simantics.modeling.template2d.ontology.Template2dResource;
141 import org.simantics.operation.Layer0X;
142 import org.simantics.project.ontology.ProjectResource;
143 import org.simantics.scenegraph.profile.ProfileUtils;
144 import org.simantics.scl.runtime.function.Function1;
145 import org.simantics.scl.runtime.tuple.Tuple;
146 import org.simantics.simulation.ontology.SimulationResource;
147 import org.simantics.structural.stubs.StructuralResource2;
148 import org.simantics.structural2.scl.StructuralComponent;
149 import org.simantics.structural2.utils.StructuralUtils;
150 import org.simantics.ui.SimanticsUI;
151 import org.simantics.utils.ObjectUtils;
152 import org.simantics.utils.datastructures.Pair;
153 import org.simantics.utils.datastructures.Triple;
154 import org.simantics.utils.datastructures.hints.HintContext;
155 import org.simantics.utils.ui.dialogs.ListDialog;
158 * @author Hannu Niemistö
160 public class ModelingUtils {
163 private WriteGraph wg;
165 private StructuralResource2 sr;
166 private DiagramResource dr;
167 public ModelingResources mr;
168 public SimulationResource SIMU;
170 public ModelingUtils(WriteGraph g) {
173 b = Layer0.getInstance(g);
174 sr = StructuralResource2.getInstance(g);
175 dr = DiagramResource.getInstance(g);
176 mr = ModelingResources.getInstance(g);
177 SIMU = SimulationResource.getInstance(g);
181 public Resource createSymbol2(String name) throws DatabaseException {
182 return createSymbol2(name, dr.Composite);
186 public Resource createSymbol2(String name, Resource type) throws DatabaseException {
187 G2DResource g2d = G2DResource.getInstance(g);
189 // Resource visibleTag = wg.newResource();
190 // wg.claim(visibleTag, b.SubrelationOf, null, dr.IsVisible);
191 // Resource focusableTag = wg.newResource();
192 // wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable);
194 Double boxDimension = 6.0;
195 Collection<Statement> grid = g.getAssertedStatements(type, dr.HasGridSize);
196 if(grid.size() == 1) {
197 Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE);
198 if(d != null) boxDimension = 2*d;
202 Resource element = GraphUtils.create(wg,
203 b.InstanceOf, dr.SVGElement,
205 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
206 // REMOVED by Tuukka, because This will cause
207 // parsers to get on the net and get the doctype
208 // definitions which can stall the UI for a long time.
209 // Besides, we're not using the validation for anything
210 // so it's useless to us.
211 //"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" +
212 "<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">" +
213 "<rect x=\"-" + boxDimension + "\" y=\"-" + boxDimension + "\" width=\"" + (2*boxDimension) + "\" height=\"" + (2*boxDimension) + "\" fill=\"none\" stroke=\"rgb(0,0,0)\" stroke-width=\"0.1\"/>" +
217 // wg.claim(element, visibleTag, element);
218 // wg.claim(element, focusableTag, element);
220 Resource orderedSet = OrderedSetUtils.create(wg, type, element);
222 // wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer,
223 // b.HasName, "Default",
224 // dr.IsActive, Boolean.TRUE,
225 // dr.HasVisibleTag, visibleTag,
226 // dr.HasFocusableTag, focusableTag));
228 Resource result = GraphUtils.create(wg,
231 sr.IsDefinedBy, orderedSet);
233 wg.claim(result, b.ConsistsOf, orderedSet);
234 wg.claimLiteral(orderedSet, b.HasName, "__DIAGRAM__", Bindings.STRING);
235 AddElement.claimFreshElementName(wg, orderedSet, element);
236 wg.claim(orderedSet, b.ConsistsOf, element);
238 wg.claim(result, b.Inherits, null, dr.DefinedElement);
242 public static Collection<Resource> getElementCorrespondendences(ReadGraph g, Resource element) throws DatabaseException {
243 DiagramResource dr = DiagramResource.getInstance(g);
244 ModelingResources mr = ModelingResources.getInstance(g);
245 if(g.isInstanceOf(element, dr.Connection)) {
246 Resource mappedComponent = g.getPossibleObject(element, mr.ElementToComponent);
247 if(mappedComponent != null) return Collections.singletonList(mappedComponent);
248 Resource mappedConnection = g.getPossibleObject(element, mr.DiagramConnectionToConnection);
249 if(mappedConnection == null)
250 return Collections.emptyList();
251 ArrayList<Resource> result = new ArrayList<Resource>();
252 Collection<Resource> relatedMappedConnections = StructuralUtils.getRelatedConnections(g, mappedConnection);
253 for(Resource relatedMappedConnection : relatedMappedConnections)
254 for(Resource relatedConnection : g.getObjects(relatedMappedConnection, mr.ConnectionToDiagramConnection))
255 result.addAll(g.getObjects(relatedConnection, mr.ElementToComponent));
259 return g.getObjects(element, mr.ElementToComponent);
262 public static Resource getPossibleElement(ReadGraph g, Resource component) throws DatabaseException {
263 ModelingResources mr = ModelingResources.getInstance(g);
264 return g.getPossibleObject(component, mr.ComponentToElement);
267 public static Resource getPossibleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {
268 Collection<Resource> corrs = getElementCorrespondendences(g, element);
269 if(corrs.size() != 1) return null;
270 else return corrs.iterator().next();
273 public static Resource getSingleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {
274 Collection<Resource> corrs = getElementCorrespondendences(g, element);
275 if(corrs.size() != 1) throw new DatabaseException("Expected 1 element correspondence, got " + corrs.size());
276 else return corrs.iterator().next();
279 public static Resource createExperiment(WriteGraph graph, Resource model) throws DatabaseException {
281 Layer0 L0 = Layer0.getInstance(graph);
282 SimulationResource SIMU = SimulationResource.getInstance(graph);
283 Resource experiment = graph.newResource();
284 graph.claim(experiment, L0.InstanceOf, SIMU.Experiment);
285 graph.claimLiteral(experiment, L0.HasName, "Experiment");
286 graph.claim(model, L0.ConsistsOf, experiment);
291 public static Resource createModel(WriteGraph graph, Resource type) throws DatabaseException {
292 return createModel(graph, type, Simantics.getProjectResource(), null);
295 public static Resource createModel(WriteGraph graph, Resource type, String name) throws DatabaseException {
296 return createModel(graph, type, Simantics.getProjectResource(), name);
299 public static Resource createModel(WriteGraph graph, Resource type, final Resource target, String name) throws DatabaseException {
301 Layer0 L0 = Layer0.getInstance(graph);
302 SimulationResource SIMU = SimulationResource.getInstance(graph);
303 StructuralResource2 STR = StructuralResource2.getInstance(graph);
304 ModelingResources MOD = ModelingResources.getInstance(graph);
307 name = NameUtils.findFreshName(graph, "Model", target, L0.ConsistsOf, "%s%d");
309 final Resource model = graph.newResource();
310 graph.newClusterSet(model);
311 graph.claim(model, L0.InstanceOf, null, type);
312 graph.claimLiteral(model, L0.HasName, name);
314 graph.claim(target, L0.ConsistsOf, model);
316 Resource configurationType = graph.getPossibleObject(model, MOD.StructuralModel_HasConfigurationType);
317 if(configurationType == null) configurationType = STR.Composite;
319 Resource configuration = graph.newResource();
320 graph.claimLiteral(configuration, L0.HasName, "Configuration", Bindings.STRING);
321 graph.claim(configuration, L0.InstanceOf, null, configurationType);
322 graph.claim(model, L0.ConsistsOf, configuration);
323 graph.claim(model, SIMU.HasConfiguration, configuration);
325 Resource joinClusterSet = graph.newResource();
326 graph.newClusterSet(joinClusterSet);
327 graph.claim(joinClusterSet, L0.InstanceOf, L0.ClusterSet);
328 graph.claim(model, STR.HasJoinClusterSet, joinClusterSet);
330 linkOntologyDependenciesToModel(graph, model, target);
332 Resource ontology = graph.syncRequest(new PossibleIndexRoot(type));
333 if(ontology != null) {
334 graph.claim(model, L0.IsLinkedTo, ontology);
337 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
338 graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("activations")) {
341 public void perform(WriteGraph graph) throws DatabaseException {
342 Layer0X L0X = Layer0X.getInstance(graph);
343 Collection<Resource> actives = graph.syncRequest(new ActiveModels(target));
344 if(actives.isEmpty()) {
345 graph.claim(model, L0X.IsActivatedBy, target);
355 public static void linkOntologyDependenciesToModel(WriteGraph graph, Resource model, Resource target)
356 throws DatabaseException {
357 Layer0 L0 = Layer0.getInstance(graph);
358 ProjectResource PROJ = ProjectResource.getInstance(graph);
359 for(Resource dep : graph.getObjects(target, L0.IsLinkedTo)) {
360 if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {
361 for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {
362 String uri = graph.getPossibleValue(req, Bindings.STRING);
364 Resource ns = graph.getResource(uri);
366 graph.claim(model, L0.IsLinkedTo, null, ns);
374 public static void addSCLMainToModel(WriteGraph graph, Resource model)
375 throws DatabaseException {
376 addSCLMainToModel(graph, model, "SCLMain", "include \"Simantics/All\"\n");
379 public static void addSCLMainToModel(WriteGraph graph, Resource model, String name, String contents)
380 throws DatabaseException {
381 Layer0 L0 = Layer0.getInstance(graph);
382 Resource sclmain = GraphUtils.create2(graph, L0.SCLModule, L0.PartOf, model, L0.HasName, name);
383 graph.claimLiteral(sclmain, L0.SCLModule_definition, contents, Bindings.STRING);
386 public static Resource createLocalLibrary(WriteGraph graph, Resource container, String name) throws DatabaseException {
387 Layer0 L0 = Layer0.getInstance(graph);
388 ModelingResources MOD = ModelingResources.getInstance(graph);
389 Resource library = graph.newResource();
390 graph.claim(library, L0.InstanceOf, null, L0.Library);
391 graph.addLiteral(library, L0.HasName, L0.NameOf, "Library", Bindings.STRING);
392 if (container != null) {
393 graph.claim(container, L0.ConsistsOf, L0.PartOf, library);
394 graph.claim(container, MOD.HasLocalLibrary, MOD.IsLocalLibraryOf, library);
399 public static void importModel(String fileName) {
401 Resource project = SimanticsUI.getProject().get();
403 try (StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName))) {
404 TransferableGraphSource tg = importer.readTG();
406 final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(project) {
408 public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {
411 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
412 library = Simantics.getProjectResource();
413 String newName = newName(graph, library, root.name);
414 nameMappings.put(root.name, newName);
418 TransferableGraphs.importGraph1(Simantics.getSession(), tg, advisor);
420 } catch (MissingDependencyException e) {
422 final Set<String> missingURIs = e.getMissingURIs();
424 class ErrorMessageDialog extends MessageDialog {
426 public ErrorMessageDialog(Shell shell) {
428 "Unsatisfied dependencies", null,
429 "The following dependencies were missing. Please import the dependencies and try again.",
430 MessageDialog.ERROR, new String[] { "Continue" }, 0);
434 protected Control createCustomArea(Composite composite) {
435 GridLayoutFactory.fillDefaults().applyTo(composite);
437 org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);
438 GridDataFactory.fillDefaults().grab(true, true).applyTo(list);
439 for(String s : missingURIs) list.add(s);
445 Display display = Display.getCurrent();
446 if(display != null) {
447 ErrorMessageDialog md = new ErrorMessageDialog(display.getActiveShell());
450 Display.getDefault().asyncExec(new Runnable() {
454 Shell shell = Display.getCurrent().getActiveShell();
455 ErrorMessageDialog md = new ErrorMessageDialog(shell);
463 } catch (Exception e) {
464 Logger.defaultLogError(e);
469 public static void primeVirtualGraphs() {
470 VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);
471 support.getWorkspacePersistent("activations");
472 support.getWorkspacePersistent("experiments");
473 support.getWorkspacePersistent("issues");
474 support.getWorkspacePersistent("preferences");
477 public static Resource createProfileEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException {
479 Layer0 L0 = Layer0.getInstance(graph);
480 DiagramResource DIA = DiagramResource.getInstance(graph);
482 Resource entry = graph.newResource();
483 graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);
484 graph.claimLiteral(entry, L0.HasName, name);
485 graph.claimLiteral(entry, L0.HasLabel, name);
486 graph.claim(entry, DIA.ProfileEntry_HasStyle, style);
487 graph.claim(entry, DIA.ProfileEntry_HasGroup, group);
493 public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException {
495 Layer0 L0 = Layer0.getInstance(graph);
496 DiagramResource DIA = DiagramResource.getInstance(graph);
498 Resource list = ListUtils.create(graph, DIA.Profile, entries);
500 Resource profile = graph.newResource();
501 graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
502 graph.claimLiteral(profile, L0.HasName, profileName);
503 graph.claim(profile, DIA.HasEntries, null, list);
509 public static Resource createProfile(WriteGraph graph, String profileName, Collection<Resource> entries) throws DatabaseException {
510 return createProfile(graph, profileName, entries.toArray(new Resource[entries.size()]));
513 public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Resource ... profiles) throws DatabaseException {
515 Resource work = createProfile(graph, name, profiles);
517 Layer0 L0 = Layer0.getInstance(graph);
518 DiagramResource DIA = DiagramResource.getInstance(graph);
520 graph.deny(model, DIA.HasActiveProfile);
521 graph.claim(model, DIA.HasActiveProfile, work);
522 graph.claim(model, L0.ConsistsOf, L0.PartOf, work);
528 public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Collection<Resource> profiles) throws DatabaseException {
529 return createToplevelProfile(graph, model, name, profiles.toArray(new Resource[profiles.size()]));
532 public static void activateProfileEntries(WriteGraph graph, final Resource profile, final Resource ... entries) {
534 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
535 graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {
538 public void perform(WriteGraph graph) throws DatabaseException {
539 SimulationResource SIMU = SimulationResource.getInstance(graph);
540 for(Resource entry : entries)
541 graph.claim(profile, SIMU.IsActive, entry);
548 public static void activateProfileEntries(WriteGraph graph, Resource profile, Collection<Resource> entries) {
549 activateProfileEntries(graph, profile, entries.toArray(new Resource[entries.size()]));
552 public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, String groupName, boolean enabled) throws DatabaseException {
553 Layer0 L0 = Layer0.getInstance(graph);
554 for (Resource group : ProfileUtils.getProfileChildren(graph, runtimeProfile)) {
555 String name = graph.getRelatedValue2(group, L0.HasName);
556 if (name.equals(groupName)) {
557 toggleProfileGroup(graph, runtimeProfile, group, enabled);
563 public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, Resource group, boolean enabled) throws DatabaseException {
564 DiagramResource DIA = DiagramResource.getInstance(graph);
566 if(graph.isInstanceOf(group, DIA.Profile)) {
568 for(Resource child : ProfileUtils.getProfileChildren(graph, group)) {
569 toggleProfileGroup(graph, runtimeProfile, child, enabled);
572 } else if(graph.isInstanceOf(group, DIA.ProfileEntry)) {
575 graph.claim(runtimeProfile, SimulationResource.getInstance(graph).IsActive, null, group);
577 graph.denyStatement(runtimeProfile, SimulationResource.getInstance(graph).IsActive, group);
583 public static void untrackDependencies() {
584 untrackDependencies(Simantics.getSession());
587 public static void untrackDependencies(RequestProcessor processor) {
590 processor.syncRequest(new ReadRequest() {
593 public void run(ReadGraph graph) throws DatabaseException {
594 Layer0X L0X = Layer0X.getInstance(graph);
595 GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);
596 index.untrack(graph.getSession(), graph.getRootLibrary());
600 } catch (DatabaseException e) {
601 Logger.defaultLogError(e);
606 public static void trackDependencies() {
607 trackDependencies(Simantics.getSession());
610 public static void trackDependencies(RequestProcessor processor) {
613 processor.syncRequest(new ReadRequest() {
616 public void run(ReadGraph graph) throws DatabaseException {
617 Layer0X L0X = Layer0X.getInstance(graph);
618 GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);
619 index.trackAndIndex(graph.getSession(), graph.getRootLibrary());
623 } catch (DatabaseException e) {
624 Logger.defaultLogError(e);
629 public static void removeIndex(WriteGraph graph, Resource model) throws DatabaseException {
630 Layer0X L0X = Layer0X.getInstance(graph);
631 IndexedRelations ir = graph.getService(IndexedRelations.class);
632 // Deletes index files
633 ir.reset(null, graph, L0X.DependenciesRelation, model);
636 public static void resetIssueSources(WriteGraph graph, Resource model) throws DatabaseException {
637 Layer0 L0 = Layer0.getInstance(graph);
638 IssueResource ISSUE = IssueResource.getInstance(graph);
639 for(Resource source : graph.sync(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.ContinuousIssueSource))) {
640 IssueSourceUtils.update(graph, source);
644 public static void copyAnnotationTypes(WriteGraph graph, Resource sourceModel, Resource targetModel) throws DatabaseException {
646 Layer0 L0 = Layer0.getInstance(graph);
647 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
649 Instances query = graph.adapt(ANNO.AnnotationType, Instances.class);
651 Resource library = graph.getPossibleObject(targetModel, ANNO.HasAnnotationTypeRoot);
653 if(library == null) {
654 library = graph.newResource();
655 graph.claim(library, L0.InstanceOf, null, ANNO.AnnotationTypeLibrary);
656 graph.claimLiteral(library, L0.HasName, L0.NameOf, L0.String, "Annotation types", Bindings.STRING);
657 graph.claim(library, L0.PartOf, L0.ConsistsOf, targetModel);
658 graph.claim(targetModel, ANNO.HasAnnotationTypeRoot, library);
661 for(Resource type : query.find(graph, sourceModel)) {
662 String name = graph.getRelatedValue(type, L0.HasName);
663 Resource existing = Layer0Utils.getPossibleChild(graph, library, name);
664 if(existing != null) {
665 RemoverUtil.remove(graph, existing);
667 Layer0Utils.copyTo(graph, library, type);
672 public static void deleteIndex(WriteGraph graph, Resource model) throws DatabaseException {
673 Layer0X L0X = Layer0X.getInstance(graph);
674 IndexedRelations ir = graph.getService(IndexedRelations.class);
675 // Deletes index files
676 ir.reset(null, graph, L0X.DependenciesRelation, model);
679 public static void disableDependencies(WriteGraph graph, Resource dummy) {
680 Layer0Utils.setDependenciesIndexingDisabled(graph, true);
683 public static void releaseMemory(WriteGraph graph) {
685 QueryControl qc = graph.getService(QueryControl.class);
686 ClusterControl cc = graph.getService(ClusterControl.class);
692 public static List<Resource> filterByIndexRoot(ReadGraph graph, Resource indexRoot, List<Resource> resources) throws DatabaseException {
693 ArrayList<Resource> result = new ArrayList<Resource>(resources.size());
694 for (Resource r : resources) {
695 Resource root = graph.syncRequest(new PossibleIndexRoot(r));
696 if (indexRoot.equals(root))
702 public static List<Resource> searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
703 return filterByIndexRoot(graph, model, searchByType(graph, model, type));
706 public static List<Resource> searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
707 Instances query = graph.adapt(type, Instances.class);
708 return Layer0Utils.sortByCluster(graph, query.find(graph, model));
711 public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, GUID guid) throws DatabaseException {
712 return searchByGUID(graph, indexRoot, guid.indexString());
715 public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException {
716 return searchByQueryShallow(graph, indexRoot, "GUID:" + indexString);
719 public static List<Resource> searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException {
720 return filterByIndexRoot(graph, model, searchByQuery(graph, model, query));
723 public static List<Resource> searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException {
724 Instances instances = graph.adapt(Layer0.getInstance(graph).Entity, Instances.class);
725 Collection<Resource> queryResult = instances.find(graph, model, query);
726 return Layer0Utils.sortByCluster(graph, queryResult);
729 public static List<Resource> searchByTypeAndFilter(ReadGraph graph, Resource model, Resource type, Function1<Resource,Boolean> filter) throws DatabaseException {
730 Instances query = graph.adapt(type, Instances.class);
731 ArrayList<Resource> result = new ArrayList<Resource>();
732 for(Resource r : query.find(graph, model)) {
739 public static List<Triple<Resource, Resource, String>> getIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {
740 Layer0 L0 = Layer0.getInstance(graph);
741 List<Resource> entries = searchByQuery(graph, model, filter);
742 List<Triple<Resource, Resource, String>> listOfTriples = new ArrayList<Triple<Resource,Resource,String>>();
743 for (Resource entry : entries) {
744 Resource type = graph.getPossibleObject(entry, L0.InstanceOf);
745 String name = NameUtils.getSafeName(graph, entry);
746 listOfTriples.add(new Triple<Resource, Resource, String>(entry, type, name));
748 return listOfTriples;
751 public static String listIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {
752 List<Triple<Resource, Resource, String>> listOfTriples = getIndexEntries(graph, model, filter);
753 StringBuilder sb = new StringBuilder();
754 sb.append("== LISTING INDEX ENTRIES OF INDEX: " + NameUtils.getSafeName(graph, model) + ". AMOUNT OF ENTRIES: " + listOfTriples.size() + " ==\n");
755 for (Triple<Resource, Resource, String> entry : listOfTriples) {
756 String instanceOf = NameUtils.getSafeName(graph, entry.second);
757 sb.append("Name: " + entry.third + " instanceOf: " + instanceOf + " Resource: " + entry.first.toString() + "\n");
759 return sb.toString();
762 public static List<Resource> searchByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
763 Instances query = graph.adapt(type, Instances.class);
764 ArrayList<Resource> result = new ArrayList<Resource>();
765 for(Resource r : query.findByName(graph, model, name)) {
766 if(graph.isInstanceOf(r, type))
772 public static List<Resource> searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
773 return filterByIndexRoot(graph, model, searchByTypeAndName(graph, model, type, name));
778 * database write access
779 * @param sourceContainer
780 * the source container to look for annotationProperty from to be
781 * used as the copy source
782 * @param targetContainer
783 * the target container for the copied annotationProperty
785 * @param annotationProperty
786 * the annotation property relation
787 * @return created copy of the original annotation or <code>null</code> if
788 * there was nothing to copy
789 * @throws DatabaseException
791 public static Resource copyPossibleAnnotation(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty) throws DatabaseException {
792 return copyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, null);
795 public static List<String> getPossibleNamePath(ReadGraph graph, Resource resource) throws DatabaseException {
796 return getPossibleNamePath(graph, resource, null);
799 private static List<String> getPossibleNamePath(ReadGraph graph, Resource resource, List<String> result) throws DatabaseException {
801 Layer0 L0 = Layer0.getInstance(graph);
802 String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);
803 if(name == null) return null;
805 if(result == null) result = new ArrayList<String>();
807 SimulationResource SIMU = SimulationResource.getInstance(graph);
808 if(graph.isInstanceOf(resource, SIMU.Model)) return result;
810 Resource parent = graph.getPossibleObject(resource, L0.PartOf);
812 getPossibleNamePath(graph, parent, result);
823 public static Resource claimLibraryPath(WriteGraph graph, Resource resource, List<String> path) throws DatabaseException {
824 Layer0 L0 = Layer0.getInstance(graph);
825 for(int i=0;i<path.size()-1;i++) {
826 String p = path.get(i);
827 Resource child = Layer0Utils.getPossibleChild(graph, resource, p);
829 child = graph.newResource();
830 graph.claim(child, L0.InstanceOf, L0.Library);
831 graph.addLiteral(child, L0.HasName, L0.NameOf, L0.String, p, Bindings.STRING);
832 graph.claim(resource, L0.ConsistsOf, L0.PartOf, child);
841 * database write access
842 * @param sourceContainer
843 * the source container to look for annotationProperty from to be
844 * used as the copy source
845 * @param targetContainer
846 * the target container for the copied annotationProperty
848 * @param annotationProperty
849 * the annotation property relation
850 * @param annotationProperty
851 * the 2nd level annotation property relation or
852 * <code>null</code> if no 2nd level annotation exists
853 * @return created copy of the original annotation or <code>null</code> if
854 * there was nothing to copy
855 * @throws DatabaseException
857 public static Resource copyPossibleAnnotation2(WriteGraph graph,
858 Resource sourceContainer, Resource targetContainer,
859 Resource annotationProperty, Resource entryType) throws DatabaseException {
861 // Delete existing target value first
862 Layer0 L0 = Layer0.getInstance(graph);
863 Resource targetValue = graph.getPossibleObject(targetContainer, annotationProperty);
864 if (targetValue != null) {
865 if(!graph.hasStatement(targetValue, L0.PartOf))
866 RemoverUtil.remove(graph, targetValue);
867 graph.deny(targetContainer, annotationProperty);
870 Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);
871 if (sourceValue == null)
874 List<String> sourceValuePath = getPossibleNamePath(graph, sourceValue);
875 if(sourceValuePath != null) {
876 Resource targetModel = graph.sync(new PossibleModel(targetContainer));
877 if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);
878 Resource library = claimLibraryPath(graph, targetModel, sourceValuePath);
879 Resource existing = Layer0Utils.getPossibleChild(graph, library, sourceValuePath.get(sourceValuePath.size()-1));
880 if(existing == null) {
881 existing = doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);
882 graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);
884 graph.claim(targetContainer, annotationProperty, existing);
887 return doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);
892 private static Resource doCopyPossibleAnnotation2(WriteGraph graph,
893 Resource sourceContainer, Resource targetContainer,
894 Resource annotationProperty, Resource entryType) throws DatabaseException {
896 Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);
897 if (sourceValue == null)
900 // Copy 1st level annotation
901 Resource targetValue = createAnnotation(graph, targetContainer, annotationProperty, sourceValue);
903 // Copy possible 2nd level annotations and attach to 1st if entry
904 // property is defined.
905 Layer0 L0 = Layer0.getInstance(graph);
906 if (entryType != null) {
908 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
909 for (Resource entry : graph.getObjects(sourceValue, ANNO.Annotation_HasEntry)) {
911 String name = graph.getRelatedValue(entry, L0.HasName, Bindings.STRING);
913 List<String> entryPath = getPossibleNamePath(graph, entry);
914 if(entryPath != null) {
915 Resource targetModel = graph.sync(new PossibleModel(targetContainer));
916 if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);
917 Resource library = claimLibraryPath(graph, targetModel, entryPath);
918 Resource existing = Layer0Utils.getPossibleChild(graph, library, entryPath.get(entryPath.size()-1));
919 if(existing == null) {
920 existing = createTypedAnnotation(graph, null, null, entry, entryType, name);
921 graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);
923 graph.claim(targetValue, ANNO.Annotation_HasEntry, existing);
925 Resource result = createTypedAnnotation(graph, null, null, entry, entryType, name);
926 graph.claim(targetValue, ANNO.Annotation_HasEntry, result);
938 * database write access
940 * the container resource to attach the new annotation to
942 * the annotation property relation. The type of the created
943 * annotation is decided from this property relation's range
944 * @param sourceAnnotation
945 * the annotation to copy data from or <code>null</code> if
946 * nothing shall be copied
947 * @return the newly created annotation resource or <code>null</code> if the
948 * annotation property relation didn't have a single range type
949 * @throws DatabaseException
951 public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation) throws DatabaseException {
952 return createAnnotation(graph, container, property, sourceAnnotation, null);
957 * database write access
959 * the container resource to attach the new annotation to
961 * the annotation property relation. The type of the created
962 * annotation is decided from this property relation's range
963 * @param sourceAnnotation
964 * the annotation to copy data from or <code>null</code> if
965 * nothing shall be copied
967 * name for newly created annotation or <code>null</code> to copy
968 * name from source if available
969 * @return the newly created annotation resource or <code>null</code> if the
970 * annotation property relation didn't have a single range type
971 * @throws DatabaseException
973 public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, String name) throws DatabaseException {
975 Layer0 L0 = Layer0.getInstance(graph);
976 Resource annotationType = graph.getSingleObject(property, L0.HasRange);
977 if (annotationType == null)
980 return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, name);
986 * database write access
988 * the container resource to attach the new annotation to
990 * the annotation property relation
991 * @param sourceAnnotation
992 * the annotation to copy data from or <code>null</code> if
993 * nothing shall be copied
994 * @param annotationType
995 * the type of the new annotation
996 * @return the newly created annotation resource
997 * @throws DatabaseException
999 public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType) throws DatabaseException {
1000 return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, null);
1005 * database write access
1007 * the container resource to attach the new annotation to
1009 * the annotation property relation
1010 * @param sourceAnnotation
1011 * the annotation to copy data from or <code>null</code> if
1012 * nothing shall be copied
1013 * @param annotationType
1014 * the type of the new annotation
1016 * name for newly created annotation or <code>null</code> to copy
1017 * name from source if available
1018 * @return the newly created annotation resource
1019 * @throws DatabaseException
1021 public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType, String name) throws DatabaseException {
1023 Layer0 L0 = Layer0.getInstance(graph);
1025 Resource anno = graph.newResource();
1027 graph.claim(anno, L0.InstanceOf, null, annotationType);
1030 graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);
1032 if (sourceAnnotation != null) {
1035 String sourceName = graph.getPossibleRelatedValue(sourceAnnotation, L0.HasName, Bindings.STRING);
1036 if(sourceName != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, sourceName, Bindings.STRING);
1039 Resource sourceType = graph.getSingleType(sourceAnnotation);
1040 List<AnnotationMap> am = getAnnotationMap(graph, annotationType, sourceType);
1041 for (AnnotationMap a : am) {
1042 Resource object = graph.getSingleObject(sourceAnnotation, a.sourcePredicate);
1043 Collection<Resource> objectTypes = graph.getTypes(object);
1044 if (objectTypes.contains(L0.Literal)) {
1045 Object value = graph.getValue(object, a.defaultValueBinding);
1046 if (!ObjectUtils.objectEquals(value, a.defaultValue)) {
1047 graph.addLiteral(anno, a.annotationPredicate, a.annotationPredicateInverse, a.defaultValueType, value, a.defaultValueBinding);
1053 if (container != null && property != null) {
1054 graph.claim(container, property, anno);
1061 private static class AnnotationMap {
1063 final public Resource sourcePredicate;
1064 final public Resource sourcePredicateInverse;
1066 final public Resource annotationPredicate;
1067 final public Resource annotationPredicateInverse;
1069 final public Resource defaultValueType;
1070 final public Object defaultValue;
1071 final public Binding defaultValueBinding;
1073 public AnnotationMap(Resource sp, Resource spi, Resource tp, Resource tpi, Resource defaultValueType, Object defaultValue, Binding defaultValueBinding) {
1074 sourcePredicate = sp;
1075 sourcePredicateInverse = spi;
1076 annotationPredicate = tp;
1077 annotationPredicateInverse = tpi;
1078 this.defaultValueType = defaultValueType;
1079 this.defaultValue = defaultValue;
1080 this.defaultValueBinding = defaultValueBinding;
1085 public static List<AnnotationMap> getAnnotationMap(ReadGraph graph, Resource annotationType, Resource sourceType) throws DatabaseException {
1086 return graph.syncRequest(new AnnotationMapRequest(annotationType, sourceType), TransientCacheListener.<List<AnnotationMap>>instance());
1089 static class AnnotationMapRequest extends ResourceRead2<List<AnnotationMap>> {
1091 public AnnotationMapRequest(Resource annotationType, Resource sourceType) {
1092 super(annotationType, sourceType);
1096 public List<AnnotationMap> perform(ReadGraph graph) throws DatabaseException {
1098 Layer0 L0 = Layer0.getInstance(graph);
1100 ArrayList<AnnotationMap> result = new ArrayList<AnnotationMap>();
1102 Map<String, Resource> annotationPredicates = new HashMap<String, Resource>();
1103 for(Resource predicate : graph.getObjects(resource, L0.DomainOf)) {
1104 String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);
1105 annotationPredicates.put(name, predicate);
1107 Map<String, Resource> sourcePredicates = new HashMap<String, Resource>();
1108 for(Resource predicate : graph.getObjects(resource2, L0.DomainOf)) {
1109 String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);
1110 sourcePredicates.put(name, predicate);
1113 for(String key : sourcePredicates.keySet()) {
1114 Resource sourcePredicate = sourcePredicates.get(key);
1115 Resource anno = annotationPredicates.get(key);
1116 if(sourcePredicate != null && anno != null) {
1117 Resource defaultValueType = graph.getSingleObject(anno, L0.HasRange);
1118 Binding defaultValueBinding = null;
1119 Object defaultValue = null;
1120 Resource assertion = graph.getPossibleObject(anno, L0.HasPredicateInverse);
1121 if (assertion != null) {
1122 Resource object = graph.getPossibleObject(assertion, L0.HasObject);
1123 if (object != null) {
1124 if(graph.isInstanceOf(object, L0.Literal)) {
1125 Datatype dt = graph.getDataType(object);
1126 defaultValueBinding = Bindings.getBeanBinding(dt);
1127 defaultValue = graph.getPossibleValue(object);
1131 result.add(new AnnotationMap(
1132 sourcePredicate, graph.getInverse(sourcePredicate),
1133 anno, graph.getInverse(anno),
1134 defaultValueType, defaultValue, defaultValueBinding));
1144 public static final String DRAWING_TEMPLATE_FORMAT = "drawingTemplate";
1145 public static final String DRAWING_TEMPLATE_FORMAT_V1 = DRAWING_TEMPLATE_FORMAT + ":1";
1146 public static final String DRAWING_TEMPLATE_FORMAT_V2 = DRAWING_TEMPLATE_FORMAT + ":2";
1148 public static Resource importDrawingTemplate(final Resource model, final File file) throws IOException, SerializationException, DatabaseException, TransferableGraphException {
1152 final Resource library = Simantics.sync(new WriteResultRequest<Resource>() {
1155 public Resource perform(WriteGraph graph) throws DatabaseException {
1157 Layer0 L0 = Layer0.getInstance(graph);
1158 Template2dResource TEMPLATE = Template2dResource.getInstance(graph);
1159 Resource root = graph.getPossibleObject(model, TEMPLATE.HasDrawingTemplateRoot);
1161 Template2dResource TEMPLATE2D = Template2dResource.getInstance(graph);
1162 root = graph.newResource();
1163 graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibrary);
1164 graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibraryUI);
1165 graph.claimLiteral(root, L0.HasName, L0.NameOf, L0.String, "Diagram Templates", Bindings.STRING);
1166 graph.claim(root, L0.PartOf, L0.ConsistsOf, model);
1167 graph.claim(model, TEMPLATE2D.HasDrawingTemplateRoot, root);
1170 String name = new Path(file.getAbsolutePath()).removeFileExtension().lastSegment();
1172 Resource existing = Layer0Utils.getPossibleChild(graph, root, name);
1173 if(existing != null)
1174 graph.deny(root, L0.ConsistsOf, existing);
1183 final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(library);
1186 HashMap<String, FormatHandler<Object>> handlers = new HashMap<String, FormatHandler<Object>>();
1187 FormatHandler<Object> handler = new FormatHandler<Object>() {
1189 public Binding getBinding() {
1190 return TransferableGraph1.BINDING;
1194 public Object process(DataContainer container) throws Exception {
1195 TransferableGraphs.importGraph1(Simantics.getSession(), (TransferableGraph1)container.content.getValue(),
1200 handlers.put(DRAWING_TEMPLATE_FORMAT_V1, handler);
1201 handlers.put(DRAWING_TEMPLATE_FORMAT_V2, handler);
1203 DataContainers.readFile(file, handlers);
1204 } catch(DataFormatException e) {
1205 throw new IOException(e);
1206 } catch(IOException e) {
1208 } catch(Exception e) {
1209 if(e instanceof RuntimeException)
1210 throw (RuntimeException)e;
1212 throw new RuntimeException(e);
1215 } catch(IOException e) {
1218 return advisor.getRoot();
1220 } catch (Throwable t) {
1221 Logger.defaultLogError("Unexpected exception while importing diagram template.", t);
1229 public static Collection<Variable> getMappedVariables(ReadGraph graph, Variable source) throws DatabaseException {
1231 ArrayList<Variable> result = new ArrayList<Variable>();
1232 Resource represents = source.getPossibleRepresents(graph);
1233 if(represents == null) return Collections.emptyList();
1234 ModelingResources MOD = ModelingResources.getInstance(graph);
1235 for(Resource r : getElementCorrespondendences(graph, represents)) {
1236 result.add(Variables.getVariable(graph, r));
1238 for(Resource r : graph.getObjects(represents, MOD.ComponentToElement)) {
1239 result.add(Variables.getVariable(graph, r));
1241 for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite)) {
1242 result.add(Variables.getVariable(graph, r));
1244 for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram)) {
1245 result.add(Variables.getVariable(graph, r));
1251 public static Resource getPossibleModel(ReadGraph graph, Resource resource) throws DatabaseException {
1253 PossibleModel pm = new PossibleModel(resource);
1254 Resource model = pm.perform(graph);
1258 public static Resource possibleIndexRoot(ReadGraph graph, Resource resource) throws DatabaseException {
1259 return graph.syncRequest(new PossibleIndexRoot(resource));
1262 public static Object getMonitorValue(StructuralComponent _variable, ReadGraph graph, String path) throws DatabaseException {
1263 Variable variable = ((VariableStructuralContext)_variable).variable;
1264 Variable var = variable.browse(graph, path);
1265 return var.getValue(graph);
1268 public static void createSharedOntologyWithUI(ReadGraph graph, Variable variable, Resource baseType) throws DatabaseException {
1269 createSharedOntologyWithUI(graph, baseType);
1272 public static void createSharedOntologyWithUI(ReadGraph graph, Resource baseType) throws DatabaseException {
1274 // Resource indexRoot_ = variable.getPossibleRepresents(graph);
1275 // if(indexRoot_ == null) return;
1277 final Map<Resource, Pair<String,ImageDescriptor>> map = new HashMap<Resource, Pair<String,ImageDescriptor>>();
1279 Layer0 L0 = Layer0.getInstance(graph);
1280 SimulationResource SIMU = SimulationResource.getInstance(graph);
1281 Instances query = graph.adapt(L0.IndexRootType, Instances.class);
1282 for(Resource ontology : Layer0Utils.listOntologies(graph)) {
1283 for(Resource type : query.find(graph, ontology)) {
1284 if(graph.isInheritedFrom(type, SIMU.Model)) continue;
1285 if(graph.hasStatement(type, L0.Abstract)) continue;
1286 if(!graph.isInheritedFrom(type, baseType)) continue;
1287 String name = graph.getPossibleRelatedValue(type, L0.HasLabel, Bindings.STRING);
1288 if(name == null) name = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
1289 map.put(type, new Pair<String,ImageDescriptor>(name, null));
1293 Display.getDefault().asyncExec(new Runnable() {
1296 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
1297 CreateSharedOntologyDialog page = new CreateSharedOntologyDialog(shell, map, "Select type and name of new shared library");
1298 if (page.open() == Window.OK) {
1299 Object[] result = page.getResult();
1300 if (result != null && result.length == 1) {
1301 final Resource res = (Resource)result[0];
1302 final String name = "http://" + page.getName();
1303 Simantics.getSession().asyncRequest(new WriteRequest() {
1306 public void perform(WriteGraph graph) throws DatabaseException {
1307 graph.markUndoPoint();
1308 Resource target = Simantics.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, name+"@A", res);
1310 ProjectResource PROJ = ProjectResource.getInstance(graph);
1311 Layer0 L0 = Layer0.getInstance(graph);
1312 for(Resource dep : graph.getObjects(Simantics.getProjectResource(), L0.IsLinkedTo)) {
1313 if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {
1314 for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {
1315 String uri = graph.getPossibleValue(req, Bindings.STRING);
1317 Resource ns = graph.getResource(uri);
1319 graph.claim(target, L0.IsLinkedTo, null, ns);
1336 public static void unlinkSharedOntologyWithUI(ReadGraph graph, Variable variable, final List<Resource> libraries) throws DatabaseException {
1338 final Resource indexRoot = variable.getPossibleRepresents(graph);
1339 if(indexRoot == null) return;
1341 StructuralResource2 STR = StructuralResource2.getInstance(graph);
1343 final List<String> instances = new ArrayList<String>();
1345 DiagramResource DIA = DiagramResource.getInstance(graph);
1347 for(Resource library : libraries) {
1348 for(Resource type : ModelingUtils.searchByTypeShallow(graph, library, STR.ComponentType)) {
1349 for(Resource instance : ModelingUtils.searchByTypeShallow(graph, indexRoot, type)) {
1351 if(graph.isInstanceOf(instance, DIA.Element)) continue;
1352 String name = Versions.getStandardPathNameString(graph, instance);
1353 instances.add(name);
1358 if(instances.isEmpty()) {
1359 graph.getSession().asyncRequest(new WriteRequest() {
1362 public void perform(WriteGraph graph) throws DatabaseException {
1363 Layer0 L0 = Layer0.getInstance(graph);
1364 for(Resource library : libraries)
1365 graph.deny(indexRoot, L0.IsLinkedTo, library);
1372 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
1376 if (!PlatformUI.isWorkbenchRunning())
1379 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
1380 ListDialog<String> dialog = new ListDialog<String>(
1383 "Cannot unlink selected libraries",
1384 "Libraries cannot be unlinked since the following instances are referring to them.") {
1386 protected void createButtonsForButtonBar(Composite parent) {
1387 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
1391 int result = dialog.open();
1392 if (result != Dialog.OK)
1400 public static void importSharedOntology(String fileName) throws Exception {
1402 DataContainer dc = DataContainers.readFile(new File(fileName));
1403 TransferableGraph1 tg = (TransferableGraph1)dc.content.getValue(TransferableGraph1.BINDING);
1404 Variant draftStatus = dc.metadata.get(DraftStatusBean.EXTENSION_KEY);
1405 MigrationUtils.importSharedOntology(Simantics.getSession(), tg, draftStatus == null);
1406 } catch (Exception e) {
1407 Logger.defaultLogError(e);
1412 public static void importSharedOntologyWithUI(ReadGraph graph, final Variable variable) throws DatabaseException {
1414 Display.getDefault().asyncExec(new Runnable() {
1418 IStructuredSelection sel = new StructuredSelection(variable);
1419 openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyImportWizard");
1426 public static class LibraryInfo implements Comparable<LibraryInfo> {
1427 public NamedResource library;
1428 public DraftStatusBean draft;
1429 public LibraryInfo(String name, Resource r, DraftStatusBean draft) {
1430 library = new NamedResource(name, r);
1434 public int compareTo(LibraryInfo o) {
1435 return library.compareTo(o.library);
1438 public int hashCode() {
1439 return library.hashCode();
1442 public boolean equals(Object object) {
1445 else if (object == null)
1447 else if (!(object instanceof LibraryInfo))
1449 LibraryInfo info = (LibraryInfo)object;
1450 return info.library.equals(library);
1455 public static void exportSharedOntologyWithUI(final Resource sharedOntology) {
1457 Display.getDefault().asyncExec(new Runnable() {
1461 HintContext hc = new HintContext();
1462 hc.setHint(SelectionHints.KEY_MAIN, sharedOntology);
1463 IStructuredSelection sel = new StructuredSelection(hc);
1464 openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyExportWizard");
1471 public static void exportSharedOntology(IProgressMonitor monitor, RequestProcessor processor, File location, String format, int version, final LibraryInfo info) throws DatabaseException, IOException {
1473 if(monitor == null) monitor = new NullProgressMonitor();
1475 // TODO: figure out a way to make the TG go directly into a file
1476 // instead of having it all in memory at once.
1478 monitor.beginTask("Exporting shared library...", 100);
1479 SimanticsClipboard clipboard = processor.syncRequest(new Read<SimanticsClipboard>() {
1481 public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException {
1482 CopyHandler ch = graph.adapt(info.library.getResource(), CopyHandler.class);
1483 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
1484 ch.copyToClipboard(graph, clipboard);
1489 TreeMap<String,Variant> metadata = getExportMetadata();
1490 DraftStatusBean draft = info.draft;
1492 metadata.put(DraftStatusBean.EXTENSION_KEY, new Variant(DraftStatusBean.BINDING ,draft));
1495 for (Set<Representation> object : clipboard.getContents()) {
1497 TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
1500 Variant edb = tg.extensions.get(ExternalDownloadBean.EXTENSION_KEY);
1502 metadata.put(ExternalDownloadBean.EXTENSION_KEY, edb);
1505 monitor.setTaskName("Writing transferable graph...");
1506 DataContainers.writeFile(location, new DataContainer(
1508 metadata, new Variant(TransferableGraph1.BINDING, tg)));
1514 public static TreeMap<String, Variant> getExportMetadata() {
1516 TreeMap<String,Variant> metadata = new TreeMap<String,Variant>();
1517 metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())));
1518 metadata.put("author", Variant.ofInstance(System.getProperty("user.name", "")));
1524 public static void createNewVersionWithoutUI(WriteGraph graph, Resource resource) throws DatabaseException {
1525 VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));
1526 int currentVersion = Integer.parseInt(info.version);
1527 String result = Integer.toString(currentVersion + 1);
1528 createNewVersion(graph, resource, info, result);
1531 public static void createNewVersionWithUI(ReadGraph graph, final Resource resource) throws DatabaseException {
1533 final VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));
1535 Display.getDefault().asyncExec(new Runnable() {
1538 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
1539 CreateVersionDialog dialog = new CreateVersionDialog(shell, info);
1540 if (dialog.open() == Window.OK) {
1541 final String result = dialog.getResult();
1542 Simantics.getSession().asyncRequest(new WriteRequest() {
1544 public void perform(WriteGraph graph) throws DatabaseException {
1545 createNewVersion(graph, resource, info, result);
1554 public static void createNewVersion(WriteGraph graph, Resource resource, final VersionInfo info, final String result) throws DatabaseException {
1555 graph.markUndoPoint();
1556 Layer0 L0 = Layer0.getInstance(graph);
1557 Resource parent = graph.getPossibleObject(resource, L0.PartOf);
1558 if(parent == null) return;
1559 final String parentURI = graph.getPossibleURI(parent);
1560 if(parentURI == null) return;
1561 Layer0Utils.copyTo(graph, parent, resource, new PasteEventHandler() {
1564 public void postProcess(WriteGraph graph, Resource root) throws DatabaseException {
1565 Layer0 L0 = Layer0.getInstance(graph);
1566 graph.deny(root, L0.Entity_published);
1570 public IImportAdvisor2 createAdvisor(ReadGraph graph, ImportAdvisorFactory factory, Resource target) throws DatabaseException {
1571 Map<String,Object> context = new HashMap<String,Object>();
1572 String base = parentURI + "/" + URIStringUtils.escape( info.baseName ) + "@";
1573 Map<String,String> renameMap = new HashMap<String,String>();
1574 renameMap.put(base + info.version, base + result);
1575 renameMap.put(info.baseName + "@" + info.version, info.baseName + "@" + result);
1576 context.put(ImportAdvisors.RENAME_MAP, renameMap);
1577 return factory.create(graph, target, context);
1581 Layer0Utils.addCommentMetadata(graph, "Created new version of " + info.baseName);
1584 public static boolean isUserComponent(ReadGraph graph, Resource type) throws DatabaseException {
1585 StructuralResource2 STR = StructuralResource2.getInstance(graph);
1586 if(graph.isInstanceOf(type, STR.ProceduralComponentType)) return true;
1587 else if (graph.hasStatement(type, STR.IsDefinedBy)) return true;
1591 public static void publishComponentTypeWithUI(WriteGraph graph, final Resource componentType) throws DatabaseException {
1593 Layer0 L0 = Layer0.getInstance(graph);
1594 StructuralResource2 STR = StructuralResource2.getInstance(graph);
1595 Resource composite = graph.getPossibleObject(componentType, STR.IsDefinedBy);
1596 final List<String> instances = new ArrayList<String>();
1597 if(composite != null) {
1598 for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {
1599 Resource type = graph.getPossibleType(component, STR.Component);
1600 if(type != null && isUserComponent(graph, type)) {
1601 if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, component));
1606 if(instances.isEmpty()) {
1607 graph.getSession().asyncRequest(new WriteRequest() {
1610 public void perform(WriteGraph graph) throws DatabaseException {
1611 graph.markUndoPoint();
1612 publish(graph, componentType);
1619 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
1623 if (!PlatformUI.isWorkbenchRunning())
1626 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
1627 ListDialog<String> dialog = new ListDialog<String>(
1630 "Cannot publish user component",
1631 "The following instances are referring to unpublished user components.") {
1633 protected void createButtonsForButtonBar(Composite parent) {
1634 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
1638 int result = dialog.open();
1639 if (result != Dialog.OK)
1647 public static void publishSharedOntologyWithUI(WriteGraph graph, final Resource sharedOntology) throws DatabaseException {
1649 Layer0 L0 = Layer0.getInstance(graph);
1650 DiagramResource DIA = DiagramResource.getInstance(graph);
1651 StructuralResource2 STR = StructuralResource2.getInstance(graph);
1652 final List<String> instances = new ArrayList<String>();
1653 for(Resource type : searchByTypeShallow(graph, sharedOntology, STR.ComponentType)) {
1655 if(graph.isInheritedFrom(type, DIA.Element)) continue;
1656 if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, type));
1658 for(Resource dep : graph.syncRequest(new ObjectsWithType(sharedOntology, L0.IsLinkedTo, L0.SharedOntology))) {
1659 if(!Layer0Utils.isPublished(graph, dep)) instances.add(Versions.getStandardPathNameString(graph, dep));
1662 if(instances.isEmpty()) {
1663 graph.getSession().asyncRequest(new WriteRequest() {
1666 public void perform(WriteGraph graph) throws DatabaseException {
1667 graph.markUndoPoint();
1668 publish(graph, sharedOntology);
1675 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
1679 if (!PlatformUI.isWorkbenchRunning())
1682 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
1683 ListDialog<String> dialog = new ListDialog<String>(
1686 "Cannot publish shared library",
1687 "The following dependencies are unpublished.") {
1689 protected void createButtonsForButtonBar(Composite parent) {
1690 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
1694 int result = dialog.open();
1695 if (result != Dialog.OK)
1704 public static void createSCLModuleDefault(WriteGraph graph, Resource target) throws DatabaseException {
1705 String name = NameUtils.findFreshEscapedName(graph, "SCLModule", target);
1706 createSCLModule(graph, target, name);
1709 public static void createSCLModule(WriteGraph graph, Resource target, String name) throws DatabaseException {
1710 graph.markUndoPoint();
1711 Layer0 L0 = Layer0.getInstance(graph);
1712 Resource sclModule = GraphUtils.create2(graph, L0.SCLModule,
1715 L0.SCLModule_definition, "");
1716 Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString());
1719 public static void createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException {
1720 String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target);
1721 createPGraph(graph, target, name);
1724 public static void createPGraph(WriteGraph graph, Resource target, String name) throws DatabaseException {
1725 graph.markUndoPoint();
1726 Layer0 L0 = Layer0.getInstance(graph);
1727 Resource file = GraphUtils.create2(graph, L0.PGraph,
1730 L0.PGraph_definition, "");
1731 Layer0Utils.addCommentMetadata(graph, "Created Ontology Definition File " + name + " " + file.toString());
1734 public static void publish(WriteGraph graph, Resource target) throws DatabaseException {
1735 Layer0 L0 = Layer0.getInstance(graph);
1736 graph.claimLiteral(target, L0.Entity_published, true, Bindings.BOOLEAN);
1737 Layer0Utils.addCommentMetadata(graph, "Published " + graph.getPossibleRelatedValue2(target, L0.HasName, Bindings.STRING) + " " + target.toString());
1740 public static boolean isLinkedToDeep(ReadGraph graph, Resource r1, Resource r2) throws DatabaseException {
1741 return graph.syncRequest(new IsLinkedTo(r1, r2));
1744 public static void openWizard(Display display, IStructuredSelection selection, String id) {
1745 // First see if this is a "new wizard".
1746 IWizardDescriptor descriptor = PlatformUI.getWorkbench()
1747 .getNewWizardRegistry().findWizard(id);
1748 // If not check if it is an "import wizard".
1749 if (descriptor == null) {
1750 descriptor = PlatformUI.getWorkbench().getImportWizardRegistry()
1753 // Or maybe an export wizard
1754 if (descriptor == null) {
1755 descriptor = PlatformUI.getWorkbench().getExportWizardRegistry()
1759 // Then if we have a wizard, open it.
1760 if (descriptor != null) {
1761 IWorkbenchWizard wizard = descriptor.createWizard();
1762 wizard.init(PlatformUI.getWorkbench(), selection);
1763 WizardDialog wd = new WizardDialog(display.getActiveShell(), wizard);
1764 wd.setTitle(wizard.getWindowTitle());
1767 } catch (CoreException e) {
1768 e.printStackTrace();
1772 public static String withinEpsilon(double value, double reference, double epsilon) {
1773 if(Math.abs(value-reference) < epsilon) return "True";
1774 else return "Not within epsilon value=" + value + ", reference=" + reference + " , epsilon=" + epsilon;
1777 public static boolean needsIdentifier(ReadGraph graph, Resource r) throws DatabaseException {
1778 Layer0 L0 = Layer0.getInstance(graph);
1779 Collection<Resource> types = graph.getPrincipalTypes(r);
1780 for(Resource type : types)
1781 if(graph.syncRequest(new IsInstanceOf(type, L0.TypeWithIdentifier), TransientCacheAsyncListener.<Boolean>instance()))
1786 public static boolean needsModificationInfo(ReadGraph graph, Resource r) throws DatabaseException {
1787 ModelingResources MOD = ModelingResources.getInstance(graph);
1788 Collection<Resource> types = graph.getPrincipalTypes(r);
1789 for(Resource type : types)
1790 if(graph.syncRequest(new IsInstanceOf(type, MOD.TypeWithChangeInformation), TransientCacheAsyncListener.<Boolean>instance()))
1795 public static void attachCreationInformation(IProgressMonitor monitor, WriteGraph graph, Resource model) throws DatabaseException {
1797 if(monitor == null) monitor = new NullProgressMonitor();
1799 final String author = System.getProperty("user.name", "");
1800 final long time = System.currentTimeMillis();
1802 monitor.setTaskName("Attach creation information");
1804 ModelingResources MOD = ModelingResources.getInstance(graph);
1805 Collection<Resource> rs = ModelingUtils.searchByType(graph, model, MOD.TypeWithChangeInformation);
1806 Collection<Resource> supers = ModelingUtils.getMostUnspecificTypes(graph, rs);
1808 CollectionSupport cs = graph.getService(CollectionSupport.class);
1809 Collection<Resource> set = cs.createSet();
1810 for(Resource type : supers) {
1811 set.addAll(ModelingUtils.searchByTypeShallow(graph, model, type));
1813 Collection<Resource> instances = Layer0Utils.sortByCluster(graph, set);
1815 int pc = instances.size() / 100;
1819 for(Resource instance : instances) {
1820 ChangeInformation info = graph.getPossibleRelatedValue(instance, MOD.changeInformation, ChangeInformation.BINDING);
1822 info = new ChangeInformation();
1823 info.createdAt = time;
1824 info.createdBy = author;
1825 info.modifiedAt = time;
1826 info.modifiedBy = author;
1827 graph.claimLiteral(instance, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING);
1832 Double d = (100.0*done)/instances.size();
1833 monitor.setTaskName("Attach creation information " + d.intValue() + "%");
1838 monitor.setTaskName("Attach creation information - commit");
1842 public static class DiagramComponentInfo {
1844 private static String CHILD_PREFIX = "child:";
1846 final private String compositePathAndName;
1847 final private String componentName;
1848 final private GUID guid;
1850 public DiagramComponentInfo(String compositePathAndName, String componentName, GUID guid) {
1851 this.compositePathAndName = compositePathAndName;
1852 this.componentName = componentName;
1856 public static boolean isDiagramComponent(String tgName) {
1857 return tgName.startsWith(CHILD_PREFIX);
1860 public String getTGName(CompositeInfo info) {
1861 return CHILD_PREFIX + info.getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + info.getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedComponentName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();
1864 public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {
1865 Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);
1866 return !res.isEmpty();
1869 public static DiagramComponentInfo fromResource(ReadGraph graph, CompositeInfo info, Resource resource) throws DatabaseException {
1870 Layer0 L0 = Layer0.getInstance(graph);
1871 GUID childId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);
1872 String childName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);
1873 return new DiagramComponentInfo(info.getStateKey(), URIStringUtils.escape(childName), childId);
1876 public GUID getGUID() {
1880 public String getEscapedCompositePathAndName() {
1881 return compositePathAndName;
1884 public String getEscapedComponentName() {
1885 return componentName;
1888 public String getUnescapedComponentName() {
1889 return URIStringUtils.unescape(getEscapedComponentName());
1892 // "child:path#compositeName#componentName#guid"
1893 public static DiagramComponentInfo parse(String tgName) {
1895 String name = tgName.substring(CHILD_PREFIX.length());
1896 String compositePathAndName = "";
1897 String moduleName = name;
1898 GUID guid = GUID.invalid();
1899 int lastHash = name.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);
1901 String first = name.substring(0, lastHash);
1902 String second = name.substring(lastHash+1);
1903 lastHash = first.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);
1905 compositePathAndName = first.substring(0, lastHash);
1906 moduleName = first.substring(lastHash+1);
1907 guid = GUID.parseIndexString(second);
1909 compositePathAndName = first;
1910 moduleName = second;
1913 return new DiagramComponentInfo(compositePathAndName, moduleName, guid);
1919 public int hashCode() {
1920 final int prime = 31;
1922 result = prime * result + ((compositePathAndName == null) ? 0 : compositePathAndName.hashCode());
1923 result = prime * result + ((componentName == null) ? 0 : componentName.hashCode());
1928 public boolean equals(Object obj) {
1933 if (getClass() != obj.getClass())
1935 DiagramComponentInfo other = (DiagramComponentInfo) obj;
1936 if (compositePathAndName == null) {
1937 if (other.compositePathAndName != null)
1939 } else if (!compositePathAndName.equals(other.compositePathAndName))
1941 if (componentName == null) {
1942 if (other.componentName != null)
1944 } else if (!componentName.equals(other.componentName))
1951 public static class CompositeInfo {
1953 public static String COMPOSITE_PREFIX = "composite:";
1955 final private boolean useGuids;
1956 final private boolean applyPaths;
1957 final private String path;
1958 final private String name;
1959 final private GUID guid;
1961 private CompositeInfo(boolean useGuids, boolean applyPaths, String path, String name, GUID guid) {
1962 this.useGuids = useGuids;
1963 this.applyPaths = applyPaths;
1970 public String toString() {
1971 return "CompositeInfo[useGuids=" + useGuids + ", applyPaths=" + applyPaths + ", path=" + path + ", name=" + name + ", guid=" + guid.indexString() + "]";
1974 public static boolean isComposite(String tgName) {
1975 return tgName.startsWith(COMPOSITE_PREFIX);
1978 public String getTGName() {
1979 return COMPOSITE_PREFIX + getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();
1982 public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {
1983 Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);
1984 return !res.isEmpty();
1987 public static CompositeInfo fromResource(ReadGraph graph, Resource resource) throws DatabaseException {
1989 Layer0 L0 = Layer0.getInstance(graph);
1990 GUID rootId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);
1991 String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);
1992 String escapedRootName = URIStringUtils.escape(rootName);
1993 String escapedPath = ModelingUtils.getDiagramCompositePath(graph, resource);
1994 return new CompositeInfo(true, true, escapedPath, escapedRootName, rootId);
1998 public static CompositeInfo parse(String tgName) {
1999 return parse(tgName, true, true);
2003 * Index 0 is root-relative folder path separated with '/' or null if target-relative positioning is used
2004 * Index 1 is diagram name
2006 public static CompositeInfo parse(String tgName, boolean applyPaths, boolean useGuids) {
2007 if(!tgName.startsWith(COMPOSITE_PREFIX)) return null;
2008 tgName = tgName.substring(COMPOSITE_PREFIX.length());
2009 if(!tgName.contains(COMPOSITE_SEPARATOR)) {
2010 if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");
2011 return new CompositeInfo(useGuids, applyPaths, null, tgName, null);
2013 String[] parts = tgName.split(COMPOSITE_SEPARATOR);
2014 if(parts.length == 2) {
2015 String name = parts[1];
2016 String path = applyPaths ? parts[0] : null;
2017 if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");
2018 return new CompositeInfo(useGuids, applyPaths, path, name, null);
2019 } else if(parts.length == 3) {
2020 String path = parts[0];
2021 String name = parts[1];
2022 GUID guid = GUID.parseIndexString(parts[2]);
2023 return new CompositeInfo(useGuids, applyPaths, path, name, guid);
2029 public GUID getGUID() {
2033 public String getEscapedName() {
2037 public String getUnescapedName() {
2038 return URIStringUtils.unescape(name);
2041 public String getOriginalPath() {
2045 public String getFinalPath() {
2046 if(applyPaths) return path;
2050 public CompositeInfo renamed(String newName) {
2051 return new CompositeInfo(useGuids, applyPaths, path, newName, guid);
2054 public String getStateKey() {
2055 return path + "#" + getEscapedName();
2058 private Resource getFromFolder(ReadGraph graph, Resource target) throws DatabaseException {
2059 Resource diagram = Layer0Utils.getPossibleChild(graph, target, URIStringUtils.unescape(name));
2060 if(diagram == null) return null;
2061 StructuralResource2 STR = StructuralResource2.getInstance(graph);
2062 return graph.isInstanceOf(diagram, STR.Composite) ? diagram : null;
2065 public Resource resolve(ReadGraph graph, Resource target) throws DatabaseException {
2067 if(useGuids && guid != null) {
2068 Resource indexRoot = graph.syncRequest(new IndexRoot(target));
2069 Collection<Resource> queryResult = searchByGUID(graph, indexRoot, guid);
2070 if(queryResult.size() == 1) {
2071 Resource composite = queryResult.iterator().next();
2072 StructuralResource2 STR = StructuralResource2.getInstance(graph);
2073 if(!graph.isInstanceOf(composite, STR.Composite)) return null;
2079 Resource folder = resolveFolder(graph, target);
2080 if(folder == null) return null;
2081 return getFromFolder(graph, folder);
2083 return getFromFolder(graph, target);
2088 public Resource resolveFolder(ReadGraph graph, Resource target) throws DatabaseException {
2090 String path = getFinalPath();
2091 if(path == null) return target;
2093 Resource folder = graph.syncRequest(new Configuration(target));
2094 String[] segments = path.split("/");
2095 for(int i=0;i<segments.length;i++) {
2096 if(segments[i].isEmpty()) continue;
2097 folder = Layer0Utils.getPossibleChild(graph, folder, URIStringUtils.unescape(segments[i]));
2098 if(folder == null) return null;
2107 public int hashCode() {
2109 if(useGuids) return guid.hashCode();
2111 final int prime = 31;
2112 int result = name.hashCode();
2113 result = prime * result + ((path == null) ? 0 : path.hashCode());
2119 public boolean equals(Object obj) {
2125 if (getClass() != obj.getClass())
2128 CompositeInfo other = (CompositeInfo) obj;
2130 if(useGuids) return guid.equals(other.guid);
2132 if (!name.equals(other.name))
2136 if (!path.equals(other.path))
2145 public static char COMPOSITE_SEPARATOR_CHAR = '#';
2146 public static String COMPOSITE_SEPARATOR = String.valueOf(COMPOSITE_SEPARATOR_CHAR);
2148 public static CompositeInfo parseCompositeNameFromRoot(Root root, boolean applyPaths, boolean useGuids) {
2149 return CompositeInfo.parse(root.name, applyPaths, useGuids);
2152 public static CompositeInfo parseCompositeNameFromRoot(Identity root, boolean applyPaths, boolean useGuids) {
2153 String coded = TransferableGraphUtils.getName(root);
2154 return CompositeInfo.parse(coded, applyPaths, useGuids);
2157 private static StringBuilder getDiagramCompositePathInternal(ReadGraph graph, Resource folder, StringBuilder builder) throws DatabaseException {
2158 SimulationResource SIMU = SimulationResource.getInstance(graph);
2159 Resource model = graph.getPossibleObject(folder, SIMU.IsConfigurationOf);
2160 if (model != null) return builder;
2162 Layer0 L0 = Layer0.getInstance(graph);
2163 String name = graph.getPossibleRelatedValue(folder, L0.HasName, Bindings.STRING);
2164 if (name == null) return null;
2165 Resource parent = graph.getPossibleObject(folder, L0.PartOf);
2166 if (parent == null) return null;
2168 StringBuilder sb = getDiagramCompositePathInternal(graph, parent, builder);
2169 if (sb == null) return null;
2170 if (sb.length() > 0)
2171 sb.append(URIStringUtils.NAMESPACE_PATH_SEPARATOR);
2172 sb.append( URIStringUtils.escape(name) );
2179 * @return diagram/folder path up until model configuration root with each
2180 * segment escaped using {@link URIStringUtils#escape(String)} and
2181 * {@value URIStringUtils#NAMESPACE_PATH_SEPARATOR} between each
2182 * segment or <code>null</code> if the specified diagram composite
2183 * is not part of any model configuration structure.
2184 * @throws DatabaseException
2186 public static String getDiagramCompositePath(ReadGraph graph, Resource diagram) throws DatabaseException {
2187 Layer0 L0 = Layer0.getInstance(graph);
2188 Resource parent = graph.getPossibleObject(diagram, L0.PartOf);
2189 if(parent == null) return null;
2190 StringBuilder sb = getDiagramCompositePathInternal(graph, parent, new StringBuilder());
2191 return sb != null ? sb.toString() : null;
2194 public static void exportModel(ReadGraph graph, Resource model, String fileName, String format, int version) throws DatabaseException {
2197 TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model, true, false);
2198 TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));
2199 TransferableGraphs.writeTransferableGraph(graph, format, version, s, new File(fileName));
2200 } catch (Exception e) {
2201 throw new DatabaseException(e);
2206 public static void exportSharedOntology(ReadGraph graph, Resource library, String fileName, String format, int version) throws DatabaseException {
2208 Layer0 L0 = Layer0.getInstance(graph);
2209 String name = graph.getRelatedValue(library, L0.HasName, Bindings.STRING);
2211 DraftStatusBean draft = null;
2212 boolean published = Layer0Utils.isPublished(graph, library);
2213 if(!published) draft = new DraftStatusBean(new String[0]);
2215 LibraryInfo info = new LibraryInfo(name, library, draft);
2218 exportSharedOntology(new NullProgressMonitor(), graph, new File(fileName), format, version, info);
2219 } catch (IOException e) {
2220 throw new DatabaseException(e);
2225 public static DraftStatusBean getDependencyDraftStatus(ReadGraph graph, Resource library) throws DatabaseException {
2226 Layer0 L0 = Layer0.getInstance(graph);
2227 List<String> drafts = new ArrayList<>();
2228 for (Resource shared : graph.syncRequest(new ObjectsWithType(library, L0.IsLinkedTo, L0.SharedOntology))) {
2229 boolean published = Layer0Utils.isPublished(graph, shared);
2231 drafts.add(graph.getURI(shared));
2233 return drafts.isEmpty() ? null : new DraftStatusBean(drafts);
2236 public static Set<Resource> getMostUnspecificTypes(final ReadGraph graph, Collection<Resource> types) throws DatabaseException {
2238 final Set<Resource> work = new HashSet<Resource>(types);
2239 for(Resource type : types) {
2240 Set<Resource> supers = graph.getSupertypes(type);
2241 if(!Collections.disjoint(supers, work)) work.remove(type);
2248 public static void rewriteGUIDS(WriteGraph graph, Resource root, boolean deep) throws DatabaseException {
2249 List<Resource> todo = new ArrayList<Resource>();
2251 Layer0 L0 = Layer0.getInstance(graph);
2252 while(!todo.isEmpty()) {
2253 Resource resource = todo.remove(todo.size()-1);
2254 graph.claimLiteral(resource, L0.identifier, L0.GUID, GUID.random(), GUID.BINDING);
2256 todo.addAll(graph.getObjects(resource, L0.ConsistsOf));
2260 public static void createMissingGUIDs(IProgressMonitor monitor, WriteGraph graph, Collection<Resource> roots) throws DatabaseException {
2262 if(monitor == null) monitor = new NullProgressMonitor();
2264 Layer0 L0 = Layer0.getInstance(graph);
2266 // Allow this process to make 50k queries
2267 QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000);
2269 for(Resource root : roots) {
2271 boolean madeChanges = false;
2273 monitor.setTaskName("Creating missing GUID identifiers " + NameUtils.getSafeName(graph, root));
2274 Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(root));
2275 for(Resource r : searchByType(graph, indexRoot, L0.Entity)) {
2279 if(graph.isImmutable(r)) continue;
2281 if(!ModelingUtils.needsIdentifier(graph, r)) continue;
2283 GUID existing = graph.getPossibleRelatedValue(r, L0.identifier, GUID.BINDING);
2284 if(existing == null) {
2285 graph.addLiteral(r, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING);
2292 ModelingUtils.deleteIndex(graph, root);
2299 public static boolean activateModel(WriteGraph graph, Resource model) throws DatabaseException {
2300 return graph.syncRequest(new ActivateModel(Simantics.getProjectResource(), model));
2303 public static File fileDialog(String title, List<Tuple> namesAndExtensions) {
2305 Display display = Display.getCurrent();
2306 Shell shell = display.getActiveShell();
2308 FileDialog dialog = new FileDialog(shell, SWT.OPEN);
2309 dialog.setText(title);
2311 String[] extensions = new String[namesAndExtensions.size()];
2312 String[] filterNames = new String[namesAndExtensions.size()];
2314 for(Tuple t : namesAndExtensions) {
2315 String filterName = (String)t.get(0);
2316 String extension = (String)t.get(1);
2317 filterNames[index] = filterName;
2318 extensions[index] = extension;
2322 dialog.setFilterExtensions(extensions);
2323 dialog.setFilterNames(filterNames);
2324 final String fileName = dialog.open();
2325 if (fileName == null) return null;
2327 return new File(fileName);
2331 public static Resource createLibrary(WriteGraph graph, Resource parent) throws DatabaseException {
2332 Layer0 l0 = Layer0.getInstance(graph);
2333 return createLibrary(graph, parent, NameUtils.findFreshName(graph, "Library", parent, l0.ConsistsOf));
2336 public static Resource createLibrary(WriteGraph graph, Resource parent, String name) throws DatabaseException {
2337 graph.markUndoPoint();
2338 Layer0 l0 = Layer0.getInstance(graph);
2340 Resource library = graph.newResource();
2341 graph.claim(library, l0.InstanceOf, null, l0.Library);
2342 graph.addLiteral(library, l0.HasName, l0.NameOf, l0.String, name, Bindings.STRING);
2343 graph.claim(library, l0.PartOf, parent);
2345 Layer0Utils.addCommentMetadata(graph, "Created new Library named " + name + ", resource " + library);