| /* |
| ----------------------------------------------------------------------- |
| -- CHESS Live/Batch Validator plugin -- |
| -- -- |
| -- Copyright (C) 2011-2012 -- |
| -- University of Padova, ITALY -- |
| -- -- |
| -- Author: Nicholas Pacini -- |
| -- -- |
| -- 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.ecore.util.EObjectResolvingEList; |
| import org.eclipse.emf.validation.AbstractModelConstraint; |
| import org.eclipse.emf.validation.IValidationContext; |
| import org.eclipse.papyrus.MARTE.MARTE_DesignModel.GCM.ClientServerKind; |
| import org.eclipse.papyrus.MARTE.MARTE_DesignModel.GCM.ClientServerPort; |
| import org.eclipse.uml2.uml.Connector; |
| import org.eclipse.uml2.uml.ConnectorEnd; |
| import org.eclipse.uml2.uml.Interface; |
| import org.eclipse.uml2.uml.Port; |
| import org.eclipse.uml2.uml.Property; |
| import org.eclipse.uml2.uml.Stereotype; |
| import org.polarsys.chess.chessmlprofile.util.Constants; |
| |
| /** |
| * The Class Connector_01. |
| * Check if Interfaces provided and/or required in Ports are not compatible, or components are not at the same level |
| */ |
| public class Connector_01 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(); |
| |
| Connector con = (Connector) ctx.getTarget(); |
| |
| String thisElement = ""; |
| thisElement = con.getName(); |
| |
| String errorMsg = ""; |
| IStatus failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| |
| try{ |
| //check that ports are compatible (provided-required) |
| ConnectorEnd ceFir = con.getEnds().get(0); |
| if(!(ceFir.getRole() instanceof Port)){ |
| errorMsg = "First end is not a port"; |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| Port portFir = (Port) ceFir.getRole(); |
| //Stereotype sFirst = portFir.getAppliedStereotype(Constants.CLIENTSERVER_PORT); |
| Stereotype clientServerPortStereo1 = portFir.getAppliedStereotype(Constants.CLIENTSERVER_PORT); |
| if(clientServerPortStereo1 == null){ |
| return success; |
| } |
| |
| ClientServerPort clientServerPort1 = (ClientServerPort) portFir.getStereotypeApplication(clientServerPortStereo1); |
| ClientServerKind kind1 = clientServerPort1.getKind(); |
| |
| //String first = portFir.getValue(sFirst, Constants.CSPORT_KIND).toString(); |
| ConnectorEnd ceSec = con.getEnds().get(1); |
| if(!(ceSec.getRole() instanceof Port)){ |
| errorMsg = "Second end is not a port"; |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| Port portSec = (Port) ceSec.getRole(); |
| Stereotype clientServerPortStereo2 = portSec.getAppliedStereotype(Constants.CLIENTSERVER_PORT); |
| if(clientServerPortStereo2 == null){ |
| return success; |
| } |
| ClientServerPort clientServerPort2 = (ClientServerPort)portSec.getStereotypeApplication(clientServerPortStereo2); |
| ClientServerKind kind2 = clientServerPort2.getKind(); |
| |
| if(kind1.equals(kind2)){ |
| //it's not an automatic failure if it's port delegation between parent and child |
| if(ceFir.getPartWithPort() == null || ceSec.getPartWithPort() == null){ |
| return success; |
| } |
| if(ceFir.getPartWithPort() instanceof Property || ceSec.getPartWithPort() instanceof Property){ |
| Property prFirst = ceFir.getPartWithPort(); |
| Property prSec = ceSec.getPartWithPort(); |
| //check that the one of the properties contains the other |
| if(prFirst.getType().getOwnedElements().contains(prSec) || |
| prSec.getType().getOwnedElements().contains(prFirst)){ |
| return success; |
| } |
| } |
| errorMsg = "Port directions are not compatible."; |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| //check that the ports are owned by components at the "same level" (no parent-child) |
| if (ceFir.getPartWithPort() == null || ceSec.getPartWithPort() == null){ |
| return failure; |
| } |
| |
| //check that interfaces provided/required are compatible (i.e the same interface or the provided can be a subtype of the required) |
| Interface iFirst = null, iSecond = null; |
| //if (first.equals(Constants.CSPORT_KIND_PROVIDED)){ |
| if (kind1.equals(ClientServerKind.PROVIDED)) { |
| //iFirst = (Interface)((EObjectResolvingEList) portFir.getValue(clientServerPort1, "provInterface")).get(0); |
| iFirst = clientServerPort1.getProvInterface().get(0); |
| } else if(kind1.equals(ClientServerKind.REQUIRED)){ |
| //iFirst = (Interface)((EObjectResolvingEList) portFir.getValue(sFirst, "reqInterface")).get(0); |
| iFirst = clientServerPort1.getReqInterface().get(0); |
| } |
| else if(kind1.equals(ClientServerKind.PROREQ)) { |
| // this is managed by constraint FV_07 |
| return success; |
| } |
| if (kind2.equals(ClientServerKind.PROVIDED)){ |
| //iSecond = (Interface)((EObjectResolvingEList) portSec.getValue(sSecond, "provInterface")).get(0); |
| iSecond = clientServerPort2.getProvInterface().get(0); |
| } else if(kind2.equals(ClientServerKind.REQUIRED)){ |
| //iSecond = (Interface)((EObjectResolvingEList) portSec.getValue(sSecond, "reqInterface")).get(0); |
| iSecond = clientServerPort2.getReqInterface().get(0); |
| } |
| else if(kind2.equals(ClientServerKind.PROREQ)) { |
| // this is managed by constraint FV_07 |
| return success; |
| } |
| //if they are different it's ok only if the Provided interface inherits the Required Interface |
| if(!iFirst.equals(iSecond)){ |
| if(kind1.equals(ClientServerKind.PROVIDED)){ |
| if(!iFirst.allParents().contains(iSecond)){ |
| errorMsg = "Interface types are not compatible."; |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| }else if(kind2.equals(ClientServerKind.PROVIDED)){ |
| if(!iSecond.allParents().contains(iFirst)){ |
| errorMsg = "Interface types are not compatible."; |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| } |
| } |
| |
| return success; |
| } |
| catch(IndexOutOfBoundsException e){ |
| errorMsg= e.toString(); |
| failure = ctx.createFailureStatus( |
| thisElement, |
| errorMsg |
| ); |
| return failure; |
| } |
| } |
| |
| } |