use of org.osate.aadl2.EndToEndFlowSegment in project osate2 by osate.
the class AadlFlowSpecificationUtil method createFlowSegmentReference.
public static FlowSegmentReference createFlowSegmentReference(final Object bo, final BusinessObjectContext container) {
if (bo instanceof FlowSegment) {
final FlowSegment flowSegment = (FlowSegment) bo;
final FlowElement flowElement = flowSegment.getFlowElement();
if (flowSegment.getContext() == null) {
return createFlowSegmentReference(flowElement, container);
} else {
return container.getChildren().stream().filter(child -> {
if (child.getBusinessObject() instanceof NamedElement) {
final NamedElement ne = (NamedElement) child.getBusinessObject();
return AgeAadlUtil.getRootRefinedElement(ne) == AgeAadlUtil.getRootRefinedElement(flowSegment.getContext());
}
return false;
}).findAny().map(contextQueryable -> createFlowSegmentReference(flowElement, contextQueryable)).orElse(null);
}
} else if (bo instanceof EndToEndFlowSegment) {
final EndToEndFlowSegment flowSegment = (EndToEndFlowSegment) bo;
final FlowElement flowElement = (FlowElement) flowSegment.getFlowElement();
if (flowSegment.getContext() == null) {
return createFlowSegmentReference(flowElement, container);
} else {
return container.getChildren().stream().filter(child -> {
if (child.getBusinessObject() instanceof NamedElement) {
final NamedElement ne = (NamedElement) child.getBusinessObject();
return AgeAadlUtil.getRootRefinedElement(ne) == AgeAadlUtil.getRootRefinedElement(flowSegment.getContext());
}
return false;
}).findAny().map(contextQueryable -> createFlowSegmentReference(flowElement, contextQueryable)).orElse(null);
}
} else if (bo instanceof InstanceObject) {
final InstanceObject io = (InstanceObject) bo;
if (bo instanceof EndToEndFlowInstance) {
return new FlowSegmentReference(io, container);
} else {
return container.getAllDescendants().filter(q -> q.getBusinessObject() == io).findAny().map(q -> new FlowSegmentReference(io, q.getParent())).orElse(null);
}
} else if (bo instanceof FlowImplementation) {
final FlowImplementation fi = (FlowImplementation) bo;
return new FlowSegmentReference(fi, container);
} else if (bo instanceof NamedElement) {
return new FlowSegmentReference((NamedElement) bo, container);
} else {
throw new RuntimeException("Unexpected business object: " + bo);
}
}
use of org.osate.aadl2.EndToEndFlowSegment in project osate2 by osate.
the class CreateEndToEndFlowsSwitch method processFlowStep.
protected void processFlowStep(ComponentInstance ci, EndToEndFlowInstance etei, Element leaf, FlowImplementation nextFlowImpl, FlowIterator iter) {
// add connection(s), will be empty when starting the ETE
if (connections.isEmpty()) {
addLeafElement(ci, etei, leaf);
lastFlowImpl.push(nextFlowImpl);
continueFlow(ci.getContainingComponentInstance(), etei, iter, ci);
lastFlowImpl.pop();
} else {
List<ConnectionInstance> connis = collectConnectionInstances(ci, etei);
if (connis.isEmpty()) {
connections.clear();
removeETEI.add(etei);
if (!lastFlowImpl.isEmpty()) {
FlowImplementation flowFilter = lastFlowImpl.peek();
if (flowFilter != null) {
/* [**] See note below. */
error(etei.getContainingComponentInstance(), "Cannot create end to end flow '" + etei.getName() + "' because there are no semantic connections that continue the flow '" + flowFilter.getSpecification().getName() + "' from feature '" + flowFilter.getOutEnd().getFeature().getName() + "'");
}
}
} else {
FlowImplementation flowFilter = lastFlowImpl.isEmpty() ? null : lastFlowImpl.peek();
/*
* Issue 1984: isValidContinuation() should be used purely as a filter, and not as an error
* reporter. We need to make a first pass through the connection instances and determine which
* ones are applicable to the current flow. Only if NONE of them are, do we report an error.
* Otherwise, we use the subset of applicable connection instances and continue on normally.
*/
final List<ConnectionInstance> connectionsToUse = new ArrayList<>();
for (final ConnectionInstance ciToCheck : connis) {
if ((flowFilter == null || isValidContinuation(etei, flowFilter, ciToCheck)) && (nextFlowImpl == null ? (leaf instanceof FlowSpecification ? isValidContinuation(etei, ciToCheck, (FlowSpecification) leaf) : true) : isValidContinuation(etei, ciToCheck, nextFlowImpl))) {
connectionsToUse.add(ciToCheck);
}
}
if (connectionsToUse.isEmpty()) {
/*
* I originally thought that this case couldn't happen, but I've been proven wrong. This happens when the
* connections inside a component implementation completely bypass the flow implementation. That is, the
* flow implies one path, but the actual connections in the implementation make a different one.
*
* This error is the opposite of the case above [**].
*/
if (flowFilter == null && nextFlowImpl == null) {
final FlowSpecification flowSpec = (FlowSpecification) leaf;
error(etei.getContainingComponentInstance(), "Cannot create end to end flow '" + etei.getName() + "' because there are no semantic connections that connect to the start of the flow '" + flowSpec.getName() + "' at feature '" + flowSpec.getAllInEnd().getFeature().getName() + "'");
} else {
final FlowImplementation ff = flowFilter == null ? nextFlowImpl : flowFilter;
error(etei.getContainingComponentInstance(), "Cannot create end to end flow '" + etei.getName() + "' because there are no semantic connections that connect to the start of the flow '" + ff.getSpecification().getName() + "' at feature '" + ff.getInEnd().getFeature().getName() + "'");
}
connections.clear();
removeETEI.add(etei);
} else {
// continue the flow along each eligible connection instance
Iterator<ConnectionInstance> connIter = connectionsToUse.iterator();
while (connIter.hasNext()) {
final ConnectionInstance conni = connIter.next();
final boolean prepareNext = connIter.hasNext();
EndToEndFlowInstance eteiClone = null;
Stack<FlowIterator> stateClone = null;
FlowIterator iterClone = null;
lastFlowImpl.push(nextFlowImpl);
if (prepareNext) {
stateClone = clone(state);
eteiClone = EcoreUtil.copy(etei);
iterClone = iter.clone();
eteiClone.getModesList().addAll(etei.getModesList());
}
etei.getFlowElements().add(conni);
addLeafElement(ci, etei, leaf);
// prepare next connection filter
connections.clear();
if (iter.hasNext()) {
Element obj = iter.next();
Connection conn = null;
if (obj instanceof FlowSegment) {
FlowElement fe = ((FlowSegment) obj).getFlowElement();
if (fe instanceof Connection) {
conn = (Connection) fe;
}
} else if (obj instanceof EndToEndFlowSegment) {
EndToEndFlowElement fe = ((EndToEndFlowSegment) obj).getFlowElement();
if (fe instanceof Connection) {
conn = (Connection) fe;
}
}
if (conn != null) {
connections.add(conn);
}
}
continueFlow(ci.getContainingComponentInstance(), etei, iter, ci);
lastFlowImpl.pop();
if (prepareNext) {
// add clone
etei.getContainingComponentInstance().getEndToEndFlows().add(eteiClone);
etei = eteiClone;
state = stateClone;
iter = iterClone;
addETEI.add(etei);
if (etei.getFlowElements() == null || etei.getFlowElements().isEmpty()) {
created.add(myInfo = new ETEInfo(etei));
} else {
created.add(myInfo = new ETEInfo(myInfo.preConns, etei));
}
}
}
}
}
}
}
use of org.osate.aadl2.EndToEndFlowSegment in project osate2 by osate.
the class Aadl2LinkingService method doGetLinkedObjects.
private List<EObject> doGetLinkedObjects(EObject context, EReference reference, INode node) throws IllegalNodeException {
NamedElement annex = AadlUtil.getContainingAnnex(context);
if (annex != null && !(reference == Aadl2Package.eINSTANCE.getModalElement_InMode())) {
String annexName = annex.getName();
if (annexName != null) {
if (annexlinkingserviceregistry == null) {
initAnnexLinkingServiceRegistry();
}
if (annexlinkingserviceregistry != null) {
AnnexLinkingService linkingservice = annexlinkingserviceregistry.getAnnexLinkingService(annexName);
if (linkingservice != null) {
return linkingservice.resolveAnnexReference(annexName, context, reference, node);
}
}
}
return Collections.<EObject>emptyList();
}
final EClass requiredType = reference.getEReferenceType();
if (requiredType == null) {
return Collections.<EObject>emptyList();
}
Aadl2Package.eINSTANCE.getPropertyType();
final EClass cl = Aadl2Package.eINSTANCE.getClassifier();
final EClass sct = Aadl2Package.eINSTANCE.getSubcomponentType();
final String name = getCrossRefNodeAsString(node);
if (sct.isSuperTypeOf(requiredType) || cl.isSuperTypeOf(requiredType)) {
// XXX: this code can be replicated in Aadl2LinkingService as it is called often in the core
// resolve classifier reference
EObject e = findClassifier(context, reference, name);
if (e != null) {
// the result satisfied the expected class
return Collections.singletonList(e);
}
if (!(context instanceof Generalization) && sct.isSuperTypeOf(requiredType)) {
// need to resolve prototype
Classifier containingClassifier = AadlUtil.getContainingClassifier(context);
/*
* This test was put here as a quick and dirty fix to a NullPointerException that was
* being thrown while typing up a component type renames statement. Need to figure out
* what we should really be doing for renames.
*/
if (containingClassifier != null) {
EObject res = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (Aadl2Package.eINSTANCE.getDataPrototype() == reference) {
if (res instanceof DataPrototype) {
return Collections.singletonList(res);
}
} else if (res instanceof ComponentPrototype) {
return Collections.singletonList(res);
}
}
}
return Collections.emptyList();
} else if (Aadl2Package.eINSTANCE.getFeatureClassifier().isSuperTypeOf(requiredType)) {
// prototype for feature or component, or data,bus,subprogram, subprogram group classifier
EObject e = findClassifier(context, reference, name);
if (Aadl2Util.isNull(e) && !(context instanceof Generalization) && !Aadl2Package.eINSTANCE.getComponentType().isSuperTypeOf(requiredType)) {
// look for prototype
e = AadlUtil.getContainingClassifier(context).findNamedElement(name);
// TODO-phf: this can be removed if the FeatureClassifier class handles it
if (!(e instanceof FeaturePrototype || e instanceof ComponentPrototype)) {
e = null;
}
}
if (e != null && requiredType.isSuperTypeOf(e.eClass())) {
return Collections.singletonList(e);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getFeaturePrototype() == requiredType) {
// look for prototype
EObject e = AadlUtil.getContainingClassifier(context).findNamedElement(name);
// TODO-phf: this can be removed if the FeatureClassifier class handles it
if (e instanceof FeaturePrototype) {
return Collections.singletonList(e);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getConnectionEnd() == requiredType) {
// resolve connection end
ConnectionEnd ce = null;
if (context.eContainer() instanceof ConnectedElement) {
ConnectedElement contextParent = (ConnectedElement) context.eContainer();
if (contextParent.getConnectionEnd() instanceof FeatureGroup) {
ce = findElementInContext(contextParent, (FeatureGroup) contextParent.getConnectionEnd(), name, ConnectionEnd.class);
}
} else {
ConnectedElement connectedElement = (ConnectedElement) context;
ce = findElementInContext(connectedElement, connectedElement.getContext(), name, ConnectionEnd.class);
}
if (ce != null) {
return Collections.singletonList((EObject) ce);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getTriggerPort() == requiredType) {
if (context instanceof ModeTransitionTrigger) {
ModeTransitionTrigger trigger = (ModeTransitionTrigger) context;
TriggerPort triggerPort = findElementInContext(trigger, trigger.getContext(), name, TriggerPort.class);
if (triggerPort != null) {
return Collections.singletonList((EObject) triggerPort);
}
}
return Collections.emptyList();
} else if (Aadl2Package.eINSTANCE.getPort().isSuperTypeOf(requiredType)) {
Classifier ns = AadlUtil.getContainingClassifier(context);
if (context instanceof Feature) {
// component being extended
if (ns.getExtended() != null) {
ns = ns.getExtended();
} else {
return Collections.emptyList();
}
// } else if (context instanceof ModeTransitionTrigger){
// // we are a mode transition trigger
// Context triggerContext = ((ModeTransitionTrigger)context).getContext();
// if (triggerContext instanceof Subcomponent){
// // look up the feature in the ComponentType
// ComponentType ct = ((Subcomponent)triggerContext).getComponentType();
// if (ct != null)
// ns = ct;
// }
// if (triggerContext instanceof FeatureGroup){
// // look up the feature in the FeaturegroupType
// FeatureGroupType ct = ((FeatureGroup)triggerContext).getFeatureGroupType();
// if (ct != null)
// ns = ct;
// }
}
EObject searchResult = AadlUtil.findNamedElementInList(ns.getAllFeatures(), name);
if (searchResult != null && searchResult instanceof Port) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getContext() == requiredType) {
// represents connection source/dest context as well as flowspec
// context
// also used in triggerport
EObject searchResult = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (searchResult instanceof Context) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getCallContext() == requiredType) {
EObject searchResult = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (searchResult != null && requiredType.isSuperTypeOf(searchResult.eClass())) {
return Collections.singletonList(searchResult);
}
searchResult = findClassifier(context, reference, name);
if (searchResult != null) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getCalledSubprogram() == requiredType) {
Classifier ns = AadlUtil.getContainingClassifier(context);
EObject searchResult;
if (!(context instanceof SubprogramCall) || (context instanceof SubprogramCall && ((SubprogramCall) context).getContext() == null)) {
// first check whether it is a reference to a classifier
searchResult = findClassifier(context, reference, name);
if (searchResult != null && requiredType.isSuperTypeOf(searchResult.eClass())) {
return Collections.singletonList(searchResult);
}
// if it was a qualified component type name it would have been found before
if (name.contains("::")) {
// Qualified classifier should have been found before
return Collections.<EObject>emptyList();
}
// no package qualifier. Look up in local name space, e.g., subprogram access feature or subprogram subcomponent
searchResult = ns.findNamedElement(name);
if (searchResult != null && requiredType.isSuperTypeOf(searchResult.eClass())) {
return Collections.singletonList(searchResult);
}
}
// lets first find it in its context
if (context instanceof SubprogramCall) {
// we have a context
// lets set it and find the called subprogram
SubprogramCall callSpec = (SubprogramCall) context;
CallContext callContext = callSpec.getContext();
if (callContext instanceof ComponentType) {
// first try to find subprogram implementation
ComponentType ct = (ComponentType) callContext;
String implname = ct.getQualifiedName() + "." + name;
searchResult = findClassifier(context, reference, implname);
if (searchResult != null && searchResult instanceof ComponentImplementation) {
return Collections.singletonList(searchResult);
}
ns = (ComponentType) callContext;
} else if (callContext instanceof SubprogramGroupSubcomponent) {
ns = ((SubprogramGroupSubcomponent) callContext).getComponentType();
if (Aadl2Util.isNull(ns)) {
return Collections.<EObject>emptyList();
}
} else if (callContext instanceof SubprogramGroupAccess && ((SubprogramGroupAccess) callContext).getKind() == AccessType.REQUIRES) {
SubprogramGroupSubcomponentType sst = ((SubprogramGroupAccess) callContext).getSubprogramGroupFeatureClassifier();
if (sst instanceof Classifier) {
ns = (Classifier) sst;
}
if (Aadl2Util.isNull(ns)) {
return Collections.<EObject>emptyList();
}
} else if (callContext instanceof FeatureGroup) {
ns = ((FeatureGroup) callContext).getFeatureGroupType();
if (Aadl2Util.isNull(ns)) {
return Collections.<EObject>emptyList();
}
}
searchResult = ns.findNamedElement(name);
if (!Aadl2Util.isNull(searchResult) && requiredType.isSuperTypeOf(searchResult.eClass())) {
return Collections.singletonList(searchResult);
}
// it might be a component implementation. The type is already recorded in the context
if (callContext instanceof SubprogramType) {
String contextName = ((SubprogramType) callContext).getName();
searchResult = findClassifier(context, reference, contextName + "." + name);
if (!Aadl2Util.isNull(searchResult)) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
}
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getPrototype() == requiredType) {
// if context prototype then find in extension source (refined)
// prototype binding as context
EObject searchResult = null;
Classifier ns = null;
if (context.eContainer() instanceof Subcomponent) {
Subcomponent sub = (Subcomponent) context.eContainer();
ns = sub.getAllClassifier();
if (!Aadl2Util.isNull(ns)) {
searchResult = ns.findNamedElement(name);
}
} else if (context.eContainer() instanceof ComponentPrototypeActual) {
ComponentPrototypeActual cpa = (ComponentPrototypeActual) context.eContainer();
SubcomponentType subT = cpa.getSubcomponentType();
if (subT instanceof ComponentClassifier) {
searchResult = ((ComponentClassifier) subT).findNamedElement(name);
}
} else if (context.eContainer() instanceof FeatureGroupPrototypeActual) {
FeatureGroupPrototypeActual cpa = (FeatureGroupPrototypeActual) context.eContainer();
FeatureType subT = cpa.getFeatureType();
if (subT instanceof FeatureGroupType) {
searchResult = ((FeatureGroupType) subT).findNamedElement(name);
}
} else if (context.eContainer() instanceof ComponentImplementationReference) {
ns = ((ComponentImplementationReference) context.eContainer()).getImplementation();
if (!Aadl2Util.isNull(ns)) {
searchResult = ns.findNamedElement(name);
}
} else {
// If resolving a prototype binding formal, don't resolve to a local prototype. Go to the generals.
// We could be in a prototype refinement. Go to the generals so that we don't resolve to context.
ns = AadlUtil.getContainingClassifier(context);
for (Iterator<Classifier> iter = ns.getGenerals().iterator(); searchResult == null && iter.hasNext(); ) {
searchResult = iter.next().findNamedElement(name);
}
}
if (!Aadl2Util.isNull(searchResult) && searchResult instanceof Prototype) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getFlowElement() == requiredType) {
// look for flow element in flow segment
FlowSegment fs = (FlowSegment) context;
FlowElement flowElement = findElementInContext(fs, fs.getContext(), name, FlowElement.class);
if (flowElement != null) {
return Collections.singletonList((EObject) flowElement);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getEndToEndFlowElement() == requiredType) {
// look for flow element in flow segment
EndToEndFlowSegment fs = (EndToEndFlowSegment) context;
EndToEndFlowElement flowElement = findElementInContext(fs, fs.getContext(), name, EndToEndFlowElement.class);
if (flowElement != null) {
return Collections.singletonList((EObject) flowElement);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getModeTransition() == requiredType) {
// referenced by in modes
EObject searchResult = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (searchResult != null && searchResult instanceof ModeTransition) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getModeFeature() == requiredType) {
// referenced by inmodes in connections and flows
EObject searchResult = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (searchResult != null && searchResult instanceof ModeFeature) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getFlowSpecification() == requiredType) {
// refined flow spec
// referenced by flow implementation
// also referenced in flow elements in impl and etef
Classifier ns = AadlUtil.getContainingClassifier(context);
if (context instanceof FlowSpecification) {
// we need to resolve a refinement
if (ns.getExtended() != null) {
ns = ns.getExtended();
} else {
return Collections.emptyList();
}
}
EObject searchResult = ns.findNamedElement(name);
if (searchResult != null && searchResult instanceof FlowSpecification) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getEndToEndFlow() == requiredType) {
// refined flow spec
// referenced by flow implementation
// also referenced in flow elements in impl and etef
Classifier ns = AadlUtil.getContainingClassifier(context);
if (context instanceof EndToEndFlow) {
// we need to resolve a refinement
if (ns.getExtended() != null) {
ns = ns.getExtended();
} else {
return Collections.emptyList();
}
}
EObject searchResult = ns.findNamedElement(name);
if (searchResult != null && searchResult instanceof EndToEndFlow) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getConnection() == requiredType) {
// refined to, flow elements
Classifier ns = AadlUtil.getContainingClassifier(context);
if (context instanceof Connection) {
// we need to resolve a refinement
if (ns.getExtended() != null) {
ns = ns.getExtended();
} else {
return Collections.emptyList();
}
}
EObject searchResult = ns.findNamedElement(name);
if (searchResult != null && searchResult instanceof Connection) {
return Collections.singletonList(searchResult);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getFeatureType() == requiredType) {
// feature group type or prototype
FeatureGroupType fgt = findFeatureGroupType(context, name, reference);
if (Aadl2Util.isNull(fgt)) {
// need to resolve prototype
EObject res = AadlUtil.getContainingClassifier(context).findNamedElement(name);
if (res instanceof FeatureGroupPrototype) {
return Collections.singletonList(res);
}
} else {
return Collections.singletonList((EObject) fgt);
}
return Collections.<EObject>emptyList();
} else if (Aadl2Package.eINSTANCE.getArraySizeProperty() == requiredType) {
// reference to a property constant or property
// look for property definition in property set
List<EObject> result = findPropertyDefinitionAsList(context, reference, name);
if (result.isEmpty()) {
result = findPropertyConstant(context, reference, name);
}
return result;
} else {
List<EObject> res = super.getLinkedObjects(context, reference, node);
return res;
}
}
use of org.osate.aadl2.EndToEndFlowSegment in project osate2 by osate.
the class ShowFlowContributionItem method createControl.
@Override
protected Control createControl(final Composite parent) {
showFlowBtn = new Button(parent, SWT.PUSH);
showFlowBtn.setImage(showIcon.createImage());
showFlowBtn.setToolTipText("Show");
updateButton();
showFlowBtn.addSelectionListener(new SelectionAdapter() {
private ProjectReferenceService referenceService;
@Override
public void widgetSelected(final SelectionEvent e) {
if (editor != null && selectedFlow != null) {
referenceService = Objects.requireNonNull(Adapters.adapt(editor, ProjectReferenceService.class), "Unable to retrieve reference service");
final DiagramUpdater diagramUpdater = editor.getDiagramUpdater();
final BusinessObjectTreeUpdater boTreeUpdater = editor.getBoTreeUpdater();
final BusinessObjectNode boTree = getBoTree(boTreeUpdater);
final BusinessObjectNode containerNode = boTree.getAllDescendants().filter(q -> q.getBusinessObject() == selectedFlow.getContainer().getBusinessObject()).findAny().map(BusinessObjectNode.class::cast).orElseThrow(() -> new RuntimeException("Cannot find container for highlightable flow: " + selectedFlow.getFlowSegment().getName()));
final Object component = getContainerComponent(selectedFlow.getContainer().getBusinessObject());
ensureFlowSegmentsExist(component, selectedFlow.getFlowSegment(), containerNode);
final AgeDiagram diagram = editor.getDiagram();
final LayoutInfoProvider layoutInfoProvider = Objects.requireNonNull(Adapters.adapt(editor, LayoutInfoProvider.class), "Unable to retrieve layout info provider");
editor.getActionExecutor().execute("Show Flow Elements", ExecutionMode.NORMAL, () -> {
// Update the diagram
diagramUpdater.updateDiagram(diagram, boTree);
// Update layout
diagram.modify("Layout Incrementally", m -> DiagramElementLayoutUtil.layoutIncrementally(diagram, m, layoutInfoProvider));
return null;
});
}
}
private List<FlowSegmentReference> findFlowSegments(final FlowSegmentReference flowElementRef) {
if (flowElementRef.flowSegmentElement instanceof FlowSpecification) {
// Check if flow specification has flow implementation(s)
return AadlClassifierUtil.getComponentImplementation(flowElementRef.container.getBusinessObject()).map(ci -> ci.getAllFlowImplementations().stream().filter(cfi -> flowElementRef.flowSegmentElement == cfi.getSpecification()).flatMap(cfi -> cfi.getOwnedFlowSegments().stream()).map(flowSegment -> createFlowSegmentReference(flowSegment, (BusinessObjectNode) flowElementRef.container))).orElse(Stream.empty()).collect(Collectors.toList());
} else if (flowElementRef.flowSegmentElement instanceof EndToEndFlow) {
final EndToEndFlow endToEndFlow = (EndToEndFlow) flowElementRef.flowSegmentElement;
final BusinessObjectNode containerNode = (BusinessObjectNode) flowElementRef.container;
return AadlClassifierUtil.getComponentImplementation(containerNode.getBusinessObject()).map(ci -> ci.getAllEndToEndFlows().stream().filter(ownedEndToEndFlow -> ownedEndToEndFlow == endToEndFlow).flatMap(ete -> ete.getAllFlowSegments().stream().flatMap(flowSegment -> {
final EndToEndFlowElement endToEndFlowElement = flowSegment.getFlowElement();
if (endToEndFlowElement instanceof EndToEndFlow) {
// Find segments of a segment that is an end to end flow
return ((EndToEndFlow) endToEndFlowElement).getAllFlowSegments().stream();
}
return Stream.of(flowSegment);
})).map(endToEndFlowSegment -> createFlowSegmentReference(endToEndFlowSegment, containerNode))).orElse(Stream.empty()).collect(Collectors.toList());
} else if (flowElementRef.flowSegmentElement instanceof EndToEndFlowInstance) {
return AadlInstanceObjectUtil.getComponentInstance(flowElementRef.container.getBusinessObject()).map(ci -> ci.getEndToEndFlows().stream().filter(ete -> ete == flowElementRef.flowSegmentElement).flatMap(ete -> {
return ete.getFlowElements().stream().flatMap(fei -> {
if (fei instanceof ConnectionInstance) {
return ((ConnectionInstance) fei).getConnectionReferences().stream().map(cr -> createFlowSegmentReference(cr, (BusinessObjectNode) flowElementRef.container));
} else {
return Stream.of(createFlowSegmentReference(fei, (BusinessObjectNode) flowElementRef.container));
}
});
})).orElse(Stream.empty()).collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
private void ensureFlowSegmentsExist(final Object component, final NamedElement flow, final BusinessObjectNode containerNode) {
if (component instanceof ComponentImplementation) {
final ComponentImplementation ci = (ComponentImplementation) component;
if (flow instanceof FlowSpecification) {
ci.getAllFlowImplementations().stream().filter(fi -> flow.getName().equalsIgnoreCase(fi.getSpecification().getName())).findAny().ifPresent(flowImpl -> {
final FlowSegmentReference flowSegmentRef = createFlowSegmentReference(flowImpl.getSpecification(), containerNode);
enableFlowSegments(findFlowSegments(flowSegmentRef));
});
} else {
final String eteName = flow.getName();
final Optional<EndToEndFlow> eteFlow = ci.getAllEndToEndFlows().stream().filter(etef -> eteName.equalsIgnoreCase(etef.getName())).findAny();
eteFlow.ifPresent(endToEndFlow -> {
final FlowSegmentReference flowSegmentRef = createFlowSegmentReference(endToEndFlow, containerNode);
enableFlowSegments(findFlowSegments(flowSegmentRef));
});
}
} else if (component instanceof ComponentInstance) {
// ETE Flows only
final EndToEndFlowInstance eteFlowInstance = (EndToEndFlowInstance) flow;
final FlowSegmentReference flowSegmentRef = createFlowSegmentReference(eteFlowInstance, containerNode);
enableFlowSegments(findFlowSegments(flowSegmentRef));
}
}
private void enableFlowSegments(final List<FlowSegmentReference> highlightableFlowElements) {
highlightableFlowElements.stream().filter(Predicates.notNull()).forEach(highlightableFlowElement -> {
final NamedElement flowSegmentElement = highlightableFlowElement.flowSegmentElement;
final BusinessObjectContext flowSegmentContainer = highlightableFlowElement.container;
// Find segments for flow and remove cycles
final List<FlowSegmentReference> flowSegmentReferences = findFlowSegments(highlightableFlowElement).stream().filter(flowSegmentReference -> flowSegmentReference.flowSegmentElement != flowSegmentElement && flowSegmentReference.container != flowSegmentContainer).collect(Collectors.toList());
enableFlowSegments(flowSegmentReferences);
});
}
private Object getContainerComponent(final Object container) {
if (container instanceof Subcomponent) {
final Subcomponent sc = (Subcomponent) container;
return sc.getComponentImplementation();
}
return container;
}
private BusinessObjectNode getBoTree(final BusinessObjectTreeUpdater treeUpdater) {
BusinessObjectNode boTree = DiagramToBusinessObjectTreeConverter.createBusinessObjectNode(editor.getDiagram());
return treeUpdater.updateTree(editor.getDiagram().getConfiguration(), boTree);
}
private FlowSegmentReference createFlowSegmentReference(final Object bo, final BusinessObjectNode container) {
if (bo instanceof FlowSegment) {
final FlowSegment flowSegment = (FlowSegment) bo;
final FlowElement flowElement = flowSegment.getFlowElement();
if (flowSegment.getContext() == null) {
return createFlowSegmentReference(flowElement, container);
} else {
final BusinessObjectNode contextNode = ensureEnabledChild(flowSegment.getContext(), container);
return createFlowSegmentReference(flowElement, contextNode);
}
} else if (bo instanceof EndToEndFlowSegment) {
final EndToEndFlowSegment flowSegment = (EndToEndFlowSegment) bo;
if (flowSegment.getFlowElement() instanceof FlowElement) {
final FlowElement flowElement = (FlowElement) flowSegment.getFlowElement();
if (flowSegment.getContext() == null) {
return createFlowSegmentReference(flowElement, container);
} else {
final BusinessObjectNode contextNode = ensureEnabledChild(flowSegment.getContext(), container);
return createFlowSegmentReference(flowElement, contextNode);
}
}
return createFlowSegmentReference(flowSegment.getFlowElement(), container);
} else if (bo instanceof InstanceObject) {
final InstanceObject io = (InstanceObject) bo;
if (bo instanceof EndToEndFlowInstance) {
return new FlowSegmentReference(io, container);
} else {
final Map<Object, BusinessObjectContext> descendantBoToQueryable = container.getAllDescendants().collect(Collectors.toMap(BusinessObjectContext::getBusinessObject, Function.identity()));
if (bo instanceof FlowSpecificationInstance) {
final FlowSpecificationInstance fsi = (FlowSpecificationInstance) bo;
enableFlowSpecificationInstanceNodes(descendantBoToQueryable, fsi);
}
if (bo instanceof ConnectionReference) {
final ConnectionReference cr = (ConnectionReference) bo;
enableConnectionReferenceNodes(descendantBoToQueryable, cr);
}
return new FlowSegmentReference(io, container);
}
} else if (bo instanceof NamedElement) {
final RelativeBusinessObjectReference ref = getRelativeBusinessObjectReference(bo);
if (ref != null) {
ensureEnabledChild(bo, container);
}
if (bo instanceof FlowSpecification) {
final FlowSpecification fs = (FlowSpecification) bo;
if (fs.getAllInEnd() != null) {
enableFlowEnd(fs.getAllInEnd(), container);
}
if (fs.getAllOutEnd() != null) {
enableFlowEnd(fs.getAllOutEnd(), container);
}
} else if (bo instanceof Connection) {
final Connection connection = (Connection) bo;
final ConnectionEnd dstEnd = connection.getAllDestination();
final Context dstContext = connection.getAllDestinationContext();
final RelativeBusinessObjectReference dstEndRef = getRelativeBusinessObjectReference(dstEnd);
// Destination context
BusinessObjectNode ctxContainer = getContextContainer(dstContext, container);
if (ctxContainer.getChild(dstEndRef) == null) {
createNode(ctxContainer, dstEndRef, dstEnd);
}
final ConnectionEnd srcEnd = connection.getAllSource();
final Context srcContext = connection.getAllSourceContext();
// Source context
ctxContainer = getContextContainer(srcContext, container);
final RelativeBusinessObjectReference srcEndRef = getRelativeBusinessObjectReference(srcEnd);
if (ctxContainer.getChild(srcEndRef) == null) {
createNode(ctxContainer, srcEndRef, srcEnd);
}
}
return new FlowSegmentReference((NamedElement) bo, container);
} else {
throw new RuntimeException("Unexpected business object: " + bo);
}
}
private BusinessObjectNode getContextContainer(final Context context, final BusinessObjectNode contextContainer) {
if (context != null) {
// Ensure context container is created
final RelativeBusinessObjectReference contextRef = getRelativeBusinessObjectReference(context);
if (contextContainer.getChild(contextRef) == null) {
// Show context
createNode(contextContainer, contextRef, context);
}
return contextContainer.getChild(contextRef);
}
return contextContainer;
}
private void enableFlowEnd(final FlowEnd flowEnd, BusinessObjectNode containerNode) {
final Feature feature = (Feature) flowEnd.getFeature();
if (flowEnd.getContext() != null) {
containerNode = ensureEnabledChild(flowEnd.getContext(), containerNode);
}
ensureEnabledChild(feature, containerNode);
}
private void enableFlowSpecificationInstanceNodes(final Map<Object, BusinessObjectContext> descendantBoToQueryable, final FlowSpecificationInstance fsi) {
enableAncestorNodes(descendantBoToQueryable, fsi);
if (fsi.getDestination() != null) {
enableAncestorNodes(descendantBoToQueryable, fsi.getDestination());
}
if (fsi.getSource() != null) {
enableAncestorNodes(descendantBoToQueryable, fsi.getSource());
}
}
private void enableConnectionReferenceNodes(final Map<Object, BusinessObjectContext> descendantBoToQueryable, final ConnectionReference cr) {
Element tmpElement = cr;
// Ancestors to ensure are enabled on the diagram
final Queue<Element> ancestors = Collections.asLifoQueue(new LinkedList<Element>());
if (!descendantBoToQueryable.containsKey(tmpElement)) {
ancestors.add(tmpElement);
tmpElement = tmpElement.getOwner();
// First owner of connection reference is connection instance
if (tmpElement instanceof ConnectionInstance) {
tmpElement = tmpElement.getOwner();
}
}
// Connection reference
populateAncestorsQueue(descendantBoToQueryable, ancestors, tmpElement);
enableAncestorNodes(descendantBoToQueryable, ancestors, ancestors.poll());
// Enable source and destination nodes
enableAncestorNodes(descendantBoToQueryable, cr.getSource());
enableAncestorNodes(descendantBoToQueryable, cr.getDestination());
}
// Gets the first element ancestor that is enabled
private void populateAncestorsQueue(final Map<Object, BusinessObjectContext> descendantBoToQueryable, final Queue<Element> ancestors, Element ancestor) {
while (!descendantBoToQueryable.containsKey(ancestor)) {
ancestors.add(ancestor);
ancestor = ancestor.getOwner();
}
ancestors.add(ancestor);
}
// Find ancestors and create if necessary
private void enableAncestorNodes(final Map<Object, BusinessObjectContext> descendantBoToQueryable, final Element ancestor) {
final Queue<Element> ancestors = Collections.asLifoQueue(new LinkedList<Element>());
populateAncestorsQueue(descendantBoToQueryable, ancestors, ancestor);
enableAncestorNodes(descendantBoToQueryable, ancestors, ancestors.poll());
}
// Create ancestor nodes
private void enableAncestorNodes(final Map<Object, BusinessObjectContext> descendantBoToQueryable, final Queue<Element> ancestors, final Element ancestor) {
BusinessObjectNode ancestorNode = (BusinessObjectNode) descendantBoToQueryable.get(ancestor);
for (final Element ancestorToEnable : ancestors) {
final RelativeBusinessObjectReference ancestorRef = getRelativeBusinessObjectReference(ancestorToEnable);
if (ancestorNode.getChild(ancestorRef) == null) {
ancestorNode = createNode(ancestorNode, ancestorRef, ancestorToEnable);
}
}
}
private BusinessObjectNode ensureEnabledChild(final Object childBo, final BusinessObjectNode parent) {
final RelativeBusinessObjectReference childRef = getRelativeBusinessObjectReference(childBo);
final BusinessObjectNode childNode = parent.getChild(childRef);
if (childRef != null && childNode == null) {
return createNode(parent, childRef, childBo);
}
return Objects.requireNonNull(childNode, "Child node does not exist");
}
private BusinessObjectNode createNode(final BusinessObjectNode parent, final RelativeBusinessObjectReference childRef, final Object childBo) {
return new BusinessObjectNode(parent, UUID.randomUUID(), childRef, childBo, Completeness.UNKNOWN, false);
}
private RelativeBusinessObjectReference getRelativeBusinessObjectReference(final Object bo) {
final RelativeBusinessObjectReference result = referenceService.getRelativeReference(bo);
return result;
}
});
return showFlowBtn;
}
Aggregations