blob: 0c050910230a96fc130778e5ffc5d0bbbc4e2490 [file] [log] [blame]
/*
-----------------------------------------------------------------------
-- CHESS Live/Batch Validator plugin --
-- --
-- Copyright (C) 2011-2012 --
-- University of Padova, ITALY --
-- --
-- --
-- --
-- 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.constraints;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.validation.AbstractModelConstraint;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.uml2.uml.Abstraction;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.Dependency;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.Port;
import org.polarsys.chess.chessmlprofile.util.Constants;
import org.polarsys.chess.core.util.uml.UMLUtils;
/**
* The Class FlowPorts_03.
* This class implements the following constraint (invoked by the EMF validation framework):
* The FlowPort should be mapped to parameters according to their directions, ie:
* port direction IN -> param direction IN or INOUT (param of PROVIDED operation)
* port direction OUT -> param direction OUT or INOUT (param of PROVIDED operation)
* port direction IN -> param direction OUT or INOUT (param of REQUIRED operation)
* port direction OUT -> param direction IN or INOUT (param of REQUIRED operation)
* port direction INOUT -> param direction IN or OUT or INOUT (param of REQUIRED or PROVIDED operation)
*/
public class FlowPorts_03 extends AbstractModelConstraint {
/* (non-Javadoc)
* @see org.eclipse.emf.validation.AbstractModelConstraint#validate(org.eclipse.emf.validation.IValidationContext)
*/
@Override
public IStatus validate(IValidationContext ctx) {
IStatus success = ctx.createSuccessStatus();
IStatus failure = ctx.createFailureStatus();
Port port = (Port) ctx.getTarget();
if(port.getAppliedStereotype(Constants.FLOW_PORT) == null){
return success;
}
Element owner = port.getOwner();
if(!UMLUtils.isComponentType(owner)){
return success;
}
/* if it is a flow port of a component type, each of its mapped parameters should have the direction consistent. ie:
* port direction IN -> param direction IN or INOUT (param of PROVIDED operation)
* port direction OUT -> param direction OUT or INOUT (param of PROVIDED operation)
* port direction IN -> param direction OUT or INOUT (param of REQUIRED operation)
* port direction OUT -> param direction IN or INOUT (param of REQUIRED operation)
* port direction INOUT -> param direction IN or OUT orINOUT (param of REQUIRED or PROVIDED operation)
* note: creating a mapping will avoid this issue, but changing the direction of the port
* or of another parameter at a different time is possible and may result in an erratic situation
*/
Component comp = (Component) owner;
String portDirection = port.getValue(port.getAppliedStereotype(Constants.FLOW_PORT),
Constants.FLOW_PORT_DIRECTION).toString();
EList<Dependency> dependencies = port.getClientDependencies();
for (Dependency dep : dependencies) {
if (dep instanceof Abstraction && dep.getAppliedStereotype(Constants.MARTE_ALLOCATE) != null){
EList<NamedElement> suppList = dep.getSuppliers();
for (NamedElement nElem : suppList) {
if(nElem instanceof Parameter){
Parameter param = (Parameter) nElem;
String paramDirection = param.getDirection().toString();
Operation op = param.getOperation();
if(provided(op, comp)){
if((portDirection.equals(Constants.FLOW_PORT_DIRECTION_IN) &&
paramDirection.equals(Constants.FLOW_PORT_DIRECTION_OUT)) ||
(portDirection.equals(Constants.FLOW_PORT_DIRECTION_OUT) &&
paramDirection.equals(Constants.FLOW_PORT_DIRECTION_IN))){
return failure;
}
}else{
if((portDirection.equals(Constants.FLOW_PORT_DIRECTION_IN) &&
paramDirection.equals(Constants.FLOW_PORT_DIRECTION_IN)) ||
(portDirection.equals(Constants.FLOW_PORT_DIRECTION_OUT) &&
paramDirection.equals(Constants.FLOW_PORT_DIRECTION_OUT))){
return failure;
}
}
}
}
}
}
return null;
}
/**
* Provided.
*
* @param op the op
* @param comp the comp
* @return true, if successful
*/
private boolean provided(Operation op, Component comp) {
boolean provided = false;
for (Operation operation : comp.getAllOperations()) {
if(operation.getName().equals(op.getName())){
provided = true;
break;
}
}
return provided;
}
}