use of org.osate.ge.internal.services.ProjectReferenceService in project osate2 by osate.
the class AgeEditor method createPartControl.
@Override
public void createPartControl(final Composite parent) {
//
// Create the FX canvas which is an SWT widget for embedding JavaFX content.
//
fxCanvas = new FXCanvas(parent, SWT.NONE);
fxCanvas.addDisposeListener(e -> {
fxCanvas.getScene().setRoot(new Group());
fxCanvas.setScene(null);
});
fxCanvas.addPaintListener(paintListener);
// Suppress SWT key press handling when interaction is active
fxCanvas.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(final org.eclipse.swt.events.KeyEvent e) {
if (activeInteraction != null) {
e.doit = false;
}
}
});
fxCanvas.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
deactivateInteraction();
}
});
// Create the context menu
contextMenuManager = new MenuManager(MENU_ID, MENU_ID);
contextMenuManager.setRemoveAllWhenShown(true);
final Menu contextMenu = contextMenuManager.createContextMenu(fxCanvas);
fxCanvas.setMenu(contextMenu);
getEditorSite().registerContextMenu(MENU_ID, contextMenuManager, selectionProvider, true);
// Create the action executor. It will append an action to activate the editor when undoing and redoing actions.
actionExecutor = (label, mode, action) -> {
final boolean reverseActionWasSpecified = actionService.execute(label, mode, action);
// This will ensure that when the action is undone, the editor will be switched to the one in which the action was performed.
if (isEditorActive() && reverseActionWasSpecified && !actionService.isActionExecuting() && mode == ExecutionMode.NORMAL) {
actionService.execute("Activate Editor", ExecutionMode.APPEND_ELSE_HIDE, new ActivateAgeEditorAction(AgeEditor.this));
}
fireDirtyPropertyChangeEvent();
return reverseActionWasSpecified;
};
// Initialize the palette model
final AgeEditorPaletteModel.ImageProvider imageProvider = id -> {
final RegisteredImage img = extRegistry.getImageMap().get(id);
if (img == null) {
return Optional.empty();
}
final URI imageUri = URI.createPlatformPluginURI("/" + img.plugin + "/" + img.path, true);
if (CommonPlugin.asLocalURI(imageUri).isFile()) {
return Optional.of(new Image(imageUri.toString()));
} else {
return Optional.empty();
}
};
Object diagramBo = AgeDiagramUtil.getConfigurationContextBusinessObject(diagram, projectReferenceService);
if (diagramBo == null) {
diagramBo = project;
}
this.paletteModel = new AgeEditorPaletteModel(extRegistry.getPaletteContributors(), diagramBo, imageProvider);
// If the palette item changes while an interaction is active, deactivate the interaction.
this.paletteModel.activeItemProperty().addListener((javafx.beans.value.ChangeListener<SimplePaletteItem>) (observable, oldValue, newValue) -> deactivateInteraction());
// Initialize the JavaFX nodes based on the diagram
canvas = new InfiniteCanvas();
// Set show grid based on preferences
canvas.setShowGrid(preferenceStore.getBoolean(Preferences.SHOW_GRID));
final Scene scene = new Scene(new DiagramEditorNode(paletteModel, canvas));
fxCanvas.setScene(scene);
gefDiagram = new GefAgeDiagram(diagram, coloringService);
// Create a wrapper around the diagram's scene node.
final Group wrapper = new DiagramNodeWrapper(gefDiagram.getSceneNode());
// Add the wrapper to the canvas
canvas.getContentGroup().getChildren().add(wrapper);
gefDiagram.updateDiagramFromSceneGraph(false);
// Treat the current state of the diagram as clean.
cleanDiagramChangeNumber = diagram.getCurrentChangeNumber();
adapterMap.put(LayoutInfoProvider.class, gefDiagram);
// Create overlays
overlays = new Overlays(gefDiagram);
selectionProvider.addSelectionChangedListener(overlays);
canvas.getScrolledOverlayGroup().getChildren().add(overlays);
// Perform the initial incremental layout
diagram.modify("Incremental Layout", m -> DiagramElementLayoutUtil.layoutIncrementally(diagram, m, gefDiagram));
// Set action executor after initial load. This occurs after the incremental layout to prevent the loading and initial layout from being undoable
diagram.setActionExecutor(actionExecutor);
// Refresh the dirty state whenever an operation occurs
final IOperationHistory history = PlatformUI.getWorkbench().getOperationSupport().getOperationHistory();
history.addOperationHistoryListener(operationHistoryListener);
canvas.setOnScroll(e -> {
if (e.isControlDown()) {
// Adjust zoom
if (e.getDeltaY() < 0.0) {
zoomOut();
} else {
zoomIn();
}
} else {
if (e.isShiftDown()) {
// Scroll in X direction
canvas.setHorizontalScrollOffset(canvas.getHorizontalScrollOffset() - e.getDeltaY());
} else {
// Scroll
canvas.setHorizontalScrollOffset(canvas.getHorizontalScrollOffset() - e.getDeltaX());
canvas.setVerticalScrollOffset(canvas.getVerticalScrollOffset() + e.getDeltaY());
}
}
});
//
// Listeners to handle tooltips
//
canvas.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, e -> {
if (e.getTarget() instanceof Node && activeInteraction == null && tooltipManager != null && gefDiagram != null) {
final DiagramElement de = gefDiagram.getDiagramElement((Node) e.getTarget());
if (de != null) {
tooltipManager.mouseEnter(de);
}
}
});
canvas.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, e -> {
if (e.getTarget() instanceof Node && activeInteraction == null && tooltipManager != null && gefDiagram != null) {
final DiagramElement de = gefDiagram.getDiagramElement((Node) e.getTarget());
if (de != null) {
tooltipManager.mouseExit(de);
}
}
});
//
// General input handlers
//
// Event handler. Delegates to input event handlers or the active interaction as appropriate
final EventHandler<? super InputEvent> handleInput = e -> {
if (activeInteraction == null) {
// Delegate processing of the event to the input event handlers
for (final InputEventHandler inputEventHandler : inputEventHandlers) {
final InputEventHandler.HandledEvent r = inputEventHandler.handleEvent(e);
if (r != null) {
activeInteraction = r.newInteraction;
if (activeInteraction != null) {
canvas.setCursor(activeInteraction.getCursor());
if (tooltipManager != null) {
tooltipManager.hideTooltip();
}
}
break;
}
}
} else {
if (activeInteraction.handleEvent(e) == InteractionState.COMPLETE) {
deactivateInteraction();
}
canvas.setCursor(activeInteraction == null ? null : activeInteraction.getCursor());
}
};
// Handle mouse button presses
canvas.addEventFilter(MouseEvent.MOUSE_PRESSED, handleInput);
canvas.addEventFilter(MouseEvent.MOUSE_DRAGGED, handleInput);
canvas.addEventFilter(MouseEvent.MOUSE_RELEASED, handleInput);
scene.addEventFilter(KeyEvent.KEY_PRESSED, handleInput);
canvas.addEventFilter(MouseEvent.MOUSE_MOVED, e -> {
if (activeInteraction == null) {
Cursor cursor = Cursor.DEFAULT;
for (final InputEventHandler inputEventHandler : inputEventHandlers) {
final Cursor overrideCursor = inputEventHandler.getCursor(e);
if (overrideCursor != null) {
cursor = overrideCursor;
break;
}
}
canvas.setCursor(cursor);
}
handleInput.handle(e);
});
// Create input event handlers
inputEventHandlers.add(new OpenPropertiesViewInputEventHandler(this));
inputEventHandlers.add(new ResizeInputEventHandler(this));
inputEventHandlers.add(new MarqueeSelectInputEventHandler(this));
inputEventHandlers.add(new MoveConnectionPointTool(this));
inputEventHandlers.add(new RenameInputEventHandler(this));
inputEventHandlers.add(new SelectInputEventHandler(this));
inputEventHandlers.add(new MoveInputEventHandler(this));
inputEventHandlers.add(new PaletteCommandInputEventHandler(this));
}
use of org.osate.ge.internal.services.ProjectReferenceService in project osate2 by osate.
the class GefDiagramExportService method loadDiagram.
private GefAgeDiagram loadDiagram(final IFile diagramFile) {
final URI uri = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);
final IProject project = ProjectUtil.getProjectOrNull(uri);
final org.osate.ge.diagram.Diagram mmDiagram = DiagramSerialization.readMetaModelDiagram(uri);
final IEclipseContext eclipseContext = EclipseContextFactory.getServiceContext(FrameworkUtil.getBundle(GefDiagramExportService.class).getBundleContext());
final ExtensionRegistryService extensionRegistry = Objects.requireNonNull(eclipseContext.get(ExtensionRegistryService.class), "Unable to retrieve extension registry");
final ReferenceService referenceService = Objects.requireNonNull(eclipseContext.get(ReferenceService.class), "unable to retrieve reference service");
final ActionService actionService = Objects.requireNonNull(eclipseContext.get(ActionService.class), "unable to retrieve action service");
final AgeDiagram diagram = DiagramSerialization.createAgeDiagram(project, mmDiagram, extensionRegistry);
// Update the diagram
final QueryService queryService = new DefaultQueryService(referenceService);
final ProjectProvider projectProvider = diagramFile::getProject;
final ProjectReferenceService projectReferenceService = new ProjectReferenceServiceProxy(referenceService, projectProvider);
final BusinessObjectNodeFactory nodeFactory = new BusinessObjectNodeFactory(projectReferenceService);
final DefaultBusinessObjectTreeUpdater boTreeUpdater = new DefaultBusinessObjectTreeUpdater(projectProvider, extensionRegistry, projectReferenceService, queryService, nodeFactory);
final DefaultDiagramElementGraphicalConfigurationProvider deInfoProvider = new DefaultDiagramElementGraphicalConfigurationProvider(queryService, () -> diagram, extensionRegistry);
final DiagramUpdater diagramUpdater = new DiagramUpdater(boTreeUpdater, deInfoProvider, actionService, projectReferenceService, projectReferenceService);
diagramUpdater.updateDiagram(diagram);
// Create the GEF Diagram
final GefAgeDiagram gefDiagram = new GefAgeDiagram(diagram, new DefaultColoringService(new org.osate.ge.internal.services.impl.DefaultColoringService.StyleRefresher() {
@Override
public void refreshDiagramColoring() {
// No-op. Handling coloring service refresh requests is not required.
}
@Override
public void refreshColoring(final Collection<DiagramElement> diagramElements) {
// No-op. Handling coloring service refresh requests is not required.
}
}));
// Add to scene. This is required for text rendering
new Scene(gefDiagram.getSceneNode());
// Update the diagram to reflect the scene graph and perform incremental layout
gefDiagram.updateDiagramFromSceneGraph(false);
diagram.modify("Incremental Layout", m -> DiagramElementLayoutUtil.layoutIncrementally(diagram, m, gefDiagram));
return gefDiagram;
}
use of org.osate.ge.internal.services.ProjectReferenceService in project osate2 by osate.
the class ConfigureDiagramHandler method execute.
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
if (!(activeEditor instanceof InternalDiagramEditor)) {
throw new RuntimeException("Unexpected editor: " + activeEditor);
}
// Get diagram and selected elements
final InternalDiagramEditor diagramEditor = (InternalDiagramEditor) activeEditor;
final List<DiagramElement> selectedDiagramElements = AgeHandlerUtil.getSelectedDiagramElements();
final AgeDiagram diagram = diagramEditor.getDiagram();
if (diagram == null) {
throw new RuntimeException("Unable to get diagram");
}
// Get services
final BusinessObjectTreeUpdater boTreeUpdater = diagramEditor.getBoTreeUpdater();
final DiagramUpdater diagramUpdater = diagramEditor.getDiagramUpdater();
final ProjectProvider projectProvider = Objects.requireNonNull(Adapters.adapt(diagramEditor, ProjectProvider.class), "Unable to retrieve project provider");
final LayoutInfoProvider layoutInfoProvider = Objects.requireNonNull(Adapters.adapt(diagramEditor, LayoutInfoProvider.class), "Unable to retrieve layout information provider");
final ExtensionRegistryService extService = Objects.requireNonNull(Adapters.adapt(diagramEditor, ExtensionRegistryService.class), "Unable to retrieve extension service");
final ProjectReferenceService referenceService = Objects.requireNonNull(Adapters.adapt(diagramEditor, ProjectReferenceService.class), "Unable to retrieve reference service");
BusinessObjectNode boTree = DiagramToBusinessObjectTreeConverter.createBusinessObjectNode(diagram);
// Update the tree so that it's business objects are refreshed
boTree = boTreeUpdater.updateTree(diagram.getConfiguration(), boTree);
final DefaultDiagramConfigurationDialogModel model = new DefaultDiagramConfigurationDialogModel(referenceService, extService, projectProvider, diagram.getConfiguration().getDiagramType());
// Create a BO path for the initial selection. The initial selection will be the first diagram element which will be included in the BO tree.
Object[] initialSelectionBoPath = null;
for (final DiagramElement selectedDiagramElement : selectedDiagramElements) {
if (model.shouldShowBusinessObject(selectedDiagramElement.getBusinessObject())) {
// Only build a selection path if the BO will be shown
DiagramNode tmp = selectedDiagramElement;
final LinkedList<Object> boList = new LinkedList<>();
while (tmp instanceof DiagramElement) {
boList.addFirst(tmp.getBusinessObject());
tmp = tmp.getParent();
}
initialSelectionBoPath = boList.toArray();
break;
}
}
// Show the dialog
final DiagramConfigurationDialog.Result result = DiagramConfigurationDialog.show(null, model, diagram.getConfiguration(), boTree, initialSelectionBoPath);
if (result != null) {
// Update the diagram
diagramEditor.getActionExecutor().execute("Set Diagram Configuration", ExecutionMode.NORMAL, () -> {
diagram.modify("Set Diagram Configuration", m -> {
m.setDiagramConfiguration(result.getDiagramConfiguration());
diagramUpdater.updateDiagram(diagram, result.getBusinessObjectTree());
});
// Clear ghosts triggered by this update to prevent them from being unghosted during the next update.
diagramUpdater.clearGhosts();
diagram.modify("Layout", m -> DiagramElementLayoutUtil.layoutIncrementally(diagram, m, layoutInfoProvider));
return null;
});
}
return null;
}
use of org.osate.ge.internal.services.ProjectReferenceService 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