use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState in project osate2 by osate.
the class PropagationGraphBackwardTraversal method traverseOutgoingErrorPropagation.
/**
* process an Outgoing Error Propagation by going backwards in the propagation graph
* if preProcessOutgoingerrorPropagation returns non-null return its value as traverse result.
* First we attempt to go backwards according to the component error behavior, i.e., the OutgoingPropagationCondition.
* If subresults is non-null then return value of postProcessingErrorPropagationCOndition.
* If not present we do it according to error flow specifications.
*
* @param component ComponentInstance
* @param errorPropagation outgoing ErrorPropagation
* @param type ErrorTypes
* @return EObject (can be null)
*/
public EObject traverseOutgoingErrorPropagation(final ComponentInstance component, final ErrorPropagation errorPropagation, TypeToken proptype, BigDecimal scale) {
List<EObject> subResults = new LinkedList<EObject>();
Collection<TypeToken> filteredTypes = filterTokenThroughConstraint(errorPropagation.getTypeSet(), proptype);
if (filteredTypes.isEmpty()) {
return null;
}
HashMultimap<ErrorPropagation, String> handledEOPs = HashMultimap.create();
boolean traverse = false;
boolean hasCycle = false;
for (TypeToken type : filteredTypes) {
// we did follow an OPC.
boolean didProp = false;
EObject found = preProcessOutgoingErrorPropagation(component, errorPropagation, type, scale);
if (found != null) {
addSubresult(subResults, found);
// found common event
continue;
}
// we want to track cycles.
// we do that by tagging the feature instance of the error propagation with the error type (as token)
ErrorModelState st = null;
FeatureInstance fi = EMV2Util.findFeatureInstance(errorPropagation, component);
if (fi != null) {
st = (ErrorModelState) ErrorModelStateAdapterFactory.INSTANCE.adapt(fi, ErrorModelState.class);
} else {
st = (ErrorModelState) ErrorModelStateAdapterFactory.INSTANCE.adapt(component, ErrorModelState.class);
}
if (st.visited(errorPropagation, type)) {
// we were there before.
hasCycle = true;
continue;
} else {
st.setVisitToken(errorPropagation, type);
}
// processing call has to be after the preproccessing call so it is not found and we proceed in processing.
// On the other hand it needs to be called here so the event exists in ftamodel and is found the next time around.
// Originally we were creating the events bottom up thus the loop did not find the event.
// EObject myEvent = processOutgoingErrorPropagation(component, errorPropagation, type, scale);
Collection<ErrorFlow> errorFlows = EMV2Util.getAllErrorFlows(component);
Collection<OutgoingPropagationCondition> opcs = EMV2Util.getAllOutgoingPropagationConditions(component);
for (OutgoingPropagationCondition opc : opcs) {
if ((opc.getTypeToken() != null && !isNoError(opc.getTypeToken())) || opc.getTypeToken() == null) {
if (opc.isAllPropagations() || (EMV2Util.isSame(opc.getOutgoing(), errorPropagation))) {
// opc token if OPC token is subtype or same type
Collection<TypeToken> opcFilteredTypes = filterTokenThroughConstraint(opc.getTypeToken(), type);
for (TypeToken opctype : opcFilteredTypes) {
if (contains(opc.getTypeToken(), opctype)) {
EObject res = handleOutgoingErrorPropagationCondition(component, opc, opctype, handledEOPs, scale);
addSubresult(subResults, res);
didProp = true;
}
}
}
}
}
// try to find a path from an outer to an inner out error propagation
EList<PropagationPathEnd> propagationSources = Util.getAllPropagationSourceEnds(currentAnalysisModel, component, errorPropagation);
for (PropagationPathEnd ppe : propagationSources) {
ComponentInstance componentSource = ppe.getComponentInstance();
ErrorPropagation propagationSource = ppe.getErrorPropagation();
if (propagationSource.getDirection() == DirectionType.OUT) {
Set<ErrorPropagation> eops = handledEOPs.keySet();
if (!containsEOP(eops, propagationSource)) {
// if not already handled by a opc
EObject res = traverseOutgoingErrorPropagation(componentSource, propagationSource, type, scale);
addSubresult(subResults, res);
didProp = true;
}
}
}
for (ErrorFlow ef : errorFlows) {
if (ef instanceof ErrorPath) {
ErrorPath ep = (ErrorPath) ef;
if (handledEOPs.containsEntry(ep.getIncoming(), EMV2Util.getPrintName(type))) {
// already handled by a opc
continue;
}
if (Util.conditionHolds(ef, component)) {
/**
* Make sure that the error type we are looking for is contained
* in the error types for the out propagation.
* This is a fix for the JMR/SAVI WBS model.
*/
if (ep.isAllOutgoing() || EMV2Util.isSame(ep.getOutgoing(), errorPropagation)) {
BigDecimal newscale = scale;
double pathprobability = EMV2Properties.getProbability(component, ep, type);
if (pathprobability > 0) {
newscale = scale.multiply(BigDecimal.valueOf((pathprobability)));
}
if (ep.getTargetToken() != null) {
Collection<TypeToken> mappedTypes = filterTokenThroughConstraint(ep.getTargetToken(), type);
for (TypeToken mappedtype : mappedTypes) {
// we have a type mapping
EList<TypeToken> result;
if (ep.getTypeTokenConstraint() != null) {
// get type from path constraint
result = mapTokenThroughConstraint(ep.getTypeTokenConstraint(), mappedtype);
} else {
// get incoming type from propagation
result = mapTokenThroughConstraint(ep.getIncoming().getTypeSet(), mappedtype);
}
for (TypeToken newToken : result) {
if (ep.isAllIncoming()) {
Collection<ErrorPropagation> inprops = EMV2Util.getAllIncomingErrorPropagations(component);
for (ErrorPropagation eprop : inprops) {
handledEOPs.put(eprop, EMV2Util.getPrintName(newToken));
EObject newEvent = traverseIncomingErrorPropagation(component, eprop, newToken, newscale);
addSubresult(subResults, newEvent);
didProp = true;
}
} else {
handledEOPs.put(ep.getIncoming(), EMV2Util.getPrintName(newToken));
EObject newEvent = traverseIncomingErrorPropagation(component, ep.getIncoming(), newToken, newscale);
addSubresult(subResults, newEvent);
didProp = true;
}
}
}
} else {
// no type mapping
if (ep.isAllIncoming()) {
Collection<ErrorPropagation> inprops = EMV2Util.getAllIncomingErrorPropagations(component);
for (ErrorPropagation eprop : inprops) {
TypeSet matchtype = ep.getTypeTokenConstraint();
if (matchtype == null) {
matchtype = eprop.getTypeSet();
}
EList<TypeToken> filteredtypes = filterTokenThroughConstraint(matchtype, type);
for (TypeToken subtype : filteredtypes) {
handledEOPs.put(eprop, EMV2Util.getPrintName(subtype));
EObject newEvent = traverseIncomingErrorPropagation(component, eprop, subtype, newscale);
addSubresult(subResults, newEvent);
didProp = true;
}
}
} else {
ErrorPropagation inep = ep.getIncoming();
TypeSet matchtype = ep.getTypeTokenConstraint();
if (matchtype == null) {
matchtype = inep.getTypeSet();
}
Collection<TypeToken> mappedtypes = filterTokenThroughConstraint(matchtype, type);
for (TypeToken subtype : mappedtypes) {
handledEOPs.put(inep, EMV2Util.getPrintName(subtype));
EObject newEvent = traverseIncomingErrorPropagation(component, inep, subtype, newscale);
addSubresult(subResults, newEvent);
didProp = true;
}
}
}
}
}
} else if (ef instanceof ErrorSource) {
ErrorSource errorSource = (ErrorSource) ef;
NamedElement src = errorSource.getSourceModelElement();
if (src instanceof ErrorPropagation) {
// check if error source was already handled by opc
ErrorPropagation srcep = (ErrorPropagation) src;
if (targetsEOP(opcs, srcep, type)) {
// already handled by a opc with the same target
continue;
}
}
if (Util.conditionHolds(ef, component)) {
if (errorSource.isAll() || EMV2Util.isSame(errorSource.getSourceModelElement(), errorPropagation)) {
Collection<TypeToken> mappedTypes = filterTokenThroughConstraint(errorSource.getTypeTokenConstraint(), type);
for (TypeToken mappedType : mappedTypes) {
if (src instanceof ErrorPropagation) {
handledEOPs.put((ErrorPropagation) src, EMV2Util.getPrintName(mappedType));
}
if (errorSource.getFailureModeReference() != null) {
List<EObject> stResults = new LinkedList<EObject>();
ErrorBehaviorState ebs = errorSource.getFailureModeReference();
EObject sEvent = traverseErrorBehaviorState(component, ebs, mappedType, scale);
addSubresult(stResults, sEvent);
EObject newEvent = postProcessErrorSource(component, errorSource, proptype, stResults, scale);
addSubresult(subResults, newEvent);
didProp = true;
} else {
EObject newEvent = processErrorSource(component, errorSource, mappedType, scale);
addSubresult(subResults, newEvent);
didProp = true;
}
}
}
}
}
}
st.removeVisitedToken(errorPropagation, type);
if (didProp) {
traverse = true;
}
}
if (!subResults.isEmpty()) {
// out propagation with sub elements
return postProcessOutgoingErrorPropagation(component, errorPropagation, proptype, subResults, scale);
}
if (hasCycle) {
return null;
}
if (traverse && !handledEOPs.isEmpty()) {
// we handled error out propagations
return null;
}
// out propagation as end point
return processOutgoingErrorPropagation(component, errorPropagation, proptype, scale);
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState in project osate2 by osate.
the class PropagationGraphBackwardTraversal method traverseErrorBehaviorState.
/**
* process error state. Recursively deal with source states of transitions (an PRIORITY AND gate).
* We only process error events (not recover or repair) and error propagations referenced by the expression.
* @param component ComponentInstance
* @param state ErrorBehaviorState
* @param type ErrorTypes
* @return EObject (can be null)
*/
public EObject traverseErrorBehaviorState(ComponentInstance component, ErrorBehaviorState state, TypeToken type, BigDecimal inscale) {
if (state == null) {
return null;
}
List<EObject> subResults = new LinkedList<EObject>();
Collection<ErrorBehaviorTransition> transitions = EMV2Util.getAllErrorBehaviorTransitions(component);
BigDecimal combinedscale = inscale;
for (ErrorBehaviorTransition ebt : transitions) {
ConditionExpression conditionExpression = null;
BigDecimal branchscale = BigOne;
boolean sameState = false;
Collection<TypeToken> newtypes = new LinkedList<TypeToken>();
if (ebt.getTarget() != null && EMV2Util.isSame(state, ebt.getTarget())) {
if (ebt.getTargetToken() != null) {
Collection<TypeToken> filteredtypes = filterTokenThroughConstraint(ebt.getTargetToken(), type);
for (TypeToken filteredtype : filteredtypes) {
if (contains(ebt.getTargetToken(), filteredtype)) {
conditionExpression = ebt.getCondition();
if (ebt.getSource() != null && EMV2Util.isSame(state, ebt.getSource()) && isSame(type, ebt.getTypeTokenConstraint())) {
sameState = true;
newtypes.add(filteredtype);
}
}
}
} else {
conditionExpression = ebt.getCondition();
if (ebt.getSource() != null && EMV2Util.isSame(state, ebt.getSource()) && isSame(type, ebt.getTypeTokenConstraint())) {
sameState = true;
newtypes.add(type);
}
}
} else if (!ebt.getDestinationBranches().isEmpty()) {
// deal with transition branches
EList<TransitionBranch> tbs = ebt.getDestinationBranches();
for (TransitionBranch transitionBranch : tbs) {
if (ebt.getSource() != null && EMV2Util.isSame(ebt.getSource(), transitionBranch.getTarget()) && ebt.getSource().getTypeSet() == null && transitionBranch.getTarget().getTypeSet() == null) {
sameState = true;
}
if (transitionBranch.getTarget() != null) {
if (EMV2Util.isSame(transitionBranch.getTarget(), state)) {
if (ebt.getTargetToken() != null) {
Collection<TypeToken> filteredtypes = filterTokenThroughConstraint(ebt.getTargetToken(), type);
for (TypeToken filteredtype : filteredtypes) {
if (contains(transitionBranch.getTargetToken(), filteredtype)) {
conditionExpression = ebt.getCondition();
if (EMV2Util.isSame(ebt.getSource(), state) && isSame(type, ebt.getTypeTokenConstraint())) {
sameState = true;
newtypes.add(filteredtype);
}
}
}
} else {
conditionExpression = ebt.getCondition();
}
}
} else if (transitionBranch.isSteadyState()) {
// same state
if (ebt.getSource() != null && EMV2Util.isSame(state, ebt.getSource()) && isSame(type, ebt.getTypeTokenConstraint())) {
conditionExpression = ebt.getCondition();
sameState = true;
newtypes.add(type);
}
}
if (conditionExpression != null) {
// get branch prob value
BranchValue val = transitionBranch.getValue();
if (val.getRealvalue() != null) {
branchscale = new BigDecimal(EMV2Util.stripUnderScore(val.getRealvalue()));
} else if (val.getSymboliclabel() != null) {
Classifier cl = EMV2Util.getAssociatedClassifier(ebt);
List<EMV2PropertyAssociation> pa = EMV2Properties.getProperty(val.getSymboliclabel().getQualifiedName(), cl, ebt, null);
for (EMV2PropertyAssociation emv2PropertyAssociation : pa) {
branchscale = BigDecimal.valueOf(EMV2Properties.getRealValue(emv2PropertyAssociation));
}
} else if (val.isOthers()) {
branchscale = BigOne;
for (TransitionBranch tb : tbs) {
BranchValue valcount = tb.getValue();
if (valcount.getRealvalue() != null) {
branchscale = branchscale.subtract(new BigDecimal(EMV2Util.stripUnderScore(valcount.getRealvalue())));
} else if (valcount.getSymboliclabel() != null) {
Classifier cl = EMV2Util.getAssociatedClassifier(ebt);
List<EMV2PropertyAssociation> pa = EMV2Properties.getProperty(valcount.getSymboliclabel().getQualifiedName(), cl, ebt, null);
for (EMV2PropertyAssociation emv2PropertyAssociation : pa) {
branchscale = branchscale.subtract(new BigDecimal(EMV2Properties.getRealValue(emv2PropertyAssociation)));
}
}
}
}
// XXX why break?
break;
}
}
} else if (ebt.isSteadyState()) {
// same state
if (ebt.getSource() != null && EMV2Util.isSame(state, ebt.getSource()) && isSame(type, ebt.getTypeTokenConstraint())) {
conditionExpression = ebt.getCondition();
sameState = true;
newtypes.add(type);
}
}
combinedscale = inscale.multiply(branchscale);
if (!sameState && conditionExpression != null) {
// don't include transition staying in same state
EObject conditionResult = processCondition(component, conditionExpression, newtypes == null ? type : null, combinedscale, false);
// we also do not traverse back if left is allstates.
if (conditionResult != null) {
EObject stateResult = null;
if (!(sameState || ebt.isAllStates())) {
if (newtypes.isEmpty()) {
stateResult = traverseErrorBehaviorState(component, ebt.getSource(), null, combinedscale);
} else {
List<EObject> subsubResults = new LinkedList<EObject>();
for (TypeToken typeToken : newtypes) {
EObject newEvent = traverseErrorBehaviorState(component, state, typeToken, combinedscale);
if (newEvent != null) {
addSubresult(subsubResults, newEvent);
}
}
if (subsubResults.isEmpty()) {
stateResult = processErrorBehaviorState(component, state, type, inscale);
} else if (subsubResults.size() == 1) {
stateResult = subsubResults.get(0);
} else {
stateResult = processTypesetElements(component, state, type, subsubResults, combinedscale);
}
}
}
if (stateResult != null) {
EObject tmpresult = processTransitionCondition(component, ebt.getSource(), type, conditionResult, stateResult, combinedscale);
if (tmpresult != null) {
addSubresult(subResults, tmpresult);
}
} else if (stateResult == null) {
addSubresult(subResults, conditionResult);
}
}
}
}
if (!subResults.isEmpty()) {
return postProcessErrorBehaviorState(component, state, type, subResults, combinedscale);
}
// or if no transitions specified for state machine
if (transitions.isEmpty()) {
// processErrorBehaviorState(component, state, type);
return traverseCompositeErrorStateOnly(component, state, type, inscale);
} else {
// Do not include
return null;
}
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState in project osate2 by osate.
the class PropagationGraphBackwardTraversal method traverseCompositeErrorState.
public EObject traverseCompositeErrorState(ComponentInstance component, ErrorBehaviorState state, TypeToken type, boolean stateOnly, BigDecimal scale) {
preProcessCompositeErrorStates(component, state, type, scale);
List<EObject> subResults = new LinkedList<EObject>();
// should only match one composite state declaration.
for (CompositeState cs : EMV2Util.getAllCompositeStates(component)) {
if (cs.getState() == state && (type == null || EMV2TypeSetUtil.contains(cs.getTypedToken(), type))) {
EObject res = processCondition(component, cs.getCondition(), null, new BigDecimal(1.0), stateOnly);
if (res != null) {
addSubresult(subResults, res);
}
}
}
if (!subResults.isEmpty()) {
return postProcessCompositeErrorStates(component, state, type, subResults, scale);
}
if (stateOnly) {
return processErrorBehaviorState(component, state, type, scale);
} else {
return traverseErrorBehaviorState(component, state, type, scale);
}
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState in project osate2 by osate.
the class CreateTransitionPaletteCommand method buildCreateOperation.
private Operation buildCreateOperation(final BusinessObjectContext srcBoc, final ErrorBehaviorState targetStateReadonly) {
final Object srcBo = srcBoc.getBusinessObject();
final URI targetStateUri = EcoreUtil.getURI(targetStateReadonly);
if (srcBo instanceof ErrorBehaviorState) {
final ErrorBehaviorState srcStateReadonly = (ErrorBehaviorState) srcBo;
final URI srcStateUri = EcoreUtil.getURI(srcStateReadonly);
return Operation.createWithBuilder(createOp -> createOp.supply(() -> StepResult.forValue(getStateMachine(srcStateReadonly))).modifyPreviousResult(stateMachine -> {
final ErrorBehaviorState targetState = (ErrorBehaviorState) stateMachine.eResource().getResourceSet().getEObject(targetStateUri, true);
final ErrorBehaviorState srcState = (ErrorBehaviorState) stateMachine.eResource().getResourceSet().getEObject(srcStateUri, true);
final NamedElementCollectionSingleSelectorModel<ErrorBehaviorEvent> model = new NamedElementCollectionSingleSelectorModel<>(stateMachine.getEvents());
if (!FilteringSelectorDialog.open(Display.getCurrent().getActiveShell(), "Select Event", new LabelFilteringListSelectorModel<>(model))) {
return null;
}
final ErrorBehaviorEvent event = model.getSelectedElement();
// Create the transition
final ErrorBehaviorTransition newTransition = ErrorModelFactory.eINSTANCE.createErrorBehaviorTransition();
newTransition.setSource(srcState);
// Set the target
if (srcState == targetState) {
newTransition.setSteadyState(true);
} else {
newTransition.setTarget(targetState);
}
newTransition.setName(ErrorModelNamingUtil.buildUniqueIdentifier(stateMachine, "new_transition"));
final ConditionElement conditionElement = ErrorModelFactory.eINSTANCE.createConditionElement();
newTransition.setCondition(conditionElement);
final EMV2PathElement conditionPathElement = ErrorModelFactory.eINSTANCE.createEMV2PathElement();
conditionPathElement.setNamedElement(event);
final QualifiedErrorEventOrPropagation errorEventOrPropogation = ErrorModelFactory.eINSTANCE.createQualifiedErrorEventOrPropagation();
errorEventOrPropogation.setEmv2Target(conditionPathElement);
conditionElement.setQualifiedErrorPropagationReference(errorEventOrPropogation);
stateMachine.getTransitions().add(newTransition);
return StepResultBuilder.create().showNewBusinessObject(srcBoc.getParent(), newTransition).build();
}));
} else if (srcBo instanceof ErrorBehaviorTransition || srcBo instanceof BehaviorTransitionTrunk || srcBo instanceof TransitionBranch) {
// Get the transition to modify
final ErrorBehaviorTransition transitionReadonly;
if (srcBo instanceof ErrorBehaviorTransition) {
transitionReadonly = (ErrorBehaviorTransition) srcBo;
} else if (srcBo instanceof BehaviorTransitionTrunk) {
transitionReadonly = ((BehaviorTransitionTrunk) srcBo).getTransition();
} else if (srcBo instanceof TransitionBranch) {
transitionReadonly = (ErrorBehaviorTransition) ((TransitionBranch) srcBo).eContainer();
} else {
throw new AadlGraphicalEditorException("Unexpected case: " + srcBo);
}
return Operation.createWithBuilder(createOp -> createOp.supply(() -> StepResult.forValue(transitionReadonly)).modifyPreviousResult(transition -> {
final ErrorBehaviorState targetState = (ErrorBehaviorState) transition.eResource().getResourceSet().getEObject(targetStateUri, true);
// Convert from using steady state and target field to using branches.
if (transition.getDestinationBranches().isEmpty()) {
final TransitionBranch firstBranch = ErrorModelFactory.eINSTANCE.createTransitionBranch();
final BranchValue firstBranchValue = ErrorModelFactory.eINSTANCE.createBranchValue();
firstBranchValue.setRealvalue("1.0");
if (transition.isSteadyState()) {
firstBranch.setSteadyState(true);
} else {
firstBranch.setTarget(transition.getTarget());
}
firstBranch.setValue(firstBranchValue);
transition.getDestinationBranches().add(firstBranch);
transition.eUnset(ErrorModelPackage.eINSTANCE.getErrorBehaviorTransition_Target());
transition.eUnset(ErrorModelPackage.eINSTANCE.getErrorBehaviorTransition_TargetToken());
transition.eUnset(ErrorModelPackage.eINSTANCE.getErrorBehaviorTransition_SteadyState());
}
// Create the new branch
final TransitionBranch newBranch = ErrorModelFactory.eINSTANCE.createTransitionBranch();
final BranchValue newBranchValue = ErrorModelFactory.eINSTANCE.createBranchValue();
newBranchValue.setRealvalue("1.0");
// Set the target
if (transition.getSource() == targetState) {
newBranch.setSteadyState(true);
} else {
newBranch.setTarget(targetState);
}
newBranch.setValue(newBranchValue);
transition.getDestinationBranches().add(newBranch);
return StepResultBuilder.create().build();
}));
} else {
throw new AadlGraphicalEditorException("Unsupported case: " + srcBo);
}
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState in project osate2 by osate.
the class TestFaultSourceEditorModel method createState.
private static ErrorBehaviorState createState(final String name) {
final ErrorBehaviorState newState = ErrorModelFactory.eINSTANCE.createErrorBehaviorState();
newState.setName(name);
return newState;
}
Aggregations