[Mobies-commit] [commit] r4271 - in UDM/trunk: include lib samples/CreateLampModel src/Udm/PythonAPIGen src/UdmBase src/UdmPython tests/test_UdmPythonDS

endre at redhat3.isis.vanderbilt.edu endre at redhat3.isis.vanderbilt.edu
Sat Mar 8 02:21:11 CST 2014


Author: endre
Date: Sat Mar  8 02:21:10 2014
New Revision: 4271

Log:
Python Domain specific API:
- metaObjects: AssociationRoles
- getter functions for associations and assoc. classes (as we have in the C++ API)

Modified:
   UDM/trunk/include/UmlExt.h
   UDM/trunk/lib/UdmPython.py
   UDM/trunk/samples/CreateLampModel/CreateLampModel.cpp
   UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp
   UDM/trunk/src/UdmBase/UmlExt.cpp
   UDM/trunk/src/UdmPython/UdmPython.cpp
   UDM/trunk/tests/test_UdmPythonDS/test.py

Modified: UDM/trunk/include/UmlExt.h
==============================================================================
--- UDM/trunk/include/UmlExt.h	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/include/UmlExt.h	Sat Mar  8 02:21:10 2014	(r4271)
@@ -184,12 +184,16 @@
 	UDM_DLL set<Attribute> AncestorAttributes(const Class &c);
 
 // find the single way a class can be contained by another, return NULL none or if multiple roles are found
-	UDM_DLL Composition matchChildToParent(Class c, Class p);
-
-	// find the single way a class can be contained by another, return NULL none or if multiple roles are found
-	// addtionally, names of the child and parent roles can be provided to constraint the possible compositions.
-	UDM_DLL Composition matchChildToParent(Class c, Class p, const char * crole, const char * prole = NULL);
-
+// addtionally, names of the child and parent roles can be provided to constraint the possible compositions.
+	UDM_DLL Composition matchChildToParent(Class c, Class p, const char * crole = NULL, const char * prole = NULL);
+    
+    //finds the only suitable AssociationRole to reach 'target_class' or 'assoc_cls' from c for the association with which has the name 'rolename' on C's side
+    //if target_aclass is provided than peer_type is ignored, and only those assoc. roles are considered which are in an assoc. cls. based assoc.
+    //rolename can be NULL. if not null, the results will be filtered against the rolename as well
+    //multiple or no result will return null object.
+    
+    UDM_DLL AssociationRole matchPeerToPeer(Class c, Class target_class, Class target_aclass, const char * rolename = NULL);
+
     // returns true if derived = base
 	UDM_DLL bool IsDerivedFrom(const Class &derived, const Class &base);
 	UDM_DLL bool IsAssocClass(const Class &cl);

Modified: UDM/trunk/lib/UdmPython.py
==============================================================================
--- UDM/trunk/lib/UdmPython.py	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/lib/UdmPython.py	Sat Mar  8 02:21:10 2014	(r4271)
@@ -56,6 +56,18 @@
 			ret.append(UdmPython(child))
 		return ret
 
+	def _get_associations(self, assoc_role, mode):
+		#assoc_role could be either Udm.Object or UdmPython (or descendants)
+		ret = []
+		assoc_role_impl = None
+		if isinstance(assoc_role, UdmPython):
+			assoc_role_impl = assoc_role.impl
+		else:
+			assoc_role_impl = assoc_role
+		for peer in self.impl.getAssociation(assoc_role_impl, mode):
+			ret.append(UdmPython(peer))
+		return ret
+
 	def __eq__(self, other):
 		return self.__dict__['impl'] == other.__dict__['impl']
 	def __ne__(self, other):
@@ -312,4 +324,23 @@
 
 	return Uml.CompositionParentRole(udm.InitParentRole(child_type.impl, parent_type.impl, crole_name, prole_name))
 	
+def GetUmlAssocRoleByPeerAndRole(my_type, peer_type, arole_name):
+	import udm
+	import Uml
+	#my_type is expected to be Uml.Class
+	#peer_type is expected to be Uml.Class
+	#arole_name is expected to be string
+
+	return Uml.AssociationRole(udm.GetUmlAssocRoleByPeerAndRole(my_type.impl, peer_type.impl, arole_name))
+
+def GetUmlAssocRoleByAClassAndRole(my_type, aclass_type, arole_name):
+	import udm
+	import Uml
+	#my_type is expected to be Uml.Class
+	#aclass_type is expected to be Uml.Class
+	#arole_name is string
+
+	return Uml.AssociationRole(udm.GetUmlAssocRoleByAClass(my_type.impl, aclass_type.impl, arole_name))
+
+
 

