blob: 5d926c51feb4e02eab85f032a9501421001860f2 [file] [log] [blame]
/*******************************************************************************
*
* Copyright (c) 2013, 2015 Intecs SpA
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nicholas Pacini nicholas.pacini@intecs.it
* Stefano Puri stefano.puri@intecs.it
* Laura Baracchi laura.baracchi@intecs.it
* Initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.opencert.chess.contracts.validation.constraints;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.validation.AbstractModelConstraint;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.emf.validation.model.ConstraintStatus;
import org.eclipse.opencert.chess.traceability.util.Utils;
import org.eclipse.opencert.evm.evidspec.evidence.Artefact;
import org.eclipse.opencert.sam.arg.arg.Claim;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Model;
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.Stereotype;
import org.polarsys.chess.contracts.profile.chesscontract.Contract;
import org.polarsys.chess.contracts.profile.chesscontract.FormalProperty;
import org.polarsys.chess.contracts.profile.chesscontract.util.Constants;
import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
public class OpenCertConstraints extends AbstractModelConstraint {
private static final String BLOCK = "SysML::Blocks::Block";
private static final String FLOWPORT = "SysML::PortAndFlows::FlowPort";
private static final String FLOWPORTMARTE = "MARTE::MARTE_DesignModel::GCM::FlowPort";
private static final String SYSVIEW = "CHESS::Core::CHESSViews::SystemView";
private static final String COMPVIEW = "CHESS::Core::CHESSViews::ComponentView";
private static final String FORMPROP = "CHESSContract::FormalProperty";
// private static final String DELEGATION = "CHESSContract::DelegationConstraint";
private static final String SYSTEM = "CHESSContract::System";
private static final String SUBSYSTEM = "CHESSContract::SubSystem";
private static final String CONTRACTPROP = "CHESSContract::ContractProperty";
public static final String BOUNDEDSUBTYPE = "MARTE::MARTE_Annexes::VSL::DataTypes::BoundedSubtype";
public static final String COLLECTIONTYPE = "MARTE::MARTE_Annexes::VSL::DataTypes::CollectionType";
@Override
public IStatus validate(IValidationContext ctx) {
IStatus success = ctx.createSuccessStatus();
IStatus failure = ctx.createFailureStatus();
// This invariant may raise multiple errors
Collection<ConstraintStatus> allResults = new ArrayList<ConstraintStatus>();
// Retrieve the model and the SystemView package
Model model = (Model) ctx.getTarget();
Package sysView = null;
Package compView = null;
for (Package pkg : model.getNestedPackages()) {
if(pkg.getAppliedStereotype(SYSVIEW) != null){
sysView = pkg;
}
if(pkg.getAppliedStereotype(COMPVIEW) != null){
compView = pkg;
}
}
// if(sysView == null){
// //return failure;
// }
//else:
// Browse through the model and get all blocks, ports, properties and associations
List<Class> allBlocks = new ArrayList<Class>();
List<Port> allFlowPorts = new ArrayList<Port>();
List<Property> allProperties = new ArrayList<Property>();
List<Association> allAssociations = new ArrayList<Association>();
List<Connector> allConnectors = new ArrayList<Connector>();
List<Constraint> allFormalProps = new ArrayList<Constraint>();
List<Property> allContractProperties = new ArrayList<Property>();
List<Parameter> allParameters = new ArrayList<Parameter>();
if (sysView != null)
for (Element elem : sysView.allOwnedElements()) {
if (elem.getAppliedStereotype(BLOCK) != null || elem.getAppliedStereotype(SUBSYSTEM) != null ||
elem.getAppliedStereotype(SYSTEM) != null) {
allBlocks.add((Class) elem);
}
if (elem instanceof Property){
if(elem.getAppliedStereotype(CONTRACTPROP) != null){
allContractProperties.add((Property) elem);
}
}
if (elem instanceof Constraint && elem.getAppliedStereotype(FORMPROP) != null){
allFormalProps.add((Constraint)elem);
}
}
if (compView != null)
for (Element elem : compView.allOwnedElements()) {
if (elem instanceof Constraint && elem.getAppliedStereotype(FORMPROP) != null){
allFormalProps.add((Constraint)elem);
}
if (elem instanceof Property){
if (elem.getAppliedStereotype(CONTRACTPROP) != null){
allContractProperties.add((Property) elem);
}
}
}
if (sysView == null){
//we are not in a CHESS model, se we have to consider the entire Model for checking
for (Element elem : model.allOwnedElements()) {
if (elem.getAppliedStereotype(BLOCK) != null || elem.getAppliedStereotype(SUBSYSTEM) != null ||
elem.getAppliedStereotype(SYSTEM) != null) {
allBlocks.add((Class) elem);
}
if (elem instanceof Property){
if (elem.getAppliedStereotype(FLOWPORT) != null || elem.getAppliedStereotype(FLOWPORTMARTE) != null){
allFlowPorts.add((Port) elem);
}else if(elem.getAppliedStereotype(CONTRACTPROP) != null){
allContractProperties.add((Property) elem);
}else if(!(elem instanceof Port) && !(elem.getOwner() instanceof DataType)){
allProperties.add((Property) elem);
}
}
if (elem instanceof Association){
allAssociations.add((Association) elem);
}
if (elem instanceof Connector){
allConnectors.add((Connector) elem);
}
if (elem instanceof Constraint && elem.getAppliedStereotype(FORMPROP) != null){
allFormalProps.add((Constraint)elem);
}
if (elem instanceof Parameter){
if (((Parameter) elem).getOperation()!= null)
allParameters.add((Parameter) elem);
}
}
}
allResults.addAll(checkConstraintForeverAnalysis(allBlocks, allFlowPorts, allProperties, allAssociations, allConnectors, allFormalProps, allContractProperties, allParameters,ctx));
if (allResults.size()>0) {
//size of all results > 0, create multistatus
return ConstraintStatus.createMultiStatus(ctx, allResults);
} else {
//no errors, return success
return success;
}
}
private Collection<? extends ConstraintStatus> checkConstraintForeverAnalysis(List<Class> allBlocks, List<Port> allFlowPorts, List<Property> allProperties, List<Association> allAssociations, List<Connector> allConnectors, List<Constraint> allFormalProps, List<Property> allContractProperties, List<Parameter> allParameters,IValidationContext ctx) {
Collection<ConstraintStatus> results = new ArrayList<ConstraintStatus>();
String errorMsg;
/**
* Here we check the Contracts
*/
List<Claim> claims = null;
List<Artefact> artefacts = null;
for (Property prop : allContractProperties) {
claims = null;
if (prop.getType() == null)
continue;
if ((prop.getType().getAppliedStereotype(Constants.CONTRACT) != null)){
Stereotype contractstereo = prop.getType().getAppliedStereotype(Constants.CONTRACT);
Contract contract = (Contract) prop.getType().getStereotypeApplication(contractstereo);
if (contract != null){
claims = org.eclipse.opencert.chess.traceability.util.Utils.getTracedClaims(contract);
if (claims == null || claims.isEmpty()){
errorMsg = "The Contract referred by " + prop.getType().getName() + " does not have any claim associated";
results.add(createWarningConstraintStatus(prop, errorMsg, ctx));
}
artefacts = Utils.getTracedArtefacts(contract);
if (artefacts == null || artefacts.isEmpty()){
errorMsg = "The Contract referred by " + prop.getType().getName() + " does not have any artefact associated";
results.add(createWarningConstraintStatus(prop, errorMsg, ctx));
}
}
}
}
/**
* Here we check the FormalProperty
*/
for (Constraint formalProp : allFormalProps) {
FormalProperty fp = EntityUtil.getInstance().getFormalProperty(formalProp);
claims = null;
if (fp != null){
claims = org.eclipse.opencert.chess.traceability.util.Utils.getTracedClaims(fp);
if (claims == null || claims.isEmpty()){
errorMsg = "The FormalProperty " + formalProp.getName() + " does not have any claim associated";
results.add(createWarningConstraintStatus(formalProp, errorMsg, ctx));
}
}
}
return results;
}
//utility method to create a constraint status in case of error
private ConstraintStatus createConstraintStatus(EObject object, String errorMsg, IValidationContext ctx) {
Collection<EObject> resultLocus = new ArrayList<EObject>();
resultLocus.add(object);
return ConstraintStatus.createStatus(ctx, object, resultLocus, IStatus.ERROR,3, errorMsg, (Object[]) null);
}
//utility method to create a constraint status in case of error
private ConstraintStatus createWarningConstraintStatus(EObject object, String errorMsg, IValidationContext ctx) {
Collection<EObject> resultLocus = new ArrayList<EObject>();
resultLocus.add(object);
return ConstraintStatus.createStatus(ctx, object, resultLocus, IStatus.WARNING,3, errorMsg, (Object[]) null);
}
}