Kaynağa Gözat

Merge pull request #539 from Yakindu/issue_184

Check Top Level Entry is default entry fixed
jdicks 9 yıl önce
ebeveyn
işleme
baa9c22f73

+ 24 - 1
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -128,7 +128,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator implements ST
 	private ResourceDescriptionsProvider resourceDescriptionsProvider;
 	@Inject(optional = true)
 	@Named("domainId")
-	private String domainID = BasePackage.Literals.DOMAIN_ELEMENT__DOMAIN_ID.getDefaultValueLiteral(); 
+	private String domainID = BasePackage.Literals.DOMAIN_ELEMENT__DOMAIN_ID.getDefaultValueLiteral();
 
 	@Check
 	public void checkExpression(VariableDefinition expression) {
@@ -484,6 +484,29 @@ public class STextJavaValidator extends AbstractSTextJavaValidator implements ST
 			}
 		}
 	}
+	@Check(CheckType.FAST)
+	public void checkTopLeveEntryIsDefaultEntry(final Entry entry) {
+		Region parentRegion = entry.getParentRegion();
+		EObject eContainer = parentRegion.eContainer();
+	
+		boolean isTopLevelRegionEntry = eContainer instanceof Statechart;
+
+		//1. check if is toplevel
+		if (isTopLevelRegionEntry) {
+			boolean isDefaultEntry = STextValidationModelUtils.isDefault(entry);
+			//2. check if is default entry
+			if (!isDefaultEntry) {
+				Map<Region, List<Entry>> regionsWithoutDefaultEntry = STextValidationModelUtils.getRegionsWithoutDefaultEntry(Lists.newArrayList(parentRegion));
+				List<Entry> list = regionsWithoutDefaultEntry.get(parentRegion);
+				if(list!=null)
+					error(TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY, entry,
+							SGraphPackage.Literals.ENTRY__KIND,-1);
+				else
+					warning(TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY, entry,
+							SGraphPackage.Literals.ENTRY__KIND,-1);
+			}
+		}
+	}
 
 	@Check(CheckType.FAST)
 	public void checkOperationArguments_FeatureCall(final FeatureCall call) {

+ 1 - 0
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextValidationMessages.java

@@ -35,6 +35,7 @@ public interface STextValidationMessages {
 	public static final String TRANSITION_UNBOUND_DEFAULT_ENTRY_POINT = "Target state has regions without 'default' entries.";
 	public static final String TRANSITION_UNBOUND_NAMED_ENTRY_POINT = "Target state has regions without named entries: ";
 	public static final String TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT = "Source State needs at least one region with the named exit point";
+	public static final String TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY = "Entry of top level region have to be a default entry.";
 	public static final String REGION_UNBOUND_DEFAULT_ENTRY_POINT = "Region must have a 'default' entry.";
 	public static final String REGION_UNBOUND_NAMED_ENTRY_POINT = "Region should have a named entry to support transitions entry specification: ";
 	public static final String ENTRY_UNUSED = "The named entry is not used by incoming transitions.";

+ 272 - 272
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextValidationModelUtils.java

@@ -1,272 +1,272 @@
-/**
- * Copyright (c) 2013 itemis AG and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- * 	itemis AG - initial API and implementation
- * 
- */
-package org.yakindu.sct.model.stext.validation;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.emf.ecore.EObject;
-import org.yakindu.base.base.NamedElement;
-import org.yakindu.sct.model.sgraph.Entry;
-import org.yakindu.sct.model.sgraph.Exit;
-import org.yakindu.sct.model.sgraph.ReactionProperty;
-import org.yakindu.sct.model.sgraph.Region;
-import org.yakindu.sct.model.sgraph.Transition;
-import org.yakindu.sct.model.stext.stext.EntryPointSpec;
-import org.yakindu.sct.model.stext.stext.ExitPointSpec;
-
-public final class STextValidationModelUtils {
-
-	private STextValidationModelUtils() {
-	}
-
-	/**
-	 * Sorts the given elements in transition without and with
-	 * {@link EntryPointSpec}s
-	 * 
-	 * @param elements
-	 *            list of transitions to sort
-	 * @return an array with the sorted elements. The first index contains a
-	 *         list of the transitions without {@link EntryPointSpec}s. The
-	 *         second index contains a list of the transitions with
-	 *         {@link EntryPointSpec}s.
-	 */
-	public static List<Transition>[] getEntrySpecSortedTransitions(
-			List<Transition> elements) {
-		@SuppressWarnings("unchecked")
-		final List<Transition>[] transitions = new ArrayList[2];
-		// first list contains Transitions without entry spec
-		transitions[0] = new ArrayList<Transition>();
-		// second list contains Transitions with entry spec
-		transitions[1] = new ArrayList<Transition>();
-		for (Transition transition : elements) {
-			boolean hasEntrySpec = false;
-			for (ReactionProperty property : transition.getProperties()) {
-				if (property instanceof EntryPointSpec) {
-					transitions[1].add(transition);
-					hasEntrySpec = true;
-					break;
-				}
-			}
-			if (!hasEntrySpec) {
-				transitions[0].add(transition);
-			}
-		}
-		return transitions;
-	}
-
-	/**
-	 * Sorts the given elements in transition without and with
-	 * {@link ExitPointSpec}s
-	 * 
-	 * @param elements
-	 *            - list of transitions to sort
-	 * @return an array with the sorted elements. The first index contains a
-	 *         list of the transitions without {@link ExitPointSpec}s. The
-	 *         second index contains a list of the transitions with
-	 *         {@link ExitPointSpec}s.
-	 */
-	public static List<Transition>[] getExitSpecSortedTransitions(
-			List<Transition> elements) {
-		@SuppressWarnings("unchecked")
-		final List<Transition>[] transitions = new ArrayList[2];
-		// first list contains Transitions without exit spec
-		transitions[0] = new ArrayList<Transition>();
-		// second list contains Transitions with exit spec
-		transitions[1] = new ArrayList<Transition>();
-		for (Transition transition : elements) {
-			boolean hasExitSpec = false;
-			for (ReactionProperty property : transition.getProperties()) {
-				if (property instanceof ExitPointSpec) {
-					transitions[1].add(transition);
-					hasExitSpec = true;
-					break;
-				}
-			}
-			if (!hasExitSpec) {
-				transitions[0].add(transition);
-			}
-		}
-		return transitions;
-	}
-
-	/**
-	 * If a {@link Region} contains no 'default' named {@link entry} it is added
-	 * as key to a map with a list of all entries of the region.
-	 * 
-	 * @param elements
-	 *            - a list with {@link Region} elements.
-	 * @return a map with a region (key) which contains no default {@link entry}
-	 *         and a list of all {@link entry} elements of the {@link Region}
-	 *         (value).
-	 */
-	public static Map<Region, List<Entry>> getRegionsWithoutDefaultEntry(
-			List<Region> elements) {
-		Map<Region, List<Entry>> regions = new HashMap<Region, List<Entry>>();
-		for (Region region : elements) {
-			boolean hasDefaultEntry = false;
-			final List<Entry> entries = getEntries(region.eContents());
-			for (Entry entry : entries) {
-				if (isDefault(entry)) {
-					hasDefaultEntry = true;
-					break;
-				}
-			}
-			if (!hasDefaultEntry) {
-				regions.put(region, entries);
-			}
-		}
-		return regions;
-	}
-
-	/**
-	 * If a {@link Region} contains no 'default' named {@link exit} it is added
-	 * as key to a map with a list of all exits of the region.
-	 * 
-	 * @param elements
-	 *            - a list with {@link Region} elements.
-	 * @return a map with a region (key) which contains no default {@link exit}
-	 *         and a list of all {@link exit} elements of the {@link Region}
-	 *         (value).
-	 */
-	public static Map<Region, List<Exit>> getRegionsWithoutDefaultExit(
-			List<Region> elements) {
-		Map<Region, List<Exit>> regions = new HashMap<Region, List<Exit>>();
-		for (Region region : elements) {
-			boolean hasDefaultExit = false;
-			final List<Exit> exits = getExits(region.eContents());
-			if (!exits.isEmpty()) {
-				for (Exit exit : exits) {
-					if (isDefault(exit)) {
-						hasDefaultExit = true;
-						break;
-					}
-				}
-			} else {
-				hasDefaultExit = true;
-			}
-
-			if (!hasDefaultExit) {
-				regions.put(region, exits);
-			}
-		}
-		return regions;
-	}
-
-	/**
-	 * Checks if the name of the given element matches the requirements to be a
-	 * 'default' element.
-	 * 
-	 * @param element
-	 *            - the {@link NamedElement}
-	 * @return {@code true} if the name is null, empty or equals 'default'
-	 *         (ignoring case).
-	 */
-	public static boolean isDefault(final NamedElement element) {
-		return element.getName() == null
-				|| (element.getName() != null && (element.getName().isEmpty() || element
-						.getName().equalsIgnoreCase("default")));
-	}
-
-	/**
-	 * Validates if the a {@link Transition} has an {@link ExitPointSpec} with
-	 * the given name.
-	 * 
-	 * @param transition
-	 *            - the transition to check
-	 * @param name
-	 *            - the name to check
-	 * @return {@code true} if the transition contains an ExitPointSpec with the
-	 *         name. Otherwise {@code false}.
-	 */
-	public static boolean isNamedExitTransition(Transition transition,
-			String name) {
-
-		boolean isNamedExitTransition = false;
-
-		Iterator<ReactionProperty> propertyIt = transition.getProperties()
-				.iterator();
-
-		while (propertyIt.hasNext() && !isNamedExitTransition) {
-
-			ReactionProperty property = propertyIt.next();
-
-			if (property instanceof ExitPointSpec) {
-
-				isNamedExitTransition = name.equals(((ExitPointSpec) property)
-						.getExitpoint());
-			}
-		}
-
-		return isNamedExitTransition;
-	}
-
-	public static boolean isDefaultExitTransition(Transition transition) {
-		boolean isDefault = false;
-		List<ExitPointSpec> exits = getExitPointSpecs(transition
-				.getProperties());
-		if (!exits.isEmpty()) {
-			for (ExitPointSpec exit : exits) {
-				if (exit.getExitpoint().equalsIgnoreCase("default")) {
-					isDefault = true;
-				}
-			}
-		} else {
-			isDefault = true;
-		}
-
-		return isDefault;
-	}
-
-	/**
-	 * Filters the given list of {@link ReactionProperty} to return only a list
-	 * of {@link ExitPointSpec}.
-	 * 
-	 * @param elements
-	 * 			- list of ReactionProperties
-	 * @return
-	 * 		A list of ExitPointSpecs.
-	 */
-	public static List<ExitPointSpec> getExitPointSpecs(
-			List<ReactionProperty> elements) {
-		List<ExitPointSpec> exits = new ArrayList<ExitPointSpec>();
-		for (ReactionProperty element : elements) {
-			if (element instanceof ExitPointSpec) {
-				exits.add((ExitPointSpec) element);
-			}
-		}
-		return exits;
-	}
-
-	public static List<Entry> getEntries(List<EObject> elements) {
-		List<Entry> entries = new ArrayList<Entry>();
-		for (EObject element : elements) {
-			if (element instanceof Entry) {
-				entries.add((Entry) element);
-			}
-		}
-		return entries;
-	}
-
-	public static List<Exit> getExits(List<EObject> elements) {
-		List<Exit> exits = new ArrayList<Exit>();
-		for (EObject element : elements) {
-			if (element instanceof Exit) {
-				exits.add((Exit) element);
-			}
-		}
-		return exits;
-	}
-}
+/**
+ * Copyright (c) 2013 itemis AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * 	itemis AG - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.model.stext.validation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.base.NamedElement;
+import org.yakindu.sct.model.sgraph.Entry;
+import org.yakindu.sct.model.sgraph.Exit;
+import org.yakindu.sct.model.sgraph.ReactionProperty;
+import org.yakindu.sct.model.sgraph.Region;
+import org.yakindu.sct.model.sgraph.Transition;
+import org.yakindu.sct.model.stext.stext.EntryPointSpec;
+import org.yakindu.sct.model.stext.stext.ExitPointSpec;
+
+public final class STextValidationModelUtils {
+
+	private STextValidationModelUtils() {
+	}
+
+	/**
+	 * Sorts the given elements in transition without and with
+	 * {@link EntryPointSpec}s
+	 * 
+	 * @param elements
+	 *            list of transitions to sort
+	 * @return an array with the sorted elements. The first index contains a
+	 *         list of the transitions without {@link EntryPointSpec}s. The
+	 *         second index contains a list of the transitions with
+	 *         {@link EntryPointSpec}s.
+	 */
+	public static List<Transition>[] getEntrySpecSortedTransitions(
+			List<Transition> elements) {
+		@SuppressWarnings("unchecked")
+		final List<Transition>[] transitions = new ArrayList[2];
+		// first list contains Transitions without entry spec
+		transitions[0] = new ArrayList<Transition>();
+		// second list contains Transitions with entry spec
+		transitions[1] = new ArrayList<Transition>();
+		for (Transition transition : elements) {
+			boolean hasEntrySpec = false;
+			for (ReactionProperty property : transition.getProperties()) {
+				if (property instanceof EntryPointSpec) {
+					transitions[1].add(transition);
+					hasEntrySpec = true;
+					break;
+				}
+			}
+			if (!hasEntrySpec) {
+				transitions[0].add(transition);
+			}
+		}
+		return transitions;
+	}
+
+	/**
+	 * Sorts the given elements in transition without and with
+	 * {@link ExitPointSpec}s
+	 * 
+	 * @param elements
+	 *            - list of transitions to sort
+	 * @return an array with the sorted elements. The first index contains a
+	 *         list of the transitions without {@link ExitPointSpec}s. The
+	 *         second index contains a list of the transitions with
+	 *         {@link ExitPointSpec}s.
+	 */
+	public static List<Transition>[] getExitSpecSortedTransitions(
+			List<Transition> elements) {
+		@SuppressWarnings("unchecked")
+		final List<Transition>[] transitions = new ArrayList[2];
+		// first list contains Transitions without exit spec
+		transitions[0] = new ArrayList<Transition>();
+		// second list contains Transitions with exit spec
+		transitions[1] = new ArrayList<Transition>();
+		for (Transition transition : elements) {
+			boolean hasExitSpec = false;
+			for (ReactionProperty property : transition.getProperties()) {
+				if (property instanceof ExitPointSpec) {
+					transitions[1].add(transition);
+					hasExitSpec = true;
+					break;
+				}
+			}
+			if (!hasExitSpec) {
+				transitions[0].add(transition);
+			}
+		}
+		return transitions;
+	}
+
+	/**
+	 * If a {@link Region} contains no 'default' named {@link entry} it is added
+	 * as key to a map with a list of all entries of the region.
+	 * 
+	 * @param elements
+	 *            - a list with {@link Region} elements.
+	 * @return a map with a region (key) which contains no default {@link entry}
+	 *         and a list of all {@link entry} elements of the {@link Region}
+	 *         (value).
+	 */
+	public static Map<Region, List<Entry>> getRegionsWithoutDefaultEntry(
+			List<Region> elements) {
+		Map<Region, List<Entry>> regions = new HashMap<Region, List<Entry>>();
+		for (Region region : elements) {
+			boolean hasDefaultEntry = false;
+			final List<Entry> entries = getEntries(region.eContents());
+			for (Entry entry : entries) {
+				if (isDefault(entry)) {
+					hasDefaultEntry = true;
+					break;
+				}
+			}
+			if (!hasDefaultEntry) {
+				regions.put(region, entries);
+			}
+		}
+		return regions;
+	}
+
+	/**
+	 * If a {@link Region} contains no 'default' named {@link exit} it is added
+	 * as key to a map with a list of all exits of the region.
+	 * 
+	 * @param elements
+	 *            - a list with {@link Region} elements.
+	 * @return a map with a region (key) which contains no default {@link exit}
+	 *         and a list of all {@link exit} elements of the {@link Region}
+	 *         (value).
+	 */
+	public static Map<Region, List<Exit>> getRegionsWithoutDefaultExit(
+			List<Region> elements) {
+		Map<Region, List<Exit>> regions = new HashMap<Region, List<Exit>>();
+		for (Region region : elements) {
+			boolean hasDefaultExit = false;
+			final List<Exit> exits = getExits(region.eContents());
+			if (!exits.isEmpty()) {
+				for (Exit exit : exits) {
+					if (isDefault(exit)) {
+						hasDefaultExit = true;
+						break;
+					}
+				}
+			} else {
+				hasDefaultExit = true;
+			}
+
+			if (!hasDefaultExit) {
+				regions.put(region, exits);
+			}
+		}
+		return regions;
+	}
+
+	/**
+	 * Checks if the name of the given element matches the requirements to be a
+	 * 'default' element.
+	 * 
+	 * @param element
+	 *            - the {@link NamedElement}
+	 * @return {@code true} if the name is null, empty or equals 'default'
+	 *         (ignoring case).
+	 */
+	public static boolean isDefault(final NamedElement element) {
+		return element.getName() == null
+				|| (element.getName() != null && (element.getName().isEmpty() || element
+						.getName().equalsIgnoreCase("default")));
+	}
+
+	/**
+	 * Validates if the a {@link Transition} has an {@link ExitPointSpec} with
+	 * the given name.
+	 * 
+	 * @param transition
+	 *            - the transition to check
+	 * @param name
+	 *            - the name to check
+	 * @return {@code true} if the transition contains an ExitPointSpec with the
+	 *         name. Otherwise {@code false}.
+	 */
+	public static boolean isNamedExitTransition(Transition transition,
+			String name) {
+
+		boolean isNamedExitTransition = false;
+
+		Iterator<ReactionProperty> propertyIt = transition.getProperties()
+				.iterator();
+
+		while (propertyIt.hasNext() && !isNamedExitTransition) {
+
+			ReactionProperty property = propertyIt.next();
+
+			if (property instanceof ExitPointSpec) {
+
+				isNamedExitTransition = name.equals(((ExitPointSpec) property)
+						.getExitpoint());
+			}
+		}
+
+		return isNamedExitTransition;
+	}
+
+	public static boolean isDefaultExitTransition(Transition transition) {
+		boolean isDefault = false;
+		List<ExitPointSpec> exits = getExitPointSpecs(transition
+				.getProperties());
+		if (!exits.isEmpty()) {
+			for (ExitPointSpec exit : exits) {
+				if (exit.getExitpoint().equalsIgnoreCase("default")) {
+					isDefault = true;
+				}
+			}
+		} else {
+			isDefault = true;
+		}
+
+		return isDefault;
+	}
+
+	/**
+	 * Filters the given list of {@link ReactionProperty} to return only a list
+	 * of {@link ExitPointSpec}.
+	 * 
+	 * @param elements
+	 * 			- list of ReactionProperties
+	 * @return
+	 * 		A list of ExitPointSpecs.
+	 */
+	public static List<ExitPointSpec> getExitPointSpecs(
+			List<ReactionProperty> elements) {
+		List<ExitPointSpec> exits = new ArrayList<ExitPointSpec>();
+		for (ReactionProperty element : elements) {
+			if (element instanceof ExitPointSpec) {
+				exits.add((ExitPointSpec) element);
+			}
+		}
+		return exits;
+	}
+
+	public static List<Entry> getEntries(List<?> elements) {
+		List<Entry> entries = new ArrayList<Entry>();
+		for (Object element : elements) {
+			if (element instanceof Entry) {
+				entries.add((Entry) element); 
+			}
+		}
+		return entries;
+	}
+
+	public static List<Exit> getExits(List<EObject> elements) {
+		List<Exit> exits = new ArrayList<Exit>();
+		for (EObject element : elements) {
+			if (element instanceof Exit) {
+				exits.add((Exit) element);
+			}
+		}
+		return exits;
+	}
+}

+ 40 - 40
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/STextJavaValidatorTest.java

@@ -413,33 +413,56 @@ public class STextJavaValidatorTest extends AbstractSTextTest implements STextVa
 		assertIssueCount(diagnostics, 1);
 		assertWarning(diagnostics, ENTRY_UNUSED);
 	}