Modified: UDM/trunk/samples/CreateLampModel/CreateLampModel.cpp
==============================================================================
--- UDM/trunk/samples/CreateLampModel/CreateLampModel.cpp	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/samples/CreateLampModel/CreateLampModel.cpp	Sat Mar  8 02:21:10 2014	(r4271)
@@ -1145,6 +1145,10 @@
 	if (a == b) cout << " a equals to b " << endl;
 	if (a == c) cout << " a equals to c " << endl;
 
+	cout << "Meta test: " << endl;
+	cout << " Switch::meta_src:" << Switch::meta_src.name() << endl;
+	cout << " Bulb::meta_dst:" << Bulb::meta_dst.name() << endl;
+	
 	return 0;
 }
 

Modified: UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp
==============================================================================
--- UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp	Sat Mar  8 02:21:10 2014	(r4271)
@@ -110,6 +110,7 @@
         for( set< ::Uml::Attribute>::iterator attrs_i = attrs.begin(); attrs_i != attrs.end(); attrs_i++)
                 m_output << "\t" << uc_i->name() << ".meta_" << attrs_i->name() << " = GetUmlAttributeByName(" << uc_i->name() << ".Meta, \"" << attrs_i->name() << "\")"<< endl;
     }
+    m_output << "\tpass" << endl;
     m_output << endl;
     m_output << "def init_childroles():" << endl;
     for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
@@ -132,9 +133,8 @@
             m_output << "\t" << cl_name << ".meta_" << rel_name << " = GetUmlChildRoleByTypesAndRolenames(" << thischildkind.name() << ".Meta," << cl_name << ".Meta, \"" << the_other.name() <<  "\", \"" << i->name() << "\")" << endl;
 
         }
-        
     }
-    
+    m_output << "\tpass" << endl;
     m_output << endl;
     m_output << "def init_parentroles():" << endl;
     for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
@@ -159,8 +159,60 @@
         
     }
     
+    m_output << "\tpass" << endl;
+    m_output << endl;
+    m_output << "def init_peer_associationroles():" << endl;
+    for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
+    {
+        ::Uml::Class c = *uc_i;
+        string cl_name = c.name();
+        set< ::Uml::AssociationRole> assocs = c.associationRoles();
+        for( set< ::Uml::AssociationRole>::iterator i = assocs.begin(); i != assocs.end(); i++) 
+	    {
+	        ::Uml::Association pp = (*i).parent();
+            ::Uml::Class aclass = pp.assocClass();
+            ::Uml::AssociationRole the_other = Uml::theOther(*i);
+            string rel_name = ::Uml::MakeRoleName(the_other);
+            ::Uml::Class oclass = the_other.target();
+            if (!aclass)
+                m_output << "\t" << cl_name << ".meta_" << rel_name << " = GetUmlAssocRoleByPeerAndRole(" << cl_name << ".Meta," << oclass.name() << ".Meta, \"" << i->name() << "\")" << endl;
+            else
+                m_output << "\t" << cl_name << ".meta_" << rel_name << " = GetUmlAssocRoleByAClassAndRole(" << cl_name << ".Meta,"  << aclass.name() << ".Meta,\"" << i->name() << "\")" << endl;
+            
+        }
+    
+    }
+    m_output << "\tpass" << endl;
+    m_output << endl;
+    m_output << "def init_class_associationroles():" << endl;
+    for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
+    {
+        ::Uml::Class c = *uc_i;
+        string cl_name = c.name();
+        ::Uml::Association assoc = c.association();
+        if (assoc)
+        {
+            set< ::Uml::AssociationRole> assocs = assoc.roles();
+            for( set< ::Uml::AssociationRole>::iterator i = assocs.begin(); i != assocs.end(); i++)
+            {
+                string rel_name = ::Uml::MakeRoleName(*i);
+                UDM_ASSERT(rel_name.size() > 0);
+                
+                ::Uml::AssociationRole the_other = ::Uml::theOther(*i);
+                string orel_name = ::Uml::MakeRoleName(the_other);
+                string otclass_name = ((::Uml::Class)(the_other.target())).name();
+                
+                ::Uml::Class tclass = (::Uml::Class)(*i).target();
+                string tclass_name = tclass.name();
+                
+				m_output << "\t" << cl_name << ".meta_" << orel_name << "_end_ = " << otclass_name << ".meta_" << rel_name << "_rev = " << tclass_name << ".meta_" << orel_name << endl;
+            }
+        }
+    }
+    
+    
 		
