| [comment |
| /********************************************************************* |
| * Copyright (c) 2019 Intecs Solutions SpA |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Intecs Solutions - Initial API and implementation |
| * |
| **********************************************************************/ |
| /] |
| [comment encoding = UTF-8 /] |
| [module atomicComponentTemplate('http://www.eclipse.org/uml2/3.0.0/UML')/] |
| [import org::polarsys::chess::mobius::templates::projectFileTemplate /] |
| |
| [template public atomicComponentTemplate(model : Model, componentQN : String){ |
| BlockQN : String = 'SysML::Blocks::Block'; |
| ErrorModelBehaviorQN : String = 'CHESS::Dependability::DependableComponent::ErrorModelBehavior'; |
| NormalStateQN : String = 'CHESS::Dependability::ThreatsPropagation::NormalState'; |
| ErrorStateQN : String = 'CHESS::Dependability::ThreatsPropagation::ErrorState'; |
| CompromisedStateQN : String = 'CHESS::Dependability::ThreatsPropagation::CompromisedState'; |
| InternalFaultQN : String = 'CHESS::Dependability::ThreatsPropagation::InternalFault'; |
| AttackQN : String = 'CHESS::Dependability::ThreatsPropagation::Attack'; |
| }] |
| |
| [comment @main /] |
| [let componentName : String = getNameFromQN(componentQN)] |
| [file (componentName.concat('.san'), false, 'UTF-8')] |
| [let globalvars : Set(String) = getEmptyStringSet()] |
| [let placeX : Integer = 0] |
| [let placeY : Integer = 75] |
| [let activityX : Integer = 50] |
| [let activityY : Integer = 150] |
| [let attackX : Integer = 100] |
| [let attackY : Integer = 200] |
| <?xml version="1.0" encoding="ISO-8859-1"?> |
| <class id="Mobius.AtomicModels.San.SanInterface"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseInterfaceClass"> |
| <int id="ClassVersion">3</int> |
| <string id="ModelName">[componentName/]</string> |
| <class id="Mobius.AtomicModels.San.SanInfoClass"> |
| <int id="ClassVersion">5</int> |
| <class id="Mobius.BaseClasses.BaseInfoClass"> |
| <int id="ClassVersion">2</int> |
| </class> |
| <class id="Mobius.AtomicModels.San.SanTypeManager"> |
| <int id="ClassVersion">1</int> |
| <int id="typeListModelSize">0</int> |
| </class> |
| <string id="CustomInitialization"></string> |
| </class> |
| <class id="Mobius.AtomicModels.San.SanEditor"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BaseEditorClass"> |
| <int id="ClassVersion">3</int> |
| <boolean id="HasPanel">true</boolean> |
| <class id="Mobius.BaseClasses.BasePanelClass"> |
| <int id="ClassVersion">2</int> |
| <point id="Size of Panel"> |
| <int id="x">900</int> |
| <int id="y">400</int> |
| </point> |
| <double id="ZoomFactor">1.0</double> |
| <boolean id="ShowGridEnabled">true</boolean> |
| <int id="ShowGridStep">10</int> |
| <boolean id="SnapGridEnabled">true</boolean> |
| <int id="SnapGridStep">10</int> |
| [let atomicBlocks : Sequence(Classifier) = getAtomicBlocks(model)] |
| [let atomicBlock : Classifier = getBlockFromQN(atomicBlocks, componentQN)] |
| [if(atomicBlock.getAppliedStereotype(ErrorModelBehaviorQN)->notEmpty())] |
| [let places : Sequence(State) = getPlaces(atomicBlock)] |
| [for (place : State | places)] |
| [comment places /] |
| <class id="Mobius.AtomicModels.San.PlacePanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[place.name/]</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| [comment: TODO save X and Y of the normal place/] |
| <int id="x">[placeX + i*150/]</int> [setOkX(placeX + i*150)/] |
| <int id="y">[placeY/]</int> [setOkY(placeY)/] |
| </point> |
| </class> |
| <boolean id="ReadOnly">false</boolean> |
| <boolean id="ConstantMarking">true</boolean> |
| [comment normal place starts with one token /] |
| [if(place.getAppliedStereotype(NormalStateQN)->notEmpty())] |
| <int id="InitialState">1</int> |
| [else] |
| <int id="InitialState">0</int> |
| [/if] |
| </class> |
| [/for] |
| [/let] |
| [let activities : Sequence(Transition) = getActivities(atomicBlock)] |
| [for (activity : Transition | activities)] |
| [if(activity.getAppliedStereotype(InternalFaultQN)->notEmpty())] |
| [comment an internalFault transition is a TimedActivity with a rate /] |
| [let timedActivityName : String = getActivityName(activity)] |
| <class id="Mobius.AtomicModels.San.TimedActivityPanelObject"> |
| <int id="ClassVersion">2</int> |
| <class id="Mobius.AtomicModels.San.ActivityPanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.ExtendedBaseVertexClass"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[timedActivityName/]</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| </class> |
| </class> |
| <int id="NumberOfCases">1</int> |
| <vector id="CaseDistributions"> |
| <string id="0"></string> |
| </vector> |
| </class> |
| [comment TODO? always Exponential for the moment/] |
| [let rate : String = getRate(activity)] |
| <class id="Mobius.BaseClasses.Distributions.DistributionFunction"> |
| <int id="ClassVersion">1</int> |
| <string id="Name">Exponential</string> |
| <vector id="MetaParameters"> |
| </vector> |
| <vector id="Parameters"> |
| [if (rate.size() = 0)] |
| [comment global variable/] |
| [addToGlobalVars(timedActivityName.concat('Rate'), globalvars)/] |
| <string id="0">[timedActivityName/]Rate</string> |
| [else] |
| <string id="0">[rate/]</string> |
| [/if] |
| </vector> |
| </class> |
| [/let] |
| <string id="Activation"></string> |
| <string id="Reactivation"></string> |
| </class> |
| [comment links for the timed activity/] |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[timedActivityName/]</string> |
| <string id="FinishVertex">[activity.target.name/]</string> |
| <boolean id="Arrows">true</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[placeX + i*150/]</int> |
| <int id="y">[placeY/]</int> |
| </point> |
| </vector> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[activity.source.name/]</string> |
| <string id="FinishVertex">[timedActivityName/]</string> |
| <boolean id="Arrows">true</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[placeX + i*150/]</int> |
| <int id="y">[placeY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| </vector> |
| </class> |
| [/let] |
| [/if] |
| [if(activity.getAppliedStereotype(AttackQN)->notEmpty())] |
| [comment an Attack transition is an instantaneous activity /] |
| [let instActivityName : String = getActivityName(activity)] |
| <class id="Mobius.AtomicModels.San.InstantaneousActivityPanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.AtomicModels.San.ActivityPanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.ExtendedBaseVertexClass"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[instActivityName/]</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| </class> |
| </class> |
| <int id="NumberOfCases">1</int> |
| <vector id="CaseDistributions"> |
| <string id="0"></string> |
| </vector> |
| </class> |
| </class> |
| [comment links for the instantaneous activity/] |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[instActivityName/]</string> |
| <string id="FinishVertex">[activity.target.name/]</string> |
| <boolean id="Arrows">true</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[placeX + i*150/]</int> |
| <int id="y">[placeY/]</int> |
| </point> |
| </vector> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[activity.source.name/]</string> |
| <string id="FinishVertex">[instActivityName/]</string> |
| <boolean id="Arrows">true</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[placeX + i*150/]</int> |
| <int id="y">[placeY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[activityX + i*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| </vector> |
| </class> |
| [comment TODO WIP: for each attack success: |
| add one place for attack_success, |
| add one place for attack_confirmed, |
| add an input attack_gate, |
| connect attack_success with attack_gate, |
| connect OK(normal state) with attack_gate, |
| connect attack_confirmed with attack_gate, |
| connect attack_confirmed with instActivityName/] |
| [let attackSuccPlaceNames : Sequence(String) = getAttackSuccName(activity)] |
| [let outerIndex : Integer = i] |
| [let normalStateName : String = getNormalState(atomicBlock).name] |
| [for (attackSuccPlaceName : String | attackSuccPlaceNames)] |
| <class id="Mobius.AtomicModels.San.PlacePanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[attackSuccPlaceName/]_success</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 100 /]</int> |
| </point> |
| </class> |
| <boolean id="ReadOnly">false</boolean> |
| <boolean id="ConstantMarking">true</boolean> |
| <int id="InitialState">0</int> |
| </class> |
| <class id="Mobius.AtomicModels.San.PlacePanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[attackSuccPlaceName/]_confirmed</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY/]</int> |
| </point> |
| </class> |
| <boolean id="ReadOnly">false</boolean> |
| <boolean id="ConstantMarking">true</boolean> |
| <int id="InitialState">0</int> |
| </class> |
| <class id="Mobius.AtomicModels.San.InputGatePanelObject"> |
| <int id="ClassVersion">1</int> |
| <class id="Mobius.BaseClasses.BaseVertexClass"> |
| <int id="ClassVersion">3</int> |
| <class id="Mobius.BaseClasses.BasePanelObjectClass"> |
| <int id="ClassVersion">5</int> |
| <string id="Name">[attackSuccPlaceName/]Gate</string> |
| <boolean id="ContainsLabel">true</boolean> |
| <boolean id="IsLabelShown">true</boolean> |
| </class> |
| <point id="CenterPoint"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 50/]</int> |
| </point> |
| </class> |
| <boolean id="MirrorImage">false</boolean> |
| <string id="Predicate"> |
| [comment predicate and function/] |
| ([attackSuccPlaceName/]_success->Mark() > 0) && ([normalStateName/]->Mar |
| k() > 0) && ([attackSuccPlaceName/]_confirmed->Mark() == 0)) |
| </string> |
| <string id="Function">[attackSuccPlaceName/]_confirmed->Mark() = 1;</string> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[attackSuccPlaceName/]_success</string> |
| <string id="FinishVertex">[attackSuccPlaceName/]Gate</string> |
| <boolean id="Arrows">false</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 100 /]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 50/]</int> |
| </point> |
| </vector> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[normalStateName/]</string> |
| <string id="FinishVertex">[attackSuccPlaceName/]Gate</string> |
| <boolean id="Arrows">false</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[getOkX()/]</int> |
| <int id="y">[getOkY()/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 50/]</int> |
| </point> |
| </vector> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[attackSuccPlaceName/]_confirmed</string> |
| <string id="FinishVertex">[attackSuccPlaceName/]Gate</string> |
| <boolean id="Arrows">false</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY + 50/]</int> |
| </point> |
| </vector> |
| </class> |
| <class id="Mobius.BaseClasses.BaseEdgeClass"> |
| <int id="ClassVersion">3</int> |
| <int id="LineType">0</int> |
| <string id="StartVertex">[attackSuccPlaceName/]_confirmed</string> |
| <string id="FinishVertex">[instActivityName/]</string> |
| <boolean id="Arrows">true</boolean> |
| <vector id="PointList"> |
| <point id="0"> |
| <int id="x">[attackX + outerIndex*150 + i*50/]</int> |
| <int id="y">[attackY/]</int> |
| </point> |
| <point id="1"> |
| <int id="x">[activityX + outerIndex*150/]</int> |
| <int id="y">[activityY/]</int> |
| </point> |
| </vector> |
| </class> |
| [/for] |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/if] |
| [/for] |
| [/let] |
| [/if] |
| [/let] |
| [/let] |
| </class> |
| <vector id="LocalGlobalNamesList"> |
| [for (globalvar : String | globalvars)] |
| <string id="[i/]">[globalvar/]</string> |
| [/for] |
| </vector> |
| <vector id="LocalGlobalTypesList"> |
| [for (globalvar : String | globalvars)] |
| <string id="[i/]">double</string> |
| [/for] |
| </vector> |
| <boolean id="DisplayToolTips">true</boolean> |
| </class> |
| </class> |
| <boolean id="Valid">true</boolean> |
| </class> |
| </class> |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/let] |
| [/file] |
| [/let] |
| [/template] |
| |
| [query public getPlaces(block : Classifier) : Sequence(State) = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getPlaces(org.eclipse.uml2.uml.Classifier)', Sequence{block})/] |
| |
| [query public getActivities(block : Classifier) : Sequence(Transition) = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getActivities(org.eclipse.uml2.uml.Classifier)', Sequence{block})/] |
| |
| [query public getActivityName(tr : Transition) : String = tr.source.name + '__' + tr.target.name/] |
| |
| [query public getRate(tr : Transition) : String = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getRate(org.eclipse.uml2.uml.Transition)', Sequence{tr})/] |
| |
| [query public getAttackSuccName(tr : Transition) : Sequence(String) = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getAttackSuccName(org.eclipse.uml2.uml.Transition)', Sequence{tr})/] |
| |
| [query public getNormalState(block : Classifier) : State = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getNormalState(org.eclipse.uml2.uml.Classifier)', Sequence{block})/] |
| |
| [query public getOkX(ctx : OclAny) : Integer = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getOkX()', Sequence{})/] |
| |
| [query public getOkY(ctx : OclAny) : Integer = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'getOkY()', Sequence{})/] |
| |
| [query public setOkX(okX : Integer) : OclAny = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'setOkX(java.lang.Integer)', Sequence{okX})/] |
| |
| [query public setOkY(okY : Integer) : OclAny = |
| invoke('org.polarsys.chess.mobius.utils.TransformationUtil', 'setOkY(java.lang.Integer)', Sequence{okY})/] |