+	@Test
+	public void checkTopLeveEntryIsDefaultEntry(){
+		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "TopLevelEntryIsDefaultEntryError.sct");
+		doValidateAllContents(Entry.class);
+		
+		assertIssueCount(diagnostics, 1);
+		assertError(diagnostics, TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY);
+		resetDiagnostics();
+		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "TopLevelEntryIsDefaultEntryWarn.sct");
+		doValidateAllContents(Entry.class);
+		
+		assertIssueCount(diagnostics, 1);
+		assertWarning(diagnostics, TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY);
+	}
 
 	@Test
 	public void checkUnusedExit() {
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedExitPoint.sct");
-		Iterator<EObject> iter = statechart.eAllContents();
-		while (iter.hasNext()) {
-			EObject element = iter.next();
-			if (element instanceof Exit) {
-				validator.validate(element, diagnostics, new HashMap<Object, Object>());
-			}
-		}
+		doValidateAllContents(Exit.class);
 
 		assertIssueCount(diagnostics, 1);
 		assertError(diagnostics, EXIT_UNUSED);
 
 		resetDiagnostics();
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedDefaultExitPoint.sct");
-		iter = statechart.eAllContents();
+		doValidateAllContents(Exit.class);
+
+		assertIssueCount(diagnostics, 1);
+		assertError(diagnostics, EXIT_DEFAULT_UNUSED);
+	}
+
+	protected void doValidateAllContents(Class<? extends EObject> clazz) {
+		Iterator<EObject> iter = statechart.eAllContents();
 		while (iter.hasNext()) {
 			EObject element = iter.next();
-			if (element instanceof Exit) {
+			if (clazz.isInstance(element)) {
 				validator.validate(element, diagnostics, new HashMap<Object, Object>());
 			}
 		}
+	}
+	protected void assertAllTransitionsAreValid(Class<? extends EObject> clazz) {
+		Iterator<EObject> iter;
+		iter = statechart.eAllContents();
 
-		assertIssueCount(diagnostics, 1);
-		assertError(diagnostics, EXIT_DEFAULT_UNUSED);
+		while (iter.hasNext()) {
+			EObject element = iter.next();
+			if (clazz.isInstance(element)) {
+				assertTrue(validator.validate(element, diagnostics, new HashMap<Object, Object>()));
+			}
+		}
 	}
 
 	@Test
@@ -447,13 +470,7 @@ public class STextJavaValidatorTest extends AbstractSTextTest implements STextVa
 		// Test source state isn't composite
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR
 				+ "TransitionEntrySpecNotComposite.sct");