-
+  m_output << "\tpass" << endl;
   m_output << endl << endl;
 
   /*INITIALIZE THE META STATIC VARIABLE*/
@@ -179,6 +231,8 @@
     m_output << "\t\t" << "init_childroles()" << endl;
     m_output << "\t\t" << "init_parentroles()" << endl;
     m_output << "\t\t" << "init_attributes()" << endl;
+    m_output << "\t\t" << "init_peer_associationroles()" << endl;
+    m_output << "\t\t" << "init_class_associationroles()" << endl;
     m_output << "\t\t" << "module_initialized = True" << endl;
     m_output << endl;
 	
@@ -290,7 +344,7 @@
                 
             }
         }
-        else m_output << "\t# access method for non-navigable association " << rel_name << " omitted";
+        else m_output << "\t# access method for non-navigable children " << rel_name << " omitted";
     }
     
     
@@ -323,157 +377,79 @@
      //childrens end ----------------------------------------------------------------
 }
 
-void PythonAPIGen::generateAssociations(::Uml::Class &cls)
+void PythonAPIGen::generateAssociations(::Uml::Class &c)
 {
-
-  m_output << "\t# Associations " << endl << endl;
-
-  // association classes
-  ::Uml::Association ass = Uml::GetAncestorAssociation( cls );
-
-  if ( ass )
-  {
-	// set of association roles
-	set < ::Uml::AssociationRole> ass_roles = ass.roles();
-	for( set< ::Uml::AssociationRole>::iterator a_r_i = ass_roles.begin(); a_r_i != ass_roles.end(); a_r_i++ )
-	{
-	  ::Uml::Class target_cl = a_r_i->target();
-
-	  string tname = target_cl.name();
-	  string ar_name = a_r_i->name();
-
-	  string pkg_name = "";//Utils::getPackageSignature(target_cl, m_ns_path, m_package_name);
-
-	  m_output << "\t\"\"\"" << endl;
-	  m_output << "\t Association with role name <code>" << ar_name << "</code>." << endl;
-	  m_output << "\t\"\"\"" << endl;
-
-	  // setter for the association
-	  
-	  //tname 
-	  m_output << "\tdef set" << ar_name << "(self, a):" << endl;
-	  m_output << "\t\t\"\"\"" << endl;
-	  m_output << "\t\tSets the end of the association with role name <code>" << ar_name << "</code>." << endl;
-	  m_output << "\t\t at param a The end of the association'''" << endl;
-	  m_output << "\t\t\"\"\"" << endl;
-	  
-	  //m_output << "\t\t#UdmPseudoObjectContainer container = new UdmPseudoObjectContainer(1);" << endl;
-	  //m_output << "\t\t#container.setAt(0, (UdmPseudoObject)a);" << endl;
-	  //m_output << "\t\t#setAssociation(\"" << ar_name << "\", container, UdmHelper.TARGET_FROM_CLASS);" << endl;
-	  m_output << "\t\tpass" << endl;
-
-	  
-	  // getter for the association
-	  m_output << "\tdef " << "get" << ar_name << "(self):" << endl;
-	  m_output << "\t\t\"\"\"" << endl;
-	  m_output << "\t\tReturns the end of the association with role name <code>" << ar_name << "</code>." << endl;
-	  m_output << "\t\t at return The end of the association" << endl;
-	  m_output << "\t\t\"\"\"" << endl;
-	  m_output << "\t\treturn " << tname << ".cast(self.impl.ar_name)" << endl;
-	  //m_ioutput << "\tpublic " << pkg_name << tname << " get" << ar_name << "() throws UdmException;" << endl;
-	  //m_output << "\t\tUdmPseudoObjectContainer container = getAssociation(\"" << ar_name << "\", UdmHelper.TARGET_FROM_CLASS);" << endl;
-	  //m_output << "\t\tif (container.getLength() > 0)" << endl << endl;
-	  //m_output << "\t\t\treturn (" << pkg_name << tname << ") " << pkg_name << "Utils.wrapWithSubclass(container.getAt(0), metaDiagram);" << endl;
-	  //m_output << "\t\treturn null;" << endl << endl;
-	  //m_output << "\t}" << endl;
-	  m_output << "\t" << endl;
-	} 
-  }
-
-	// associations
-  // set of associations
-  set < ::Uml::AssociationRole> assroles = cls.associationRoles();
-
-  if ( assroles.size() )
+    string cl_name = c.name();
+	set< ::Uml::AssociationRole> assocs = c.associationRoles();
+    
+    
+	for( set< ::Uml::AssociationRole>::iterator i = assocs.begin(); i != assocs.end(); i++)
 	{
-	for( set< ::Uml::AssociationRole>::iterator ar_i = assroles.begin(); ar_i != assroles.end(); ar_i++ )
+		::Uml::Association pp = (*i).parent();
+		::Uml::Class aclass = pp.assocClass();
+        
+		::Uml::AssociationRole the_other = Uml::theOther(*i);
+        
+		string rel_name = ::Uml::MakeRoleName(the_other);
+		::Uml::Class oclass = the_other.target();
+        if (the_other.isNavigable())
+        {
+            m_output << "\tdef " << rel_name << "(self):" << endl;
+            int max = the_other.max();
+            m_output << "\t\t#return the " << ( max == 1 ?"only peer" : "peers") << " via role_name: " << i->name() << endl;
+            m_output << "\t\tpeers = self._get_associations(" << cl_name << ".meta_" << rel_name << ", udm." << (aclass ? "CLASSFROMTARGET" : "TARGETFROMPEER") << ")" << endl;
+            
+            
+            if (max != 1)
+            {
+                m_output << "\t\tlist=[]" << endl;
+                m_output << "\t\t" << "for i in peers:" << endl;
+                m_output << "\t\t\t" << "list.append(globals()[i._type().name](i))"  << endl;
+                m_output << "\t\treturn list" << endl;
+                    
+            }
+            else
+            {
+                
+                m_output << "\t\tif len(peers) > 0:" << endl;
+                m_output << "\t\t\t" << "return globals()[peers[0]._type().name](peers[0])"  << endl;
+                m_output << "\t\telse:" << endl;
+                m_output << "\t\t\t" << "return None" << endl;
+            
+            }
+        }
+        else m_output << "\t# access method for non-navigable associationrole " << rel_name << " omitted";
+        
+        
+    }
+    
+    ::Uml::Association assoc = c.association();
+	if(assoc)
 	{
-	  string asr_name = ar_i->name();
-	  string to_asr_name = (string)Uml::theOther(*ar_i).name();
-
-	  ::Uml::Class to_class = (::Uml::Class)((Uml::theOther(*ar_i)).target());
-	  string helper_mode = "TARGET_FROM_PEER";
-	  ::Uml::Association ass = ar_i->parent();
-	  ::Uml::Class ass_class = ass.assocClass();
-
-	  if ( ass_class )
-	  {
-		  to_class = ass_class;
-		  helper_mode = "CLASS_FROM_TARGET";
-	  }
-
-	  string tname = to_class.name();
-
-	  m_output << "\t\"\"\"" << endl;
-	  m_output << "\t Association with role name <code>" << to_asr_name << "</code>." << endl;
-	  m_output << "\t\"\"\"" << endl;
-	  m_output << endl;
-
-	  // the canonical form of the to_class
-	  string pckg_signature = "";//Utils::getPackageSignature(to_class, m_ns_path, m_package_name);
-
-	  if ( (Uml::theOther(*ar_i).max() == 0) || (Uml::theOther(*ar_i).max() == 1) )
-	  {
-		//single cardinality
-		//method signature
-		m_output << "\tdef " << "set" << to_asr_name << "(self," << " a): " << endl;//<< tname 
-		
-		//doc comment
-		m_output << "\t\t\"\"\"" << endl;
-		m_output << "\t\tSets the other end of the association with role name <code>" << to_asr_name << "</code>." << endl;
-		m_output << "\t\t at param a The other end of the association" << endl;
-		m_output << "\t\t\"\"\"" << endl;
-
-		
-		//m_output << "\t\t'''setAssociation(\"" << to_asr_name << "\", a, UdmHelper." << helper_mode << ");" << endl;
-		m_output << "\t\tpass" << endl;
-		m_output << endl;
-		
-		m_output << "\tdef " << to_asr_name << "(self):" << endl;
+		set< ::Uml::AssociationRole> assocs = assoc.roles();
+        for( set< ::Uml::AssociationRole>::iterator i = assocs.begin(); i != assocs.end(); i++)
+		{
+			string rel_name = ::Uml::MakeRoleName(*i);
+			UDM_ASSERT(rel_name.size() > 0);
+            
+			::Uml::AssociationRole the_other = ::Uml::theOther(*i);
+			string orel_name = ::Uml::MakeRoleName(the_other);
+			string otclass_cpp_name = UmlClassCPPName(the_other.target());
+            
+			::Uml::Class tclass = (::Uml::Class)(*i).target();
+			string tclass_cpp_name = UmlClassCPPName(tclass);
+            
+            m_output << "\tdef " << rel_name << "_end(self):" << endl;
+            m_output << "\t\t#return the assoc class end via role name:" << i->name() << endl;
+            m_output << "\t\tpeers = self._get_associations(" << cl_name << ".meta_" << rel_name << "_end_ ,udm.TARGETFROMCLASS)" << endl;
+            m_output << "\t\tif len(peers) > 0:" << endl;
+            m_output << "\t\t\t" << "return globals()[peers[0]._type().name](peers[0])"  << endl;
+            m_output << "\t\telse:" << endl;
+            m_output << "\t\t\t" << "return None" << endl;
 
-		m_output << "\t\t\"\"\" Returns the other end of the association with role name <code>" << to_asr_name << "</code>." << endl;
-		m_output << "\t\t at return The other end of the association" << endl;
-		m_output << "\t\t\"\"\"" << endl;
-		//m_ioutput << "\tpublic " << pckg_signature << tname << " get" << to_asr_name << "() throws UdmException;" << endl;
-		m_output << "\t\treturn " << tname << ".cast(self.impl." << to_asr_name << ")" << endl;
-		/*
-		if (isInterfaceNeeded(to_class)) {
-			m_output << "\t\treturn (result == null) ? null : (" << pckg_signature << tname << ")Utils.wrapWithSubclass(new UdmPseudoObject(result, getDiagram()), getDiagram());" << endl;
-		} else {
-			m_output << "\t\treturn (result == null) ? null : new " << pckg_signature << tname << "(result, getDiagram());" << endl;
-		}
-		*/
-		m_output << "\t" << endl;
-		
-	  }
-	  else
-	  {
-		
-		m_output << "\tdef set" << to_asr_name << "(self," << " a): " << endl; //tname []<<
-		m_output << "\t\t\"\"\"" << endl;
-		m_output << "\t\tSets the other ends of the association with role name <code>" << to_asr_name << "</code>." << endl;
-		m_output << "\t\t at param a The other ends of the association" << endl;
-		m_output << "\t\t\"\"\"" << endl;
-		
-		//m_output << "\t\t#setAssociation(\"" << to_asr_name << "\", new UdmPseudoObjectContainer(a), UdmHelper." << helper_mode << ");" << endl;
-		m_output << "\t\tpass" << endl;
-		m_output << endl;
+            
+        }
+        
+    }
+}
 
-		
-		m_output << "\tdef " << to_asr_name << "(self):" << endl;
-		m_output << "\t\t\"\"\"" << endl;
-		m_output << "\t\tReturns the other ends of the association with role name <code>" << to_asr_name << "</code>." << endl;
-		m_output << "\t\t at return The other ends of the association" << endl;
-		m_output << "\t\t\"\"\" " << endl;
-		//m_ioutput << "\tpublic " << pckg_signature << tname << "[] get" << to_asr_name << "() throws UdmException;" << endl;
-		m_output << "\t\t" << "list = []" << endl;
-		m_output << "\t\t" << "for i in self.impl." << to_asr_name << ":" << endl;
-		m_output << "\t\t\t" << "list.append(" << tname << ".cast(i))" << endl;			 
-		m_output << "\t\t" << "return list" << endl;
-		m_output << "\t" << endl;
-		m_output << endl;
-	  }
-	} 
-  }
-  
-}
\ No newline at end of file

