/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.modeling; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWizard; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.wizards.IWizardDescriptor; import org.simantics.Simantics; import org.simantics.annotation.ontology.AnnotationResource; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.container.DataContainer; import org.simantics.databoard.container.DataContainers; import org.simantics.databoard.container.DataFormatException; import org.simantics.databoard.container.FormatHandler; import org.simantics.databoard.serialization.SerializationException; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.URIStringUtils; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.WriteGraph; import org.simantics.db.common.NamedResource; import org.simantics.db.common.QueryMemoryWatcher; import org.simantics.db.common.primitiverequest.IsInstanceOf; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.ResourceRead2; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.request.WriteResultRequest; import org.simantics.db.common.utils.ListUtils; import org.simantics.db.common.utils.Logger; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.common.utils.VersionInfo; import org.simantics.db.common.utils.VersionInfoRequest; import org.simantics.db.common.utils.Versions; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.adapter.CopyHandler; import org.simantics.db.layer0.adapter.GenericRelationIndex; import org.simantics.db.layer0.adapter.Instances; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory; import org.simantics.db.layer0.genericrelation.IndexedRelations; import org.simantics.db.layer0.migration.MigrationUtils; import org.simantics.db.layer0.request.ActivateModel; import org.simantics.db.layer0.request.ActiveModels; import org.simantics.db.layer0.request.Configuration; import org.simantics.db.layer0.request.IsLinkedTo; import org.simantics.db.layer0.request.PossibleModel; import org.simantics.db.layer0.util.ClipboardUtils; import org.simantics.db.layer0.util.DraftStatusBean; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; import org.simantics.db.layer0.util.PasteEventHandler; import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.db.layer0.util.SimanticsClipboard; import org.simantics.db.layer0.util.SimanticsClipboard.Representation; import org.simantics.db.layer0.util.SimanticsClipboardImpl; import org.simantics.db.layer0.util.SimanticsKeys; import org.simantics.db.layer0.util.TransferableGraphConfiguration2; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.db.request.Read; import org.simantics.db.service.ClusterControl; import org.simantics.db.service.CollectionSupport; import org.simantics.db.service.QueryControl; import org.simantics.db.service.VirtualGraphSupport; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.stubs.G2DResource; import org.simantics.diagram.synchronization.graph.AddElement; import org.simantics.graph.db.IImportAdvisor2; import org.simantics.graph.db.ImportAdvisors; import org.simantics.graph.db.MissingDependencyException; import org.simantics.graph.db.StreamingTransferableGraphFileReader; import org.simantics.graph.db.TransferableGraphException; import org.simantics.graph.db.TransferableGraphSource; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.Identity; import org.simantics.graph.representation.Root; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.graph.representation.TransferableGraphUtils; import org.simantics.issues.common.IssueSourceUtils; import org.simantics.issues.ontology.IssueResource; import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.modeling.adapters.ChangeInformation; import org.simantics.modeling.template2d.ontology.Template2dResource; import org.simantics.operation.Layer0X; import org.simantics.project.ontology.ProjectResource; import org.simantics.scenegraph.profile.ProfileUtils; import org.simantics.scl.runtime.function.Function1; import org.simantics.scl.runtime.tuple.Tuple; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.scl.StructuralComponent; import org.simantics.structural2.utils.StructuralUtils; import org.simantics.ui.SimanticsUI; import org.simantics.utils.ObjectUtils; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.Triple; import org.simantics.utils.datastructures.hints.HintContext; import org.simantics.utils.ui.dialogs.ListDialog; /** * @author Hannu Niemistö */ public class ModelingUtils { private ReadGraph g; private WriteGraph wg; public Layer0 b; private StructuralResource2 sr; private DiagramResource dr; public ModelingResources mr; public SimulationResource SIMU; public ModelingUtils(WriteGraph g) { wg = g; this.g = g; b = Layer0.getInstance(g); sr = StructuralResource2.getInstance(g); dr = DiagramResource.getInstance(g); mr = ModelingResources.getInstance(g); SIMU = SimulationResource.getInstance(g); } @Deprecated public Resource createSymbol2(String name) throws DatabaseException { return createSymbol2(name, dr.Composite); } @Deprecated public Resource createSymbol2(String name, Resource type) throws DatabaseException { G2DResource g2d = G2DResource.getInstance(g); // Resource visibleTag = wg.newResource(); // wg.claim(visibleTag, b.SubrelationOf, null, dr.IsVisible); // Resource focusableTag = wg.newResource(); // wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable); Double boxDimension = 6.0; Collection grid = g.getAssertedStatements(type, dr.HasGridSize); if(grid.size() == 1) { Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE); if(d != null) boxDimension = 2*d; } Resource element = GraphUtils.create(wg, b.InstanceOf, dr.SVGElement, g2d.HasSVGDocument, "" + // REMOVED by Tuukka, because This will cause // parsers to get on the net and get the doctype // definitions which can stall the UI for a long time. // Besides, we're not using the validation for anything // so it's useless to us. //"" + "" + "" + "" ); // wg.claim(element, visibleTag, element); // wg.claim(element, focusableTag, element); Resource orderedSet = OrderedSetUtils.create(wg, type, element); // wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer, // b.HasName, "Default", // dr.IsActive, Boolean.TRUE, // dr.HasVisibleTag, visibleTag, // dr.HasFocusableTag, focusableTag)); Resource result = GraphUtils.create(wg, b.HasName, name, b.HasLabel, "", sr.IsDefinedBy, orderedSet); wg.claim(result, b.ConsistsOf, orderedSet); wg.claimLiteral(orderedSet, b.HasName, "__DIAGRAM__", Bindings.STRING); AddElement.claimFreshElementName(wg, orderedSet, element); wg.claim(orderedSet, b.ConsistsOf, element); wg.claim(result, b.Inherits, null, dr.DefinedElement); return result; } public static Collection getElementCorrespondendences(ReadGraph g, Resource element) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(g); ModelingResources mr = ModelingResources.getInstance(g); if(g.isInstanceOf(element, dr.Connection)) { Resource mappedComponent = g.getPossibleObject(element, mr.ElementToComponent); if(mappedComponent != null) return Collections.singletonList(mappedComponent); Resource mappedConnection = g.getPossibleObject(element, mr.DiagramConnectionToConnection); if(mappedConnection == null) return Collections.emptyList(); ArrayList result = new ArrayList(); Collection relatedMappedConnections = StructuralUtils.getRelatedConnections(g, mappedConnection); for(Resource relatedMappedConnection : relatedMappedConnections) for(Resource relatedConnection : g.getObjects(relatedMappedConnection, mr.ConnectionToDiagramConnection)) result.addAll(g.getObjects(relatedConnection, mr.ElementToComponent)); return result; } else return g.getObjects(element, mr.ElementToComponent); } public static Resource getPossibleElement(ReadGraph g, Resource component) throws DatabaseException { ModelingResources mr = ModelingResources.getInstance(g); return g.getPossibleObject(component, mr.ComponentToElement); } public static Resource getPossibleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException { Collection corrs = getElementCorrespondendences(g, element); if(corrs.size() != 1) return null; else return corrs.iterator().next(); } public static Resource getSingleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException { Collection corrs = getElementCorrespondendences(g, element); if(corrs.size() != 1) throw new DatabaseException("Expected 1 element correspondence, got " + corrs.size()); else return corrs.iterator().next(); } public static Resource createExperiment(WriteGraph graph, Resource model) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); SimulationResource SIMU = SimulationResource.getInstance(graph); Resource experiment = graph.newResource(); graph.claim(experiment, L0.InstanceOf, SIMU.Experiment); graph.claimLiteral(experiment, L0.HasName, "Experiment"); graph.claim(model, L0.ConsistsOf, experiment); return experiment; } public static Resource createModel(WriteGraph graph, Resource type) throws DatabaseException { return createModel(graph, type, Simantics.getProjectResource(), null); } public static Resource createModel(WriteGraph graph, Resource type, String name) throws DatabaseException { return createModel(graph, type, Simantics.getProjectResource(), name); } public static Resource createModel(WriteGraph graph, Resource type, final Resource target, String name) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); SimulationResource SIMU = SimulationResource.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); if(name == null) name = NameUtils.findFreshName(graph, "Model", target, L0.ConsistsOf, "%s%d"); final Resource model = graph.newResource(); graph.newClusterSet(model); graph.claim(model, L0.InstanceOf, null, type); graph.claimLiteral(model, L0.HasName, name); graph.claim(target, L0.ConsistsOf, model); Resource configurationType = graph.getPossibleObject(model, MOD.StructuralModel_HasConfigurationType); if(configurationType == null) configurationType = STR.Composite; Resource configuration = graph.newResource(); graph.claimLiteral(configuration, L0.HasName, "Configuration", Bindings.STRING); graph.claim(configuration, L0.InstanceOf, null, configurationType); graph.claim(model, L0.ConsistsOf, configuration); graph.claim(model, SIMU.HasConfiguration, configuration); Resource joinClusterSet = graph.newResource(); graph.newClusterSet(joinClusterSet); graph.claim(joinClusterSet, L0.InstanceOf, L0.ClusterSet); graph.claim(model, STR.HasJoinClusterSet, joinClusterSet); linkOntologyDependenciesToModel(graph, model, target); Resource ontology = graph.syncRequest(new PossibleIndexRoot(type)); if(ontology != null) { graph.claim(model, L0.IsLinkedTo, ontology); } VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("activations")) { @Override public void perform(WriteGraph graph) throws DatabaseException { Layer0X L0X = Layer0X.getInstance(graph); Collection actives = graph.syncRequest(new ActiveModels(target)); if(actives.isEmpty()) { graph.claim(model, L0X.IsActivatedBy, target); } } }); return model; } public static void linkOntologyDependenciesToModel(WriteGraph graph, Resource model, Resource target) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ProjectResource PROJ = ProjectResource.getInstance(graph); for(Resource dep : graph.getObjects(target, L0.IsLinkedTo)) { if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) { for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) { String uri = graph.getPossibleValue(req, Bindings.STRING); if(uri != null) { Resource ns = graph.getResource(uri); if(ns != null) { graph.claim(model, L0.IsLinkedTo, null, ns); } } } } } } public static void addSCLMainToModel(WriteGraph graph, Resource model) throws DatabaseException { addSCLMainToModel(graph, model, "SCLMain", "include \"Simantics/All\"\n"); } public static void addSCLMainToModel(WriteGraph graph, Resource model, String name, String contents) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource sclmain = GraphUtils.create2(graph, L0.SCLModule, L0.PartOf, model, L0.HasName, name); graph.claimLiteral(sclmain, L0.SCLModule_definition, contents, Bindings.STRING); } public static Resource createLocalLibrary(WriteGraph graph, Resource container, String name) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Resource library = graph.newResource(); graph.claim(library, L0.InstanceOf, null, L0.Library); graph.addLiteral(library, L0.HasName, L0.NameOf, "Library", Bindings.STRING); if (container != null) { graph.claim(container, L0.ConsistsOf, L0.PartOf, library); graph.claim(container, MOD.HasLocalLibrary, MOD.IsLocalLibraryOf, library); } return library; } public static void importModel(String fileName) { Resource project = SimanticsUI.getProject().get(); try { StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName)); TransferableGraphSource tg = importer.readTG(); final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(project) { @Override public void analyzeType(ReadGraph graph, Root root) throws DatabaseException { } @Override public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException { library = Simantics.getProjectResource(); String newName = newName(graph, library, root.name); nameMappings.put(root.name, newName); return null; } }; TransferableGraphs.importGraph1(Simantics.getSession(), tg, advisor); } catch (MissingDependencyException e) { final Set missingURIs = e.getMissingURIs(); class ErrorMessageDialog extends MessageDialog { public ErrorMessageDialog(Shell shell) { super(shell, "Unsatisfied dependencies", null, "The following dependencies were missing. Please import the dependencies and try again.", MessageDialog.ERROR, new String[] { "Continue" }, 0); } @Override protected Control createCustomArea(Composite composite) { GridLayoutFactory.fillDefaults().applyTo(composite); org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, true).applyTo(list); for(String s : missingURIs) list.add(s); return composite; } } Display display = Display.getCurrent(); if(display != null) { ErrorMessageDialog md = new ErrorMessageDialog(display.getActiveShell()); md.open(); } else { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { Shell shell = Display.getCurrent().getActiveShell(); ErrorMessageDialog md = new ErrorMessageDialog(shell); md.open(); } }); } } catch (Exception e) { Logger.defaultLogError(e); } } public static void primeVirtualGraphs() { VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); support.getWorkspacePersistent("activations"); support.getWorkspacePersistent("experiments"); support.getWorkspacePersistent("issues"); support.getWorkspacePersistent("preferences"); } public static Resource createProfileEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource entry = graph.newResource(); graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry); graph.claimLiteral(entry, L0.HasName, name); graph.claimLiteral(entry, L0.HasLabel, name); graph.claim(entry, DIA.ProfileEntry_HasStyle, style); graph.claim(entry, DIA.ProfileEntry_HasGroup, group); return entry; } public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource list = ListUtils.create(graph, DIA.Profile, entries); Resource profile = graph.newResource(); graph.claim(profile, L0.InstanceOf, null, DIA.Profile); graph.claimLiteral(profile, L0.HasName, profileName); graph.claim(profile, DIA.HasEntries, null, list); return profile; } public static Resource createProfile(WriteGraph graph, String profileName, Collection entries) throws DatabaseException { return createProfile(graph, profileName, entries.toArray(new Resource[entries.size()])); } public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Resource ... profiles) throws DatabaseException { Resource work = createProfile(graph, name, profiles); Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); graph.deny(model, DIA.HasActiveProfile); graph.claim(model, DIA.HasActiveProfile, work); graph.claim(model, L0.ConsistsOf, L0.PartOf, work); return work; } public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Collection profiles) throws DatabaseException { return createToplevelProfile(graph, model, name, profiles.toArray(new Resource[profiles.size()])); } public static void activateProfileEntries(WriteGraph graph, final Resource profile, final Resource ... entries) { VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { @Override public void perform(WriteGraph graph) throws DatabaseException { SimulationResource SIMU = SimulationResource.getInstance(graph); for(Resource entry : entries) graph.claim(profile, SIMU.IsActive, entry); } }); } public static void activateProfileEntries(WriteGraph graph, Resource profile, Collection entries) { activateProfileEntries(graph, profile, entries.toArray(new Resource[entries.size()])); } public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, String groupName, boolean enabled) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for (Resource group : ProfileUtils.getProfileChildren(graph, runtimeProfile)) { String name = graph.getRelatedValue2(group, L0.HasName); if (name.equals(groupName)) { toggleProfileGroup(graph, runtimeProfile, group, enabled); return; } } } public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, Resource group, boolean enabled) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); if(graph.isInstanceOf(group, DIA.Profile)) { for(Resource child : ProfileUtils.getProfileChildren(graph, group)) { toggleProfileGroup(graph, runtimeProfile, child, enabled); } } else if(graph.isInstanceOf(group, DIA.ProfileEntry)) { if(enabled) { graph.claim(runtimeProfile, SimulationResource.getInstance(graph).IsActive, null, group); } else { graph.denyStatement(runtimeProfile, SimulationResource.getInstance(graph).IsActive, group); } } } public static void untrackDependencies() { untrackDependencies(Simantics.getSession()); } public static void untrackDependencies(RequestProcessor processor) { try { processor.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { Layer0X L0X = Layer0X.getInstance(graph); GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class); index.untrack(graph.getSession(), graph.getRootLibrary()); } }); } catch (DatabaseException e) { Logger.defaultLogError(e); } } public static void trackDependencies() { trackDependencies(Simantics.getSession()); } public static void trackDependencies(RequestProcessor processor) { try { processor.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { Layer0X L0X = Layer0X.getInstance(graph); GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class); index.trackAndIndex(graph.getSession(), graph.getRootLibrary()); } }); } catch (DatabaseException e) { Logger.defaultLogError(e); } } public static void removeIndex(WriteGraph graph, Resource model) throws DatabaseException { Layer0X L0X = Layer0X.getInstance(graph); IndexedRelations ir = graph.getService(IndexedRelations.class); // Deletes index files ir.reset(null, graph, L0X.DependenciesRelation, model); } public static void resetIssueSources(WriteGraph graph, Resource model) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); IssueResource ISSUE = IssueResource.getInstance(graph); for(Resource source : graph.sync(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.ContinuousIssueSource))) { IssueSourceUtils.update(graph, source); } } public static void copyAnnotationTypes(WriteGraph graph, Resource sourceModel, Resource targetModel) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); AnnotationResource ANNO = AnnotationResource.getInstance(graph); Instances query = graph.adapt(ANNO.AnnotationType, Instances.class); Resource library = graph.getPossibleObject(targetModel, ANNO.HasAnnotationTypeRoot); // HAXX: if(library == null) { library = graph.newResource(); graph.claim(library, L0.InstanceOf, null, ANNO.AnnotationTypeLibrary); graph.claimLiteral(library, L0.HasName, L0.NameOf, L0.String, "Annotation types", Bindings.STRING); graph.claim(library, L0.PartOf, L0.ConsistsOf, targetModel); graph.claim(targetModel, ANNO.HasAnnotationTypeRoot, library); } for(Resource type : query.find(graph, sourceModel)) { String name = graph.getRelatedValue(type, L0.HasName); Resource existing = Layer0Utils.getPossibleChild(graph, library, name); if(existing != null) { RemoverUtil.remove(graph, existing); } Layer0Utils.copyTo(graph, library, type); } } public static void deleteIndex(WriteGraph graph, Resource model) throws DatabaseException { Layer0X L0X = Layer0X.getInstance(graph); IndexedRelations ir = graph.getService(IndexedRelations.class); // Deletes index files ir.reset(null, graph, L0X.DependenciesRelation, model); } public static void disableDependencies(WriteGraph graph, Resource dummy) { Layer0Utils.setDependenciesIndexingDisabled(graph, true); } public static void releaseMemory(WriteGraph graph) { QueryControl qc = graph.getService(QueryControl.class); ClusterControl cc = graph.getService(ClusterControl.class); cc.flushClusters(); qc.flush(graph); } public static List filterByIndexRoot(ReadGraph graph, Resource indexRoot, List resources) throws DatabaseException { ArrayList result = new ArrayList(resources.size()); for (Resource r : resources) { Resource root = graph.syncRequest(new PossibleIndexRoot(r)); if (indexRoot.equals(root)) result.add(r); } return result; } public static List searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException { return filterByIndexRoot(graph, model, searchByType(graph, model, type)); } public static List searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException { Instances query = graph.adapt(type, Instances.class); return Layer0Utils.sortByCluster(graph, query.find(graph, model)); } public static List searchByGUID(ReadGraph graph, Resource indexRoot, GUID guid) throws DatabaseException { return searchByGUID(graph, indexRoot, guid.indexString()); } public static List searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException { return searchByQueryShallow(graph, indexRoot, "GUID:" + indexString); } public static List searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException { return filterByIndexRoot(graph, model, searchByQuery(graph, model, query)); } public static List searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException { Instances instances = graph.adapt(Layer0.getInstance(graph).Entity, Instances.class); Collection queryResult = instances.find(graph, model, query); return Layer0Utils.sortByCluster(graph, queryResult); } public static List searchByTypeAndFilter(ReadGraph graph, Resource model, Resource type, Function1 filter) throws DatabaseException { Instances query = graph.adapt(type, Instances.class); ArrayList result = new ArrayList(); for(Resource r : query.find(graph, model)) { if(filter.apply(r)) result.add(r); } return result; } public static List> getIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); List entries = searchByQuery(graph, model, filter); List> listOfTriples = new ArrayList>(); for (Resource entry : entries) { Resource type = graph.getPossibleObject(entry, L0.InstanceOf); String name = NameUtils.getSafeName(graph, entry); listOfTriples.add(new Triple(entry, type, name)); } return listOfTriples; } public static String listIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException { List> listOfTriples = getIndexEntries(graph, model, filter); StringBuilder sb = new StringBuilder(); sb.append("== LISTING INDEX ENTRIES OF INDEX: " + NameUtils.getSafeName(graph, model) + ". AMOUNT OF ENTRIES: " + listOfTriples.size() + " ==\n"); for (Triple entry : listOfTriples) { String instanceOf = NameUtils.getSafeName(graph, entry.second); sb.append("Name: " + entry.third + " instanceOf: " + instanceOf + " Resource: " + entry.first.toString() + "\n"); } return sb.toString(); } public static List searchByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException { Instances query = graph.adapt(type, Instances.class); ArrayList result = new ArrayList(); for(Resource r : query.findByName(graph, model, name)) { if(graph.isInstanceOf(r, type)) result.add(r); } return result; } public static List searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException { return filterByIndexRoot(graph, model, searchByTypeAndName(graph, model, type, name)); } /** * @param graph * database write access * @param sourceContainer * the source container to look for annotationProperty from to be * used as the copy source * @param targetContainer * the target container for the copied annotationProperty * annotation * @param annotationProperty * the annotation property relation * @return created copy of the original annotation or null if * there was nothing to copy * @throws DatabaseException */ public static Resource copyPossibleAnnotation(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty) throws DatabaseException { return copyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, null); } public static List getPossibleNamePath(ReadGraph graph, Resource resource) throws DatabaseException { return getPossibleNamePath(graph, resource, null); } private static List getPossibleNamePath(ReadGraph graph, Resource resource, List result) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING); if(name == null) return null; if(result == null) result = new ArrayList(); SimulationResource SIMU = SimulationResource.getInstance(graph); if(graph.isInstanceOf(resource, SIMU.Model)) return result; Resource parent = graph.getPossibleObject(resource, L0.PartOf); if(parent != null) { getPossibleNamePath(graph, parent, result); } else { return null; } result.add(name); return result; } public static Resource claimLibraryPath(WriteGraph graph, Resource resource, List path) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(int i=0;inull if no 2nd level annotation exists * @return created copy of the original annotation or null if * there was nothing to copy * @throws DatabaseException */ public static Resource copyPossibleAnnotation2(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty, Resource entryType) throws DatabaseException { // Delete existing target value first Layer0 L0 = Layer0.getInstance(graph); Resource targetValue = graph.getPossibleObject(targetContainer, annotationProperty); if (targetValue != null) { if(!graph.hasStatement(targetValue, L0.PartOf)) RemoverUtil.remove(graph, targetValue); graph.deny(targetContainer, annotationProperty); } Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty); if (sourceValue == null) return null; List sourceValuePath = getPossibleNamePath(graph, sourceValue); if(sourceValuePath != null) { Resource targetModel = graph.sync(new PossibleModel(targetContainer)); if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer); Resource library = claimLibraryPath(graph, targetModel, sourceValuePath); Resource existing = Layer0Utils.getPossibleChild(graph, library, sourceValuePath.get(sourceValuePath.size()-1)); if(existing == null) { existing = doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType); graph.claim(library, L0.ConsistsOf, L0.PartOf, existing); } graph.claim(targetContainer, annotationProperty, existing); return existing; } else { return doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType); } } private static Resource doCopyPossibleAnnotation2(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty, Resource entryType) throws DatabaseException { Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty); if (sourceValue == null) return null; // Copy 1st level annotation Resource targetValue = createAnnotation(graph, targetContainer, annotationProperty, sourceValue); // Copy possible 2nd level annotations and attach to 1st if entry // property is defined. Layer0 L0 = Layer0.getInstance(graph); if (entryType != null) { AnnotationResource ANNO = AnnotationResource.getInstance(graph); for (Resource entry : graph.getObjects(sourceValue, ANNO.Annotation_HasEntry)) { String name = graph.getRelatedValue(entry, L0.HasName, Bindings.STRING); List entryPath = getPossibleNamePath(graph, entry); if(entryPath != null) { Resource targetModel = graph.sync(new PossibleModel(targetContainer)); if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer); Resource library = claimLibraryPath(graph, targetModel, entryPath); Resource existing = Layer0Utils.getPossibleChild(graph, library, entryPath.get(entryPath.size()-1)); if(existing == null) { existing = createTypedAnnotation(graph, null, null, entry, entryType, name); graph.claim(library, L0.ConsistsOf, L0.PartOf, existing); } graph.claim(targetValue, ANNO.Annotation_HasEntry, existing); } else { Resource result = createTypedAnnotation(graph, null, null, entry, entryType, name); graph.claim(targetValue, ANNO.Annotation_HasEntry, result); } } } return targetValue; } /** * @param graph * database write access * @param container * the container resource to attach the new annotation to * @param property * the annotation property relation. The type of the created * annotation is decided from this property relation's range * @param sourceAnnotation * the annotation to copy data from or null if * nothing shall be copied * @return the newly created annotation resource or null if the * annotation property relation didn't have a single range type * @throws DatabaseException */ public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation) throws DatabaseException { return createAnnotation(graph, container, property, sourceAnnotation, null); } /** * @param graph * database write access * @param container * the container resource to attach the new annotation to * @param property * the annotation property relation. The type of the created * annotation is decided from this property relation's range * @param sourceAnnotation * the annotation to copy data from or null if * nothing shall be copied * @param name * name for newly created annotation or null to copy * name from source if available * @return the newly created annotation resource or null if the * annotation property relation didn't have a single range type * @throws DatabaseException */ public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, String name) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource annotationType = graph.getSingleObject(property, L0.HasRange); if (annotationType == null) return null; return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, name); } /** * @param graph * database write access * @param container * the container resource to attach the new annotation to * @param property * the annotation property relation * @param sourceAnnotation * the annotation to copy data from or null if * nothing shall be copied * @param annotationType * the type of the new annotation * @return the newly created annotation resource * @throws DatabaseException */ public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType) throws DatabaseException { return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, null); } /** * @param graph * database write access * @param container * the container resource to attach the new annotation to * @param property * the annotation property relation * @param sourceAnnotation * the annotation to copy data from or null if * nothing shall be copied * @param annotationType * the type of the new annotation * @param name * name for newly created annotation or null to copy * name from source if available * @return the newly created annotation resource * @throws DatabaseException */ public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType, String name) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource anno = graph.newResource(); graph.claim(anno, L0.InstanceOf, null, annotationType); if (name != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING); if (sourceAnnotation != null) { if (name == null) { String sourceName = graph.getPossibleRelatedValue(sourceAnnotation, L0.HasName, Bindings.STRING); if(sourceName != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, sourceName, Bindings.STRING); } Resource sourceType = graph.getSingleType(sourceAnnotation); List am = getAnnotationMap(graph, annotationType, sourceType); for (AnnotationMap a : am) { Resource object = graph.getSingleObject(sourceAnnotation, a.sourcePredicate); Collection objectTypes = graph.getTypes(object); if (objectTypes.contains(L0.Literal)) { Object value = graph.getValue(object, a.defaultValueBinding); if (!ObjectUtils.objectEquals(value, a.defaultValue)) { graph.addLiteral(anno, a.annotationPredicate, a.annotationPredicateInverse, a.defaultValueType, value, a.defaultValueBinding); } } } } if (container != null && property != null) { graph.claim(container, property, anno); } return anno; } private static class AnnotationMap { final public Resource sourcePredicate; final public Resource sourcePredicateInverse; final public Resource annotationPredicate; final public Resource annotationPredicateInverse; final public Resource defaultValueType; final public Object defaultValue; final public Binding defaultValueBinding; public AnnotationMap(Resource sp, Resource spi, Resource tp, Resource tpi, Resource defaultValueType, Object defaultValue, Binding defaultValueBinding) { sourcePredicate = sp; sourcePredicateInverse = spi; annotationPredicate = tp; annotationPredicateInverse = tpi; this.defaultValueType = defaultValueType; this.defaultValue = defaultValue; this.defaultValueBinding = defaultValueBinding; } } public static List getAnnotationMap(ReadGraph graph, Resource annotationType, Resource sourceType) throws DatabaseException { return graph.syncRequest(new AnnotationMapRequest(annotationType, sourceType), TransientCacheListener.>instance()); } static class AnnotationMapRequest extends ResourceRead2> { public AnnotationMapRequest(Resource annotationType, Resource sourceType) { super(annotationType, sourceType); } @Override public List perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ArrayList result = new ArrayList(); Map annotationPredicates = new HashMap(); for(Resource predicate : graph.getObjects(resource, L0.DomainOf)) { String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING); annotationPredicates.put(name, predicate); } Map sourcePredicates = new HashMap(); for(Resource predicate : graph.getObjects(resource2, L0.DomainOf)) { String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING); sourcePredicates.put(name, predicate); } for(String key : sourcePredicates.keySet()) { Resource sourcePredicate = sourcePredicates.get(key); Resource anno = annotationPredicates.get(key); if(sourcePredicate != null && anno != null) { Resource defaultValueType = graph.getSingleObject(anno, L0.HasRange); Binding defaultValueBinding = null; Object defaultValue = null; Resource assertion = graph.getPossibleObject(anno, L0.HasPredicateInverse); if (assertion != null) { Resource object = graph.getPossibleObject(assertion, L0.HasObject); if (object != null) { if(graph.isInstanceOf(object, L0.Literal)) { Datatype dt = graph.getDataType(object); defaultValueBinding = Bindings.getBeanBinding(dt); defaultValue = graph.getPossibleValue(object); } } } result.add(new AnnotationMap( sourcePredicate, graph.getInverse(sourcePredicate), anno, graph.getInverse(anno), defaultValueType, defaultValue, defaultValueBinding)); } } return result; } } public static final String DRAWING_TEMPLATE_FORMAT = "drawingTemplate"; public static final String DRAWING_TEMPLATE_FORMAT_V1 = DRAWING_TEMPLATE_FORMAT + ":1"; public static final String DRAWING_TEMPLATE_FORMAT_V2 = DRAWING_TEMPLATE_FORMAT + ":2"; public static Resource importDrawingTemplate(final Resource model, final File file) throws IOException, SerializationException, DatabaseException, TransferableGraphException { try { final Resource library = Simantics.sync(new WriteResultRequest() { @Override public Resource perform(WriteGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Template2dResource TEMPLATE = Template2dResource.getInstance(graph); Resource root = graph.getPossibleObject(model, TEMPLATE.HasDrawingTemplateRoot); if(root == null) { Template2dResource TEMPLATE2D = Template2dResource.getInstance(graph); root = graph.newResource(); graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibrary); graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibraryUI); graph.claimLiteral(root, L0.HasName, L0.NameOf, L0.String, "Diagram Templates", Bindings.STRING); graph.claim(root, L0.PartOf, L0.ConsistsOf, model); graph.claim(model, TEMPLATE2D.HasDrawingTemplateRoot, root); } String name = new Path(file.getAbsolutePath()).removeFileExtension().lastSegment(); if(name != null) { Resource existing = Layer0Utils.getPossibleChild(graph, root, name); if(existing != null) graph.deny(root, L0.ConsistsOf, existing); } return root; } }); final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(library); try { HashMap> handlers = new HashMap>(); FormatHandler handler = new FormatHandler() { @Override public Binding getBinding() { return TransferableGraph1.BINDING; } @Override public Object process(DataContainer container) throws Exception { TransferableGraphs.importGraph1(Simantics.getSession(), (TransferableGraph1)container.content.getValue(), advisor, null); return null; } }; handlers.put(DRAWING_TEMPLATE_FORMAT_V1, handler); handlers.put(DRAWING_TEMPLATE_FORMAT_V2, handler); try { DataContainers.readFile(file, handlers); } catch(DataFormatException e) { throw new IOException(e); } catch(IOException e) { throw e; } catch(Exception e) { if(e instanceof RuntimeException) throw (RuntimeException)e; else throw new RuntimeException(e); } } catch(IOException e) { } return advisor.getRoot(); } catch (Throwable t) { Logger.defaultLogError("Unexpected exception while importing diagram template.", t); } finally { } return null; } public static Collection getMappedVariables(ReadGraph graph, Variable source) throws DatabaseException { ArrayList result = new ArrayList(); Resource represents = source.getPossibleRepresents(graph); if(represents == null) return Collections.emptyList(); ModelingResources MOD = ModelingResources.getInstance(graph); for(Resource r : getElementCorrespondendences(graph, represents)) { result.add(Variables.getVariable(graph, r)); } for(Resource r : graph.getObjects(represents, MOD.ComponentToElement)) { result.add(Variables.getVariable(graph, r)); } for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite)) { result.add(Variables.getVariable(graph, r)); } for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram)) { result.add(Variables.getVariable(graph, r)); } return result; } public static Resource getPossibleModel(ReadGraph graph, Resource resource) throws DatabaseException { PossibleModel pm = new PossibleModel(resource); Resource model = pm.perform(graph); return model; } public static Resource possibleIndexRoot(ReadGraph graph, Resource resource) throws DatabaseException { return graph.syncRequest(new PossibleIndexRoot(resource)); } public static Object getMonitorValue(StructuralComponent _variable, ReadGraph graph, String path) throws DatabaseException { Variable variable = ((VariableStructuralContext)_variable).variable; Variable var = variable.browse(graph, path); return var.getValue(graph); } public static void createSharedOntologyWithUI(ReadGraph graph, Variable variable, Resource baseType) throws DatabaseException { createSharedOntologyWithUI(graph, baseType); } public static void createSharedOntologyWithUI(ReadGraph graph, Resource baseType) throws DatabaseException { // Resource indexRoot_ = variable.getPossibleRepresents(graph); // if(indexRoot_ == null) return; final Map> map = new HashMap>(); Layer0 L0 = Layer0.getInstance(graph); SimulationResource SIMU = SimulationResource.getInstance(graph); Instances query = graph.adapt(L0.IndexRootType, Instances.class); for(Resource ontology : Layer0Utils.listOntologies(graph)) { for(Resource type : query.find(graph, ontology)) { if(graph.isInheritedFrom(type, SIMU.Model)) continue; if(graph.hasStatement(type, L0.Abstract)) continue; if(!graph.isInheritedFrom(type, baseType)) continue; String name = graph.getPossibleRelatedValue(type, L0.HasLabel, Bindings.STRING); if(name == null) name = graph.getRelatedValue(type, L0.HasName, Bindings.STRING); map.put(type, new Pair(name, null)); } } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); CreateSharedOntologyDialog page = new CreateSharedOntologyDialog(shell, map, "Select type and name of new shared library"); if (page.open() == Window.OK) { Object[] result = page.getResult(); if (result != null && result.length == 1) { final Resource res = (Resource)result[0]; final String name = "http://" + page.getName(); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { graph.markUndoPoint(); Resource target = Simantics.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, name+"@A", res); ProjectResource PROJ = ProjectResource.getInstance(graph); Layer0 L0 = Layer0.getInstance(graph); for(Resource dep : graph.getObjects(Simantics.getProjectResource(), L0.IsLinkedTo)) { if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) { for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) { String uri = graph.getPossibleValue(req, Bindings.STRING); if(uri != null) { Resource ns = graph.getResource(uri); if(ns != null) { graph.claim(target, L0.IsLinkedTo, null, ns); } } } } } } }); } } } }); } public static void unlinkSharedOntologyWithUI(ReadGraph graph, Variable variable, final List libraries) throws DatabaseException { final Resource indexRoot = variable.getPossibleRepresents(graph); if(indexRoot == null) return; StructuralResource2 STR = StructuralResource2.getInstance(graph); final List instances = new ArrayList(); DiagramResource DIA = DiagramResource.getInstance(graph); for(Resource library : libraries) { for(Resource type : ModelingUtils.searchByTypeShallow(graph, library, STR.ComponentType)) { for(Resource instance : ModelingUtils.searchByTypeShallow(graph, indexRoot, type)) { // TODO: haxx if(graph.isInstanceOf(instance, DIA.Element)) continue; String name = Versions.getStandardPathNameString(graph, instance); instances.add(name); } } } if(instances.isEmpty()) { graph.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Resource library : libraries) graph.deny(indexRoot, L0.IsLinkedTo, library); } }); return; } PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { if (!PlatformUI.isWorkbenchRunning()) return; Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); ListDialog dialog = new ListDialog( shell, instances, "Cannot unlink selected libraries", "Libraries cannot be unlinked since the following instances are referring to them.") { protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true); } }; int result = dialog.open(); if (result != Dialog.OK) return; } }); } public static void importSharedOntology(String fileName) throws Exception { try { DataContainer dc = DataContainers.readFile(new File(fileName)); TransferableGraph1 tg = (TransferableGraph1)dc.content.getValue(TransferableGraph1.BINDING); Variant draftStatus = dc.metadata.get(DraftStatusBean.EXTENSION_KEY); MigrationUtils.importSharedOntology(Simantics.getSession(), tg, draftStatus == null); } catch (Exception e) { Logger.defaultLogError(e); throw e; } } public static void importSharedOntologyWithUI(ReadGraph graph, final Variable variable) throws DatabaseException { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { IStructuredSelection sel = new StructuredSelection(variable); openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyImportWizard"); } }); } public static class LibraryInfo implements Comparable { public NamedResource library; public DraftStatusBean draft; public LibraryInfo(String name, Resource r, DraftStatusBean draft) { library = new NamedResource(name, r); this.draft = draft; } @Override public int compareTo(LibraryInfo o) { return library.compareTo(o.library); } @Override public int hashCode() { return library.hashCode(); } @Override public boolean equals(Object object) { if (this == object) return true; else if (object == null) return false; else if (!(object instanceof LibraryInfo)) return false; LibraryInfo info = (LibraryInfo)object; return info.library.equals(library); } } public static void exportSharedOntologyWithUI(final Resource sharedOntology) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { HintContext hc = new HintContext(); hc.setHint(SelectionHints.KEY_MAIN, sharedOntology); IStructuredSelection sel = new StructuredSelection(hc); openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyExportWizard"); } }); } public static void exportSharedOntology(IProgressMonitor monitor, RequestProcessor processor, File location, String format, int version, final LibraryInfo info) throws DatabaseException, IOException { if(monitor == null) monitor = new NullProgressMonitor(); // TODO: figure out a way to make the TG go directly into a file // instead of having it all in memory at once. monitor.beginTask("Exporting shared library...", 100); SimanticsClipboard clipboard = processor.syncRequest(new Read() { @Override public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException { CopyHandler ch = graph.adapt(info.library.getResource(), CopyHandler.class); SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl(); ch.copyToClipboard(graph, clipboard); return clipboard; } }); TreeMap metadata = getExportMetadata(); DraftStatusBean draft = info.draft; if(draft != null) { metadata.put(DraftStatusBean.EXTENSION_KEY, new Variant(DraftStatusBean.BINDING ,draft)); } for (Set object : clipboard.getContents()) { TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH); monitor.worked(95); monitor.setTaskName("Writing transferable graph..."); DataContainers.writeFile(location, new DataContainer( format, version, metadata, new Variant(TransferableGraph1.BINDING, tg))); monitor.worked(5); } } public static TreeMap getExportMetadata() { TreeMap metadata = new TreeMap(); metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()))); metadata.put("author", Variant.ofInstance(System.getProperty("user.name", ""))); return metadata; } public static void createNewVersionWithoutUI(WriteGraph graph, Resource resource) throws DatabaseException { VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource)); int currentVersion = Integer.parseInt(info.version); String result = Integer.toString(currentVersion + 1); createNewVersion(graph, resource, info, result); } public static void createNewVersionWithUI(ReadGraph graph, final Resource resource) throws DatabaseException { final VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource)); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); CreateVersionDialog dialog = new CreateVersionDialog(shell, info); if (dialog.open() == Window.OK) { final String result = dialog.getResult(); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { createNewVersion(graph, resource, info, result); } }); } } }); } public static void createNewVersion(WriteGraph graph, Resource resource, final VersionInfo info, final String result) throws DatabaseException { graph.markUndoPoint(); Layer0 L0 = Layer0.getInstance(graph); Resource parent = graph.getPossibleObject(resource, L0.PartOf); if(parent == null) return; final String parentURI = graph.getPossibleURI(parent); if(parentURI == null) return; Layer0Utils.copyTo(graph, parent, resource, new PasteEventHandler() { @Override public void postProcess(WriteGraph graph, Resource root) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); graph.deny(root, L0.Entity_published); } @Override public IImportAdvisor2 createAdvisor(ReadGraph graph, ImportAdvisorFactory factory, Resource target) throws DatabaseException { Map context = new HashMap(); String base = parentURI + "/" + URIStringUtils.escape( info.baseName ) + "@"; Map renameMap = new HashMap(); renameMap.put(base + info.version, base + result); renameMap.put(info.baseName + "@" + info.version, info.baseName + "@" + result); context.put(ImportAdvisors.RENAME_MAP, renameMap); return factory.create(graph, target, context); } }); Layer0Utils.addCommentMetadata(graph, "Created new version of " + info.baseName); } public static boolean isUserComponent(ReadGraph graph, Resource type) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(graph); if(graph.isInstanceOf(type, STR.ProceduralComponentType)) return true; else if (graph.hasStatement(type, STR.IsDefinedBy)) return true; return false; } public static void publishComponentTypeWithUI(WriteGraph graph, final Resource componentType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource composite = graph.getPossibleObject(componentType, STR.IsDefinedBy); final List instances = new ArrayList(); if(composite != null) { for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) { Resource type = graph.getPossibleType(component, STR.Component); if(type != null && isUserComponent(graph, type)) { if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, component)); } } } if(instances.isEmpty()) { graph.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { graph.markUndoPoint(); publish(graph, componentType); } }); return; } PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { if (!PlatformUI.isWorkbenchRunning()) return; Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); ListDialog dialog = new ListDialog( shell, instances, "Cannot publish user component", "The following instances are referring to unpublished user components.") { protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true); } }; int result = dialog.open(); if (result != Dialog.OK) return; } }); } public static void publishSharedOntologyWithUI(WriteGraph graph, final Resource sharedOntology) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); final List instances = new ArrayList(); for(Resource type : searchByTypeShallow(graph, sharedOntology, STR.ComponentType)) { // TODO: haxx if(graph.isInheritedFrom(type, DIA.Element)) continue; if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, type)); } for(Resource dep : graph.syncRequest(new ObjectsWithType(sharedOntology, L0.IsLinkedTo, L0.SharedOntology))) { if(!Layer0Utils.isPublished(graph, dep)) instances.add(Versions.getStandardPathNameString(graph, dep)); } if(instances.isEmpty()) { graph.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { graph.markUndoPoint(); publish(graph, sharedOntology); } }); return; } PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { if (!PlatformUI.isWorkbenchRunning()) return; Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); ListDialog dialog = new ListDialog( shell, instances, "Cannot publish shared library", "The following dependencies are unpublished.") { protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true); } }; int result = dialog.open(); if (result != Dialog.OK) return; } }); } public static void createSCLModuleDefault(WriteGraph graph, Resource target) throws DatabaseException { String name = NameUtils.findFreshEscapedName(graph, "SCLModule", target); createSCLModule(graph, target, name); } public static void createSCLModule(WriteGraph graph, Resource target, String name) throws DatabaseException { graph.markUndoPoint(); Layer0 L0 = Layer0.getInstance(graph); Resource sclModule = GraphUtils.create2(graph, L0.SCLModule, L0.HasName, name, L0.PartOf, target, L0.SCLModule_definition, ""); Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString()); } public static void createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException { String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target); createPGraph(graph, target, name); } public static void createPGraph(WriteGraph graph, Resource target, String name) throws DatabaseException { graph.markUndoPoint(); Layer0 L0 = Layer0.getInstance(graph); Resource file = GraphUtils.create2(graph, L0.PGraph, L0.HasName, name, L0.PartOf, target, L0.PGraph_definition, ""); Layer0Utils.addCommentMetadata(graph, "Created Ontology Definition File " + name + " " + file.toString()); } public static void publish(WriteGraph graph, Resource target) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); graph.claimLiteral(target, L0.Entity_published, true, Bindings.BOOLEAN); Layer0Utils.addCommentMetadata(graph, "Published " + graph.getPossibleRelatedValue2(target, L0.HasName, Bindings.STRING) + " " + target.toString()); } public static boolean isLinkedToDeep(ReadGraph graph, Resource r1, Resource r2) throws DatabaseException { return graph.syncRequest(new IsLinkedTo(r1, r2)); } public static void openWizard(Display display, IStructuredSelection selection, String id) { // First see if this is a "new wizard". IWizardDescriptor descriptor = PlatformUI.getWorkbench() .getNewWizardRegistry().findWizard(id); // If not check if it is an "import wizard". if (descriptor == null) { descriptor = PlatformUI.getWorkbench().getImportWizardRegistry() .findWizard(id); } // Or maybe an export wizard if (descriptor == null) { descriptor = PlatformUI.getWorkbench().getExportWizardRegistry() .findWizard(id); } try { // Then if we have a wizard, open it. if (descriptor != null) { IWorkbenchWizard wizard = descriptor.createWizard(); wizard.init(PlatformUI.getWorkbench(), selection); WizardDialog wd = new WizardDialog(display.getActiveShell(), wizard); wd.setTitle(wizard.getWindowTitle()); wd.open(); } } catch (CoreException e) { e.printStackTrace(); } } public static String withinEpsilon(double value, double reference, double epsilon) { if(Math.abs(value-reference) < epsilon) return "True"; else return "Not within epsilon value=" + value + ", reference=" + reference + " , epsilon=" + epsilon; } public static boolean needsIdentifier(ReadGraph graph, Resource r) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Collection types = graph.getPrincipalTypes(r); for(Resource type : types) if(graph.syncRequest(new IsInstanceOf(type, L0.TypeWithIdentifier), TransientCacheAsyncListener.instance())) return true; return false; } public static boolean needsModificationInfo(ReadGraph graph, Resource r) throws DatabaseException { ModelingResources MOD = ModelingResources.getInstance(graph); Collection types = graph.getPrincipalTypes(r); for(Resource type : types) if(graph.syncRequest(new IsInstanceOf(type, MOD.TypeWithChangeInformation), TransientCacheAsyncListener.instance())) return true; return false; } public static void attachCreationInformation(IProgressMonitor monitor, WriteGraph graph, Resource model) throws DatabaseException { if(monitor == null) monitor = new NullProgressMonitor(); final String author = System.getProperty("user.name", ""); final long time = System.currentTimeMillis(); monitor.setTaskName("Attach creation information"); ModelingResources MOD = ModelingResources.getInstance(graph); Collection rs = ModelingUtils.searchByType(graph, model, MOD.TypeWithChangeInformation); Collection supers = ModelingUtils.getMostUnspecificTypes(graph, rs); CollectionSupport cs = graph.getService(CollectionSupport.class); Collection set = cs.createSet(); for(Resource type : supers) { set.addAll(ModelingUtils.searchByTypeShallow(graph, model, type)); } Collection instances = Layer0Utils.sortByCluster(graph, set); int pc = instances.size() / 100; int done = 0; int stint = pc; for(Resource instance : instances) { ChangeInformation info = graph.getPossibleRelatedValue(instance, MOD.changeInformation, ChangeInformation.BINDING); if(info == null) { info = new ChangeInformation(); info.createdAt = time; info.createdBy = author; info.modifiedAt = time; info.modifiedBy = author; graph.claimLiteral(instance, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING); } done++; stint--; if(stint == 0) { Double d = (100.0*done)/instances.size(); monitor.setTaskName("Attach creation information " + d.intValue() + "%"); stint = pc; } } monitor.setTaskName("Attach creation information - commit"); } public static class DiagramComponentInfo { private static String CHILD_PREFIX = "child:"; final private String compositePathAndName; final private String componentName; final private GUID guid; public DiagramComponentInfo(String compositePathAndName, String componentName, GUID guid) { this.compositePathAndName = compositePathAndName; this.componentName = componentName; this.guid = guid; } public static boolean isDiagramComponent(String tgName) { return tgName.startsWith(CHILD_PREFIX); } public String getTGName(CompositeInfo info) { return CHILD_PREFIX + info.getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + info.getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedComponentName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString(); } public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException { Collection res = ModelingUtils.searchByGUID(graph, indexRoot, guid); return !res.isEmpty(); } public static DiagramComponentInfo fromResource(ReadGraph graph, CompositeInfo info, Resource resource) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); GUID childId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING); String childName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING); return new DiagramComponentInfo(info.getStateKey(), URIStringUtils.escape(childName), childId); } public GUID getGUID() { return guid; } public String getEscapedCompositePathAndName() { return compositePathAndName; } public String getEscapedComponentName() { return componentName; } public String getUnescapedComponentName() { return URIStringUtils.unescape(getEscapedComponentName()); } // "child:path#compositeName#componentName#guid" public static DiagramComponentInfo parse(String tgName) { String name = tgName.substring(CHILD_PREFIX.length()); String compositePathAndName = ""; String moduleName = name; GUID guid = GUID.invalid(); int lastHash = name.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR); if(lastHash >= 0) { String first = name.substring(0, lastHash); String second = name.substring(lastHash+1); lastHash = first.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR); if(lastHash >= 0) { compositePathAndName = first.substring(0, lastHash); moduleName = first.substring(lastHash+1); guid = GUID.parseIndexString(second); } else { compositePathAndName = first; moduleName = second; } } return new DiagramComponentInfo(compositePathAndName, moduleName, guid); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((compositePathAndName == null) ? 0 : compositePathAndName.hashCode()); result = prime * result + ((componentName == null) ? 0 : componentName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DiagramComponentInfo other = (DiagramComponentInfo) obj; if (compositePathAndName == null) { if (other.compositePathAndName != null) return false; } else if (!compositePathAndName.equals(other.compositePathAndName)) return false; if (componentName == null) { if (other.componentName != null) return false; } else if (!componentName.equals(other.componentName)) return false; return true; } } public static class CompositeInfo { public static String COMPOSITE_PREFIX = "composite:"; final private boolean useGuids; final private boolean applyPaths; final private String path; final private String name; final private GUID guid; private CompositeInfo(boolean useGuids, boolean applyPaths, String path, String name, GUID guid) { this.useGuids = useGuids; this.applyPaths = applyPaths; this.path = path; this.name = name; this.guid = guid; } @Override public String toString() { return "CompositeInfo[useGuids=" + useGuids + ", applyPaths=" + applyPaths + ", path=" + path + ", name=" + name + ", guid=" + guid.indexString() + "]"; } public static boolean isComposite(String tgName) { return tgName.startsWith(COMPOSITE_PREFIX); } public String getTGName() { return COMPOSITE_PREFIX + getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString(); } public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException { Collection res = ModelingUtils.searchByGUID(graph, indexRoot, guid); return !res.isEmpty(); } public static CompositeInfo fromResource(ReadGraph graph, Resource resource) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); GUID rootId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING); String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING); String escapedRootName = URIStringUtils.escape(rootName); String escapedPath = ModelingUtils.getDiagramCompositePath(graph, resource); return new CompositeInfo(true, true, escapedPath, escapedRootName, rootId); } public static CompositeInfo parse(String tgName) { return parse(tgName, true, true); } /* * Index 0 is root-relative folder path separated with '/' or null if target-relative positioning is used * Index 1 is diagram name */ public static CompositeInfo parse(String tgName, boolean applyPaths, boolean useGuids) { if(!tgName.startsWith(COMPOSITE_PREFIX)) return null; tgName = tgName.substring(COMPOSITE_PREFIX.length()); if(!tgName.contains(COMPOSITE_SEPARATOR)) { if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams."); return new CompositeInfo(useGuids, applyPaths, null, tgName, null); } String[] parts = tgName.split(COMPOSITE_SEPARATOR); if(parts.length == 2) { String name = parts[1]; String path = applyPaths ? parts[0] : null; if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams."); return new CompositeInfo(useGuids, applyPaths, path, name, null); } else if(parts.length == 3) { String path = parts[0]; String name = parts[1]; GUID guid = GUID.parseIndexString(parts[2]); return new CompositeInfo(useGuids, applyPaths, path, name, guid); } else { return null; } } public GUID getGUID() { return guid; } public String getEscapedName() { return name; } public String getUnescapedName() { return URIStringUtils.unescape(name); } public String getOriginalPath() { return path; } public String getFinalPath() { if(applyPaths) return path; else return null; } public CompositeInfo renamed(String newName) { return new CompositeInfo(useGuids, applyPaths, path, newName, guid); } public String getStateKey() { return path + "#" + getEscapedName(); } private Resource getFromFolder(ReadGraph graph, Resource target) throws DatabaseException { Resource diagram = Layer0Utils.getPossibleChild(graph, target, URIStringUtils.unescape(name)); if(diagram == null) return null; StructuralResource2 STR = StructuralResource2.getInstance(graph); return graph.isInstanceOf(diagram, STR.Composite) ? diagram : null; } public Resource resolve(ReadGraph graph, Resource target) throws DatabaseException { if(useGuids && guid != null) { Resource indexRoot = graph.syncRequest(new IndexRoot(target)); Collection queryResult = searchByGUID(graph, indexRoot, guid); if(queryResult.size() == 1) { Resource composite = queryResult.iterator().next(); StructuralResource2 STR = StructuralResource2.getInstance(graph); if(!graph.isInstanceOf(composite, STR.Composite)) return null; return composite; } } if(applyPaths) { Resource folder = resolveFolder(graph, target); if(folder == null) return null; return getFromFolder(graph, folder); } else { return getFromFolder(graph, target); } } public Resource resolveFolder(ReadGraph graph, Resource target) throws DatabaseException { String path = getFinalPath(); if(path == null) return target; Resource folder = graph.syncRequest(new Configuration(target)); String[] segments = path.split("/"); for(int i=0;i 0) sb.append(URIStringUtils.NAMESPACE_PATH_SEPARATOR); sb.append( URIStringUtils.escape(name) ); return sb; } /** * @param graph * @param diagram * @return diagram/folder path up until model configuration root with each * segment escaped using {@link URIStringUtils#escape(String)} and * {@value URIStringUtils#NAMESPACE_PATH_SEPARATOR} between each * segment or null if the specified diagram composite * is not part of any model configuration structure. * @throws DatabaseException */ public static String getDiagramCompositePath(ReadGraph graph, Resource diagram) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource parent = graph.getPossibleObject(diagram, L0.PartOf); if(parent == null) return null; StringBuilder sb = getDiagramCompositePathInternal(graph, parent, new StringBuilder()); return sb != null ? sb.toString() : null; } public static void exportModel(ReadGraph graph, Resource model, String fileName, String format, int version) throws DatabaseException { try { TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model, true, false); TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); TransferableGraphs.writeTransferableGraph(graph, format, version, s, new File(fileName)); } catch (Exception e) { throw new DatabaseException(e); } } public static void exportSharedOntology(ReadGraph graph, Resource library, String fileName, String format, int version) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); String name = graph.getRelatedValue(library, L0.HasName, Bindings.STRING); DraftStatusBean draft = null; boolean published = Layer0Utils.isPublished(graph, library); if(!published) draft = new DraftStatusBean(new String[0]); LibraryInfo info = new LibraryInfo(name, library, draft); try { exportSharedOntology(new NullProgressMonitor(), graph, new File(fileName), format, version, info); } catch (IOException e) { throw new DatabaseException(e); } } public static DraftStatusBean getDependencyDraftStatus(ReadGraph graph, Resource library) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); List drafts = new ArrayList<>(); for (Resource shared : graph.syncRequest(new ObjectsWithType(library, L0.IsLinkedTo, L0.SharedOntology))) { boolean published = Layer0Utils.isPublished(graph, shared); if (!published) drafts.add(graph.getURI(shared)); } return drafts.isEmpty() ? null : new DraftStatusBean(drafts); } public static Set getMostUnspecificTypes(final ReadGraph graph, Collection types) throws DatabaseException { final Set work = new HashSet(types); for(Resource type : types) { Set supers = graph.getSupertypes(type); if(!Collections.disjoint(supers, work)) work.remove(type); } return work; } public static void rewriteGUIDS(WriteGraph graph, Resource root, boolean deep) throws DatabaseException { List todo = new ArrayList(); todo.add(root); Layer0 L0 = Layer0.getInstance(graph); while(!todo.isEmpty()) { Resource resource = todo.remove(todo.size()-1); graph.claimLiteral(resource, L0.identifier, L0.GUID, GUID.random(), GUID.BINDING); if(deep) todo.addAll(graph.getObjects(resource, L0.ConsistsOf)); } } public static void createMissingGUIDs(IProgressMonitor monitor, WriteGraph graph, Collection roots) throws DatabaseException { if(monitor == null) monitor = new NullProgressMonitor(); Layer0 L0 = Layer0.getInstance(graph); // Allow this process to make 50k queries QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000); for(Resource root : roots) { boolean madeChanges = false; monitor.setTaskName("Creating missing GUID identifiers " + NameUtils.getSafeName(graph, root)); Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(root)); for(Resource r : searchByType(graph, indexRoot, L0.Entity)) { memory.maintain(); if(graph.isImmutable(r)) continue; if(!ModelingUtils.needsIdentifier(graph, r)) continue; GUID existing = graph.getPossibleRelatedValue(r, L0.identifier, GUID.BINDING); if(existing == null) { graph.addLiteral(r, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING); madeChanges = true; } } if(madeChanges) ModelingUtils.deleteIndex(graph, root); } } public static boolean activateModel(WriteGraph graph, Resource model) throws DatabaseException { return graph.syncRequest(new ActivateModel(Simantics.getProjectResource(), model)); } public static File fileDialog(String title, List namesAndExtensions) { Display display = Display.getCurrent(); Shell shell = display.getActiveShell(); FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setText(title); String[] extensions = new String[namesAndExtensions.size()]; String[] filterNames = new String[namesAndExtensions.size()]; int index = 0; for(Tuple t : namesAndExtensions) { String filterName = (String)t.get(0); String extension = (String)t.get(1); filterNames[index] = filterName; extensions[index] = extension; } dialog.setFilterExtensions(extensions); dialog.setFilterNames(filterNames); final String fileName = dialog.open(); if (fileName == null) return null; return new File(fileName); } public static Resource createLibrary(WriteGraph graph, Resource parent) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); return createLibrary(graph, parent, NameUtils.findFreshName(graph, "Library", parent, l0.ConsistsOf)); } public static Resource createLibrary(WriteGraph graph, Resource parent, String name) throws DatabaseException { graph.markUndoPoint(); Layer0 l0 = Layer0.getInstance(graph); Resource library = graph.newResource(); graph.claim(library, l0.InstanceOf, null, l0.Library); graph.addLiteral(library, l0.HasName, l0.NameOf, l0.String, name, Bindings.STRING); graph.claim(library, l0.PartOf, parent); Layer0Utils.addCommentMetadata(graph, "Created new Library named " + name + ", resource " + library); return library; } }