-		Iterator<EObject> iter = statechart.eAllContents();
-		while (iter.hasNext()) {
-			EObject element = iter.next();
-			if (element instanceof Transition) {
-				assertTrue(validator.validate(element, diagnostics, new HashMap<Object, Object>()));
-			}
-		}
+		doValidateAllContents(Transition.class);
 		// Test target state isn't composite
 		assertIssueCount(diagnostics, 2);
 		assertWarning(diagnostics, TRANSITION_ENTRY_SPEC_NOT_COMPOSITE);
@@ -461,14 +478,7 @@ public class STextJavaValidatorTest extends AbstractSTextTest implements STextVa
 		resetDiagnostics();
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR
 				+ "TransitionExitSpecNotComposite.sct");
-		iter = statechart.eAllContents();
-
-		while (iter.hasNext()) {
-			EObject element = iter.next();
-			if (element instanceof Transition) {
-				assertTrue(validator.validate(element, diagnostics, new HashMap<Object, Object>()));
-			}
-		}
+		assertAllTransitionsAreValid(Transition.class);
 
 		assertIssueCount(diagnostics, 1);
 		assertWarning(diagnostics, TRANSITION_EXIT_SPEC_NOT_COMPOSITE);
@@ -477,13 +487,7 @@ public class STextJavaValidatorTest extends AbstractSTextTest implements STextVa
 		resetDiagnostics();
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR
 				+ "TransitionExitSpecOnMultipleSiblings.sct");