Modified: UDM/trunk/src/UdmBase/UmlExt.cpp
==============================================================================
--- UDM/trunk/src/UdmBase/UmlExt.cpp	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/src/UdmBase/UmlExt.cpp	Sat Mar  8 02:21:10 2014	(r4271)
@@ -599,6 +599,46 @@
 		return comp;
 	}
 
+    
+    UDM_DLL AssociationRole matchPeerToPeer(Class c, Class target_class, Class target_aclass, const char * rolename)
+    {
+        
+        set<AssociationRole> assocs = c.associationRoles();
+        AssociationRole found;
+        
+        for( set<AssociationRole>::iterator i = assocs.begin(); i != assocs.end(); i++)
+        {
+            AssociationRole the_other = theOther(*i);
+            Class oclass = the_other.target();
+            
+            Association pp = (*i).parent();
+            Class aclass = pp.assocClass();
+            std::string thisrolename = i->name();
+            
+            if (  (!target_aclass && (target_class == oclass)) || ( target_aclass && (target_aclass == aclass)) )
+            {
+                
+                if (rolename != NULL)
+                {
+                    if (thisrolename.compare(rolename) == 0)
+                    {
+                        if (found) return Uml::AssociationRole();
+                        found = theOther(*i);
+                    }
+                    
+                }
+                else
+                {
+                    if (found) return Uml::AssociationRole();
+                    found = theOther(*i);
+                }
+                
+            }
+        }
+        
+        return found;
+    }
+    
 	UDM_DLL bool IsAssocClass(const Class &cl) 
 	{
 		return (Association)cl.association();

Modified: UDM/trunk/src/UdmPython/UdmPython.cpp
==============================================================================
--- UDM/trunk/src/UdmPython/UdmPython.cpp	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/src/UdmPython/UdmPython.cpp	Sat Mar  8 02:21:10 2014	(r4271)
@@ -196,6 +196,50 @@
 }
 
 
