blob: cb7282871b2efbcb861857f44ad6fab8de3b1fe5 [file] [log] [blame]
/*
-----------------------------------------------------------------------
-- CHESS validator plugin --
-- --
-- Copyright (C) 2011-2012 --
-- University of Padova, ITALY --
-- --
-- Author: Alessandro Zovi azovi@math.unipd.it --
-- Stefano Puri stefano.puri@intecs.it --
-- --
-- All rights reserved. This program and the accompanying materials --
-- are made available under the terms of the Eclipse Public License --
-- v1.0 which accompanies this distribution, and is available at --
-- http://www.eclipse.org/legal/epl-v20.html --
-----------------------------------------------------------------------
*/
package org.polarsys.chess.validator.libs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.impl.EReferenceImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.papyrus.MARTE.MARTE_AnalysisModel.GQAM.GaAnalysisContext;
import org.eclipse.papyrus.MARTE.MARTE_AnalysisModel.SAM.SaAnalysisContext;
import org.eclipse.papyrus.MARTE.MARTE_AnalysisModel.SAM.impl.SaAnalysisContextImpl;
import org.eclipse.papyrus.MARTE.MARTE_DesignModel.GCM.ClientServerPort;
import org.eclipse.papyrus.MARTE.MARTE_DesignModel.GCM.FlowPort;
import org.eclipse.papyrus.MARTE.MARTE_Foundations.Alloc.Assign;
import org.eclipse.papyrus.MARTE.MARTE_Foundations.NFPs.NfpConstraint;
import org.eclipse.papyrus.commands.wrappers.EMFtoGMFCommandWrapper;
import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.resource.IModel;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForActionHandlers;
import org.eclipse.papyrus.uml.tools.listeners.PapyrusStereotypeListener;
import org.eclipse.papyrus.uml.tools.model.ExtendedUmlModel;
import org.eclipse.papyrus.uml.tools.model.UmlModel;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Dependency;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.InterfaceRealization;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Realization;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.internal.impl.ClassImpl;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.polarsys.chess.chessmlprofile.ComponentModel.FunctionalPartition;
import org.polarsys.chess.chessmlprofile.Core.CHESS;
import org.polarsys.chess.chessmlprofile.Core.PSMPackage;
import org.polarsys.chess.chessmlprofile.Core.CHESSViews.AnalysisView;
import org.polarsys.chess.chessmlprofile.Core.CHESSViews.ComponentView;
import org.polarsys.chess.chessmlprofile.Core.CHESSViews.DeploymentView;
import org.polarsys.chess.chessmlprofile.Core.CHESSViews.PSMView;
import org.polarsys.chess.chessmlprofile.Core.CHESSViews.RTAnalysisView;
import org.polarsys.chess.chessmlprofile.Predictability.DeploymentConfiguration.HardwareBaseline.CH_HwProcessor;
import org.polarsys.chess.chessmlprofile.Predictability.RTComponentModel.CHRtSpecification;
import org.polarsys.chess.chessmlprofile.util.Constants;
import org.polarsys.chess.validator.automatedActions.IAutomatedAction;
import org.polarsys.chess.core.profiles.CHESSProfileManager;
import org.polarsys.chess.core.util.CHESSProjectSupport;
import org.polarsys.chess.core.util.uml.ModelError;
import org.polarsys.chess.core.util.uml.ResourceUtils;
import org.polarsys.chess.core.util.uml.UMLUtils;
import org.polarsys.chess.core.views.ViewUtils;
import org.polarsys.chess.service.gui.utils.CHESSEditorUtils;
import org.polarsys.chess.validator.Activator;
import org.polarsys.chess.validator.managers.AddDiagramElement;
import org.polarsys.chess.validator.messages.Messages;
/**
* The Class ActionsLib contains the implementation of the Automated Actions
*/
public class ActionsLib {
/** The port modification action. */
public static IAutomatedAction portModificationAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) {
Object notifier = notification.getNotifier();
// in case of modification of a clientserverport
if (notifier instanceof Port
&& notification.getEventType() == PapyrusStereotypeListener.MODIFIED_STEREOTYPE) {
// if
// (((EObject)notification.getNewValue()).eClass().getName().equals("ClientServerPort")){}
if (notification.getNewValue() instanceof ClientServerPort) {
if (((Port) notifier).getOwner() instanceof Component) {
Component comp = (Component) ((Port) notifier).getOwner();
if (!(UMLUtils.isComponentType(comp) && ViewUtils.isComponentView(ViewUtils.getView(comp))))
return null;
ClientServerPort port = (ClientServerPort) notification.getNewValue();
EList<Dependency> cDependenciesToRemove = UMLUtils.computeDependenciesToRemove(comp);
EList<InterfaceRealization> cRealizationsToRemove = UMLUtils.computeRealizationsToRemove(comp);
// CompositeCommand cc = new
// CompositeCommand("portAutomations");
// cc.add(new
// EMFtoGMFCommandWrapper(AddDiagramElement.destroyDependencies(domain,
// cDependenciesToRemove)));
// cc.add(new
// EMFtoGMFCommandWrapper(AddDiagramElement.destroyDependencies(domain,
// cRealizationsToRemove)));
// cc.add(new
// EMFtoGMFCommandWrapper(AddDiagramElement.createDependencies(domain,
// comp, port)));
// if (!cc.isEmpty()){
// return new GMFToEMFCommand(ccc);
// }
CompoundCommand ccc = new CompoundCommand("portAutomations");
ccc.append(AddDiagramElement.updateImplementationsPorts(domain, port));
ccc.append(AddDiagramElement.destroyDependencies(domain, cDependenciesToRemove));
ccc.append(AddDiagramElement.destroyDependencies(domain, cRealizationsToRemove));
ccc.append(AddDiagramElement.createDependencies(domain, comp, port));
return ccc;
}
}
else if(notification.getNewValue() instanceof FlowPort){
if (((Port) notifier).getOwner() instanceof Component) {
Component comp = (Component) ((Port) notifier).getOwner();
if (!(UMLUtils.isComponentType(comp) && ViewUtils.isComponentView(ViewUtils.getView(comp))))
return null;
FlowPort flPort = (FlowPort) notification.getNewValue();
CompoundCommand cc = new CompoundCommand("portAutomations");
cc.append(AddDiagramElement.updateImplementationsFlowPorts(domain, flPort));
return cc;
}
}
}
return null;
}
};
/** The port removal action. */
public static IAutomatedAction portRemovalAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) {
Object notifier = notification.getNotifier();
// in case of removal of a clientserverport or FlowPort
if ((notifier instanceof ClientServerPort || notifier instanceof FlowPort)
&& notification.getEventType() == Notification.SET) {
if (notification.getFeature() instanceof EReference
&& ((EReference) notification.getFeature()).getName().equals("base_Port")
&& notification.getNewValue() == null) {
Port p = (Port) notification.getOldValue();
Element el = p.getOwner();
if (!(el instanceof NamedElement
&& UMLUtils.isComponentType((NamedElement) el)
&& ViewUtils.isComponentView(ViewUtils.getView(el))))
return null;
Component comp = (Component) el;
EList<Dependency> cDependenciesToRemove = UMLUtils.computeDependenciesToRemove(comp);
EList<InterfaceRealization> cRealizationsToRemove = UMLUtils.computeRealizationsToRemove(comp);
CompoundCommand ccc = new CompoundCommand("portAutomations");
ccc.append(AddDiagramElement.removeImplementationsPorts(domain, p));
ccc.append(AddDiagramElement.destroyDependencies(domain,
cDependenciesToRemove));
ccc.append(AddDiagramElement.destroyDependencies(domain,
cRealizationsToRemove));
return ccc;
}
}
return null;
}
};
/*
* inherited operations are automatically added
*/
/** The component interface realization action. */
public static IAutomatedAction componentInterfaceRealizationAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) {
Object notifier = notification.getNotifier();
if (notifier instanceof Component) {
Component comp = (Component) notifier;
if (notification.getEventType() == Notification.ADD && notification.getNewValue() instanceof InterfaceRealization) {
InterfaceRealization link = (InterfaceRealization) notification.getNewValue();
Interface contract = link.getContract();
// cheks to be verified only in case the current component
// belongs to the functional view
if (ViewUtils.isComponentView(ViewUtils.getView(comp)) && UMLUtils.isComponentType(comp)) {
return AddDiagramElement.addOperationCommand(domain, contract, comp);
}
}
}
return null;
}
};
/** The component realization action. */
public static IAutomatedAction componentRealizationAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) {
Object notifier = notification.getNotifier();
Object feature = notification.getFeature();
if(feature instanceof EReference){
EReference ref = (EReference) feature;
if(notifier instanceof Realization && ref.getName().equals("supplier")){
Realization link = (Realization) notifier;
//get the client (ComponentImplementation) - according to the notifications chain, the client is set before the supplier
if (link.getClients().size() != 1)
return null;
Component clientComp = (Component) link.getClients().get(0);
//now get the supplier (ComponentType)
Object newVal = notification.getNewValue();
if(newVal instanceof Component){
Component supplierComp = (Component) newVal;
//checks to be verified only in case the current ComponentImplementation belongs to the functional view
if (!ViewUtils.isComponentView(ViewUtils.getView(clientComp)) || !UMLUtils.isComponentImplementation(clientComp))
return null;
//add operations and ports to the client (ComponentImplementation)
CompositeCommand cc = new CompositeCommand("portAndOpCommand");
Command cmd = AddDiagramElement.addOperationCommand(domain, supplierComp, clientComp);
cc.add(new EMFtoGMFCommandWrapper(cmd));
Command cmd2 = AddDiagramElement.addAllPortsCommand(domain, supplierComp, clientComp);
cc.add(new EMFtoGMFCommandWrapper(cmd2));
if (!cc.isEmpty()) {
return new GMFtoEMFCommandWrapper(cc);
}
}
}
}
return null;
}
};
/** The remove realization operations action. */
public static IAutomatedAction removeRealizationOperationsAction = new IAutomatedAction() {
private IStatus operationAborted = new Status(IStatus.ERROR,
Activator.PLUGIN_ID, Messages.operationAborted);
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Component) {
Component comp = (Component) notifier;
// Deletion of a Realization link
if (notification.getEventType() == Notification.REMOVE
&& notification.getOldValue().getClass().equals(Realization.class) && notification.getFeature() instanceof EReference && ((EReference)notification.getFeature()).getName().equals("clientDependency")) {
Package view = ViewUtils.getView((Component) notifier);
// checks to be verified only in case the current component
// belongs to the functional view
Realization rel = (Realization) notification.getOldValue();
if (!(ViewUtils.isComponentView(view) && UMLUtils.isComponentImplementation(comp)))
return null;
PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor();
if (editor == null)
return null;
MessageDialog md = CHESSEditorUtils.showConfirmDialog(editor, "Confirm", "Do you want to propagate the removal of the operations of this realization "+rel.getName()+"?");
// * 0 - OK
int result = md.open();
if (result == 0){
return deleteOperations(comp, view, domain);
}
// CANCEL
if (result == 2){
CHESSProjectSupport.CHESS_CONSOLE.println(operationAborted.getMessage());
// TODO why?
//throw new RollbackException(operationAborted);
}
}
}
return null;
}
//TODO it needs to be checked
private Command deleteOperations(Component component, Package view,
TransactionalEditingDomain domain) {
CompositeCommand cmd = new CompositeCommand("delOpCommand");
// Delete all the operations of the component
// implementation
ArrayList<Operation> opToDel = new ArrayList<Operation>();
// Delete all the activity diagram
ArrayList<Behavior> behaviorToDel = new ArrayList<Behavior>();
// Delete all the owned port
ArrayList<Port> portToDel = new ArrayList<Port>();
// Delete all ChRtSpecification attached to the ports
ArrayList<Comment> commentToDel = new ArrayList<Comment>();
for (Operation op : component.getOwnedOperations()) {
opToDel.add(op);
behaviorToDel.addAll(op.getMethods());
}
for (Port p : component.getOwnedPorts()) {
if (!UMLUtils.isClientServerPort(p))
continue;
portToDel.add(p);
commentToDel.addAll(UMLUtils.getCHRtSpecificationComments(view, p));
}
behaviorToDel.addAll(component.getOwnedBehaviors());
DeleteCommand delC = new DeleteCommand(domain, opToDel);
cmd.add(new EMFtoGMFCommandWrapper(delC));
if (portToDel.size() > 0) {
for (int i = 0; i < portToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(portToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
portToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if (commentToDel.size() > 0) {
for (int i = 0; i < commentToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(commentToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
commentToDel.get(i), false);
ICommand deleteCommand = provider.getEditCommand(request);
cmd.add(deleteCommand);
}
}
// remove all the bahavior related to the selected
// operation
if (behaviorToDel.size() > 0) {
for (int i = 0; i < behaviorToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(behaviorToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
behaviorToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
return null;
}
};
/** The propagate operation modification. */
public static IAutomatedAction propagateOperationModification = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Operation) {
// in case of addition
if (notification.getEventType() == Notification.SET) {
Operation op = (Operation) notifier;
EObject container = op.eContainer();
// if (container == null && notification.getOldValue() instanceof Interface){
// container = (EObject) notification.getOldValue();
// }
if (!(container instanceof Interface))
return null;
if (!ViewUtils.isComponentView(ViewUtils.getView(container)))
return null;
EList<Component> relationships = UMLUtils.getAllInterfaceComponents((Interface) container);
if (relationships == null || relationships.isEmpty())
return null;
CompositeCommand cmd = new CompositeCommand("setCommand");
for (Component comp : relationships) {
propagateFeature(notification, domain, op, cmd, comp);
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
}
}
return null;
}
private void propagateFeature(Notification notification,
TransactionalEditingDomain domain, Operation op,
CompositeCommand cmd, Component comp) {
String opName = op.getName();
if (notification.getFeature() instanceof EAttribute && ((EAttribute)notification.getFeature()).getName().equals("name"))
opName = (String) notification.getOldValue();
for (Operation cOperation : comp.getOwnedOperations()) {
if (cOperation.getName().equalsIgnoreCase(opName)) {
if (UMLUtils.areParametersEquals(cOperation, op)) {
SetCommand setC = new SetCommand(domain, cOperation, (EStructuralFeature) notification.getFeature(),
notification.getNewValue());
cmd.add(new EMFtoGMFCommandWrapper(setC));
}
}
}
}
};
/** The propagate interface modification. */
public static IAutomatedAction propagateInterfaceModification = new IAutomatedAction() {
private IStatus operationAborted = new Status(IStatus.ERROR,
Activator.PLUGIN_ID, Messages.operationAborted);
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Interface) {
Interface interfce = (Interface) notifier;
if (notification.getEventType() == Notification.ADD
&& notification.getNewValue() instanceof Operation) {
Operation operation = (Operation) notification.getNewValue();
// checks to be verified only in case the current component
// belongs to the functional view
if (ViewUtils.isComponentView(ViewUtils.getView(interfce))) {
return AddDiagramElement.addOperationCommand1(domain, interfce, operation);
}
}
// Deletion of an operation belonging to an interface
if (notification.getEventType() == Notification.REMOVE
&& notification.getOldValue() instanceof Operation) {
Operation operation = (Operation) notification.getOldValue();
if (!ViewUtils.isComponentView(ViewUtils.getView(interfce)))
return null;
PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor();
if (editor == null)
return null;
MessageDialog md = CHESSEditorUtils.showConfirmDialog(editor, "Confirm", "Do you want to propagate the removal of "+operation.getName()+" from all the related model elements?");
// * 0 - OK
int result = md.open();
// * 0 - OK
// * 1 - No
// * 2 - Cancel
switch (result) {
case 0:
EList<Component> relationships = UMLUtils.getAllInterfaceComponents(interfce);
CompositeCommand cmd = new CompositeCommand("delOpCommand");
ArrayList<Operation> opToDel = new ArrayList<Operation>();
ArrayList<Behavior> behaviorToDel = new ArrayList<Behavior>();
//opToDel.add(operation);
for (Component cmp : relationships) {
for (Operation op : cmp.getOwnedOperations()) {
if (UMLUtils.isOperationEquals(op, operation)) {
opToDel.add(op);
behaviorToDel.addAll(op.getMethods());
}
}
}
cmd.add(new EMFtoGMFCommandWrapper(new DeleteCommand(domain, opToDel)));
// Remove all <<ChRtSpecification>> with the context
// attribute set to the equivalent operation of the
// component implementation
// <<ChRtSpecification>> are only inside system
ArrayList<Comment> commentToDel = new ArrayList<Comment>();
for (Notification aNotification : notificationList) {
if (aNotification.equals(notification))
continue;
if (aNotification.getNotifier() instanceof CHRtSpecification
&& aNotification.getEventType() == Notification.SET) {
if (aNotification.getOldValue() instanceof Operation && aNotification.getOldValue().equals(operation)) {
commentToDel.add(((CHRtSpecification) aNotification.getNotifier()).getBase_Comment());
}
}
}
if (!commentToDel.isEmpty()) {
for (Comment comment : commentToDel) {
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(comment);
if (provider == null)
continue;
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(comment, false);
ICommand deleteCommand = provider.getEditCommand(request);
cmd.add(deleteCommand);
}
}
// remove all the bahavior related to the selected
// operation
if (!behaviorToDel.isEmpty()) {
for (Behavior behavior : behaviorToDel) {
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(behavior);
if (provider == null)
continue;
DestroyElementRequest request = new DestroyElementRequest(behavior, false);
ICommand deleteCommand = provider.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
break;
case 2:
CHESSProjectSupport.CHESS_CONSOLE.println(operationAborted.getMessage());
throw new RollbackException(operationAborted);
}
}
}
return null;
}
};
/** The propagate parameter removal action. */
public static IAutomatedAction propagateParameterRemovalAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Operation) {
if ((notification.getEventType() == Notification.REMOVE && notification
.getOldValue() instanceof Parameter)) {
Parameter param = (Parameter) notification.getOldValue();
Operation operation = (Operation) notifier;
CompositeCommand cmd = new CompositeCommand("delCommand");
EObject opCont = operation.eContainer();
if (!(opCont instanceof Interface) || !ViewUtils.isComponentView(ViewUtils.getView(opCont)))
return null;
EList<Component> relationships = UMLUtils.getAllInterfaceComponents((Interface) opCont);
if (relationships == null || relationships.isEmpty())
return null;
for (Component comp : relationships) {
checkOperation:
for (Operation op : comp.getOwnedOperations()) {
if (!UMLUtils.areOperationsEqual(op, operation, param))
continue;
for (Parameter p : op.getOwnedParameters()) {
if (UMLUtils.areParametersEqual(p, param)) {
cmd.add(new DestroyElementCommand(new DestroyElementRequest(p, false)));
break checkOperation;
}
}
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
}
//case REMOVE_MANY
if ((notification.getEventType() == Notification.REMOVE_MANY && notification
.getOldValue() instanceof EList)) {
@SuppressWarnings("rawtypes")
EList paramList = (EList) notification.getOldValue();
boolean test = true;
for (Object ob : paramList){
if ((ob instanceof Parameter)) {
Parameter param = (Parameter) ob;
Operation operation = (Operation) notifier;
CompositeCommand cmd = new CompositeCommand("delCommand");
EObject opCont = operation.eContainer();
if (!(opCont instanceof Interface) || !ViewUtils.isComponentView(ViewUtils.getView(opCont)))
return null;
EList<Component> relationships = UMLUtils.getAllInterfaceComponents((Interface) opCont);
for (Component comp : relationships) {
checkOperation:
for (Operation op : comp.getOwnedOperations()) {
if (!UMLUtils.areOperationsEqual(op, operation, param))
continue;
for (Parameter p : op.getOwnedParameters()) {
if (UMLUtils.areParametersEqual(p, param)) {
cmd.add(new DestroyElementCommand(new DestroyElementRequest(p, false)));
break checkOperation;
}
}
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
}
}
}
// end case
}
return null;
}
};
/** The propagate parameter addition action. */
public static IAutomatedAction propagateParameterAdditionAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Operation) {
if ((notification.getEventType() == Notification.ADD && notification
.getNewValue() instanceof Parameter)) {
Parameter param = (Parameter) notification.getNewValue();
Operation operation = param.getOperation();
EObject opCont = operation.eContainer();
if ((opCont instanceof Interface) && ViewUtils.isComponentView(ViewUtils.getView(opCont)))
return AddDiagramElement.addParameterCommand((Interface) opCont, param, operation, domain);
}
if (notification.getEventType() == Notification.ADD_MANY && notification.getNewValue() instanceof EList){
@SuppressWarnings("rawtypes")
EList paramList = (EList) notification.getNewValue();
boolean test = true;
EObject opCont = null;
Operation operation = null;
for (Object ob : paramList){
if (!(ob instanceof Parameter)) {
test = false;
break;
}else{
Parameter par = (Parameter) ob;
operation = par.getOperation();
opCont = operation.eContainer();
if (!(opCont instanceof Interface) || !(ViewUtils.isComponentView(ViewUtils.getView(opCont)))){
test = false;
break;
}
}
}
if (test){
Parameter param = (Parameter) paramList.get(paramList.size() - 1);
return AddDiagramElement.addParameterCommand((Interface) opCont, param, operation, domain);
}
}
}
return null;
}
};
/** The comment action. */
public static IAutomatedAction commentAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
if (notification.getNotifier() instanceof Comment) {
Comment comment = (Comment) notification.getNotifier();
if (notification.getEventType() == PapyrusStereotypeListener.APPLIED_STEREOTYPE) {
return AddDiagramElement.addCommentCommand(domain, comment);
}
if (notification.getEventType() == PapyrusStereotypeListener.UNAPPLIED_STEREOTYPE) {
return AddDiagramElement.removeCommentCommand(domain, comment);
}
}
return null;
}
};
/** The port addition action. */
public static IAutomatedAction portAdditionAction = new IAutomatedAction() {
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
if (notification.getNotifier() instanceof Port && notification.getEventType()==Notification.SET && notification.getFeature() instanceof EAttribute && ((EAttribute)notification.getFeature()).getName().equals("visibility")){
Port port = (Port)notification.getNotifier();
Element supplierComp = port.getOwner();
if (!(UMLUtils.isClientServerPort(port) && UMLUtils.isComponentType(supplierComp)))
return null;
CompositeCommand cc = new CompositeCommand("portAndOpCommand");
for(Component cImpl: UMLUtils.getComponentImplementations((Component) supplierComp)){
Command cmd2 = AddDiagramElement.addPortCommand(domain, (Component) supplierComp, cImpl, port);
cc.add(new EMFtoGMFCommandWrapper(cmd2));
}
if (!cc.isEmpty()) {
return new GMFtoEMFCommandWrapper(cc);
}
}
return null;
}
};
/** The propagate port modification. */
public static IAutomatedAction propagatePortModification = new IAutomatedAction() {
@Override
public Command compile(Notification notification, List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof Port) {
// in case of addition
if (notification.getEventType() == Notification.SET) {
//PAPYRUS BUG: do NOT propagate the name "Port0"
if (notification.getFeature() instanceof EAttribute && ((EAttribute)notification.getFeature()).getName().equals("name") && notification.getNewValue().equals("Port0"))
return null;
Port port = (Port) notifier;
EObject container = port.eContainer();
if (!(container instanceof Component))
return null;
if (!ViewUtils.isComponentView(ViewUtils.getView(container)) || !UMLUtils.isComponentType(container))
return null;
EList<Component> relationships = UMLUtils.getComponentImplementations((Component) container);
if (relationships == null || relationships.isEmpty())
return null;
CompositeCommand cmd = new CompositeCommand("setCommand");
for (Component comp : relationships) {
propagateFeature(notification, domain, port, cmd, comp);
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
}
}
return null;
}
private void propagateFeature(Notification notification,
TransactionalEditingDomain domain, Port port,
CompositeCommand cmd, Component comp) {
String opName = port.getName();
if (notification.getFeature() instanceof EAttribute && ((EAttribute)notification.getFeature()).getName().equals("name"))
opName = (String) notification.getOldValue();
Type portType = port.getType();
if (notification.getFeature() instanceof EAttribute && ((EAttribute)notification.getFeature()).getName().equals("type"))
portType = (Type) notification.getOldValue();
Port portComp = comp.getOwnedPort(opName, portType);
if (portComp == null)
return;
SetCommand setC = new SetCommand(domain, portComp, (EStructuralFeature) notification.getFeature(),
notification.getNewValue());
cmd.add(new EMFtoGMFCommandWrapper(setC));
}
};
// LB 20150929 for todo#26
/** The core modification action. */
public static IAutomatedAction coreModificationAction = new IAutomatedAction() {
private IStatus operationAborted = new Status(IStatus.ERROR,
Activator.PLUGIN_ID, Messages.operationAborted);
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (notifier instanceof CH_HwProcessor) {
CH_HwProcessor chHwProcessor = (CH_HwProcessor) notifier;
if (chHwProcessor.getBase_Classifier() == null){
return null;
}
String chHwProcessorName = chHwProcessor.getBase_Classifier().getName();
if (notification.getEventType() == Notification.SET) {
if (notification.getFeature() instanceof EAttribute &&
((EAttribute)notification.getFeature()).getName().equals(Constants.CHHWPROCESSOR_NB_CORES)) {
Object oldValue = notification.getOldValue();
Object newValue = notification.getNewValue();
if (oldValue!=null && newValue!=null &&
Integer.parseInt(oldValue.toString()) <= Integer.parseInt(newValue.toString())) {
// if we are increasing the number of cores or not changing it, do nothing
return null;
}
// Ask user if he is sure he wants to modify this attribute,
// warning that the associations to the processor will be deleted
PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor();
if (editor == null) {
return null;
}
MessageDialog md = CHESSEditorUtils.showConfirmDialog(editor, "Confirm", "Do you want to propagate the removal of the associations related to this processor "+chHwProcessorName);
int result = md.open();
if (result == 0) {
Model umlModel = ((Element)chHwProcessor.getBase_Classifier()).getModel();
Classifier chHwProcClassifier = chHwProcessor.getBase_Classifier();
return deleteAssignments(umlModel, chHwProcClassifier, Constants.DEPLOYMENT_VIEW_NAME, domain);
}
// CANCEL
if (result == 2) {
CHESSProjectSupport.CHESS_CONSOLE.println(operationAborted.getMessage());
// TODO why?
//throw new RollbackException(operationAborted);
}
}
return null;
}
}
return null;
}
};
/**
* Delete all assignments to this processor: this deletes all the comments that are assignments to the
* processor and all the related nfpConstraints (if any)
* @param chHwProcClassifier
* @param umlModel
* @param viewName
* @param domain
* @return
*/
private static Command deleteAssignments(Model umlModel, Classifier chHwProcClassifier, String viewName,
TransactionalEditingDomain domain) {
CompositeCommand cmd = new CompositeCommand("delAssignmentsCommand");
//Delete all assignments to this Processor
ArrayList<Comment> assignmentsToDel = new ArrayList<Comment>();
ArrayList<Constraint> nfpConstraintsToDel = new ArrayList<Constraint>();
try {
for (Assign assignment : UMLUtils.getAll2CoreAssignments(umlModel , viewName)) {
Element to = assignment.getTo().get(0);
Comment assignComment =assignment.getBase_Comment();
if (to instanceof InstanceSpecification) {
InstanceSpecification instSpec = (InstanceSpecification)to;
Classifier theClassifier = instSpec.getClassifiers().get(0);
if (theClassifier.equals(chHwProcClassifier)) {
assignmentsToDel.add(assignComment);
if (assignment.getImpliedConstraint().size() > 0) {
for (Object c : assignment.getImpliedConstraint().toArray()) {
if (c instanceof NfpConstraint) {
NfpConstraint n = (NfpConstraint) c;
nfpConstraintsToDel.add(n.getBase_Constraint());
}
}
}
}
}
}
}
catch (ModelError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (assignmentsToDel.size()>0) {
for (int i = 0; i < assignmentsToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(assignmentsToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
assignmentsToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if(nfpConstraintsToDel.size()>0) {
for (int i = 0; i < nfpConstraintsToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(nfpConstraintsToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
nfpConstraintsToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
return null;
};
/** The partitions modification action. */
public static IAutomatedAction partitionsModificationAction = new IAutomatedAction() {
private IStatus operationAborted = new Status(IStatus.ERROR,
Activator.PLUGIN_ID, Messages.operationAborted);
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
Object notifier = notification.getNotifier();
if (!(notifier instanceof Element)) {
return null;
}
if (notification.getEventType() == Notification.SET) {
if (notifier instanceof Property) {
Object oldValue = notification.getOldValue();
if(oldValue == null) {
return null;
}
Object feature = notification.getFeature();
if (feature instanceof EReferenceImpl) {
EReferenceImpl feat = (EReferenceImpl)feature;
if(feat.getName().equals("type")) {
if (oldValue instanceof Component) {
Component oldValueComponent = (Component)oldValue;
if(oldValueComponent.getAppliedStereotype(Constants.CH_FunctionalPartition)!=null) {
Stereotype functionalPartitionStereo = oldValueComponent.getAppliedStereotype(Constants.CH_FunctionalPartition);
EObject functPartObj = oldValueComponent.getStereotypeApplication(functionalPartitionStereo);
FunctionalPartition functPart = (FunctionalPartition)functPartObj;
System.out.println("found a functional partition"+functPart.toString());
// Ask user if he is sure he wants to modify this attribute,
// warning that the associations to the processor will be deleted
PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor();
if (editor == null) {
return null;
}
MessageDialog md = CHESSEditorUtils.showConfirmDialog(editor, "Confirm", "Do you want to propagate the removal of the associations related to functional partitions?");
int result = md.open();
if (result == 0) {
Model umlModel = functPart.getBase_Component().getModel();
return deletePartitionAssignments(umlModel, functPart, domain);
}
// CANCEL
if (result == 2) {
CHESSProjectSupport.CHESS_CONSOLE.println(operationAborted.getMessage());
// TODO why?
//throw new RollbackException(operationAborted);
}
}
}
}
}
}
return null;
}
// }
return null;
}
/**
* Delete all assignments that have the input functional partition
* either in the To field (Component to Partition Assignment), or
* in the From field (Partition to ProcessorAssignment)
* and all the related nfpConstraints (if any)
*
* @param umlModel
* @param functPart
* @param viewName
* @param domain
* @return
*/
private Command deletePartitionAssignments(Model umlModel, FunctionalPartition functPart,
TransactionalEditingDomain domain) {
CompositeCommand cmd = new CompositeCommand("delPartitionAssignmentsCommand");
//Delete all assignments to or from Partitions
ArrayList<Comment> assignmentsToDel = new ArrayList<Comment>();
ArrayList<Constraint> nfpConstraintsToDel = new ArrayList<Constraint>();
try {
for (Assign assignment : UMLUtils.getPartitionAssignments(umlModel , functPart)) {
Comment assignComment =assignment.getBase_Comment();
assignmentsToDel.add(assignComment);
if (assignment.getImpliedConstraint().size() > 0) {
for (Object c : assignment.getImpliedConstraint().toArray()) {
if (c instanceof NfpConstraint) {
NfpConstraint n = (NfpConstraint) c;
nfpConstraintsToDel.add(n.getBase_Constraint());
}
}
}
}
}
catch (ModelError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (assignmentsToDel.size()>0) {
for (int i = 0; i < assignmentsToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(assignmentsToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
assignmentsToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if(nfpConstraintsToDel.size()>0) {
for (int i = 0; i < nfpConstraintsToDel.size(); i++) {
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(nfpConstraintsToDel.get(i));
if (provider == null) {
continue;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
nfpConstraintsToDel.get(i), false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
}
}
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
return null;
}
};
// LB 20160517 for deleting automatically the PSM Package related to an saAnalysisContext that is being deleted
/** The deletion of a saAnalysisContext action. */
public static IAutomatedAction saAnalysisContextDeletionAction = new IAutomatedAction() {
private IStatus operationAborted = new Status(IStatus.ERROR,
Activator.PLUGIN_ID, Messages.operationAborted);
@Override
public Command compile(Notification notification,
List<Notification> notificationList,
TransactionalEditingDomain domain) throws RollbackException {
PSMPackage psmPackageStereoToDelete = null;
Object notifier = notification.getNotifier();
Package psmPackageToDelete = null;
org.eclipse.uml2.uml.Class oldAnalysisContextClass = null;
Object feature = notification.getFeature();
if (notifier instanceof SaAnalysisContext && notification.getNewValue()== null &&
notification.getOldValue() instanceof org.eclipse.uml2.uml.Class && notification.getEventType() == Notification.SET
&& (feature instanceof EReferenceImpl) && ((EReferenceImpl) feature).getName().equals("base_StructuredClassifier")
){
//check if there is a PSMPackage which refer this SaAnalysisContext
oldAnalysisContextClass = (org.eclipse.uml2.uml.Class) notification.getOldValue();
PapyrusMultiDiagramEditor editor = (PapyrusMultiDiagramEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().getActiveEditor();
Resource res = null;
try {
res = ResourceUtils.getUMLResource(editor.getServicesRegistry());
} catch (ServiceException e) {
CHESSProjectSupport.CHESS_CONSOLE.println("Unable to retrieve the UML resource via the Service Registry");
e.printStackTrace();
return null;
}
Model model = ResourceUtils.getModel(res);
CHESS chess = (CHESS) model.getStereotypeApplication(model.getAppliedStereotype("CHESS::Core::CHESS"));
PSMView psmView = chess.getPsmView();
Package psmViewPkg = psmView.getBase_Package();
for (Package p : psmViewPkg.getNestedPackages()){
if (p.getAppliedStereotype("CHESS::Core::PSMPackage") != null){
PSMPackage psmPackageStero = (PSMPackage) p.getStereotypeApplication(p.getAppliedStereotype("CHESS::Core::PSMPackage"));
if (notifier.equals(psmPackageStero.getAnalysisContext())){
psmPackageStereoToDelete = psmPackageStero;
psmPackageToDelete = psmPackageStero.getBase_Package();
}
}
}
}
// If the PSM Package related to this SaAnalysisContext does not exist (e.g. has been purged)
if (psmPackageStereoToDelete == null) {
return null;
}
String saAnalysisContextName = "";
if(oldAnalysisContextClass.getName() != null) {
saAnalysisContextName = oldAnalysisContextClass.getName();
}
String psmPackageName = "";
if (psmPackageToDelete!= null && psmPackageToDelete.getName() != null) {
psmPackageName = psmPackageToDelete.getName();
}
// Ask user if he is sure he wants to delete this saAnalysisContext
// warning that the related PSM Package will be deleted
PapyrusMultiDiagramEditor editor = CHESSEditorUtils.getCHESSEditor();
if (editor == null) {
return null;
}
MessageDialog md = CHESSEditorUtils.showConfirmDialog(editor, "Confirm",
"Do you want to remove also the PSM Package: "+psmPackageName+" related to the SaAnalysisContext: "+saAnalysisContextName+" ?");
int result = md.open();
// OK
if (result == 0) {
Model umlModel = oldAnalysisContextClass.getModel();
if (psmPackageToDelete != null) {
Command cmd = deletePackage(umlModel, psmPackageToDelete);
return cmd;
}
return null;
}
// CANCEL
if (result == 2) {
CHESSProjectSupport.CHESS_CONSOLE.println(operationAborted.getMessage());
throw new RollbackException(operationAborted);
}
// NO
if (result == 1) {
return null;
}
return null;
}
/**
* Delete the given Package
* (used to delete the PSM package related to a saAnalysisContext that was deleted)
* @param umlModel
* @param thePackage
* @return
*/
private Command deletePackage(Model umlModel, Package thePackage) {
CompositeCommand cmd = new CompositeCommand("delPackageCommand");
IElementEditService provider = ElementEditServiceUtils
.getCommandProvider(thePackage);
if (provider == null) {
return null;
}
// Retrieve delete command from the Element Edit
// service
DestroyElementRequest request = new DestroyElementRequest(
thePackage, false);
ICommand deleteCommand = provider
.getEditCommand(request);
cmd.add(deleteCommand);
if (!cmd.isEmpty())
return new GMFtoEMFCommandWrapper(cmd);
return null;
}
};
// public static IAutomatedAction[] actionList = {portModificationAction,
// portRemovalAction, componentInterfaceRealizationAction,
// componentRealizationAction, removeRealizationOperationsAction,
// propagateOperationModification, propagateInterfaceModification,
// propagateParameterRemovalAction, propagateParameterAdditionAction,
// commentAction, portAdditionAction, propagatePortModification};
/** The static list of the actions that will be checked at run-time. */
public static IAutomatedAction[] actionList = {portModificationAction,
componentInterfaceRealizationAction, componentRealizationAction,
commentAction, coreModificationAction, saAnalysisContextDeletionAction, partitionsModificationAction};
}