-		iter = statechart.eAllContents();
-		while (iter.hasNext()) {
-			EObject element = iter.next();
-			if (element instanceof Transition) {
-				assertTrue(validator.validate(element, diagnostics, new HashMap<Object, Object>()));
-			}
-		}
+		assertAllTransitionsAreValid(Transition.class);
 
 		assertIssueCount(diagnostics, 4);
 		assertWarning(diagnostics, TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS);
@@ -492,18 +496,14 @@ public class STextJavaValidatorTest extends AbstractSTextTest implements STextVa
 		resetDiagnostics();
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR
 				+ "TransitionNotExistingNamedExitPoint.sct");
-		iter = statechart.eAllContents();
-		while (iter.hasNext()) {
-			EObject element = iter.next();
-			if (element instanceof Transition) {
-				validator.validate(element, diagnostics, new HashMap<Object, Object>());
-			}
-		}
+		doValidateAllContents(Transition.class);
 
 		assertIssueCount(diagnostics, 1);
 		assertError(diagnostics, TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT);
 	}
 
+
+
 	@Test
 	public void checkUnboundEntryPoints() {
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnboundDefaultEntryPoints.sct");

+ 73 - 0
test-plugins/org.yakindu.sct.test.models/testmodels/validation/TopLevelEntryIsDefaultEntryError.sct

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
+  <sgraph:Statechart xmi:id="_DIlH4PZ4EeWYUs-59Co8bA" specification="interface:&#xA;" name="default">
+    <regions xmi:id="_DJYZIPZ4EeWYUs-59Co8bA" name="main region">
+      <vertices xsi:type="sgraph:State" xmi:id="_DJ26QPZ4EeWYUs-59Co8bA" name="StateA" incomingTransitions="_d2xcAPcsEeW_G_kvoQD5Ug"/>
+      <vertices xsi:type="sgraph:Entry" xmi:id="_dcxnoPcsEeW_G_kvoQD5Ug" name="Name">
+        <outgoingTransitions xmi:id="_d2xcAPcsEeW_G_kvoQD5Ug" specification="" target="_DJ26QPZ4EeWYUs-59Co8bA"/>
+      </vertices>
+    </regions>
+  </sgraph:Statechart>
+  <notation:Diagram xmi:id="_DJV84PZ4EeWYUs-59Co8bA" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_DIlH4PZ4EeWYUs-59Co8bA" measurementUnit="Pixel">
+    <children xmi:id="_DJefwPZ4EeWYUs-59Co8bA" type="Region" element="_DJYZIPZ4EeWYUs-59Co8bA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_DJqtAPZ4EeWYUs-59Co8bA" type="RegionName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_DJqtAfZ4EeWYUs-59Co8bA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_DJqtAvZ4EeWYUs-59Co8bA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_DJr7IPZ4EeWYUs-59Co8bA" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+        <children xmi:id="_DJ8Z0PZ4EeWYUs-59Co8bA" type="State" element="_DJ26QPZ4EeWYUs-59Co8bA">
+          <children xsi:type="notation:DecorationNode" xmi:id="_DJ8Z1PZ4EeWYUs-59Co8bA" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_DJ8Z1fZ4EeWYUs-59Co8bA"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_DJ8Z1vZ4EeWYUs-59Co8bA"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_DJ-PAPZ4EeWYUs-59Co8bA" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_DJ-PAfZ4EeWYUs-59Co8bA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJ-PAvZ4EeWYUs-59Co8bA"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_DJ-PA_Z4EeWYUs-59Co8bA" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_DJ8Z0fZ4EeWYUs-59Co8bA" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_DJ8Z0vZ4EeWYUs-59Co8bA"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_DJ-2EPZ4EeWYUs-59Co8bA" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJ_dIPZ4EeWYUs-59Co8bA" x="52" y="138" width="59" height="53"/>
+        </children>
+        <children xmi:id="_dc3HMPcsEeW_G_kvoQD5Ug" type="Entry" element="_dcxnoPcsEeW_G_kvoQD5Ug">
+          <children xmi:id="_dc3uQPcsEeW_G_kvoQD5Ug" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_dc4VUPcsEeW_G_kvoQD5Ug" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_dc4VUfcsEeW_G_kvoQD5Ug"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_dc4VUvcsEeW_G_kvoQD5Ug"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_dc3uQfcsEeW_G_kvoQD5Ug" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_dc3uQvcsEeW_G_kvoQD5Ug"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_dc3HMfcsEeW_G_kvoQD5Ug" fontName="Verdana" fillColor="0" lineColor="16777215"/>
+          <styles xsi:type="notation:NamedStyle" xmi:id="_dc3HMvcsEeW_G_kvoQD5Ug" name="allowColors"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_dc3HM_csEeW_G_kvoQD5Ug" x="51" y="41"/>
+        </children>
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJr7IfZ4EeWYUs-59Co8bA"/>
+      </children>
+      <styles xsi:type="notation:ShapeStyle" xmi:id="_DJefwfZ4EeWYUs-59Co8bA" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJsiMPZ4EeWYUs-59Co8bA" x="220" y="7" width="977" height="317"/>
+    </children>
+    <children xsi:type="notation:Shape" xmi:id="_DKPUwPZ4EeWYUs-59Co8bA" type="StatechartText" fontName="Verdana" lineColor="4210752">
+      <children xsi:type="notation:DecorationNode" xmi:id="_DKPUwvZ4EeWYUs-59Co8bA" type="StatechartName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_DKPUw_Z4EeWYUs-59Co8bA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_DKP70PZ4EeWYUs-59Co8bA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_DKP70fZ4EeWYUs-59Co8bA" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DKP70vZ4EeWYUs-59Co8bA"/>
+      </children>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DKP70_Z4EeWYUs-59Co8bA" x="10" y="10" width="201" height="311"/>
+    </children>
+    <styles xsi:type="notation:DiagramStyle" xmi:id="_DJV84fZ4EeWYUs-59Co8bA"/>
+    <edges xmi:id="_d2zRMPcsEeW_G_kvoQD5Ug" type="Transition" element="_d2xcAPcsEeW_G_kvoQD5Ug" source="_dc3HMPcsEeW_G_kvoQD5Ug" target="_DJ8Z0PZ4EeWYUs-59Co8bA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_d2z4QfcsEeW_G_kvoQD5Ug" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_d2z4QvcsEeW_G_kvoQD5Ug"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_d20fUPcsEeW_G_kvoQD5Ug" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_d2zRMfcsEeW_G_kvoQD5Ug" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_d2z4QPcsEeW_G_kvoQD5Ug" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_d2zRMvcsEeW_G_kvoQD5Ug" points="[1, 7, -20, -107]$[28, 90, 7, -24]"/>
+    </edges>
+  </notation:Diagram>
+</xmi:XMI>

+ 98 - 0
test-plugins/org.yakindu.sct.test.models/testmodels/validation/TopLevelEntryIsDefaultEntryWarn.sct

@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
+  <sgraph:Statechart xmi:id="_DIlH4PZ4EeWYUs-59Co8bA" specification="interface:&#xA;" name="default">
+    <regions xmi:id="_DJYZIPZ4EeWYUs-59Co8bA" name="main region">
+      <vertices xsi:type="sgraph:State" xmi:id="_DJ26QPZ4EeWYUs-59Co8bA" name="StateA" incomingTransitions="_d2xcAPcsEeW_G_kvoQD5Ug _ilk4APctEeW_G_kvoQD5Ug"/>
+      <vertices xsi:type="sgraph:Entry" xmi:id="_dcxnoPcsEeW_G_kvoQD5Ug" name="Name">
+        <outgoingTransitions xmi:id="_d2xcAPcsEeW_G_kvoQD5Ug" specification="" target="_DJ26QPZ4EeWYUs-59Co8bA"/>
+      </vertices>
+      <vertices xsi:type="sgraph:Entry" xmi:id="_iOplwPctEeW_G_kvoQD5Ug">
+        <outgoingTransitions xmi:id="_ilk4APctEeW_G_kvoQD5Ug" specification="" target="_DJ26QPZ4EeWYUs-59Co8bA"/>
+      </vertices>
+    </regions>
+  </sgraph:Statechart>
+  <notation:Diagram xmi:id="_DJV84PZ4EeWYUs-59Co8bA" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_DIlH4PZ4EeWYUs-59Co8bA" measurementUnit="Pixel">
+    <children xmi:id="_DJefwPZ4EeWYUs-59Co8bA" type="Region" element="_DJYZIPZ4EeWYUs-59Co8bA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_DJqtAPZ4EeWYUs-59Co8bA" type="RegionName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_DJqtAfZ4EeWYUs-59Co8bA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_DJqtAvZ4EeWYUs-59Co8bA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_DJr7IPZ4EeWYUs-59Co8bA" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+        <children xmi:id="_DJ8Z0PZ4EeWYUs-59Co8bA" type="State" element="_DJ26QPZ4EeWYUs-59Co8bA">
+          <children xsi:type="notation:DecorationNode" xmi:id="_DJ8Z1PZ4EeWYUs-59Co8bA" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_DJ8Z1fZ4EeWYUs-59Co8bA"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_DJ8Z1vZ4EeWYUs-59Co8bA"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_DJ-PAPZ4EeWYUs-59Co8bA" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_DJ-PAfZ4EeWYUs-59Co8bA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJ-PAvZ4EeWYUs-59Co8bA"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_DJ-PA_Z4EeWYUs-59Co8bA" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_DJ8Z0fZ4EeWYUs-59Co8bA" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_DJ8Z0vZ4EeWYUs-59Co8bA"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_DJ-2EPZ4EeWYUs-59Co8bA" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJ_dIPZ4EeWYUs-59Co8bA" x="52" y="138" width="59" height="53"/>
+        </children>
+        <children xmi:id="_dc3HMPcsEeW_G_kvoQD5Ug" type="Entry" element="_dcxnoPcsEeW_G_kvoQD5Ug">
+          <children xmi:id="_dc3uQPcsEeW_G_kvoQD5Ug" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_dc4VUPcsEeW_G_kvoQD5Ug" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_dc4VUfcsEeW_G_kvoQD5Ug"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_dc4VUvcsEeW_G_kvoQD5Ug"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_dc3uQfcsEeW_G_kvoQD5Ug" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_dc3uQvcsEeW_G_kvoQD5Ug"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_dc3HMfcsEeW_G_kvoQD5Ug" fontName="Verdana" fillColor="0" lineColor="16777215"/>
+          <styles xsi:type="notation:NamedStyle" xmi:id="_dc3HMvcsEeW_G_kvoQD5Ug" name="allowColors"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_dc3HM_csEeW_G_kvoQD5Ug" x="51" y="41"/>
+        </children>
+        <children xmi:id="_iOqM0PctEeW_G_kvoQD5Ug" type="Entry" element="_iOplwPctEeW_G_kvoQD5Ug">
+          <children xmi:id="_iOqz4PctEeW_G_kvoQD5Ug" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_iOqz4_ctEeW_G_kvoQD5Ug" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_iOqz5PctEeW_G_kvoQD5Ug"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_iOqz5fctEeW_G_kvoQD5Ug"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_iOqz4fctEeW_G_kvoQD5Ug" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_iOqz4vctEeW_G_kvoQD5Ug"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_iOqM0fctEeW_G_kvoQD5Ug" fontName="Verdana" fillColor="0" lineColor="16777215"/>
+          <styles xsi:type="notation:NamedStyle" xmi:id="_iOqM0vctEeW_G_kvoQD5Ug" name="allowColors"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_iOqM0_ctEeW_G_kvoQD5Ug" x="151" y="35"/>
+        </children>
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJr7IfZ4EeWYUs-59Co8bA"/>
+      </children>
+      <styles xsi:type="notation:ShapeStyle" xmi:id="_DJefwfZ4EeWYUs-59Co8bA" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DJsiMPZ4EeWYUs-59Co8bA" x="220" y="7" width="977" height="317"/>
+    </children>
+    <children xsi:type="notation:Shape" xmi:id="_DKPUwPZ4EeWYUs-59Co8bA" type="StatechartText" fontName="Verdana" lineColor="4210752">
+      <children xsi:type="notation:DecorationNode" xmi:id="_DKPUwvZ4EeWYUs-59Co8bA" type="StatechartName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_DKPUw_Z4EeWYUs-59Co8bA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_DKP70PZ4EeWYUs-59Co8bA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_DKP70fZ4EeWYUs-59Co8bA" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DKP70vZ4EeWYUs-59Co8bA"/>
+      </children>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_DKP70_Z4EeWYUs-59Co8bA" x="10" y="10" width="201" height="311"/>
+    </children>
+    <styles xsi:type="notation:DiagramStyle" xmi:id="_DJV84fZ4EeWYUs-59Co8bA"/>
+    <edges xmi:id="_d2zRMPcsEeW_G_kvoQD5Ug" type="Transition" element="_d2xcAPcsEeW_G_kvoQD5Ug" source="_dc3HMPcsEeW_G_kvoQD5Ug" target="_DJ8Z0PZ4EeWYUs-59Co8bA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_d2z4QfcsEeW_G_kvoQD5Ug" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_d2z4QvcsEeW_G_kvoQD5Ug"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_d20fUPcsEeW_G_kvoQD5Ug" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_d2zRMfcsEeW_G_kvoQD5Ug" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_d2z4QPcsEeW_G_kvoQD5Ug" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_d2zRMvcsEeW_G_kvoQD5Ug" points="[1, 7, -20, -107]$[28, 90, 7, -24]"/>
+    </edges>
+    <edges xmi:id="_ilmtMPctEeW_G_kvoQD5Ug" type="Transition" element="_ilk4APctEeW_G_kvoQD5Ug" source="_iOqM0PctEeW_G_kvoQD5Ug" target="_DJ8Z0PZ4EeWYUs-59Co8bA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_ilnUQfctEeW_G_kvoQD5Ug" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_ilnUQvctEeW_G_kvoQD5Ug"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_iln7UPctEeW_G_kvoQD5Ug" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_ilmtMfctEeW_G_kvoQD5Ug" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_ilnUQPctEeW_G_kvoQD5Ug" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_ilmtMvctEeW_G_kvoQD5Ug" points="[-4, 6, 75, -114]$[-85, 144, -6, 24]"/>
+    </edges>
+  </notation:Diagram>
+</xmi:XMI>