+Udm::Object GetUmlAssocRoleByPeerAndRole(Udm::Object& my_type, Udm::Object& peer_type, str _arole)
+{
+    ::Uml::Class c  = ::Uml::Class::Cast(my_type);
+    if (!c) throw std::runtime_error (std::string("my_type is null, can not identify associationroles for a NULL class in GetUmlAssocRoleByPeerAndRole"));
+    
+    ::Uml::Class target_class = ::Uml::Class::Cast(peer_type);
+    if (!target_class) throw std::runtime_error (std::string("peer type is null, can not identify associationroles to a NULL class in GetUmlAssocRoleByPeerAndRole"));
+    
+    std::string arole = extract<std::string>(_arole);
+    
+    std::string err_string = std::string("GetUmlPeerAssocRoleByPeerAndRole(") + (std::string)c.name() + "," + (std::string)target_class.name() + std::string(",") + (arole.empty() ? std::string("NULL") : arole) + std::string(")");
+    
+    ::Uml::AssociationRole found = matchPeerToPeer(c, target_class, ::Uml::Class(), (arole.empty() ? NULL : arole.c_str()) );
+    
+    if (!found)
+        throw std::runtime_error (std::string ("No associations found: ") + err_string);
+
+    return (Udm::Object) (found);
+}
+
+Udm::Object GetUmlAssocRoleByAClass(Udm::Object& my_type, Udm::Object& aclass_type, str _arole)
+{
+    ::Uml::Class c  = ::Uml::Class::Cast(my_type);
+    if (!c) throw std::runtime_error (std::string("my_type is null, can not identify associationroles for a NULL class in GetUmlClassAssocRoleByAClass"));
+    
+    ::Uml::Class target_aclass = ::Uml::Class::Cast(aclass_type);
+    if (!target_aclass) throw std::runtime_error (std::string("association class is null, can not identify associationroles to a NULL class in GetUmlClassAssocRoleByAClass"));
+    std::string arole = extract<std::string>(_arole);
+    
+    std::string err_string = std::string("GetUmlClassAssocRoleByAClass(") + (std::string)c.name() + std::string(",") + (std::string)target_aclass.name() + std::string(",") + (arole.empty() ? std::string("NULL") : arole) + std::string(")") ;
+    
+    
+    ::Uml::AssociationRole found = matchPeerToPeer(c, ::Uml::Class(), target_aclass, (arole.empty() ? NULL : arole.c_str()));
+    
+    if (!found)
+        throw std::runtime_error (std::string ("No associations found: ") + err_string);
+    
+    return (Udm::Object) (found);
+
+    
+}
+
+
+
 template<typename colT>
 boost::python::list toList(colT collection) {
 	boost::python::list ret;
@@ -373,6 +417,25 @@
     
 }
 
