use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorFlow in project osate2 by osate.
the class EMV2Util method getAllErrorPaths.
/**
* return list of error paths including those inherited from classifiers being extended
* @param cl Classifier
* @return Collection<ErrorSource> list of error paths declared in the flow section
*/
public static Collection<ErrorPath> getAllErrorPaths(Classifier cl) {
HashMap<String, ErrorPath> result = new LinkedHashMap<>();
EList<ErrorModelSubclause> emslist = getAllContainingClassifierEMV2Subclauses(cl);
for (ErrorModelSubclause errorModelSubclause : emslist) {
EList<ErrorFlow> eflist = errorModelSubclause.getFlows();
for (ErrorFlow errorFlow : eflist) {
if (errorFlow instanceof ErrorPath) {
if (!result.containsKey(errorFlow.getName())) {
result.put(errorFlow.getName(), (ErrorPath) errorFlow);
}
}
}
}
return result.values();
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorFlow in project osate2 by osate.
the class PropagateErrorSources method traceErrorFlows.
/**
* traverse through the destination of the connection instance
* @param conni
*/
protected void traceErrorFlows(ComponentInstance ci, ErrorPropagation ep, TypeToken tt, int depth, String entryText) {
if (ci == null) {
return;
}
/**
* With alreadyTreated, we have a cache that keep track of existing report
* text for each component. For each component, we maintain a list of existing
* entryText already reported. So, we do not duplicate the error report for each component
* and make sure to report each entry only once.
*/
if (!alreadyTreated.containsKey(ci)) {
alreadyTreated.put(ci, new ArrayList<String>());
}
if (alreadyTreated.get(ci).contains(entryText)) {
return;
}
alreadyTreated.get(ci).add(entryText);
boolean handled = false;
Collection<ErrorFlow> outefs = EMV2Util.findErrorFlowFromComponentInstance(ci, ep);
for (ErrorFlow ef : outefs) {
if (ef instanceof ErrorSink && Util.conditionHolds(ef, ci)) {
/**
* We try to find additional error propagation for this error sink.
* For example, if the error sink triggers to switch to
* another behavior state and that states is used to propagate
* an error through an error source. Then, we do not consider
* it as an error sink but as an error path and continue
* to trace the flow using this additional error propagation.
*/
if (EMV2TypeSetUtil.contains(ef.getTypeTokenConstraint(), tt)) {
String maskText = ", " + generateFailureModeText(ci, ep, tt) + " [Masked],";
reportEntry(entryText + maskText, depth);
handled = true;
} else {
Collection<TypeToken> intersection = EMV2TypeSetUtil.getConstrainedTypeTokens(ef.getTypeTokenConstraint(), tt);
for (TypeToken typeToken : intersection) {
String maskText = ", " + generateFailureModeText(ci, ep, typeToken) + " [Masked],";
reportEntry(entryText + maskText, depth);
handled = true;
}
}
} else if (ef instanceof ErrorPath) {
// error path
Collection<ErrorPropagation> eplist = EMV2Util.getOutgoingPropagationOrAll((ErrorPath) ef);
ErrorPropagation inep = ((ErrorPath) ef).getIncoming();
if (ef.getTypeTokenConstraint() != null ? EMV2TypeSetUtil.contains(ef.getTypeTokenConstraint(), tt) : (inep != null ? EMV2TypeSetUtil.contains(inep.getTypeSet(), tt) : ((ErrorPath) ef).isAllIncoming())) {
TypeToken newtt = EMV2Util.mapToken(tt, ef);
for (ErrorPropagation outp : eplist) {
traceErrorPaths(ci, outp, newtt, depth + 1, entryText + ", " + generateFailureModeText(ci, ep, tt));
handled = true;
}
} else {
Collection<TypeToken> intersection = Collections.emptyList();
TypeSet ts = null;
if (ef.getTypeTokenConstraint() != null) {
ts = ef.getTypeTokenConstraint();
} else if (inep != null) {
ts = inep.getTypeSet();
}
if (ts != null) {
intersection = EMV2TypeSetUtil.getConstrainedTypeTokens(ts, tt);
}
for (TypeToken typeToken : intersection) {
TypeToken newtt = EMV2Util.mapToken(typeToken, ef);
for (ErrorPropagation outp : eplist) {
traceErrorPaths(ci, outp, newtt, depth + 1, entryText + ",\"" + generateFailureModeText(ci, ep, typeToken) + " [Subtype]\"");
handled = true;
}
}
}
}
}
if (!handled) {
// no error flows:. and no flows condition
// try flows or propagate to all outgoing error propagations
EList<FlowSpecificationInstance> flowlist = ci.getFlowSpecifications();
if (!flowlist.isEmpty()) {
for (FlowSpecificationInstance flowSpecificationInstance : flowlist) {
if (flowSpecificationInstance.getSource() != null && flowSpecificationInstance.getSource().getFeature() == EMV2Util.getErrorPropagationFeature(ep, ci)) {
FeatureInstance outfi = flowSpecificationInstance.getDestination();
if (outfi != null) {
ErrorPropagation outp = EMV2Util.getOutgoingErrorPropagation(outfi);
if (outp != null) {
TypeToken newtt = EMV2Util.mapToken(tt, flowSpecificationInstance);
if (EMV2TypeSetUtil.contains(outp.getTypeSet(), newtt)) {
traceErrorPaths(ci, outp, newtt, depth + 1, entryText + ", " + generateFailureModeText(ci, ep, tt) + " [FlowPath]");
handled = true;
} else {
Collection<TypeToken> intersection = EMV2TypeSetUtil.getConstrainedTypeTokens(outp.getTypeSet(), newtt);
for (TypeToken typeToken : intersection) {
traceErrorPaths(ci, outp, typeToken, depth + 1, entryText + ", " + generateFailureModeText(ci, ep, tt) + " [FlowPath TypeSubset]");
handled = true;
}
}
}
} else {
// do all since we have a flow sink
EList<FeatureInstance> filist = ci.getFeatureInstances();
boolean res = doAllOutPropagationsOrFeatures(ci, filist, ep, tt, depth, entryText);
if (res) {
handled = true;
}
}
}
}
} else {
// now all outgoing propagations or features since we did not find flows
EList<FeatureInstance> filist = ci.getFeatureInstances();
boolean res = doAllOutPropagationsOrFeatures(ci, filist, ep, tt, depth, entryText);
if (res) {
handled = true;
}
}
}
if (!handled) {
String errorText = "," + generateFailureModeText(ci, ep, tt) + " [Unhandled Failure Effect]";
reportEntry(entryText + errorText, depth);
}
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorFlow 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.ErrorFlow in project osate2 by osate.
the class ErrorFlowHandler method getGraphicalConfiguration.
@Override
public Optional<GraphicalConfiguration> getGraphicalConfiguration(final GetGraphicalConfigurationContext ctx) {
final ErrorFlow bo = ctx.getBusinessObjectContext().getBusinessObject(ErrorFlow.class).get();
final BusinessObjectContext classifierBoc = ctx.getBusinessObjectContext().getParent();
if (classifierBoc == null) {
return Optional.empty();
}
// Determine the type of graphic and the source and destination of the connection
final ErrorFlowEnd src;
final ErrorFlowEnd dst;
final Graphic graphic;
if (bo instanceof ErrorSource) {
graphic = SOURCE_GRAPHIC;
final ErrorSource es = (ErrorSource) bo;
src = getErrorFlowEnd(ctx.getQueryService(), classifierBoc, es.isAll(), es.getSourceModelElement()).orElse(null);
dst = null;
} else if (bo instanceof ErrorSink) {
graphic = SINK_GRAPHIC;
final ErrorSink es = (ErrorSink) bo;
src = getErrorFlowEnd(ctx.getQueryService(), classifierBoc, es.isAllIncoming(), es.getIncoming()).orElse(null);
dst = null;
} else if (bo instanceof ErrorPath) {
graphic = PATH_GRAPHIC;
final ErrorPath ep = (ErrorPath) bo;
src = getErrorFlowEnd(ctx.getQueryService(), classifierBoc, ep.isAllIncoming(), ep.getIncoming()).orElse(null);
dst = getErrorFlowEnd(ctx.getQueryService(), classifierBoc, ep.isAllOutgoing(), ep.getOutgoing()).orElse(null);
} else {
return Optional.empty();
}
// Determine style
final StyleBuilder sb = StyleBuilder.create(GraphicalExtensionUtil.isInherited(ctx.getBusinessObjectContext()) ? GraphicalExtensionUtil.STYLE_INHERITED_ELEMENT : Style.EMPTY).lineWidth(4.0);
final boolean partial = (src != null && src.partial) || (dst != null && dst.partial);
if (partial) {
sb.dotted();
}
return Optional.of(GraphicalConfigurationBuilder.create().graphic(graphic).style(sb.build()).defaultDockingPosition(DockingPosition.ANY).source(src == null ? null : src.boc).destination(dst == null ? null : dst.boc).build());
}
use of org.osate.xtext.aadl2.errormodel.errorModel.ErrorFlow in project osate2 by osate.
the class ErrorModelTooltipContributor method createLabel.
private void createLabel(final Composite parent, final EObject bo) {
final boolean showSource = bo instanceof ErrorType || bo instanceof TypeSet || bo instanceof ErrorBehaviorTransition || bo instanceof TransitionBranch || bo instanceof ErrorBehaviorEvent || bo instanceof ErrorBehaviorState || bo instanceof ErrorPropagation || bo instanceof PropagationPoint || bo instanceof ErrorFlow || bo instanceof PropagationPath;
if (!showSource) {
return;
}
final INode n = NodeModelUtils.getNode(bo);
if (n == null) {
return;
}
final String txt = NodeModelUtils.getTokenText(n);
if (txt == null) {
return;
}
final Label lbl = new Label(parent, SWT.WRAP);
lbl.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
lbl.setText(txt);
}
Aggregations