1 /*******************************************************************************
\r
2 * Copyright (c) 2012 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.typicals;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collection;
\r
16 import java.util.Collections;
\r
17 import java.util.List;
\r
18 import java.util.Map;
\r
19 import java.util.Set;
\r
20 import java.util.concurrent.Semaphore;
\r
21 import java.util.concurrent.atomic.AtomicReference;
\r
22 import java.util.function.Consumer;
\r
24 import org.simantics.NameLabelMode;
\r
25 import org.simantics.NameLabelUtil;
\r
26 import org.simantics.Simantics;
\r
27 import org.simantics.databoard.Bindings;
\r
28 import org.simantics.db.ReadGraph;
\r
29 import org.simantics.db.RequestProcessor;
\r
30 import org.simantics.db.Resource;
\r
31 import org.simantics.db.WriteGraph;
\r
32 import org.simantics.db.WriteOnlyGraph;
\r
33 import org.simantics.db.common.CommentMetadata;
\r
34 import org.simantics.db.common.NamedResource;
\r
35 import org.simantics.db.common.request.FreshName;
\r
36 import org.simantics.db.common.request.ObjectsWithType;
\r
37 import org.simantics.db.common.request.PossibleIndexRoot;
\r
38 import org.simantics.db.common.request.UniqueRead;
\r
39 import org.simantics.db.common.request.WriteResultRequest;
\r
40 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
\r
41 import org.simantics.db.common.utils.CommonDBUtils;
\r
42 import org.simantics.db.common.utils.NameUtils;
\r
43 import org.simantics.db.exception.DatabaseException;
\r
44 import org.simantics.db.exception.RuntimeDatabaseException;
\r
45 import org.simantics.db.layer0.adapter.CopyHandler;
\r
46 import org.simantics.db.layer0.adapter.Instances;
\r
47 import org.simantics.db.layer0.request.Configuration;
\r
48 import org.simantics.db.layer0.request.PossibleModel;
\r
49 import org.simantics.db.layer0.util.ClipboardUtils;
\r
50 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
\r
51 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
\r
52 import org.simantics.db.layer0.util.SimanticsKeys;
\r
53 import org.simantics.db.layer0.variable.Variable;
\r
54 import org.simantics.db.layer0.variable.Variables;
\r
55 import org.simantics.db.procedure.Procedure;
\r
56 import org.simantics.db.request.WriteResult;
\r
57 import org.simantics.diagram.stubs.DiagramResource;
\r
58 import org.simantics.graph.db.IImportAdvisor;
\r
59 import org.simantics.graph.db.TransferableGraphs;
\r
60 import org.simantics.graph.representation.Root;
\r
61 import org.simantics.graph.representation.TransferableGraph1;
\r
62 import org.simantics.layer0.Layer0;
\r
63 import org.simantics.modeling.ModelingResources;
\r
64 import org.simantics.modeling.ModelingUtils.CompositeInfo;
\r
65 import org.simantics.modeling.ModelingUtils.DiagramComponentInfo;
\r
66 import org.simantics.modeling.services.ComponentNamingUtil;
\r
67 import org.simantics.modeling.services.NamingException;
\r
68 import org.simantics.operation.Layer0X;
\r
69 import org.simantics.scl.runtime.function.Function2;
\r
70 import org.simantics.scl.runtime.function.Function4;
\r
71 import org.simantics.structural.stubs.StructuralResource2;
\r
72 import org.simantics.structural2.utils.StructuralUtils;
\r
73 import org.simantics.ui.SimanticsUI;
\r
74 import org.simantics.utils.datastructures.Pair;
\r
75 import org.simantics.utils.ui.dialogs.ShowMessage;
\r
78 * @author Tuukka Lehtonen
\r
80 public class TypicalUtil {
\r
82 private static final boolean DEBUG = false;
\r
84 private static class TypicalNamingFunction implements Function2<ReadGraph, Resource, String> {
\r
85 private NameLabelMode mode;
\r
88 public String apply(ReadGraph graph, Resource r) {
\r
91 mode = NameLabelUtil.getNameLabelMode(graph);
\r
92 Variable v = Variables.getPossibleVariable(graph, r);
\r
94 Resource root = Variables.getPossibleIndexRoot(graph, v);
\r
96 Variable rootV = Variables.getVariable(graph, root);
\r
97 List<Variable> path = Variables.getPath(graph, rootV, v);
\r
99 return typicalLabel(graph, v, path);
\r
102 return TypicalUtil.getName(graph, r);
\r
103 } catch (DatabaseException e) {
\r
104 throw new RuntimeDatabaseException(e);
\r
108 protected String typicalLabel(ReadGraph graph, Variable v, List<Variable> path) throws DatabaseException {
\r
109 StringBuilder sb = new StringBuilder();
\r
110 labelVariable(graph, v, sb);
\r
111 if (path.size() > 0) {
\r
113 for (Variable vv : path) {
\r
115 labelVariable(graph, vv, sb);
\r
119 return sb.toString();
\r
122 protected StringBuilder labelVariable(ReadGraph graph, Variable v, StringBuilder result) throws DatabaseException {
\r
123 Resource r = v.getPossibleRepresents(graph);
\r
125 result.append(NameLabelUtil.modalName(graph, r, mode));
\r
127 result.append(NameLabelUtil.modalName(graph, v, mode));
\r
133 public static Collection<NamedResource> toNamedResources(RequestProcessor processor, final Collection<Resource> rs) throws DatabaseException {
\r
134 return toNamedResources(processor, rs, new TypicalNamingFunction());
\r
137 public static Collection<NamedResource> toNamedResources(RequestProcessor processor, final Collection<Resource> rs, final Function2<ReadGraph, Resource, String> namingFunction) throws DatabaseException {
\r
138 return processor.syncRequest(new UniqueRead<Collection<NamedResource>>() {
\r
140 public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {
\r
141 return toNamedResources(graph, rs, namingFunction);
\r
146 public static Collection<NamedResource> toNamedResources(ReadGraph graph, Collection<Resource> rs, final Function2<ReadGraph, Resource, String> namingFunction) throws DatabaseException {
\r
147 Collection<NamedResource> result = new ArrayList<NamedResource>(rs.size());
\r
148 for (Resource r : rs)
\r
149 result.add(new NamedResource(namingFunction.apply(graph, r), r));
\r
153 public static String getName(ReadGraph graph, Resource r) throws DatabaseException {
\r
154 String s = graph.getPossibleAdapter(r, String.class);
\r
156 s = NameUtils.getSafeLabel(graph, r);
\r
160 public static WriteResult<Resource> instantiateTemplate(final Resource target, final NamedResource template,
\r
161 final Consumer<Pair<WriteGraph, Resource>> successContinuation) {
\r
162 return new WriteResultRequest<Resource>() {
\r
164 public Resource perform(WriteGraph graph) throws DatabaseException {
\r
165 // Custom instantiation by copying the original and mapping the original to the copy
\r
166 CommonDBUtils.selectClusterSet(graph, target);
\r
167 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
\r
168 CopyHandler ch = new TypicalCompositeCopyHandler(template.getResource());
\r
169 ch.copyToClipboard(graph, clipboard);
\r
171 Map<String,Object> hints = Collections.singletonMap(ClipboardUtils.HINT_TARGET_RESOURCE, target);
\r
173 for (Set<Representation> object : clipboard.getContents()) {
\r
174 TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH, hints);
\r
176 DiagramPasteImportAdvisor advisor = new DiagramPasteImportAdvisor(graph, target, template.getName());
\r
177 TransferableGraphs.importGraph1(graph, tg, advisor);
\r
178 Resource copy = advisor.getRoot();
\r
180 configureCopyType(graph, copy, template.getResource());
\r
181 associateCopyToTemplate(graph, copy, template.getResource());
\r
183 if (successContinuation!= null)
\r
184 successContinuation.accept(Pair.make(graph, copy));
\r
189 throw new DatabaseException("Failed to instantiate typical template through clipboard");
\r
194 public static void configureCopyType(WriteGraph graph, Resource copy, Resource template) throws DatabaseException {
\r
195 // Remove master template instance tag type(s)
\r
196 Layer0 L0 = Layer0.getInstance(graph);
\r
197 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
198 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
199 for (Resource type : graph.getObjects(template, L0.InstanceOf)) {
\r
200 if (graph.isInheritedFrom(type, MOD.MasterTypicalCompositeType))
\r
201 graph.deny(copy, L0.InstanceOf, type);
\r
203 graph.claim(copy, L0.InstanceOf, null, type);
\r
205 for (Resource templateDiagram : graph.getObjects(template, MOD.CompositeToDiagram)) {
\r
206 Resource templateDiagramType = graph.getPossibleType(templateDiagram, DIA.Diagram);
\r
207 if (templateDiagramType != null) {
\r
208 for (Resource copiedDiagram : graph.getObjects(copy, MOD.CompositeToDiagram)) {
\r
209 graph.claim(copiedDiagram, L0.InstanceOf, null, templateDiagramType);
\r
215 public static void associateCopyToTemplate(WriteGraph graph, Resource copy, Resource template) throws DatabaseException {
\r
216 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
217 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
218 Resource templateDiagram = graph.getSingleObject(template, MOD.CompositeToDiagram);
\r
219 Resource copyDiagram = graph.getSingleObject(copy, MOD.CompositeToDiagram);
\r
220 Map<String, Resource> templateDiagramElements = graph.syncRequest(new UnescapedChildMapOfResource(templateDiagram));
\r
221 Map<String, Resource> copyDiagramElements = graph.syncRequest(new UnescapedChildMapOfResource(copyDiagram));
\r
223 // Associations are intentionally bi-directional
\r
224 graph.claim(copyDiagram, MOD.HasDiagramSource, MOD.DiagramHasInstance, templateDiagram);
\r
225 for (String element : templateDiagramElements.keySet()) {
\r
226 Resource templateElement = templateDiagramElements.get(element);
\r
227 if (!graph.isInstanceOf(templateElement, DIA.Element))
\r
229 Resource copyElement = copyDiagramElements.get(element);
\r
230 graph.claim(copyElement, MOD.HasElementSource, MOD.ElementHasInstance, templateElement);
\r
231 graph.claim(copyElement, MOD.IsTemplatized, MOD.IsTemplatized, copyElement);
\r
234 Long modCount = graph.getPossibleRelatedValue(copyDiagram, DIA.HasModCount);
\r
235 if (modCount == null)
\r
237 modCount += 1L << 32;
\r
238 graph.claimLiteral(copyDiagram, DiagramResource.getInstance(graph).HasModCount, modCount, Bindings.LONG);
\r
243 * @param typicalCompositeInstance
\r
244 * @param excludedComponents the set of components in the specified
\r
245 * composite that are not freshly renamed or <code>null</code> to
\r
246 * freshly name all components
\r
247 * @throws DatabaseException
\r
249 public static void generateFreshModuleNames(WriteGraph graph, Resource typicalCompositeInstance, Set<Resource> excludedComponents) throws DatabaseException {
\r
250 Layer0 L0 = Layer0.getInstance(graph);
\r
251 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
252 Resource configurationRoot = graph.sync(new Configuration(typicalCompositeInstance));
\r
253 for(Map.Entry<String, Resource> entry : graph.syncRequest(new UnescapedChildMapOfResource(typicalCompositeInstance)).entrySet()) {
\r
254 Resource component = entry.getValue();
\r
255 if (!graph.isInstanceOf(component, STR.Component))
\r
257 if (excludedComponents != null && excludedComponents.contains(component))
\r
260 String renamed = ComponentNamingUtil.findFreshInstanceName(graph, SimanticsUI.getProject(), configurationRoot, typicalCompositeInstance, component);
\r
262 System.out.println("Typicals: renamed " + entry.getKey() + " -> " + renamed);
\r
263 graph.claimLiteral(entry.getValue(), L0.HasName, L0.NameOf, renamed, Bindings.STRING);
\r
264 } catch (NamingException e) {
\r
265 throw new DatabaseException(e);
\r
270 public static class DiagramPasteImportAdvisor implements IImportAdvisor {
\r
272 protected final Resource library;
\r
273 protected final Resource model;
\r
274 protected Resource diagram;
\r
275 protected final String diagramName;
\r
277 public DiagramPasteImportAdvisor(ReadGraph graph, Resource library, String originalName) throws DatabaseException {
\r
278 this.library = library;
\r
279 this.diagram = null;
\r
280 this.diagramName = graph.syncRequest(new FreshName(library, originalName));
\r
281 this.model = graph.syncRequest(new PossibleModel(library));
\r
284 public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {
\r
288 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
\r
289 if("%model".equals(root.name)) return model;
\r
293 public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {
\r
295 Layer0 l0 = graph.getService(Layer0.class);
\r
296 if(CompositeInfo.isComposite(root.name)) {
\r
297 // Use existing if available
\r
298 if(diagram == null) diagram = graph.newResource();
\r
299 graph.claim(library, l0.ConsistsOf, l0.PartOf, diagram);
\r
300 graph.newClusterSet(diagram);
\r
301 graph.setClusterSet4NewResource(diagram);
\r
302 graph.addLiteral(diagram, l0.HasName, l0.NameOf, l0.String, diagramName, Bindings.STRING);
\r
304 } else if (DiagramComponentInfo.isDiagramComponent(root.name)) {
\r
305 DiagramComponentInfo info = DiagramComponentInfo.parse(root.name);
\r
306 Resource child = graph.newResource();
\r
307 graph.addLiteral(child, l0.HasName, l0.NameOf, l0.String, info.getUnescapedComponentName(), Bindings.STRING);
\r
310 throw new DatabaseException("Unclassified root " + root.name);
\r
315 public Resource getRoot() {
\r
323 * @param typicalInstanceComposite
\r
324 * @param renamedComponentsOutput a set that can be provided to get the set
\r
325 * of components that was renamed as output from this method or
\r
326 * <code>null</code> to not collect renamed components
\r
327 * @throws DatabaseException
\r
329 public static void applyTypicalModuleNames(WriteGraph graph, Resource typicalInstanceComposite, Set<Resource> renamedComponentsOutput) throws DatabaseException {
\r
331 Layer0 L0 = Layer0.getInstance(graph);
\r
332 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
334 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = getTypicalNamingFunction(graph, typicalInstanceComposite);
\r
335 if (nameEvaluator == null)
\r
338 Collection<Resource> components = graph.syncRequest(new ObjectsWithType(typicalInstanceComposite, L0.ConsistsOf, STR.Component));
\r
339 for (Resource component : components) {
\r
340 applyTypicalModuleName(graph, component, nameEvaluator, renamedComponentsOutput);
\r
345 public static boolean applyTypicalModuleName(WriteGraph graph, Resource instanceComponent, Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator, Set<Resource> renamedComponentsOutput) throws DatabaseException {
\r
347 Layer0 L0 = Layer0.getInstance(graph);
\r
348 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
349 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
351 Resource componentType = graph.getPossibleType(instanceComponent, STR.Component);
\r
352 if (componentType == null)
\r
355 Resource instanceElement = graph.getPossibleObject(instanceComponent, MOD.ComponentToElement);
\r
356 if (instanceElement == null)
\r
359 Resource templateElement = graph.getPossibleObject(instanceElement, MOD.HasElementSource);
\r
360 if (templateElement == null)
\r
363 Resource templateComponent = graph.getPossibleObject(templateElement, MOD.ElementToComponent);
\r
364 if (templateComponent == null)
\r
367 // TODO: Use variables and EXPRESSION property instead ?
\r
368 String nameExpression = graph.getPossibleRelatedValue(templateComponent, L0.HasName, Bindings.STRING);
\r
369 if (nameExpression == null)
\r
372 Resource instanceComposite = graph.getPossibleObject(instanceComponent, L0.PartOf);
\r
373 if (instanceComposite == null)
\r
376 // This evaluator replaces % with assigned primary position name
\r
377 String evaluatedInstanceName = (String) nameEvaluator.apply(graph, instanceComposite, instanceComponent, nameExpression);
\r
378 if(evaluatedInstanceName == null)
\r
381 String instanceName = graph.getPossibleRelatedValue(instanceComponent, L0.HasName, Bindings.STRING);
\r
382 if(instanceName == null)
\r
385 if(!evaluatedInstanceName.equals(instanceName)) {
\r
387 graph.claimLiteral(instanceComponent, L0.HasName, evaluatedInstanceName, Bindings.STRING);
\r
388 if (renamedComponentsOutput != null)
\r
389 renamedComponentsOutput.add(instanceComponent);
\r
392 System.out.println("TypicalUtil.applyTypicalModuleName: applied name expression " + nameExpression + " -> " + instanceName + " -> " + evaluatedInstanceName);
\r
404 * @param typicalComposite
\r
405 * @param componentsToCheck the set of components to check for required
\r
407 * @throws DatabaseException
\r
409 public static void applySelectedModuleNames(WriteGraph graph, Resource typicalComposite, List<Resource> componentsToCheck) throws DatabaseException {
\r
410 Layer0 L0 = Layer0.getInstance(graph);
\r
411 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
412 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
414 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = getTypicalNamingFunction(graph, typicalComposite);
\r
415 if (nameEvaluator == null)
\r
418 for (Resource component : componentsToCheck) {
\r
419 Resource componentType = graph.getPossibleType(component, STR.Component);
\r
420 if (componentType == null)
\r
423 Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);
\r
424 if (element == null)
\r
427 Resource templateElement = graph.getPossibleObject(element, MOD.HasElementSource);
\r
428 if (templateElement == null)
\r
431 Resource templateComponent = graph.getPossibleObject(templateElement, MOD.ElementToComponent);
\r
432 if (templateComponent == null)
\r
435 String nameExpression = graph.getPossibleRelatedValue(templateComponent, L0.HasName, Bindings.STRING);
\r
436 if (nameExpression == null)
\r
439 // NOTE: This assumes that nameEvaluator also makes sure that the
\r
440 // evaluated names do not collide with any existing names in the
\r
442 String evaluatedInstanceName = (String) nameEvaluator.apply(graph, typicalComposite, component, nameExpression);
\r
443 if (evaluatedInstanceName != null && !evaluatedInstanceName.equals(nameExpression)) {
\r
445 System.out.println("TypicalUtil.applySelectionModuleNames: applied name expression " + nameExpression + " -> " + evaluatedInstanceName);
\r
446 graph.claimLiteral(component, L0.HasName, evaluatedInstanceName, Bindings.STRING);
\r
453 * @param typicalComposite
\r
454 * @return f :: ReadGraph -> Resource composite -> Resource component -> String expression -> String name
\r
455 * @throws DatabaseException
\r
457 public static Function4<ReadGraph, Resource, Resource, String, String> getTypicalNamingFunction(ReadGraph graph, Resource typicalComposite) throws DatabaseException {
\r
458 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
459 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = graph.getPossibleRelatedValue2(typicalComposite, MOD.TypicalComposite_typicalNamingFunction);
\r
460 return nameEvaluator;
\r
467 * @throws DatabaseException
\r
469 public static Collection<Resource> findModelTypicals(RequestProcessor processor, final Resource model) throws DatabaseException {
\r
470 return processor.syncRequest(new UniqueRead<Collection<Resource>>() {
\r
472 public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
\r
473 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
474 Resource typicalMasterType = graph.getSingleObject(model, MOD.StructuralModel_HasMasterTypicalCompositeType);
\r
475 Instances query = graph.adapt(typicalMasterType, Instances.class);
\r
476 return query.find(graph, model);
\r
482 * A utility for synchronous execution of asynchronous procedures.
\r
483 * @param runnable the callback that contains asynchronous execution
\r
484 * @return the result received from the specified callback
\r
485 * @throws DatabaseException
\r
487 public static <T> T syncExec(Consumer<Procedure<T>> runnable) throws DatabaseException {
\r
488 final AtomicReference<T> ref = new AtomicReference<T>();
\r
489 final AtomicReference<Throwable> exc = new AtomicReference<Throwable>();
\r
490 final Semaphore sem = new Semaphore(0);
\r
491 runnable.accept(new Procedure<T>() {
\r
493 public void execute(T result) {
\r
494 if (ref.compareAndSet(null, result))
\r
498 public void exception(Throwable t) {
\r
499 if (exc.compareAndSet(null, t))
\r
505 Throwable t = exc.get();
\r
507 if (t instanceof DatabaseException)
\r
508 throw (DatabaseException) t;
\r
509 throw new DatabaseException(t);
\r
511 return (T) ref.get();
\r
512 } catch (InterruptedException ex) {
\r
513 throw new DatabaseException(ex);
\r
520 public static void syncTypicalInstance(WriteGraph graph, Resource instance) throws DatabaseException {
\r
521 SyncTypicalTemplatesToInstances sync = SyncTypicalTemplatesToInstances.syncSingleInstance(null, instance);
\r
522 sync.perform(graph);
\r
526 * Creates a new master typical diagram and its corresponding composites.
\r
529 * The created typical composite and diagram type are specified by the model
\r
530 * using {@link ModelingResources#StructuralModel_HasTypicalCompositeBaseType}
\r
531 * and {@link ModelingResources#StructuralModel_HasTypicalDiagramBaseType}.
\r
534 * Marks the created master composite with the model-specified master composite
\r
535 * type to support searching. The master type is specified by the model using
\r
536 * {@link ModelingResources#StructuralModel_HasMasterTypicalCompositeType}.
\r
539 * Clones symbol contributions from the sources specified by the model through
\r
540 * {@link ModelingResources#StructuralModel_CloneTypicalDiagramSymbolContributionsFrom}
\r
543 * @author Tuukka Lehtonen
\r
546 public static Resource newMasterTypical(final Resource target) throws DatabaseException {
\r
548 return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
\r
551 public Resource perform(WriteGraph graph) throws DatabaseException {
\r
552 Layer0 L0 = Layer0.getInstance(graph);
\r
553 Layer0X L0X = Layer0X.getInstance(graph);
\r
554 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
555 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
557 Resource indexRoot = graph.sync(new PossibleIndexRoot(target));
\r
558 if (indexRoot == null) {
\r
559 ShowMessage.showInformation("No Model or Shared Library", "Cannot find a containing model or shared library from the input selection. Typical master diagram creation not possible.");
\r
563 Resource compositeBaseType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasTypicalCompositeBaseType);
\r
564 Resource diagramBaseType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasTypicalDiagramBaseType);
\r
565 Resource masterCompositeType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasMasterTypicalCompositeType);
\r
566 Collection<Resource> cloneSymbolContributionsFrom = graph.getObjects(indexRoot, MOD.StructuralModel_CloneTypicalDiagramSymbolContributionsFrom);
\r
567 if (compositeBaseType == null || diagramBaseType == null || masterCompositeType == null) {
\r
568 ShowMessage.showInformation("No Typical Support", "Creation of typical diagrams is not supported for this container.");
\r
572 Resource compositeType = graph.newResource();
\r
573 graph.claim(compositeType, L0.Inherits, compositeBaseType);
\r
574 String compositeTypeName = NameUtils.findFreshName(graph, "TypicalCompositeType", target);
\r
575 graph.claimLiteral(compositeType, L0.HasName, compositeTypeName);
\r
577 Resource diagramType = graph.newResource();
\r
578 graph.claim(diagramType, L0.Inherits, diagramBaseType);
\r
579 graph.claimLiteral(diagramType, L0.HasName, "Type");
\r
581 String name = NameUtils.findFreshName(graph, "Typical", target, L0.ConsistsOf, "%s%d");
\r
583 Resource composite = StructuralUtils.newComponent(graph, target, name + "@1", compositeType);
\r
584 graph.claim(composite, L0.InstanceOf, null, masterCompositeType);
\r
586 Resource diagram = graph.newResource();
\r
587 graph.claim(diagram, L0.InstanceOf, null, diagramType);
\r
588 graph.claimLiteral(diagram, L0.HasName, "__DIAGRAM__", Bindings.STRING);
\r
589 graph.claim(diagram, L0.SubrelationOf, null, L0.HasNext);
\r
590 graph.claim(diagram, MOD.DiagramToComposite, composite);
\r
591 Resource diagramInv = graph.newResource();
\r
592 graph.claim(diagramInv, L0.InverseOf, diagram);
\r
593 graph.claim(diagramInv, L0.SubrelationOf, null, L0.HasPrevious);
\r
594 graph.claimLiteral(diagramInv, L0.HasName, "Inverse", Bindings.STRING);
\r
595 graph.claim(diagram, L0.ConsistsOf, diagramInv);
\r
596 graph.claim(diagram, diagram, diagramInv, diagram);
\r
598 Resource mapping = graph.newResource();
\r
599 graph.claim(diagram, L0X.HasTrigger, mapping);
\r
600 graph.claim(mapping, L0.InstanceOf, null, MOD.DiagramToCompositeMapping);
\r
602 // Make diagram part of a dummy container entity attached to the parent
\r
603 // composite if it's not already part of something.
\r
604 Resource container = graph.newResource();
\r
605 graph.claim(container, L0.InstanceOf, null, DIA.DiagramContainer);
\r
606 graph.addLiteral(container, L0.HasName, L0.NameOf, L0.String, "__CONTAINER__", Bindings.STRING);
\r
608 // Compose all created resources into the following hierarchy:
\r
609 // Typical Composite : TypicalCompositeType
\r
610 // Typical Composite Type : STR.CompositeType
\r
611 // __CONTAINER__ : DIA.DiagramContainer
\r
612 // "__DIAGRAM__" : "Type"
\r
613 // "Type" <T DIA.Diagram
\r
614 graph.claim(diagram, L0.ConsistsOf, diagramType);
\r
615 graph.claim(container, L0.ConsistsOf, diagram);
\r
616 graph.claim(composite, L0.ConsistsOf, container);
\r
617 graph.claim(composite, L0.ConsistsOf, compositeType);
\r
619 // Attach the same symbol contributions to the created typical
\r
620 // diagram type as are attached to the model-designated
\r
621 // contribution source diagram type.
\r
622 for (Resource symbolContributionSource : cloneSymbolContributionsFrom) {
\r
623 for (Resource contribution : graph.getObjects(symbolContributionSource, DIA.HasSymbolContribution)) {
\r
624 graph.claim(diagramType, DIA.HasSymbolContribution, contribution);
\r
628 Resource indexContribution = graph.newResource();
\r
629 graph.claim(indexContribution, L0.InstanceOf, DIA.IndexRootSymbolContribution);
\r
630 graph.claim(diagramType, DIA.HasSymbolContribution, indexContribution);
\r
632 // Add comment to change set.
\r
633 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
\r
634 graph.addMetadata(cm.add("Created typical master diagram " + composite));
\r