| [comment encoding = UTF-8 /] |
| [comment |
| /***************************************************************************** |
| * Copyright (c) 2013 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 |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * 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 |
| * |
| *****************************************************************************/ |
| /] |
| |
| [module generateFaultExtensions('http://www.eclipse.org/uml2/5.0.0/UML')] |
| |
| |
| [template public generateFaultExtensions(model : Model, sysQN : String , sysName : String, filename : String){ |
| ErrorModelQN : String = 'CHESS::Dependability::ThreatsPropagation::ErrorModel'; |
| ErrorQN : String = 'CHESS::Dependability::ThreatsPropagation::ErrorState'; |
| StuckAtQN : String = 'CHESS::Dependability::ThreatsPropagation::StuckAt'; |
| StuckAtFixedQN : String = 'CHESS::Dependability::ThreatsPropagation::StuckAtFixed'; |
| InvertedQN : String = 'CHESS::Dependability::ThreatsPropagation::Inverted'; |
| RampDownQN : String = 'CHESS::Dependability::ThreatsPropagation::RampDown'; |
| InternalFaultQN : String = 'CHESS::Dependability::ThreatsPropagation::InternalFault'; |
| ExternalFaultQN : String = 'CHESS::Dependability::ThreatsPropagation::InternalPropagation'; |
| }] |
| [comment @main/] |
| [file (model.name.concat('_').concat(sysName).concat('.fei'), false, 'UTF-8')] |
| [let system : Class = getSystem(model, sysQN)] |
| <fault_extension_info name="[system.name/]" desc="Generated by CHESS" smv_file="[model.name.concat('_').concat(sysName).concat('.smv')/]"> |
| <extensions> |
| [let systemProps : Set(Property) = system.allOwnedElements()->filter(Property)->select(prop : Property | prop.type.oclIsTypeOf(Class))] |
| [let systemClasses : Set(Class) = systemProps->collect(pr : Property | pr.type.oclAsType(Class))->asSet()] |
| [let nominalComponents : Set(Class) = model.allOwnedElements()->filter(Class)->select(cl : Class | cl.ownedBehavior->filter(StateMachine) |
| ->exists(sm : StateMachine | sm.getAppliedStereotype(ErrorModelQN)->notEmpty()))] |
| [for (cl : Class | nominalComponents)] |
| <nominal_component_extensions module="[cl.name/]"> |
| <fault_models> |
| [for (errorModel : StateMachine | cl.ownedBehavior->filter(StateMachine)->select(sm : StateMachine | sm.getAppliedStereotype(ErrorModelQN)->notEmpty()))] |
| <fault_model name="[errorModel.name/]"> |
| <fault_modes> |
| [for (errorState : State | errorModel.region.subvertex->filter(State)->select(error : State | error.getAppliedStereotype(ErrorQN)->notEmpty()))] |
| [let errorStereo : Stereotype = errorState.getAppliedStereotype(ErrorQN)] |
| <fault_mode enabled="yes" probability="[errorState.getValue(errorStereo, 'probability')/]"> |
| <user_info> |
| <name>[errorState.name/]</name> |
| <desc></desc> |
| </user_info> |
| [if (errorState.getAppliedStereotype(StuckAtQN)->notEmpty())] |
| [let stuckAtStereo : Stereotype = errorState.getAppliedStereotype(StuckAtQN)] |
| <effects_model name="StuckAtByReference_D" desc=""> |
| <values> |
| <input reads="term" value="[errorState.getValue(stuckAtStereo, 'value')/]"/> |
| [let prop : Property = errorState.getValue(stuckAtStereo, 'property').oclAsType(Property)] |
| <output writes="varout" reads="input" binds="[prop.name/]" type="[getTypeNameForProperty(prop)/]"/> |
| [/let] |
| </values> |
| </effects_model> |
| [/let] |
| [elseif (errorState.getAppliedStereotype(InvertedQN)->notEmpty())] |
| [let invertedStereo : Stereotype = errorState.getAppliedStereotype(InvertedQN)] |
| <effects_model name="Inverted" desc=""> |
| <values> |
| [let prop : Property = errorState.getValue(invertedStereo, 'property').oclAsType(Property)] |
| <output writes="varout" reads="input" binds="[prop.name/]" type="[getType(prop.type)/]"/> |
| [/let] |
| </values> |
| </effects_model> |
| [/let] |
| [elseif (errorState.getAppliedStereotype(StuckAtFixedQN)->notEmpty())] |
| [let stuckAtFixedStereo : Stereotype = errorState.getAppliedStereotype(InvertedQN)] |
| <effects_model name="StuckAtFixed" desc=""> |
| <values> |
| [let prop : Property = errorState.getValue(stuckAtFixedStereo, 'property').oclAsType(Property)] |
| <output writes="varout" reads="input" binds="[prop.name/]" type="[getType(prop.type)/]"/> |
| [/let] |
| </values> |
| </effects_model> |
| [/let] |
| [elseif (errorState.getAppliedStereotype(RampDownQN)->notEmpty())] |
| [let rampDownStereo : Stereotype = errorState.getAppliedStereotype(InvertedQN)] |
| <effects_model name="RampDown" desc=""> |
| <values> |
| <input reads="decr" value="[errorState.getValue(rampDownStereo, 'decr')/]"/> |
| <input reads="end_value" value="[errorState.getValue(rampDownStereo, 'endValue')/]"/> |
| [let prop : Property = errorState.getValue(rampDownStereo, 'property').oclAsType(Property)] |
| <output writes="varout" reads="input" binds="[prop.name/]" type="[getType(prop.type)/]"/> |
| [/let] |
| </values> |
| </effects_model> |
| [/let] |
| [/if] |
| [let tr : Transition = errorState.incoming->any(fault : Transition | fault.getAppliedStereotype(InternalFaultQN)->notEmpty() |
| or fault.getAppliedStereotype(ExternalFaultQN)->notEmpty())] |
| <local_dynamics_model name="Permanent" desc=""> |
| <events> |
| <event type="output" name="failure" connected="no"/> |
| </events> |
| </local_dynamics_model> |
| [/let] |
| [/let] |
| </fault_mode> |
| [/for] |
| </fault_modes> |
| </fault_model> |
| [/for] |
| </fault_models> |
| </nominal_component_extensions> |
| [/for] |
| </extensions> |
| </fault_extension_info> |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/file] |
| [/template] |
| |
| |
| [query public getSystem(model : Model, sysQN : String) : Class = self.allOwnedElements()->filter(NamedElement)-> |
| select(elem : NamedElement | elem.qualifiedName->notEmpty() and elem.qualifiedName.equalsIgnoreCase(sysQN))->asSequence()->first().oclAsType(Class)/] |
| |
| [query public getType(type : Type) : String = |
| invoke('org.polarsys.chess.contracts.transformations.service.Service', 'getType(org.eclipse.uml2.uml.Type)', Sequence{type})/] |
| |
| [query public getTypeNameForProperty(prop : Property) : String = |
| invoke('org.polarsys.chess.contracts.transformations.service.Service','getTypeNameForProperty(org.eclipse.uml2.uml.Property)', Sequence{prop}) /] |