Commit f587bea4 authored by Florian Hölzl's avatar Florian Hölzl
Browse files

bugfix

refs 884
parent 5f3955a4
......@@ -62,6 +62,11 @@
<details key="body" value="return org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf(&#xA;&#x9;&#x9;&#x9;&#x9;org.fortiss.af3.state.model.TransitionSegmentSpecification.class,&#xA;&#x9;&#x9;&#x9;&#x9;getStateSpecification().getIdleTransitionsSpecificationsList());"/>
</eAnnotations>
</eOperations>
<eOperations name="isAtomic" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="return this.getSubStates().isEmpty();"/>
</eAnnotations>
</eOperations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="TransitionSegmentConnector" abstract="true"
eSuperTypes="platform:/plugin/org.fortiss.tooling.base/model/base.ecore#//base/ConnectorBase">
......
......@@ -28,6 +28,7 @@
<genOperations ecoreOperation="state.ecore#//State/getTransitionSegmentExitConnectors"/>
<genOperations ecoreOperation="state.ecore#//State/getIncomingTransitionSegments"/>
<genOperations ecoreOperation="state.ecore#//State/getIdleTransitionSpecification"/>
<genOperations ecoreOperation="state.ecore#//State/isAtomic"/>
</genClasses>
<genClasses image="false" ecoreClass="state.ecore#//TransitionSegmentConnector">
<genOperations ecoreOperation="state.ecore#//TransitionSegmentConnector/getState"/>
......
......@@ -20,6 +20,7 @@ package org.fortiss.af3.state.constraint;
import static org.fortiss.tooling.kernel.extension.data.IConstraintViolation.ESeverity.ERROR;
import org.fortiss.af3.state.model.StateAutomaton;
import org.fortiss.af3.state.model.TransitionSegment;
import org.fortiss.tooling.kernel.extension.base.ConstraintViolationBase;
/**
......@@ -36,23 +37,31 @@ final class ConstraintMessage {
public static ConstraintViolationBase<StateAutomaton> createMissingInitialStateViolation(
StateAutomaton automaton) {
return new ConstraintViolationBase<StateAutomaton>(automaton, ERROR,
"Automaton of component " + automaton.getComponent().getName()
+ " has no initial state.");
"Automaton of component " + automaton.getComponent().getName() +
" has no initial state.");
}
/** Creates the violation for non-atomic initial state. */
public static ConstraintViolationBase<StateAutomaton> createNonAtomicInitialStateViolation(
StateAutomaton automaton) {
return new ConstraintViolationBase<StateAutomaton>(automaton, ERROR,
"Automaton of component " + automaton.getComponent().getName()
+ " has non-atomic initial state.");
"Automaton of component " + automaton.getComponent().getName() +
" has non-atomic initial state.");
}
/** Creates the violation for non-atomic initial state. */
public static ConstraintViolationBase<StateAutomaton> createMultipleInitialStatesViolation(
StateAutomaton automaton) {
return new ConstraintViolationBase<StateAutomaton>(automaton, ERROR,
"Automaton of component " + automaton.getComponent().getName()
+ " has multiple initial states.");
"Automaton of component " + automaton.getComponent().getName() +
" has multiple initial states.");
}
/** Creates the violation for non-atomic transition segments. */
public static ConstraintViolationBase<TransitionSegment> createNonAtomicTransitionSegment(
TransitionSegment segment, StateAutomaton automaton) {
return new ConstraintViolationBase<TransitionSegment>(segment, ERROR, "Transition " +
segment.getName() + " in automaton of component " +
automaton.getComponent().getName() + " has not connected to atomic state.");
}
}
......@@ -18,15 +18,19 @@ $Id$
package org.fortiss.af3.state.constraint;
import static org.fortiss.af3.state.constraint.ConstraintMessage.createMissingInitialStateViolation;
import static org.fortiss.af3.state.constraint.ConstraintMessage.createMultipleInitialStatesViolation;
import static org.fortiss.af3.state.constraint.ConstraintMessage.createNonAtomicInitialStateViolation;
import static org.fortiss.af3.state.constraint.ConstraintMessage.createNonAtomicTransitionSegment;
import static org.fortiss.af3.state.utils.StateAutomatonUtils.getSubStatesRecursively;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.af3.state.model.State;
import org.fortiss.af3.state.model.StateAutomaton;
import org.fortiss.af3.state.utils.StateAutomatonUtils;
import org.fortiss.af3.state.model.TransitionSegment;
import org.fortiss.tooling.kernel.extension.base.ConstraintCheckerBase;
import org.fortiss.tooling.kernel.extension.data.IConstraintViolation;
......@@ -38,8 +42,7 @@ import org.fortiss.tooling.kernel.extension.data.IConstraintViolation;
* @version $Rev$
* @ConQAT.Rating GREEN Hash: 1A38A7724A407D43112A654831582B1F
*/
public class StateAutomatonConstraintChecker extends
ConstraintCheckerBase<StateAutomaton> {
public class StateAutomatonConstraintChecker extends ConstraintCheckerBase<StateAutomaton> {
/** {@inheritDoc} */
@Override
......@@ -49,30 +52,55 @@ public class StateAutomatonConstraintChecker extends
/** {@inheritDoc} */
@Override
public List<? extends IConstraintViolation<? extends EObject>> apply(
StateAutomaton modelElement) {
List<IConstraintViolation<? extends EObject>> result = new ArrayList<IConstraintViolation<? extends EObject>>();
public List<? extends IConstraintViolation<? extends EObject>>
apply(StateAutomaton modelElement) {
List<IConstraintViolation<? extends EObject>> result =
new ArrayList<IConstraintViolation<? extends EObject>>();
doInitialStateCheck(modelElement, result);
doLooseTransitionSegmentCheck(modelElement, result);
return result;
}
/** Checks that no chain of transistion segments ends or starts in a non-atomic state. */
private void doLooseTransitionSegmentCheck(StateAutomaton modelElement,
List<IConstraintViolation<? extends EObject>> result) {
for(Iterator<EObject> iter = modelElement.eAllContents(); iter.hasNext();) {
EObject n = iter.next();
if(n instanceof TransitionSegment) {
TransitionSegment seg = (TransitionSegment)n;
if(!seg.getSourceConnector().getState().isAtomic() &&
seg.getSourceConnector().getIncomingTransitionSegments().isEmpty()) {
result.add(createNonAtomicTransitionSegment(seg, modelElement));
} else if(!seg.getTargetConnector().getState().isAtomic() &&
seg.getTargetConnector().getOutgoingTransitionSegments().isEmpty()) {
result.add(createNonAtomicTransitionSegment(seg, modelElement));
}
}
}
}
/** Checks for a single, atomic, initial state within the given automaton. */
private void doInitialStateCheck(StateAutomaton modelElement,
List<IConstraintViolation<? extends EObject>> result) {
State initial = null;
for (State st : StateAutomatonUtils
.getSubStatesRecursively(modelElement.getRootState())) {
if (!st.getContainedElementsList().isEmpty()) {
if (st.isInitial()) {
for(State st : getSubStatesRecursively(modelElement.getRootState())) {
if(!st.getContainedElementsList().isEmpty()) {
if(st.isInitial()) {
result.add(createNonAtomicInitialStateViolation(modelElement));
}
} else {
if (st.isInitial()) {
if (initial == null) {
if(st.isInitial()) {
if(initial == null) {
initial = st;
} else {
result.add(ConstraintMessage
.createMultipleInitialStatesViolation(modelElement));
result.add(createMultipleInitialStatesViolation(modelElement));
}
}
}
}
if (initial == null) {
if(initial == null) {
result.add(createMissingInitialStateViolation(modelElement));
}
return result;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment