1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling.typicals;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
20 import java.util.concurrent.Semaphore;
21 import java.util.concurrent.atomic.AtomicReference;
22 import java.util.function.Consumer;
24 import org.simantics.NameLabelMode;
25 import org.simantics.NameLabelUtil;
26 import org.simantics.Simantics;
27 import org.simantics.databoard.Bindings;
28 import org.simantics.db.ReadGraph;
29 import org.simantics.db.RequestProcessor;
30 import org.simantics.db.Resource;
31 import org.simantics.db.WriteGraph;
32 import org.simantics.db.WriteOnlyGraph;
33 import org.simantics.db.common.CommentMetadata;
34 import org.simantics.db.common.NamedResource;
35 import org.simantics.db.common.request.FreshName;
36 import org.simantics.db.common.request.ObjectsWithType;
37 import org.simantics.db.common.request.PossibleIndexRoot;
38 import org.simantics.db.common.request.UniqueRead;
39 import org.simantics.db.common.request.WriteResultRequest;
40 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
41 import org.simantics.db.common.utils.CommonDBUtils;
42 import org.simantics.db.common.utils.NameUtils;
43 import org.simantics.db.exception.DatabaseException;
44 import org.simantics.db.exception.RuntimeDatabaseException;
45 import org.simantics.db.layer0.adapter.CopyHandler;
46 import org.simantics.db.layer0.adapter.Instances;
47 import org.simantics.db.layer0.request.Configuration;
48 import org.simantics.db.layer0.request.PossibleModel;
49 import org.simantics.db.layer0.util.ClipboardUtils;
50 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
51 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
52 import org.simantics.db.layer0.util.SimanticsKeys;
53 import org.simantics.db.layer0.variable.Variable;
54 import org.simantics.db.layer0.variable.Variables;
55 import org.simantics.db.procedure.Procedure;
56 import org.simantics.db.request.WriteResult;
57 import org.simantics.diagram.stubs.DiagramResource;
58 import org.simantics.graph.db.IImportAdvisor;
59 import org.simantics.graph.db.TransferableGraphs;
60 import org.simantics.graph.representation.Root;
61 import org.simantics.graph.representation.TransferableGraph1;
62 import org.simantics.layer0.Layer0;
63 import org.simantics.modeling.ModelingResources;
64 import org.simantics.modeling.ModelingUtils.CompositeInfo;
65 import org.simantics.modeling.ModelingUtils.DiagramComponentInfo;
66 import org.simantics.modeling.services.ComponentNamingUtil;
67 import org.simantics.modeling.services.NamingException;
68 import org.simantics.operation.Layer0X;
69 import org.simantics.scl.runtime.function.Function2;
70 import org.simantics.scl.runtime.function.Function4;
71 import org.simantics.structural.stubs.StructuralResource2;
72 import org.simantics.structural2.utils.StructuralUtils;
73 import org.simantics.ui.SimanticsUI;
74 import org.simantics.utils.datastructures.Pair;
75 import org.simantics.utils.ui.dialogs.ShowMessage;
78 * @author Tuukka Lehtonen
80 public class TypicalUtil {
82 private static final boolean DEBUG = false;
84 private static class TypicalNamingFunction implements Function2<ReadGraph, Resource, String> {
85 private NameLabelMode mode;
88 public String apply(ReadGraph graph, Resource r) {
91 mode = NameLabelUtil.getNameLabelMode(graph);
92 Variable v = Variables.getPossibleVariable(graph, r);
94 Resource root = Variables.getPossibleIndexRoot(graph, v);
96 Variable rootV = Variables.getVariable(graph, root);
97 List<Variable> path = Variables.getPath(graph, rootV, v);
99 return typicalLabel(graph, v, path);
102 return TypicalUtil.getName(graph, r);
103 } catch (DatabaseException e) {
104 throw new RuntimeDatabaseException(e);
108 protected String typicalLabel(ReadGraph graph, Variable v, List<Variable> path) throws DatabaseException {
109 StringBuilder sb = new StringBuilder();
110 labelVariable(graph, v, sb);
111 if (path.size() > 0) {
113 for (Variable vv : path) {
115 labelVariable(graph, vv, sb);
119 return sb.toString();
122 protected StringBuilder labelVariable(ReadGraph graph, Variable v, StringBuilder result) throws DatabaseException {
123 Resource r = v.getPossibleRepresents(graph);
125 result.append(NameLabelUtil.modalName(graph, r, mode));
127 result.append(NameLabelUtil.modalName(graph, v, mode));
133 public static List<NamedResource> toNamedResources(RequestProcessor processor, final Collection<Resource> rs) throws DatabaseException {
134 return toNamedResources(processor, rs, new TypicalNamingFunction());
137 public static List<NamedResource> toNamedResources(RequestProcessor processor, final Collection<Resource> rs, final Function2<ReadGraph, Resource, String> namingFunction) throws DatabaseException {
138 return processor.syncRequest(new UniqueRead<List<NamedResource>>() {
140 public List<NamedResource> perform(ReadGraph graph) throws DatabaseException {
141 return toNamedResources(graph, rs, namingFunction);
146 public static List<NamedResource> toNamedResources(ReadGraph graph, Collection<Resource> rs, final Function2<ReadGraph, Resource, String> namingFunction) throws DatabaseException {
147 List<NamedResource> result = new ArrayList<>(rs.size());
148 for (Resource r : rs)
149 result.add(new NamedResource(namingFunction.apply(graph, r), r));
153 public static String getName(ReadGraph graph, Resource r) throws DatabaseException {
154 String s = graph.getPossibleAdapter(r, String.class);
156 s = NameUtils.getSafeLabel(graph, r);
160 public static WriteResult<Resource> instantiateTemplate(
162 NamedResource template,
163 Consumer<Pair<WriteGraph, Resource>> successContinuation)
165 return new WriteResultRequest<Resource>() {
167 public Resource perform(WriteGraph graph) throws DatabaseException {
168 // Custom instantiation by copying the original and mapping the original to the copy
169 CommonDBUtils.selectClusterSet(graph, target);
170 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
171 CopyHandler ch = new TypicalCompositeCopyHandler(template.getResource());
172 ch.copyToClipboard(graph, clipboard);
174 Map<String,Object> hints = Collections.singletonMap(ClipboardUtils.HINT_TARGET_RESOURCE, target);
176 for (Set<Representation> object : clipboard.getContents()) {
177 TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH, hints);
179 DiagramPasteImportAdvisor advisor = new DiagramPasteImportAdvisor(graph, target, template.getName());
180 TransferableGraphs.importGraph1(graph, tg, advisor);
181 Resource copy = advisor.getRoot();
183 configureCopyType(graph, copy, template.getResource());
184 associateCopyToTemplate(graph, copy, template.getResource());
186 if (successContinuation!= null)
187 successContinuation.accept(Pair.make(graph, copy));
192 throw new DatabaseException("Failed to instantiate typical template through clipboard");
197 public static void configureCopyType(WriteGraph graph, Resource copy, Resource template) throws DatabaseException {
198 // Remove master template instance tag type(s)
199 Layer0 L0 = Layer0.getInstance(graph);
200 DiagramResource DIA = DiagramResource.getInstance(graph);
201 ModelingResources MOD = ModelingResources.getInstance(graph);
202 for (Resource type : graph.getObjects(template, L0.InstanceOf)) {
203 if (graph.isInheritedFrom(type, MOD.MasterTypicalCompositeType))
204 graph.deny(copy, L0.InstanceOf, type);
206 graph.claim(copy, L0.InstanceOf, null, type);
208 for (Resource templateDiagram : graph.getObjects(template, MOD.CompositeToDiagram)) {
209 Resource templateDiagramType = graph.getPossibleType(templateDiagram, DIA.Diagram);
210 if (templateDiagramType != null) {
211 for (Resource copiedDiagram : graph.getObjects(copy, MOD.CompositeToDiagram)) {
212 graph.claim(copiedDiagram, L0.InstanceOf, null, templateDiagramType);
218 public static void associateCopyToTemplate(WriteGraph graph, Resource copy, Resource template) throws DatabaseException {
219 DiagramResource DIA = DiagramResource.getInstance(graph);
220 ModelingResources MOD = ModelingResources.getInstance(graph);
221 Resource templateDiagram = graph.getSingleObject(template, MOD.CompositeToDiagram);
222 Resource copyDiagram = graph.getSingleObject(copy, MOD.CompositeToDiagram);
223 Map<String, Resource> templateDiagramElements = graph.syncRequest(new UnescapedChildMapOfResource(templateDiagram));
224 Map<String, Resource> copyDiagramElements = graph.syncRequest(new UnescapedChildMapOfResource(copyDiagram));
226 // Associations are intentionally bi-directional
227 graph.claim(copyDiagram, MOD.HasDiagramSource, MOD.DiagramHasInstance, templateDiagram);
228 for (String element : templateDiagramElements.keySet()) {
229 Resource templateElement = templateDiagramElements.get(element);
230 if (!graph.isInstanceOf(templateElement, DIA.Element))
232 Resource copyElement = copyDiagramElements.get(element);
233 graph.claim(copyElement, MOD.HasElementSource, MOD.ElementHasInstance, templateElement);
234 graph.claim(copyElement, MOD.IsTemplatized, MOD.IsTemplatized, copyElement);
237 Long modCount = graph.getPossibleRelatedValue(copyDiagram, DIA.HasModCount);
238 if (modCount == null)
240 modCount += 1L << 32;
241 graph.claimLiteral(copyDiagram, DiagramResource.getInstance(graph).HasModCount, modCount, Bindings.LONG);
246 * @param typicalCompositeInstance
247 * @param excludedComponents the set of components in the specified
248 * composite that are not freshly renamed or <code>null</code> to
249 * freshly name all components
250 * @throws DatabaseException
252 public static void generateFreshModuleNames(WriteGraph graph, Resource typicalCompositeInstance, Set<Resource> excludedComponents) throws DatabaseException {
253 Layer0 L0 = Layer0.getInstance(graph);
254 StructuralResource2 STR = StructuralResource2.getInstance(graph);
255 Resource configurationRoot = graph.sync(new Configuration(typicalCompositeInstance));
256 for(Map.Entry<String, Resource> entry : graph.syncRequest(new UnescapedChildMapOfResource(typicalCompositeInstance)).entrySet()) {
257 Resource component = entry.getValue();
258 if (!graph.isInstanceOf(component, STR.Component))
260 if (excludedComponents != null && excludedComponents.contains(component))
263 String renamed = ComponentNamingUtil.findFreshInstanceName(graph, SimanticsUI.getProject(), configurationRoot, typicalCompositeInstance, component);
265 System.out.println("Typicals: renamed " + entry.getKey() + " -> " + renamed);
266 graph.claimLiteral(entry.getValue(), L0.HasName, L0.NameOf, renamed, Bindings.STRING);
267 } catch (NamingException e) {
268 throw new DatabaseException(e);
273 public static class DiagramPasteImportAdvisor implements IImportAdvisor {
275 protected final Resource library;
276 protected final Resource model;
277 protected Resource diagram;
278 protected final String diagramName;
280 public DiagramPasteImportAdvisor(ReadGraph graph, Resource library, String originalName) throws DatabaseException {
281 this.library = library;
283 this.diagramName = graph.syncRequest(new FreshName(library, originalName));
284 this.model = graph.syncRequest(new PossibleModel(library));
287 public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {
291 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
292 if("%model".equals(root.name)) return model;
296 public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {
298 Layer0 l0 = graph.getService(Layer0.class);
299 if(CompositeInfo.isComposite(root.name)) {
300 // Use existing if available
301 if(diagram == null) diagram = graph.newResource();
302 graph.claim(library, l0.ConsistsOf, l0.PartOf, diagram);
303 graph.newClusterSet(diagram);
304 graph.setClusterSet4NewResource(diagram);
305 graph.addLiteral(diagram, l0.HasName, l0.NameOf, l0.String, diagramName, Bindings.STRING);
307 } else if (DiagramComponentInfo.isDiagramComponent(root.name)) {
308 DiagramComponentInfo info = DiagramComponentInfo.parse(root.name);
309 Resource child = graph.newResource();
310 graph.addLiteral(child, l0.HasName, l0.NameOf, l0.String, info.getUnescapedComponentName(), Bindings.STRING);
313 throw new DatabaseException("Unclassified root " + root.name);
318 public Resource getRoot() {
326 * @param typicalInstanceComposite
327 * @param renamedComponentsOutput a set that can be provided to get the set
328 * of components that was renamed as output from this method or
329 * <code>null</code> to not collect renamed components
330 * @throws DatabaseException
332 public static void applyTypicalModuleNames(WriteGraph graph, Resource typicalInstanceComposite, Set<Resource> renamedComponentsOutput) throws DatabaseException {
334 Layer0 L0 = Layer0.getInstance(graph);
335 StructuralResource2 STR = StructuralResource2.getInstance(graph);
337 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = getTypicalNamingFunction(graph, typicalInstanceComposite);
338 if (nameEvaluator == null)
341 Collection<Resource> components = graph.syncRequest(new ObjectsWithType(typicalInstanceComposite, L0.ConsistsOf, STR.Component));
342 for (Resource component : components) {
343 applyTypicalModuleName(graph, component, nameEvaluator, renamedComponentsOutput);
348 public static boolean applyTypicalModuleName(WriteGraph graph, Resource instanceComponent, Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator, Set<Resource> renamedComponentsOutput) throws DatabaseException {
350 Layer0 L0 = Layer0.getInstance(graph);
351 StructuralResource2 STR = StructuralResource2.getInstance(graph);
352 ModelingResources MOD = ModelingResources.getInstance(graph);
354 Resource componentType = graph.getPossibleType(instanceComponent, STR.Component);
355 if (componentType == null)
358 Resource instanceElement = graph.getPossibleObject(instanceComponent, MOD.ComponentToElement);
359 if (instanceElement == null)
362 Resource templateElement = graph.getPossibleObject(instanceElement, MOD.HasElementSource);
363 if (templateElement == null)
366 Resource templateComponent = graph.getPossibleObject(templateElement, MOD.ElementToComponent);
367 if (templateComponent == null)
370 // TODO: Use variables and EXPRESSION property instead ?
371 String nameExpression = graph.getPossibleRelatedValue(templateComponent, L0.HasName, Bindings.STRING);
372 if (nameExpression == null)
375 Resource instanceComposite = graph.getPossibleObject(instanceComponent, L0.PartOf);
376 if (instanceComposite == null)
379 // This evaluator replaces % with assigned primary position name
380 String evaluatedInstanceName = (String) nameEvaluator.apply(graph, instanceComposite, instanceComponent, nameExpression);
381 if(evaluatedInstanceName == null)
384 String instanceName = graph.getPossibleRelatedValue(instanceComponent, L0.HasName, Bindings.STRING);
385 if(instanceName == null)
388 if(!evaluatedInstanceName.equals(instanceName)) {
390 graph.claimLiteral(instanceComponent, L0.HasName, evaluatedInstanceName, Bindings.STRING);
391 if (renamedComponentsOutput != null)
392 renamedComponentsOutput.add(instanceComponent);
395 System.out.println("TypicalUtil.applyTypicalModuleName: applied name expression " + nameExpression + " -> " + instanceName + " -> " + evaluatedInstanceName);
407 * @param typicalComposite
408 * @param componentsToCheck the set of components to check for required
410 * @throws DatabaseException
412 public static void applySelectedModuleNames(WriteGraph graph, Resource typicalComposite, List<Resource> componentsToCheck) throws DatabaseException {
413 Layer0 L0 = Layer0.getInstance(graph);
414 StructuralResource2 STR = StructuralResource2.getInstance(graph);
415 ModelingResources MOD = ModelingResources.getInstance(graph);
417 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = getTypicalNamingFunction(graph, typicalComposite);
418 if (nameEvaluator == null)
421 for (Resource component : componentsToCheck) {
422 Resource componentType = graph.getPossibleType(component, STR.Component);
423 if (componentType == null)
426 Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);
430 Resource templateElement = graph.getPossibleObject(element, MOD.HasElementSource);
431 if (templateElement == null)
434 Resource templateComponent = graph.getPossibleObject(templateElement, MOD.ElementToComponent);
435 if (templateComponent == null)
438 String nameExpression = graph.getPossibleRelatedValue(templateComponent, L0.HasName, Bindings.STRING);
439 if (nameExpression == null)
442 // NOTE: This assumes that nameEvaluator also makes sure that the
443 // evaluated names do not collide with any existing names in the
445 String evaluatedInstanceName = (String) nameEvaluator.apply(graph, typicalComposite, component, nameExpression);
446 if (evaluatedInstanceName != null && !evaluatedInstanceName.equals(nameExpression)) {
448 System.out.println("TypicalUtil.applySelectionModuleNames: applied name expression " + nameExpression + " -> " + evaluatedInstanceName);
449 graph.claimLiteral(component, L0.HasName, evaluatedInstanceName, Bindings.STRING);
456 * @param typicalComposite
457 * @return f :: ReadGraph -> Resource composite -> Resource component -> String expression -> String name
458 * @throws DatabaseException
460 public static Function4<ReadGraph, Resource, Resource, String, String> getTypicalNamingFunction(ReadGraph graph, Resource typicalComposite) throws DatabaseException {
461 ModelingResources MOD = ModelingResources.getInstance(graph);
462 Function4<ReadGraph, Resource, Resource, String, String> nameEvaluator = graph.getPossibleRelatedValue2(typicalComposite, MOD.TypicalComposite_typicalNamingFunction);
463 return nameEvaluator;
470 * @throws DatabaseException
472 public static Collection<Resource> findModelTypicals(RequestProcessor processor, final Resource model) throws DatabaseException {
473 return processor.syncRequest(new UniqueRead<Collection<Resource>>() {
475 public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
476 ModelingResources MOD = ModelingResources.getInstance(graph);
477 Resource typicalMasterType = graph.getSingleObject(model, MOD.StructuralModel_HasMasterTypicalCompositeType);
478 Instances query = graph.adapt(typicalMasterType, Instances.class);
479 return query.find(graph, model);
485 * A utility for synchronous execution of asynchronous procedures.
486 * @param runnable the callback that contains asynchronous execution
487 * @return the result received from the specified callback
488 * @throws DatabaseException
490 public static <T> T syncExec(Consumer<Procedure<T>> runnable) throws DatabaseException {
491 final AtomicReference<T> ref = new AtomicReference<T>();
492 final AtomicReference<Throwable> exc = new AtomicReference<Throwable>();
493 final Semaphore sem = new Semaphore(0);
494 runnable.accept(new Procedure<T>() {
496 public void execute(T result) {
497 if (ref.compareAndSet(null, result))
501 public void exception(Throwable t) {
502 if (exc.compareAndSet(null, t))
508 Throwable t = exc.get();
510 if (t instanceof DatabaseException)
511 throw (DatabaseException) t;
512 throw new DatabaseException(t);
514 return (T) ref.get();
515 } catch (InterruptedException ex) {
516 throw new DatabaseException(ex);
523 public static void syncTypicalInstance(WriteGraph graph, Resource instance) throws DatabaseException {
524 SyncTypicalTemplatesToInstances sync = SyncTypicalTemplatesToInstances.syncSingleInstance(null, instance);
529 * Creates a new master typical diagram and its corresponding composites.
532 * The created typical composite and diagram type are specified by the model
533 * using {@link ModelingResources#StructuralModel_HasTypicalCompositeBaseType}
534 * and {@link ModelingResources#StructuralModel_HasTypicalDiagramBaseType}.
537 * Marks the created master composite with the model-specified master composite
538 * type to support searching. The master type is specified by the model using
539 * {@link ModelingResources#StructuralModel_HasMasterTypicalCompositeType}.
542 * Clones symbol contributions from the sources specified by the model through
543 * {@link ModelingResources#StructuralModel_CloneTypicalDiagramSymbolContributionsFrom}
546 * @author Tuukka Lehtonen
549 public static Resource newMasterTypical(final Resource target) throws DatabaseException {
551 return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
554 public Resource perform(WriteGraph graph) throws DatabaseException {
555 Layer0 L0 = Layer0.getInstance(graph);
556 Layer0X L0X = Layer0X.getInstance(graph);
557 DiagramResource DIA = DiagramResource.getInstance(graph);
558 ModelingResources MOD = ModelingResources.getInstance(graph);
560 Resource indexRoot = graph.sync(new PossibleIndexRoot(target));
561 if (indexRoot == null) {
562 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.");
566 Resource compositeBaseType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasTypicalCompositeBaseType);
567 Resource diagramBaseType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasTypicalDiagramBaseType);
568 Resource masterCompositeType = graph.getPossibleObject(indexRoot, MOD.StructuralModel_HasMasterTypicalCompositeType);
569 Collection<Resource> cloneSymbolContributionsFrom = graph.getObjects(indexRoot, MOD.StructuralModel_CloneTypicalDiagramSymbolContributionsFrom);
570 if (compositeBaseType == null || diagramBaseType == null || masterCompositeType == null) {
571 ShowMessage.showInformation("No Typical Support", "Creation of typical diagrams is not supported for this container.");
575 Resource compositeType = graph.newResource();
576 graph.claim(compositeType, L0.Inherits, compositeBaseType);
577 String compositeTypeName = NameUtils.findFreshName(graph, "TypicalCompositeType", target);
578 graph.claimLiteral(compositeType, L0.HasName, compositeTypeName);
580 Resource diagramType = graph.newResource();
581 graph.claim(diagramType, L0.Inherits, diagramBaseType);
582 graph.claimLiteral(diagramType, L0.HasName, "Type");
584 String name = NameUtils.findFreshName(graph, "Typical", target, L0.ConsistsOf, "%s%d");
586 Resource composite = StructuralUtils.newComponent(graph, target, name + "@1", compositeType);
587 graph.claim(composite, L0.InstanceOf, null, masterCompositeType);
589 Resource diagram = graph.newResource();
590 graph.claim(diagram, L0.InstanceOf, null, diagramType);
591 graph.claimLiteral(diagram, L0.HasName, "__DIAGRAM__", Bindings.STRING);
592 graph.claim(diagram, L0.SubrelationOf, null, L0.HasNext);
593 graph.claim(diagram, MOD.DiagramToComposite, composite);
594 Resource diagramInv = graph.newResource();
595 graph.claim(diagramInv, L0.InverseOf, diagram);
596 graph.claim(diagramInv, L0.SubrelationOf, null, L0.HasPrevious);
597 graph.claimLiteral(diagramInv, L0.HasName, "Inverse", Bindings.STRING);
598 graph.claim(diagram, L0.ConsistsOf, diagramInv);
599 graph.claim(diagram, diagram, diagramInv, diagram);
601 Resource mapping = graph.newResource();
602 graph.claim(diagram, L0X.HasTrigger, mapping);
603 graph.claim(mapping, L0.InstanceOf, null, MOD.DiagramToCompositeMapping);
605 // Make diagram part of a dummy container entity attached to the parent
606 // composite if it's not already part of something.
607 Resource container = graph.newResource();
608 graph.claim(container, L0.InstanceOf, null, DIA.DiagramContainer);
609 graph.addLiteral(container, L0.HasName, L0.NameOf, L0.String, "__CONTAINER__", Bindings.STRING);
611 // Compose all created resources into the following hierarchy:
612 // Typical Composite : TypicalCompositeType
613 // Typical Composite Type : STR.CompositeType
614 // __CONTAINER__ : DIA.DiagramContainer
615 // "__DIAGRAM__" : "Type"
616 // "Type" <T DIA.Diagram
617 graph.claim(diagram, L0.ConsistsOf, diagramType);
618 graph.claim(container, L0.ConsistsOf, diagram);
619 graph.claim(composite, L0.ConsistsOf, container);
620 graph.claim(composite, L0.ConsistsOf, compositeType);
622 // Attach the same symbol contributions to the created typical
623 // diagram type as are attached to the model-designated
624 // contribution source diagram type.
625 boolean clonedIndexRootContribution = false;
626 for (Resource symbolContributionSource : cloneSymbolContributionsFrom) {
627 for (Resource contribution : graph.getObjects(symbolContributionSource, DIA.HasSymbolContribution)) {
628 graph.claim(diagramType, DIA.HasSymbolContribution, contribution);
629 clonedIndexRootContribution |= graph.isInstanceOf(contribution, DIA.IndexRootSymbolContribution);
633 if (!clonedIndexRootContribution) {
634 Resource indexContribution = graph.newResource();
635 graph.claim(indexContribution, L0.InstanceOf, DIA.IndexRootSymbolContribution);
636 graph.claim(diagramType, DIA.HasSymbolContribution, indexContribution);
639 // Add comment to change set.
640 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
641 graph.addMetadata(cm.add("Created typical master diagram " + composite));