+object Object_getAssociation(Udm::Object& self, Udm::Object& arole, object _mode)
+{
+    // arole must be non-null.
+    // Associations with names on both sides are navigable from both directions.
+    if (!self) throw std::runtime_error(std::string("Object is null in get_Association()"));
+    if (!arole) throw std::runtime_error(std::string("AssociationRole is null in get_Association()"));
+    
+    int mode;
+    if (_mode != object())
+        mode = extract<int>(_mode);
+    else
+        mode = Udm::TARGETFROMPEER;
+
+    if ( (mode != Udm::TARGETFROMPEER) && (mode != Udm::TARGETFROMCLASS) && (mode != Udm::CLASSFROMTARGET) )
+        throw std::runtime_error(std::string("Invalid mode in get_Association()"));
+        
+    return toList(self.getAssociation(::Uml::AssociationRole::Cast(arole), mode));
+}
+
 
 Udm::Object Object_type(Udm::Object& self) {
 	return Udm::Object(self.type());
@@ -772,6 +835,7 @@
 		.def("delete", &Udm::Object::DeleteObject)
 		.def("_children", Object_children)
         .def("getChildren", Object_getChildren)
+        .def("getAssociation", Object_getAssociation)
 		.def("_adjacent", Object_adjacent)
 		.def("get_attribute",&Object_attr_by_uml_attr_as_udm_object)
 		.def("set_attribute",&Object_set_attr_by_uml_attr_as_udm_object)
@@ -803,6 +867,10 @@
 	scope().attr("Object").attr("__nonzero__") = eval("lambda self: self.id != 0");
 
 	scope().attr("null") = Udm::null;
+    scope().attr("TARGETFROMPEER") = Udm::TARGETFROMPEER;
+    scope().attr("TARGETFROMCLASS") = Udm::TARGETFROMCLASS;
+    scope().attr("CLASSFROMTARGET") = Udm::CLASSFROMTARGET;
+    
 
 	class_<Uml::Diagram>("_UmlDiagram")
 		;
@@ -815,6 +883,8 @@
 	def("CopyObjectHierarchy", &CopyObjectHierarchy_);
     def("InitChildRole",&InitChildRole);
     def("InitParentRole", &InitParentRole);
+    def("GetUmlAssocRoleByPeerAndRole", &GetUmlAssocRoleByPeerAndRole);
+    def("GetUmlAssocRoleByAClass", &GetUmlAssocRoleByAClass);
 
 
 	class_<Udm::SmartDataNetwork>("SmartDataNetwork", no_init) //, init<const Udm::UdmDiagram &>())

Modified: UDM/trunk/tests/test_UdmPythonDS/test.py
==============================================================================
--- UDM/trunk/tests/test_UdmPythonDS/test.py	Fri Mar  7 10:30:35 2014	(r4270)
+++ UDM/trunk/tests/test_UdmPythonDS/test.py	Sat Mar  8 02:21:10 2014	(r4271)
@@ -103,6 +103,49 @@
 
 #print lamp1.parent == rf
 
+bulbs = lamp_1.Bulb_kind_children()
+for bulb in bulbs:
+    print "----------------------------"
+    print "Bulb :", type(bulb), bulb
+    cl = bulb.dst()
+    if len(cl):
+        print "Controllink", type(cl[0]), cl[0]
+        sw = cl[0].dst_end()
+        print "switch", type(sw), sw
+        cl1  = sw.src()
+        if len(cl1):
+        
+            print "Controllink1", type(cl1[0]), cl1[0]
+            print cl1[0] == cl[0]
+            bulb1 = cl1[0].src_end()
+            print "Bulb1", type(bulb1), bulb1
+            print bulb == bulb1
+
+
+
+print "Switch.meta_src: "  + LampDiagram.Switch.meta_src.name  #this should be src
+print "Bulb.meta_dst: "  + LampDiagram.Bulb.meta_dst.name      #this should be dst
+
+print "descendants of ElectricDevice are: "
+classes = LampDiagram.ElectricDevice.Meta.subTypes()
+for cl in classes:
+    print cl.name
+    print cl.baseTypes()[0] == LampDiagram.ElectricDevice.Meta
+
+
+
+controllinks = lamp_1.ControlLink_kind_children()
+for cl in controllinks:
+    print "Controllink :" + cl.name
+    bulb  = cl.src_end()
+    switch  = cl.dst_end()
+
+    print "this should be bulb!:"
+    print bulb
+
+    print "this should be switch!:"
+    print switch
+
 
 
 


More information about the Mobies-commit mailing list