/******************************************************************************* | |
* | |
* 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); | |
} | |
} |