Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EDITORS-294: Allow selecting inherited signatures in calls #37

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/bin/
**/*.class
target/
xtend-gen/
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.palladiosimulator.editors.sirius.custom.util;

import java.util.ArrayDeque;
import java.util.Collection;
import java.util.HashSet;
import java.util.Queue;

import org.palladiosimulator.pcm.repository.OperationInterface;

public final class PCMQueryUtils {

private PCMQueryUtils() {
// intentionally empty
}

public static Collection<OperationInterface> getTransitiveParentInterfaceClosureIncludingSelf(
OperationInterface self) {
Collection<OperationInterface> closure = new HashSet<>();
Queue<OperationInterface> queue = new ArrayDeque<>();
queue.add(self);
while (!queue.isEmpty()) {
OperationInterface current = queue.poll();
closure.add(current);
current.getParentInterfaces__Interface()
.stream()
.filter(OperationInterface.class::isInstance)
.map(OperationInterface.class::cast)
.filter(i -> !closure.contains(i))
.forEach(queue::add);
}
return closure;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,131 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.stream.Collectors;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.sirius.tools.api.ui.IExternalJavaAction;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.palladiosimulator.editors.commons.dialogs.selection.PalladioSelectEObjectDialog;
import org.palladiosimulator.editors.sirius.custom.util.PCMQueryUtils;
import org.palladiosimulator.pcm.repository.BasicComponent;
import org.palladiosimulator.pcm.repository.OperationInterface;
import org.palladiosimulator.pcm.repository.OperationRequiredRole;
import org.palladiosimulator.pcm.repository.OperationSignature;
import org.palladiosimulator.pcm.repository.Repository;
import org.palladiosimulator.pcm.repository.RequiredRole;
import org.palladiosimulator.pcm.seff.ExternalCallAction;
import org.palladiosimulator.pcm.seff.ResourceDemandingBehaviour;
import org.palladiosimulator.pcm.seff.ServiceEffectSpecification;

public class AddExternalCallAction implements IExternalJavaAction {


public static final Shell SHELL = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();


@Override
public void execute(Collection<? extends EObject> selections, Map<String, Object> parameters) {
ExternalCallAction extCall = (ExternalCallAction) parameters.get("instance");
HashMap<OperationInterface, OperationRequiredRole> requiredRolesMap = new HashMap<OperationInterface, OperationRequiredRole>();
OperationSignature os = getOperationSignature(extCall, requiredRolesMap);
if (os != null) {
extCall.setCalledService_ExternalService(os);
extCall.setRole_ExternalService(requiredRolesMap.get(os.getInterface__OperationSignature()));
}

}

private OperationSignature getOperationSignature(ExternalCallAction extCall, HashMap<OperationInterface, OperationRequiredRole> requiredRolesMap) {

Collection<Object> filter = new ArrayList<Object>();

filter.add(Repository.class);
filter.add(OperationInterface.class);
filter.add(OperationSignature.class);

Collection<EReference> additionalChildReferences = new ArrayList<EReference>();

PalladioSelectEObjectDialog dialog = new PalladioSelectEObjectDialog(SHELL, filter, additionalChildReferences,
extCall.eResource().getResourceSet());


dialog.setProvidedService(OperationSignature.class);

for (Object o : dialog.getTreeViewer().getExpandedElements()) {
if (!(o instanceof OperationInterface)) //if the current object is not an OperationInterface, skip.
continue;

ResourceDemandingBehaviour rd = extCall.getResourceDemandingBehaviour_AbstractAction();

ServiceEffectSpecification seff = SEFFUtil.getEnclosingSEFF(rd);
BasicComponent parent = seff.getBasicComponent_ServiceEffectSpecification();

//if o is not referenced by any OperationRequiredRole, remove it from the tree viewer
OperationRequiredRole requiredRole = getOperationRequiredRole(parent.getRequiredRoles_InterfaceRequiringEntity(), (OperationInterface) o);
if (requiredRole != null)
requiredRolesMap.put((OperationInterface) o, requiredRole);
else
dialog.getTreeViewer().remove(o);


}

dialog.open();

return (OperationSignature) dialog.getResult();
}

private OperationRequiredRole getOperationRequiredRole(Collection<RequiredRole> requiredRoles, OperationInterface operationInterface) {
for (RequiredRole r : requiredRoles) {
if (!(r instanceof OperationRequiredRole))
continue;

if (((OperationRequiredRole) r).getRequiredInterface__OperationRequiredRole() == operationInterface)
return (OperationRequiredRole) r;
}
return null;
}


@Override
public boolean canExecute(Collection<? extends EObject> selections) {
return true;
}

public interface SignatureSelector {
OperationSignature selectOperationSignature(ExternalCallAction extCall,
Collection<OperationInterface> requiredInterfaces);
}

private final SignatureSelector signatureSelector;

public AddExternalCallAction() {
this(AddExternalCallAction::selectOperationSignature);
}

public AddExternalCallAction(SignatureSelector signatureSelector) {
this.signatureSelector = signatureSelector;
}

@Override
public void execute(Collection<? extends EObject> selections, Map<String, Object> parameters) {
ExternalCallAction extCall = (ExternalCallAction) parameters.get("instance");
if (extCall == null) {
return;
}
Map<OperationInterface, Collection<OperationRequiredRole>> requiredRolesMap = createRequiredRolesMap(extCall);
OperationSignature os = signatureSelector.selectOperationSignature(extCall, requiredRolesMap.keySet());
if (os != null) {
extCall.setCalledService_ExternalService(os);
Collection<OperationRequiredRole> potentialRoles = requiredRolesMap
.getOrDefault(os.getInterface__OperationSignature(), Collections.emptyList());
// TODO add selection logic for potentialRoles.size() > 1 as part of EDITORS-215
OperationRequiredRole firstrole = potentialRoles.isEmpty() ? null
: potentialRoles.iterator()
.next();
extCall.setRole_ExternalService(firstrole);
}

}

protected Map<OperationInterface, Collection<OperationRequiredRole>> createRequiredRolesMap(
ExternalCallAction eca) {
Map<OperationInterface, Collection<OperationRequiredRole>> result = new HashMap<OperationInterface, Collection<OperationRequiredRole>>();

ResourceDemandingBehaviour rd = eca.getResourceDemandingBehaviour_AbstractAction();
ServiceEffectSpecification seff = SEFFUtil.getEnclosingSEFF(rd);
BasicComponent parent = seff.getBasicComponent_ServiceEffectSpecification();
Collection<OperationRequiredRole> operationRequiredRoles = parent.getRequiredRoles_InterfaceRequiringEntity()
.stream()
.filter(OperationRequiredRole.class::isInstance)
.map(OperationRequiredRole.class::cast)
.collect(Collectors.toList());

// add required role and required interfaces to map
for (OperationRequiredRole operationRequiredRole : operationRequiredRoles) {
OperationInterface operationInterface = operationRequiredRole.getRequiredInterface__OperationRequiredRole();
Collection<OperationInterface> operationInterfaces = PCMQueryUtils.getTransitiveParentInterfaceClosureIncludingSelf(
operationInterface);
for (OperationInterface i : operationInterfaces) {
Collection<OperationRequiredRole> requiredRoles = result.computeIfAbsent(i,
key -> new LinkedHashSet<OperationRequiredRole>());
requiredRoles.add(operationRequiredRole);
}
}

return result;
}

protected static OperationSignature selectOperationSignature(ExternalCallAction extCall,
Collection<OperationInterface> requiredInterfaces) {
Collection<Object> filter = new ArrayList<Object>();
filter.add(Repository.class);
filter.add(OperationInterface.class);
filter.add(OperationSignature.class);

Collection<EReference> additionalChildReferences = new ArrayList<EReference>();
Shell shell = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getShell();
PalladioSelectEObjectDialog dialog = new PalladioSelectEObjectDialog(shell, filter, additionalChildReferences,
extCall.eResource()
.getResourceSet());

dialog.setProvidedService(OperationSignature.class);

for (Object o : dialog.getTreeViewer()
.getExpandedElements()) {
if (!(o instanceof OperationInterface)) { // if the current object is not an
// OperationInterface, skip.
continue;
}
if (!requiredInterfaces.contains(o)) {
dialog.getTreeViewer()
.remove(o);
}
}

dialog.open();

return (OperationSignature) dialog.getResult();
}

@Override
public boolean canExecute(Collection<? extends EObject> selections) {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.palladiosimulator.editors.commons.dialogs.selection.PalladioSelectEObjectDialog;
import org.palladiosimulator.editors.sirius.custom.util.PCMQueryUtils;
import org.palladiosimulator.pcm.repository.OperationInterface;
import org.palladiosimulator.pcm.repository.OperationProvidedRole;
import org.palladiosimulator.pcm.repository.OperationSignature;
Expand Down Expand Up @@ -46,22 +47,24 @@ private OperationSignature getOperationSignature(EntryLevelSystemCall element) {
filter.add(OperationInterface.class);
filter.add(OperationSignature.class);


Collection<EReference> additionalChildReferences = new ArrayList<EReference>();

PalladioSelectEObjectDialog dialog = new PalladioSelectEObjectDialog(SHELL, filter, additionalChildReferences,
element.eResource().getResourceSet());

Collection<OperationInterface> calledInterfaces = PCMQueryUtils
.getTransitiveParentInterfaceClosureIncludingSelf(element.getProvidedRole_EntryLevelSystemCall()
.getProvidedInterface__OperationProvidedRole());

dialog.setProvidedService(OperationSignature.class);


for (Object o : dialog.getTreeViewer().getExpandedElements()) {
if (!(o instanceof OperationInterface))
continue;
OperationInterface oi = (OperationInterface) o;
if (!element.getProvidedRole_EntryLevelSystemCall().getProvidedInterface__OperationProvidedRole().equals(oi))
dialog.getTreeViewer().remove(o);

if (!calledInterfaces.contains(oi)) {
dialog.getTreeViewer().remove(o);
}
}

dialog.open();
Expand All @@ -87,7 +90,6 @@ private OperationProvidedRole getOperationProvidedRole(EntryLevelSystemCall elem
return (OperationProvidedRole) dialog.getResult();
}


@Override
public boolean canExecute(final Collection<? extends EObject> arg0) {
return true;
Expand Down
33 changes: 0 additions & 33 deletions bundles/pom.xml

This file was deleted.

18 changes: 0 additions & 18 deletions features/pom.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<unit id="org.eclipse.sirius.runtime.ide.eef.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/releases/2021-09/202109151000/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="false" type="InstallableUnit">
<unit id="org.apache.commons.lang3" version="0.0.0"/>
<repository location="http://download.eclipse.org/tools/orbit/downloads/2021-09/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="false" type="InstallableUnit" filter="release">
<unit id="org.palladiosimulator.pcm.feature.feature.group" version="0.0.0"/>
<repository location="https://updatesite.palladio-simulator.com/palladio-core-pcm/releases/latest/"/>
Expand Down
14 changes: 0 additions & 14 deletions releng/org.palladiosimulator.editors.sirius.updatesite/pom.xml

This file was deleted.

18 changes: 0 additions & 18 deletions releng/pom.xml

This file was deleted.

Loading