DiagramToBusinessObjectTreeConverter.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.ge.internal.diagram.runtime.updating;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.osate.ge.RelativeBusinessObjectReference;
import org.osate.ge.internal.diagram.runtime.AgeDiagram;
import org.osate.ge.internal.diagram.runtime.DiagramElement;
import org.osate.ge.internal.diagram.runtime.DiagramNode;
import org.osate.ge.internal.model.EmbeddedBusinessObject;
/**
* Utility class which builds a business object tree from an AgeDiagram
* The nodes generated by this class will not have their business object fields set. They should be processed by a {@link BusinessObjectTreeUpdater}
* to set the business object.
*/
public final class DiagramToBusinessObjectTreeConverter {
/**
* Private constructor to prevent instantiation.
*/
private DiagramToBusinessObjectTreeConverter() {
}
/**
* Creates a new business object tree from the specified diagram.
* @param diagram the diagram from which to create the business object tree
* @return the new business object tree
* @see #createBusinessObjectNode(AgeDiagram, Map, Map)
*/
public static BusinessObjectNode createBusinessObjectNode(final AgeDiagram diagram) {
return createBusinessObjectNode(diagram, Collections.emptyMap(), Collections.emptyMap());
}
/**
* Creates a new business object tree from the specified diagram.
* @param diagram the diagram from which to create the business object tree
* @param futureElementInfoMap a mapping from parent {@link DiagramNode} objects to a map containing information about elements which should be created.
* @param containerToRelativeReferenceToGhostMap a mapping from parent {@link DiagramNode} objects to a map containing ghost diagram elements.
* @return the new tree.
*/
public static BusinessObjectNode createBusinessObjectNode(final AgeDiagram diagram,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, FutureElementInfo>> futureElementInfoMap,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, DiagramElement>> containerToRelativeReferenceToGhostMap) {
final BusinessObjectNode rootNode = new BusinessObjectNode(null, UUID.randomUUID(), null, null,
Completeness.UNKNOWN,
true);
createBusinessObjectNodesForElements(rootNode, diagram.getChildren(), futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
createBusinessObjectNodesForGhostedElements(rootNode, diagram, futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
createBusinessObjectNodesForFutureElements(rootNode, diagram, futureElementInfoMap);
return rootNode;
}
private static void createBusinessObjectNodesForElements(final BusinessObjectNode parent,
final Collection<DiagramElement> elements,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, FutureElementInfo>> futureElementInfoMap,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, DiagramElement>> containerToRelativeReferenceToGhostMap) {
for(final DiagramElement e : elements) {
createBusinessObjectNodesForElements(parent, e, futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
}
}
private static void createBusinessObjectNodesForElements(final BusinessObjectNode parent,
final DiagramElement e,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, FutureElementInfo>> futureElementInfoMap,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, DiagramElement>> containerToRelativeReferenceToGhostMap) {
// For embedded business objects, store the object in the business object node.
// Typically, the business object node isn't stored in the business object node to prevent retaining references
// to old business objects.
final Object bo = e.getBusinessObject() instanceof EmbeddedBusinessObject ? e.getBusinessObject() : null;
// Don't keep the business object when building the business object tree. This will ensure that tree expander or other user of the tree updates
// the business object based on the model.
final BusinessObjectNode childNode = new BusinessObjectNode(parent, e.getId(), e.getRelativeReference(), bo,
Completeness.UNKNOWN, true);
createBusinessObjectNodesForElements(childNode, e.getChildren(), futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
createBusinessObjectNodesForGhostedElements(childNode, e, futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
createBusinessObjectNodesForFutureElements(childNode, e, futureElementInfoMap);
}
private static void createBusinessObjectNodesForGhostedElements(final BusinessObjectNode parent,
final DiagramNode diagramNode,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, FutureElementInfo>> futureElementInfoMap,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, DiagramElement>> containerToRelativeReferenceToGhostMap) {
final Map<RelativeBusinessObjectReference, DiagramElement> ghostedElements = containerToRelativeReferenceToGhostMap.get(diagramNode);
if(ghostedElements != null) {
for(final DiagramElement ghostedElement : ghostedElements.values()) {
// Don't create a node if a node has already been created for the relative reference.
if (parent.getChild(ghostedElement.getRelativeReference()) == null) {
createBusinessObjectNodesForElements(parent, ghostedElement, futureElementInfoMap,
containerToRelativeReferenceToGhostMap);
}
}
}
}
private static void createBusinessObjectNodesForFutureElements(final BusinessObjectNode parent,
final DiagramNode diagramNode,
final Map<DiagramNode, Map<RelativeBusinessObjectReference, FutureElementInfo>> futureElementInfoMap) {
final Map<RelativeBusinessObjectReference, FutureElementInfo> futureElements = futureElementInfoMap
.get(diagramNode);
if(futureElements != null) {
for (final Entry<RelativeBusinessObjectReference, FutureElementInfo> futureElementEntry : futureElements
.entrySet()) {
// An incomplete node is created. The tree expander will fill in missing fields.
final RelativeBusinessObjectReference ref = futureElementEntry.getKey();
if (parent.getChild(ref) == null) {
new BusinessObjectNode(parent, UUID.randomUUID(), ref, futureElementEntry.getValue().embeddedBo,
Completeness.UNKNOWN, false);
}
}
}
}
}