Bug 512000 - [codegen] check for name clashes in inheritance hierarchy

Adding check for attributes, protocol messages, and states

Change-Id: I38f8daa744d3b72a8dcf2002c3206bb896bed404
Signed-off-by: Young-Soo Roh <ysroh@zeligsoft.com>
diff --git a/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/validation/PostUML2xtumlrtValidator.xtend b/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/validation/PostUML2xtumlrtValidator.xtend
index 02f270f..384eb2e 100644
--- a/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/validation/PostUML2xtumlrtValidator.xtend
+++ b/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/validation/PostUML2xtumlrtValidator.xtend
@@ -29,6 +29,18 @@
 import org.eclipse.uml2.uml.Pseudostate
 import static extension org.eclipse.papyrusrt.xtumlrt.util.XTUMLRTUtil.*
 import static extension org.eclipse.papyrusrt.xtumlrt.util.XTUMLRTExtensions.*
+import org.eclipse.papyrusrt.xtumlrt.common.Attribute
+import org.eclipse.papyrusrt.xtumlrt.common.Operation
+import org.eclipse.papyrusrt.xtumlrt.common.Signal
+import org.eclipse.papyrusrt.xtumlrt.common.Protocol
+import org.eclipse.papyrusrt.xtumlrt.statemach.State
+import org.eclipse.papyrusrt.xtumlrt.statemach.StateMachine
+import java.util.List
+import org.eclipse.papyrusrt.xtumlrt.common.RedefinableElement
+import java.util.ArrayList
+import org.eclipse.papyrusrt.xtumlrt.util.ContainmentUtils
+import org.eclipse.papyrusrt.xtumlrt.common.NamedElement
+import org.eclipse.papyrusrt.xtumlrt.util.QualifiedNames
 
 /**
  * Post UML2xtumlrt SM validation
@@ -52,9 +64,7 @@
 	protected def void validateGeneratedElement(EObject o, MultiStatus result) {
 		if(o instanceof CommonElement) {
 			val source = translator.getSource(o)
-			if(source !== null) {
-				o.validateElement(source, result)
-			}
+			o.validateElement(source, result)
 		}
 	}
 
@@ -189,5 +199,73 @@
         }
     }
 
+    protected dispatch def void validateElement(Attribute attr, EObject source, MultiStatus result) {
+        val capsule = attr.owner as Capsule
+        val capsuleParent = capsule.redefines
+        if (capsuleParent instanceof Capsule) {
+            val allParentAttrs = capsuleParent.allAttributes
+            if (allParentAttrs.exists[ name == attr.name && attr.redefines !== it ]) {
+                val qn = (source as org.eclipse.uml2.uml.Property).qualifiedName
+                val exception = new DetailedException(
+                    "Attribute " + qn + " has the same name as a attribute in the parent capsule but it does not redefine it"
+                )
+                val status = new Status(IStatus.WARNING, CodeGenPlugin.ID, exception.message, exception)
+                result.add(status)
+            }
+        }
+    }
 
+    protected dispatch def void validateElement(Signal signal, EObject source, MultiStatus result) {
+        val protocol = signal.owner as Protocol
+        val protocolParent = protocol.redefines
+        if (protocolParent instanceof Protocol) {
+            val allParentSignals = protocolParent.allSignals
+            if (allParentSignals.exists[ name == signal.name && signal.redefines !== it ]) {
+                val qn = (source as org.eclipse.uml2.uml.Operation).qualifiedName
+                val exception = new DetailedException(
+                    "Protocol message " + qn + " has the same name as a protocol message in the parent protocol but it does not redefine it"
+                )
+                val status = new Status(IStatus.ERROR, CodeGenPlugin.ID, exception.message, exception)
+                result.add(status)
+            }
+        }
+    }
+    
+    protected dispatch def void validateElement(State state, EObject source, MultiStatus result) {
+        val owner = state.owner as RedefinableElement
+        if(owner instanceof StateMachine){
+        	// don't need to validate top composite
+        	return
+        }
+        val redefine = owner.redefines
+        if(redefine instanceof CompositeState){
+            val allParentStates = redefine.substates
+            if (allParentStates.exists[ name == state.name && state.redefines !== it ]) {
+                val qn = state.stateQualifiedName
+                val exception = new DetailedException(
+                    "State " + qn + " has the same name as a state in the parent state but it does not redefine it"
+                )
+                val status = new Status(IStatus.ERROR, CodeGenPlugin.ID, exception.message, exception)
+                result.add(status)
+            }
+        }
+    }
+    
+    	/** 
+	 * Calculate qualified name for object's container in the context of UMLRT codegen
+	 */
+	static def String getStateQualifiedName(NamedElement context) {
+		val hierarchy =	ContainmentUtils.cachedFullContainmentChain(context)
+		var result = ""
+		for(parent : hierarchy){
+			if (!(parent.eContainer instanceof StateMachine)) {
+				if(result != ""){
+					result += QualifiedNames.SEPARATOR
+				}
+				result += parent.name
+			}
+		}
+
+		return result
+	}
 }