FlowContributionItemUtil.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.aadl2.ui.internal.editor;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.osate.aadl2.ComponentImplementation;
import org.osate.aadl2.FlowEnd;
import org.osate.aadl2.FlowImplementation;
import org.osate.aadl2.FlowSegment;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.Subcomponent;
import org.osate.ge.BusinessObjectContext;
import org.osate.ge.aadl2.internal.util.AgeAadlUtil;
import org.osate.ge.aadl2.ui.internal.tools.FlowDialogUtil;
public class FlowContributionItemUtil {
private FlowContributionItemUtil() {
}
/**
* Allows a specific flow implementation to be selected
* when a flow specification has multiple flow implementations
*/
static class FlowImplementationSelectionDialog extends MessageDialog {
private ComboViewer comboViewer;
private final List<FlowImplementation> input;
private FlowImplementation selectedFlowImpl;
public FlowImplementationSelectionDialog(final Shell parentShell, final List<FlowImplementation> input,
final String dialogTitle, final String dialogMessage) {
super(parentShell, dialogTitle, null, dialogMessage, MessageDialog.CONFIRM, 0, "OK", "Cancel");
setShellStyle(SWT.CLOSE | SWT.PRIMARY_MODAL | SWT.BORDER | SWT.TITLE | SWT.RESIZE);
this.input = input;
}
@Override
protected void configureShell(final Shell shell) {
super.configureShell(shell);
shell.setMinimumSize(new Point(550, 275));
}
@Override
protected Control createCustomArea(final Composite parent) {
final Composite composite = new Composite(parent, SWT.BORDER);
final GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
layout.numColumns = 2;
composite.setLayout(layout);
composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
composite.setFont(parent.getFont());
new Label(composite, SWT.NONE).setText("Flow Implementation: ");
// List of flow implementations to choose from
comboViewer = new ComboViewer(composite, SWT.READ_ONLY);
final StyledText flowSegmentLabels = FlowDialogUtil.createFlowSegmentLabel(composite);
flowSegmentLabels.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).span(2, 1).create());
comboViewer.setContentProvider(ArrayContentProvider.getInstance());
comboViewer.setLabelProvider(new LabelProvider() {
@Override
public String getText(final Object element) {
final FlowImplementation fi = (FlowImplementation) element;
final StringBuilder sb = new StringBuilder(getName(fi.getSpecification()));
// Add index label
if (input.size() > 1) {
final int index = input.indexOf(fi) + 1;
sb.append(" #");
sb.append(index);
}
return sb.toString();
}
});
// Show segments for selected flow implementation
comboViewer.addSelectionChangedListener(event -> {
selectedFlowImpl = (FlowImplementation) event.getStructuredSelection().getFirstElement();
String flowStr = "";
final List<String> flowSegmentStrings = new ArrayList<>();
final FlowEnd inEnd = selectedFlowImpl.getInEnd();
if (inEnd != null) {
flowSegmentStrings.add(flowEndToString(inEnd));
}
for (final FlowSegment flowSegment : selectedFlowImpl.getOwnedFlowSegments()) {
flowSegmentStrings.add(flowSegmentToString(flowSegment));
}
final FlowEnd outEnd = selectedFlowImpl.getOutEnd();
if (outEnd != null) {
flowSegmentStrings.add(flowEndToString(outEnd));
}
flowStr += flowSegmentStrings.stream().collect(Collectors.joining(" -> "));
final int modeStartIndex = flowStr.length();
if (!selectedFlowImpl.getInModeOrTransitions().isEmpty()) {
flowStr += " in modes (" + selectedFlowImpl.getInModeOrTransitions().stream()
.map(mf -> mf.getName()).collect(Collectors.joining(", ")) + ")";
}
final int modeEndIndex = flowStr.length();
flowStr += ";";
flowSegmentLabels.setText(flowStr);
if (modeStartIndex != modeEndIndex) {
flowSegmentLabels.setStyleRange(new StyleRange(modeStartIndex, 10,
Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED), null, SWT.BOLD));
}
});
comboViewer.setInput(input);
comboViewer.setSelection(new StructuredSelection(input.get(0)));
return composite;
}
private static String flowEndToString(final FlowEnd flowEnd) {
String name = "";
FlowEnd end = flowEnd;
if (end.getFeature() != null) {
name = getName(flowEnd.getFeature());
}
while (end.getContext() != null) {
name = getName(flowEnd.getContext().getFeature()) + "." + name;
end = end.getContext();
}
return name;
}
private static String flowSegmentToString(final FlowSegment flowSegment) {
final StringBuilder sb = new StringBuilder();
if (flowSegment.getContext() != null) {
sb.append(getName(flowSegment.getContext()));
sb.append('.');
}
if (flowSegment.getFlowElement() != null) {
sb.append(getName(flowSegment.getFlowElement()));
}
return sb.toString();
}
public FlowImplementation getSelectedFlowImplementation() {
return selectedFlowImpl;
}
}
static String getName(NamedElement ne) {
ne = AgeAadlUtil.getRootRefinedElement(ne);
return ne.getName() == null ? "<unknown>" : ne.getName();
}
static ComponentImplementation getComponentImplementation(final Object container) {
if (container instanceof BusinessObjectContext) {
return getComponentImplementation(((BusinessObjectContext) container).getBusinessObject());
} else if (container instanceof ComponentImplementation) {
return (ComponentImplementation) container;
} else if (container instanceof Subcomponent) {
final Subcomponent sc = (Subcomponent) AgeAadlUtil.getRootRefinedElement((NamedElement) container);
return sc.getComponentImplementation();
} else {
throw new RuntimeException("Invalid flow container: " + container);
}
}
}