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

endre at redhat3.isis.vanderbilt.edu endre at redhat3.isis.vanderbilt.edu
Wed Mar 5 22:36:26 CST 2014


Author: endre
Date: Wed Mar  5 22:36:25 2014
New Revision: 4262

Log:
Python Domain Specific API:
- added composition child and parent roles
- added getChildren() wrapper function to the wrapper python class (keeping ObjectImpl->getChildren() functionality)
- added children access functions like in C++ Api (one function for each role name and
- added inheritance to the Domain Specific API

Modified:
   UDM/trunk/include/UmlExt.h
   UDM/trunk/lib/UdmPython.py
   UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp
   UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.h
   UDM/trunk/src/Udm/Udm.cpp
   UDM/trunk/src/Udm/Udm.h
   UDM/trunk/src/Udm/UdmCpp.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	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/include/UmlExt.h	Wed Mar  5 22:36:25 2014	(r4262)
@@ -184,9 +184,10 @@
 	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);
+// 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);
 
-// returns true if derived = base
+    // returns true if derived = base
 	UDM_DLL bool IsDerivedFrom(const Class &derived, const Class &base);
 	UDM_DLL bool IsAssocClass(const Class &cl);
 	UDM_DLL bool IsAssocClass(const Association &ass);

Modified: UDM/trunk/lib/UdmPython.py
==============================================================================
--- UDM/trunk/lib/UdmPython.py	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/lib/UdmPython.py	Wed Mar  5 22:36:25 2014	(r4262)
@@ -30,17 +30,31 @@
 		import Uml
 		return Uml.Class.cast(self.impl.type)
 
-	def children(self,child_role=None, parent_role=None, child_type=None):
-		#child_type could be either Udm.Object or UdmPython (or descendants)
+	def children(self,child_role=None, child_type=None):
+		#child_type could be either Udm.Object or UdmPython (or descendants: it is expected to be Uml.Class)
+		#child_role could be either Udm.Object or UdmPython (or descendants: it is expected to be Uml.CompositionChildRole)
+		#if role is given, return only those children that have that role (ignore kind)
+		#else if kind is not null, return all children which are compatible with kind
+		#else if kind is null, return all children
+
+
 		ret = []
+		child_type_impl = None
+		child_role_impl = None
+		
 		if isinstance(child_type, UdmPython):
-			for child in self.impl.children(child_role, parent_role, child_type.impl):
-				ret.append(UdmPython(child))
-			return ret
+			child_type_impl = child_type.impl
+		else:
+			child_type_impl = child_type;
+
+		if isinstance(child_role, UdmPython):
+			child_role_impl = child_role.impl
 		else:
-			for child in self.impl.children(child_role, parent_role, child_type):
-				ret.append(UdmPython(child))
-			return ret
+			child_role_impl = child_role;
+
+		for child in self.impl.getChildren(child_role_impl, child_type_impl):
+			ret.append(UdmPython(child))
+		return ret
 
 	def __eq__(self, other):
 		return self.__dict__['impl'] == other.__dict__['impl']
@@ -62,7 +76,8 @@
 		line = indent(indent_tabs) + "--------------------------------------------------------------------" + "\n"
 		line += indent(indent_tabs) + "Object's type:"  + cl.name + "\n"
 		line += indent(indent_tabs) + self.impl.__repr__() + "\n"
-		attrs= cl.getAttributeChildren()
+		#attrs= cl.getAttributeChildren()
+		attrs= cl.attributes()
 		for attr in attrs:
 			attr_value = self.impl.get_attribute(attr.impl)
 			if attr.max == 1 or attr.max == 0:
@@ -262,7 +277,8 @@
 def GetUmlAttributeByName(cl, name):
 	import udm
 	import Uml
-	attrs = cl.getAttributeChildren()
+	#attrs = cl.getAttributeChildren()
+	attrs = cl.attributes()
 	for attr in attrs:
 		if attr.name == name:
 			return attr
@@ -271,8 +287,29 @@
 def GetUmlClassByName(dgr, name):
 	import udm
 	import Uml
-	classes = dgr.getClassChildren()
+	#classes = dgr.getClassChildren()
+	classes = dgr.Class_kind_children()
 	for cl in classes:
 		if cl.name == name:
 			return cl
 	return Uml.Class(udm.null)	
+
+def GetUmlChildRoleByTypesAndRolenames(child_type, parent_type, crole_name, prole_name):
+	import udm
+	import Uml
+	#child_type is expected to be Uml.Class
+	#parent_type is expected to be Uml.Class
+	#crole_name and prole_name are expected to be strings
+
+	return Uml.CompositionChildRole(udm.InitChildRole(child_type.impl, parent_type.impl, crole_name, prole_name))
+
+def GetUmlParentRoleByTypesAndRolenames(child_type, parent_type, crole_name, prole_name):
+	import udm
+	import Uml
+	#child_type is expected to be Uml.Class
+	#parent_type is expected to be Uml.Class
+	#crole_name and prole_name are expected to be strings
+
+	return Uml.CompositionParentRole(udm.InitParentRole(child_type.impl, parent_type.impl, crole_name, prole_name))
+	
+

Modified: UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp
==============================================================================
--- UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.cpp	Wed Mar  5 22:36:25 2014	(r4262)
@@ -1,7 +1,39 @@
+#include "../Udm.h"
 #include "PythonAPIGen.h"
 
 #include <iterator>
 
+
+PythonInheritanceSolver::PythonInheritanceSolver(const Uml::Diagram &diagram, bool sort_by_namespace) : ::UdmCPPGen::InheritanceSolver(diagram, sort_by_namespace) {};
+string PythonInheritanceSolver::getAncestorList(const ::Uml::Class &cl ) const
+{
+    string ret;
+	typedef set< ::Uml::Class, ::UdmCPPGen::name_less<Uml::Class> > SortedClasses;
+	::UdmCPPGen::name_less< ::Uml::Class> sort;
+	SortedClasses bases = cl.baseTypes_sorted< ::UdmCPPGen::name_less<Uml::Class> >(sort);
+	if( bases.size() == 0)
+        ret += "(UdmPython)";
+	else
+	{
+        ret += "(";
+		string sep = "";
+		SortedClasses::iterator h;
+		for(h = bases.begin(); h != bases.end(); h++)
+		{
+			if(*h != cl)
+			{
+				ret += sep;
+				ret += h->name();
+				sep = ", ";
+			}
+		}
+        ret += ")";
+	}
+    
+	return ret;
+
+}
+
 void GeneratePythonClass(const ::Uml::Class &cl, const string & pckg_hierarcy, const string& diagName);
 
 //! Constructor.
@@ -52,15 +84,13 @@
   m_output << "from UdmPython import *" << endl << endl;
 
 
-  /*GENERATE PYTHON CLASSES*/
-  set< ::Uml::Class> uml_classes = m_diagram.classes();
-  for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
-  {
-
-	  ::Uml::Class currCls = *uc_i;
-	  generateClass(currCls);  
-	  
-  }
+    /*GENERATE PYTHON CLASSES*/
+    set< ::Uml::Class> uml_classes = m_diagram.classes();
+    PythonInheritanceSolver is(m_diagram);
+    for ( vector < ::Uml::Class>::iterator gio_i = is.good_inheritence_order.begin(); gio_i != is.good_inheritence_order.end(); gio_i++)
+        generateClass(*gio_i,is );
+    
+   
 
   /*INITIALIZE THE META STATIC VARIABLES*/
   
@@ -72,34 +102,85 @@
         m_output << "\t" << uc_i->name() << ".Meta = GetUmlClassByName(diagram,\"" << uc_i->name()   << "\")"<< endl;
     }
 
-  m_output << endl;
-  m_output << "def init_attributes():" << endl;
+    m_output << endl;
+    m_output << "def init_attributes():" << endl;
     for( set< ::Uml::Class>::iterator uc_i = uml_classes.begin(); uc_i != uml_classes.end(); uc_i++ )
     {
         set< ::Uml::Attribute> attrs = uc_i->attributes();
         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 << endl;
+    m_output << "def init_childroles():" << 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::Class> childrenkinds;
+        set< ::Uml::CompositionParentRole> children = c.parentRoles();
+        
+        for( set< ::Uml::CompositionParentRole>::iterator i = children.begin(); i != children.end(); i++)
+        {
+            ::Uml::CompositionChildRole the_other = Uml::theOther(*i);
+            
+            ::Uml::Class thischildkind = (::Uml::Class)the_other.target();
+            //childrenkinds.insert(thischildkind);
+            
+            string rel_name = ::Uml::MakeRoleName(the_other);
+            
+            m_output << "\t" << cl_name << ".meta_" << rel_name << " = GetUmlChildRoleByTypesAndRolenames(" << thischildkind.name() << ".Meta," << cl_name << ".Meta, \"" << the_other.name() <<  "\", \"" << i->name() << "\")" << 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++ )
+    {
+        ::Uml::Class c = *uc_i;
+        string cl_name = c.name();
+        
+        set< ::Uml::Class> parentkinds;
+        set< ::Uml::CompositionChildRole> parents = c.childRoles();
+        
+        for( set< ::Uml::CompositionChildRole>::iterator i = parents.begin(); i != parents.end(); i++)
+        {
+            ::Uml::CompositionParentRole the_other = Uml::theOther(*i);
+            
+            ::Uml::Class thisparentkind = (::Uml::Class)the_other.target();
+            //parentkinds.insert(thischildkind);
+            
+            string rel_name = ::Uml::MakeRoleName(the_other);
+            
+            m_output << "\t" << cl_name << ".meta_" << rel_name << " = GetUmlParentRoleByTypesAndRolenames(" << cl_name << ".Meta," << thisparentkind.name() << ".Meta, \"" << i->name() <<  "\", \"" << the_other.name() << "\")" << endl;
+        }
+        
+    }
+    
 		
 
   m_output << endl << endl;
 
   /*INITIALIZE THE META STATIC VARIABLE*/
 
-  m_output << "def initialize(diagram):" << endl;
-  m_output << "\t" << "try:" << endl;
-  m_output << "\t\t" << "module_initialized" << endl;
-  m_output << "\t" << "except NameError:" << endl;
-  m_output << "\t\t" << "if sys.modules[__name__] != Uml:" << endl;
-  m_output << "\t\t\t" << "Uml.initialize(udm.uml_diagram())" << endl;
-  m_output << "\t\t" << "if sys.modules[__name__] == Uml:" << endl;
-  m_output << "\t\t\t" << "meta_map = udm.map_uml_names(diagram)" << endl;
-  m_output << "\t\t\t" << "#the only meta-object needed to bootstrap" << endl;
-  m_output << "\t\t\t" << "Class.Meta = meta_map.Class" << endl;
-  m_output << "\t\t" << "init_classes(Uml.Diagram(diagram))" << endl;
-  m_output << "\t\t" << "init_attributes()" << endl;
-  m_output << "\t\t" << "module_initialized = True" << endl;
-  m_output << endl;
+    m_output << "def initialize(diagram):" << endl;
+    m_output << "\t" << "try:" << endl;
+    m_output << "\t\t" << "module_initialized" << endl;
+    m_output << "\t" << "except NameError:" << endl;
+    m_output << "\t\t" << "if sys.modules[__name__] != Uml:" << endl;
+    m_output << "\t\t\t" << "Uml.initialize(udm.uml_diagram())" << endl;
+    m_output << "\t\t" << "if sys.modules[__name__] == Uml:" << endl;
+    m_output << "\t\t\t" << "meta_map = udm.map_uml_names(diagram)" << endl;
+    m_output << "\t\t\t" << "#the only meta-object needed to bootstrap" << endl;
+    m_output << "\t\t\t" << "Class.Meta = meta_map.Class" << endl;
+    m_output << "\t\t" << "init_classes(Uml.Diagram(diagram))" << endl;
+    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" << "module_initialized = True" << endl;
+    m_output << endl;
 	
 
   
@@ -119,9 +200,10 @@
 		throw udm_exception( "Error opening for write "+fname );
 }
 
-void PythonAPIGen::generateClass(::Uml::Class &cls)
+void PythonAPIGen::generateClass(::Uml::Class &cls, const PythonInheritanceSolver &is)
 {
-	m_output << "class " << cls.name() << "(UdmPython):" << endl;
+
+	m_output << "class " << cls.name() << is.getAncestorList(cls) <<  ":" << endl;
    	m_output << "\t\"\"\"Generated\"\"\"" << endl;
     m_output << "\t at property" << endl;
     m_output << "\tdef parent(self):" << endl;
@@ -137,13 +219,7 @@
 	m_output << "\t\treturn " << cls.name() << "(obj)" << endl;
 	m_output << "\t" << endl;
 
-	//type method
-	// we have this at UdmPython level
-	//m_output << "\tdef type(self):"<< endl;
-	//m_output << "\t\t\"\"\"returning the type of object (Uml.Class)\"\"\"" << endl;
-	//m_output << "\t\treturn " << "Uml.Class.cast(self.meta)" << endl;
-	//m_output << "\t" << endl;
-
+	
 	generateChildrenAccess(cls);
 	generateAssociations(cls);
 }
@@ -174,175 +250,77 @@
 
 void PythonAPIGen::generateChildrenAccess(::Uml::Class &cls)
 {
-  //childrens ---------------------------------------------------
-  set<Uml::Class> allContainedClasses;
-
-  // set of contained classes
-  set< ::Uml::Class> conts = Uml::ContainedClasses( cls );
-  for ( set< ::Uml::Class>::iterator c_i = conts.begin(); c_i != conts.end(); c_i++ )
-  {
-	// the descendants of the contained class
-	set < ::Uml::Class> conts_der = Uml::DescendantClasses( *c_i );
-	std::copy(conts_der.begin(), conts_der.end(), std::inserter(allContainedClasses, allContainedClasses.begin()));
-  }
-
-  {
-	for ( set< ::Uml::Class>::iterator c_d_i = allContainedClasses.begin(); c_d_i != allContainedClasses.end(); c_d_i++ )
+    
+    string cl_name = cls.name();
+    
+	set< ::Uml::Class> childrenkinds;
+	set< ::Uml::CompositionParentRole> children = cls.parentRoles();
+    
+    for( set< ::Uml::CompositionParentRole>::iterator i = children.begin(); i != children.end(); i++)
 	{
-	  if ( c_d_i->isAbstract() )
-		continue; 
-
-	  ::Uml::Composition comp = Uml::matchChildToParent( *c_d_i, cls );
-	  string c_i_name = (*c_d_i).name();
-	  string pkg_name = "";
-
-	  // without child role
-	  if ( comp )
-	  {
-		::Uml::CompositionChildRole ccr = comp.childRole();
-		string ccr_name = ccr.name();
-
-		if ( (ccr.max() == -1) || (ccr.max() > 1) )
-		{
-		  m_output << "\tdef " << "get" << c_i_name << "Children(self):" << endl;
-		  m_output << "\t\t\"\"\"" << endl;
-		  m_output << "\t\tReturns all the children of type <code>" << c_i_name << "<code> of this container. " << endl;
-		  m_output << "\t\t at return  The children in a lisst" << endl;
-		  m_output << "\t\t\"\"\"" << endl;
-
-		  m_output << "\t\tchilds = self.children(child_type=" << c_i_name << ".Meta)" << endl;
-		  m_output << "\t\tlist = []" << endl;
-		  m_output << "\t\t" << "for i in childs:" << endl;
-		  m_output << "\t\t\t" << "list.append(" << c_i_name << "(i))" << endl;
-		  m_output << "\t\treturn list" << endl;
-		  m_output << endl;
-		  
-		}
-		else
-		{
-		  m_output << "\tdef " << "get" << c_i_name << "Child(self): " << endl;
-		  m_output << "\t\t\"\"\"" << endl;
-		  m_output << "\t\tReturn the child of type <code>" << c_i_name << "<code> of this container. " << endl;
-		  m_output << "\t\t at return  The child" << endl;
-		  m_output << "\t\t\"\"\"" << endl;
-		  m_output << "\t\tchilds = self.impl.children(child_type=" << c_i_name << ".meta)" << endl;
-		  m_output << "\t\t" << "if len(childs) > 0:" << endl;
-		  m_output << "\t\t\t" << "return " << c_i_name << "(childs[0])" << endl;
-		  m_output << "\t\t" << "else: " << endl;
-		  m_output << "\t\t\t" << "return None" << endl;
-		  m_output << "\t" << endl;
-		
-		  /*
-		  if ( strcmp(ccr_name.c_str(), "") == 0 )
-		  {
-			m_output << "\t\t'''UdmPseudoObjectContainer container = getChildren(null, " ;
-			m_output << pkg_name << c_i_name << ".META_TYPE, " << pkg_name << c_i_name << ".META_TYPE_NS); " << endl;
-		  }
-		  else
-		  {
-			m_output << "\t\tUdmPseudoObjectContainer container = getChildren(\"" << ccr_name << "\",";
-			m_output << pkg_name << c_i_name << ".META_TYPE, " << pkg_name << c_i_name << ".META_TYPE_NS); " << endl;
-		  }
-		  */
-		  
-		  //m_output << "\t\tif (container.getLength() > 0)" << endl << endl;
-		  //m_output << "\t\t\treturn (" << pkg_name << c_i_name << ")" << pkg_name << "Utils.wrapWithSubclass(container.getAt(0), metaDiagram);" << endl;
-		  //m_output << "\t\treturn null;'''" << endl << endl;
-		  //m_output << "\t" << endl << endl;
-		}
-	  }
-	  // with child role
-	  else
-	  {
-		//generate a common getter function for these types of children
-		/*
-		m_output << "\t'''" << endl;
-		m_output << "\t * Returns all the children of type <code>" << c_i_name << "<code> of this container. " << endl;
-		m_output << "\t * @return  The children in a list" << endl;
-		m_output << "\t ''' " << endl;
+        ::Uml::CompositionChildRole the_other = Uml::theOther(*i);
+        
+		::Uml::Class thischildkind = (::Uml::Class)the_other.target();
+		childrenkinds.insert(thischildkind);
+        
+		string rel_name = ::Uml::MakeRoleName(the_other);
 		
-		m_output << "\tdef " << "get" << c_i_name << "Children(self):" << endl;
-		m_output << "\t" << endl;
-		m_output << "\t\t'''UdmPseudoObjectContainer container = getChildren(null," ;
-		m_output << pkg_name << c_i_name << ".META_TYPE, " << pkg_name << c_i_name << ".META_TYPE_NS);" << endl;
-		m_output << "\t\t" << pkg_name << c_i_name << "[] array = new " << pkg_name << c_i_name << "[container.getLength()];" << endl;
-		m_output << "\t\tfor (int i = 0; i < container.getLength(); i++) " << endl;
-		m_output << "\t\t{" << endl;
-		m_output << "\t\t\tarray[i] = (" << pkg_name << c_i_name << ")" << pkg_name << "Utils.wrapWithSubclass(container.getAt(i), metaDiagram);" << endl;
-		m_output << "\t\t}" << endl;
-		m_output << "\t\treturn array;'''" << endl;
-		m_output << "\t" << endl;
-		*/
-		//end of common getter function generation
-
-		set < ::Uml::CompositionChildRole> ccrs = ::Uml::CompositionPeerChildRoles( cls );
-		for ( set< ::Uml::CompositionChildRole>::iterator ccrs_i = ccrs.begin(); ccrs_i != ccrs.end(); ccrs_i++ )
+        if (the_other.isNavigable())
+        {
+            m_output << "\tdef " << rel_name << "(self):" <<endl;
+            
+            if(the_other.max() == 1)
+            {
+                m_output << "\t\t# return the single child contained via rolename: " << the_other.name() << ", rel_name: " << rel_name << endl;
+                m_output << "\t\tchilds = self.children(child_role=" << cl_name << ".meta_" << rel_name <<")" << endl;
+                m_output << "\t\t" << "if len(childs) > 0:" << endl;
+                m_output << "\t\t\t" << "return globals()[childs[0]._type().name](childs[0])" << endl;
+                m_output << "\t\t" << "else: " << endl;
+                m_output << "\t\t\t" << "return None" << endl;
+                
+            }
+            else
+            {
+                m_output << "\t\t# return the children contained via rolename: " << the_other.name() << ", rel_name: " << rel_name << endl;
+                m_output << "\t\tchilds = self.children(child_role=" << cl_name << ".meta_" << rel_name <<")" << endl;
+                m_output << "\t\tlist = []" << endl;
+                m_output << "\t\t" << "for i in childs:" << endl;
+                m_output << "\t\t\t" << "list.append(globals()[i._type().name](i))"  << endl;
+                m_output << "\t\treturn list" << endl;
+                
+            }
+        }
+        else m_output << "\t# access method for non-navigable association " << rel_name << " omitted";
+    }
+    
+    
+    ::Uml::Diagram dgr = ::Uml::GetDiagram(cls);
+	::Uml::DiagramClasses allclasses = ::Uml::DiagramClasses(dgr);
+    
+	for (::Uml::DiagramClasses::iterator j = allclasses.begin(); j != allclasses.end(); j++)
+	{
+		for (set< ::Uml::Class>::iterator k = childrenkinds.begin(); k != childrenkinds.end(); k++)
 		{
-		  ::Uml::Class parent = Uml::theOther(*ccrs_i).target();
-		  ::Uml::Class child = ccrs_i->target();
-		  string child_name = string(child.name());
-		  
-		  ::Uml::Composition comp = Uml::matchChildToParent( child, parent );
-
-		  if ( !comp )
-		  {
-			//will reach here only if more than one composition is possible
-
-			//string child role name
-			string ccr_name = ccrs_i->name();
-			m_output << "\t'''" << endl;
-			m_output << "\t *  Composition role name <code>" << ccr_name << "</code>." << endl;
-			m_output << "\t '''" << endl;
-			
-			m_output << endl << endl;
-
-			//getRoleName
-			if ( (ccrs_i->max() == -1) || (ccrs_i->max() > 1) )
-			{
-			  m_output << "\t'''" << endl;
-			  m_output << "\t * Returns the children <code>" << child_name << "<code> of this container. " << endl;
-			  m_output << "\t * which have role <code>" << ccr_name << "<code>." << endl;
-			  m_output << "\t * @return  The children in an array" << endl;
-			  m_output << "\t ''' " << endl;
-			  
-			  m_output << "\tdef " << "get" << ccr_name << "Children(self):" << endl;
-			  
-			  m_output << "\t" << endl;
-			  m_output << "\t\t'''UdmPseudoObjectContainer container = getChildren(";
-			  
-			  m_output << "\t\t" << pkg_name << child_name << "[] array = new " << pkg_name << child_name << "[container.getLength()];" << endl;
-			  m_output << "\t\tfor (int i = 0; i < container.getLength(); i++) " << endl;
-			  m_output << "\t\t{" << endl;
-			  m_output << "\t\t\tarray[i] = (" << pkg_name << child_name << ")" << pkg_name << "Utils.wrapWithSubclass(container.getAt(i), metaDiagram);" << endl;
-			  m_output << "\t\t}" << endl;
-			  m_output << "\t\treturn array;'''" << endl;
-			  m_output << "\t" << endl;
-			}
-			else
+			if (Uml::IsDerivedFrom(*j, *k) || Uml::IsDerivedFrom(*k, *j))
 			{
-			  /*
-			  m_output << "\t'''" << endl;
-			  m_output << "\t * Returns the child <code>" << child_name << "<code> of this container. " << endl;
-			  m_output << "\t * which has role <code>" << ccr_name << "<code>." << endl;
-			  m_output << "\t * @return  The children in a list" << endl;
-			  m_output << "\t ''' " << endl;
-			  
-			  m_output << "\tdef " << " get" << ccr_name << "Child(self):" << endl;
-			  m_output << "\t" << endl;
-			  m_output << "\t\t'''UdmPseudoObjectContainer container = getChildren(" ;
-			  //m_output << Utils::getCCRString(*ccrs_i) << "," << pkg_name << child_name << ".META_TYPE, " << pkg_name << child_name << ".META_TYPE_NS);" << endl;
-			  m_output << "\t\tif (container.getLength() > 0)" << endl << endl;
-			  m_output << "\t\t\t return (" << pkg_name << child_name << ")" << pkg_name << "Utils.wrapWithSubclass(container.getAt(0), metaDiagram);" << endl;
-			  m_output << "\t\treturn null;'''" << endl << endl;
-			  m_output << "\t" << endl;
-			  */
+				string kind_children_name = j->name();
+				
+                
+                m_output << "\tdef " << kind_children_name << "_kind_children(self):" << endl;
+                m_output << "\t\t# return the children of type: "  << kind_children_name << endl;
+                m_output << "\t\tchilds = self.children(child_type=" << kind_children_name << ".Meta)" << endl;
+                m_output << "\t\tlist = []" << endl;
+                m_output << "\t\t" << "for i in childs:" << endl;
+                m_output << "\t\t\t" << "list.append(globals()[i._type().name](i))"  << endl;
+                m_output << "\t\treturn list" << endl;
+
+
+				break;
 			}
-		  } 
-		} 
-	  }
+		}
 	}
-  }
-  //childrens end ----------------------------------------------------------------
+    
+     //childrens end ----------------------------------------------------------------
 }
 
 void PythonAPIGen::generateAssociations(::Uml::Class &cls)
@@ -498,4 +476,4 @@
 	} 
   }
   
-}
+}
\ No newline at end of file

Modified: UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.h
==============================================================================
--- UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.h	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/Udm/PythonAPIGen/PythonAPIGen.h	Wed Mar  5 22:36:25 2014	(r4262)
@@ -7,6 +7,15 @@
 
 using namespace std;
 
+class PythonAPIGen;
+
+class PythonInheritanceSolver : public ::UdmCPPGen::InheritanceSolver
+{
+    friend class PythonAPIGen;
+public:
+    PythonInheritanceSolver(const ::Uml::Diagram &diagram, bool sort_by_namespace = false);
+    virtual string getAncestorList(const ::Uml::Class &cl) const;
+};
 class PythonAPIGen
 {
   public:
@@ -23,7 +32,7 @@
 
   private:  
     void open();
-	void generateClass(::Uml::Class &cls);
+	void generateClass(::Uml::Class &cls, const PythonInheritanceSolver &is);
 	void generateAttributes(::Uml::Class &cls);
 	void generateChildrenAccess(::Uml::Class &cls);
 	void generateAssociations(::Uml::Class &cls);

Modified: UDM/trunk/src/Udm/Udm.cpp
==============================================================================
--- UDM/trunk/src/Udm/Udm.cpp	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/Udm/Udm.cpp	Wed Mar  5 22:36:25 2014	(r4262)
@@ -17,7 +17,7 @@
 
 #include <UdmXmi.h>
 #include <fstream>
-
+#include "Udm.h"
 #include "./JavaAPIGen/JavaAPIGen.h"
 #include "./PythonAPIGen/PythonAPIGen.h"
 
@@ -30,7 +30,7 @@
 #include <minizip/unzip.h>
 #endif
 
-#include "Udm.h"
+
 
 static const char* udm_usage = 
 "Usage: udm <diagramfilename> [<genfilesnamebase>] [-d <Uml.XSD searchpath>] \

Modified: UDM/trunk/src/Udm/Udm.h
==============================================================================
--- UDM/trunk/src/Udm/Udm.h	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/Udm/Udm.h	Wed Mar  5 22:36:25 2014	(r4262)
@@ -20,6 +20,7 @@
 #include <UdmDom.h>
 #include <UmlExt.h>
 
+
 using namespace std;
 
 struct UdmOpts {
@@ -97,7 +98,15 @@
 void GenerateDSD(const ::Uml::Diagram &dgr, const string &fname, const UdmOpts &opts, bool qualified_attrs_ns);
 
 
-namespace UdmCPPGen {
+namespace UdmCPPGen
+{
+    
+    template<class T>
+    struct name_less : binary_function <T, T, bool> {
+        bool operator() (const T& x, const T& y) const {
+            return static_cast<const std::string>(x.name()) < static_cast<const std::string>(y.name());
+        }
+    };
 
 void OutFmts(ostream &out, const string &idt, const vector<boost::format> &v, bool semicolon = true);
 void OutVecFmts(ostream &out, const string &idt, const vector< vector<boost::format> > &v, const string &label = "");
@@ -112,8 +121,7 @@
 	cltoclsmap explicitinits;
 	cltoboolmap objectneeded_map;
 	set< ::Uml::Class> virtualbaseclasses;
-	vector< ::Uml::Class> good_inheritence_order;
-
+	
 	struct sortByActiveNamespace : public binary_function< ::Uml::Class, ::Uml::Class, bool>
 	{
 	private:
@@ -123,11 +131,14 @@
 		bool operator()(const ::Uml::Class &a, const ::Uml::Class &b) const;
 	};
 
-	friend class DiagramGen;
+    protected:
+    vector< ::Uml::Class> good_inheritence_order;
 
+	friend class DiagramGen;
+    
 public:
 	InheritanceSolver(const ::Uml::Diagram &diagram, bool sort_by_namespace = false);
-	string getAncestorList(const ::Uml::Class &cl) const;
+	virtual string getAncestorList(const ::Uml::Class &cl) const;
 	string getInitializers(const ::Uml::Class &cl, const string &argument) const;
 };
 

Modified: UDM/trunk/src/Udm/UdmCpp.cpp
==============================================================================
--- UDM/trunk/src/Udm/UdmCpp.cpp	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/Udm/UdmCpp.cpp	Wed Mar  5 22:36:25 2014	(r4262)
@@ -22,12 +22,7 @@
 
 namespace UdmCPPGen {
 
-template<class T>
-struct name_less : binary_function <T, T, bool> {
-	bool operator() (const T& x, const T& y) const {
-		return static_cast<const std::string>(x.name()) < static_cast<const std::string>(y.name());
-	}
-};
+
 
 
 

Modified: UDM/trunk/src/UdmBase/UmlExt.cpp
==============================================================================
--- UDM/trunk/src/UdmBase/UmlExt.cpp	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/UdmBase/UmlExt.cpp	Wed Mar  5 22:36:25 2014	(r4262)
@@ -565,21 +565,31 @@
 		return attributes;
 	}
 
-	UDM_DLL Composition matchChildToParent(Class c, Class p) 
+	UDM_DLL Composition matchChildToParent(Class c, Class p, const char * crole, const char * prole)
 	{
 		Composition comp;
 		set<Class> pancs = AncestorClasses(p);
 		set<Class> cancs = AncestorClasses(c);
-		for(set<Class>::iterator j = cancs.begin(); j != cancs.end(); j++) {
+		for(set<Class>::iterator j = cancs.begin(); j != cancs.end(); j++)
+        {
 			set<CompositionChildRole> cr = (*j).childRoles();
-			for(set<CompositionChildRole>::iterator i = cr.begin(); i != cr.end(); i++) {
-				if(pancs.find(theOther(*i).target()) != pancs.end()) {
-					if(comp) {
-						return NULL;
-					}
-					comp = (*i).parent();
-				}
-			}
+            for(set<CompositionChildRole>::iterator i = cr.begin(); i != cr.end(); i++)
+            {
+                if (crole == NULL  || i->name() == string(crole))
+                {
+                    if (prole == NULL || theOther((*i)).name() == string(prole))
+                    {
+                        if(pancs.find(theOther(*i).target()) != pancs.end())
+                        {
+                            if(comp)
+                            {
+                                return NULL;
+                            }
+                            comp = (*i).parent();
+                        }
+                    }
+                }
+            }
 		}
 		return comp;
 	}

Modified: UDM/trunk/src/UdmPython/UdmPython.cpp
==============================================================================
--- UDM/trunk/src/UdmPython/UdmPython.cpp	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/src/UdmPython/UdmPython.cpp	Wed Mar  5 22:36:25 2014	(r4262)
@@ -150,6 +150,35 @@
 	return (Udm::Object) Uml::Class::meta.parent();
 }
 
+Udm::Object InitChildRole(Udm::Object& c, Udm::Object &p, str _crole, str _prole)
+{
+    
+    std::string crole = extract<std::string>(_crole);
+    std::string prole = extract<std::string>(_prole);
+    
+    Uml::Composition comp = matchChildToParent(Uml::Class::Cast(c), Uml::Class::Cast(p), crole.empty() ? NULL : crole.c_str(), prole.empty() ? NULL : prole.c_str());
+    
+    if (!comp)
+        throw std::runtime_error(std::string("Insufficient information to initialize Uml::CompositionChildRole in InitChildRole"));
+    
+    return (Udm::Object) (comp.childRole()) ;
+}
+
+Udm::Object InitParentRole(Udm::Object& c, Udm::Object &p, str _crole, str _prole)
+{
+    
+    std::string crole = extract<std::string>(_crole);
+    std::string prole = extract<std::string>(_prole);
+    
+    Uml::Composition comp = matchChildToParent(Uml::Class::Cast(c), Uml::Class::Cast(p), crole.empty() ? NULL : crole.c_str(), prole.empty() ? NULL : prole.c_str());
+    
+    if (!comp)
+        throw std::runtime_error(std::string("Insufficient information to initialize Uml::CompositionParentRole in InitParentRole"));
+    
+    return (Udm::Object) (comp.parentRole());
+}
+
+
 template<typename colT>
 boost::python::list toList(colT collection) {
 	boost::python::list ret;
@@ -264,12 +293,17 @@
 
 }
 
-object Object_children(Udm::Object& self, object child_role, object parent_role, object _child_type) {
-	bool roles_none = true;
+object Object_children(Udm::Object& self, object child_role, object parent_role, object _child_type)
+{
+    //To be removed and use only getChildren below.
+	
+    bool roles_none = true;
 	Uml::Class child_type;
-	if (_child_type != object()) {
+	if (_child_type != object())
+    {
 		child_type = Uml::Class::Cast(extract<Udm::Object&>(_child_type));
 	}
+    
 	Udm::Object::CompositionInfo comp_info;
 	if (child_role != object()) {
 		comp_info.strChildRoleName = extract<const char*>(child_role);
@@ -279,16 +313,50 @@
 		comp_info.strParentRoleName = extract<const char*>(parent_role);
 		roles_none = false;
 	}
-	if (!roles_none) {
+    
+	if (!roles_none)
+    {
 		// FIXME: might need to be a singleton if child_role is specified
 		return toList(self.GetChildObjects(comp_info, child_type));
-	} else if (child_type) {
+	}
+    else if (child_type)
+    {
 		return toList(self.GetChildObjects(child_type));
-	} else {
+	}
+    else
+    {
 		return toList(self.GetChildObjects());
 	}
 }
 
+object Object_getChildren(Udm::Object& self, object _ccrole, object _kind)
+{
+    //this function works in exactly the same way as ObjectImpl::getChildren()
+    // if role is given, return only those children that have that role (ignore kind)
+    // else if kind is not null, return all children which are compatible with kind
+    // else if kind is null, return all children
+
+    if (!self) throw std::runtime_error(std::string("Object is null in getChildren()"));
+    
+    Uml::CompositionChildRole ccrole;
+    if (_ccrole != object())
+        ccrole = Uml::CompositionChildRole::Cast(extract<Udm::Object&>(_ccrole));
+    
+    Uml::Class kind;
+    if (_kind != object())
+        kind = Uml::Class::Cast(extract<Udm::Object&>(_kind));
+    
+    vector< ::Udm::ObjectImpl*> children = self.__impl()->getChildren(ccrole, kind);
+
+    set< ::Udm::Object> ret;
+    for (vector< ::Udm::ObjectImpl*>::iterator child = children.begin(); child!=children.end(); child++)
+        ret.insert(*child);
+    
+    return toList(ret);
+    
+}
+
+
 Udm::Object Object_type(Udm::Object& self) {
 	return Udm::Object(self.type());
 }
@@ -686,6 +754,7 @@
 		.staticmethod("__cast")
 		.def("delete", &Udm::Object::DeleteObject)
 		.def("_children", Object_children)
+        .def("getChildren", Object_getChildren)
 		.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)
@@ -727,6 +796,8 @@
 	def("uml_diagram", Uml_Diagram);
 
 	def("CopyObjectHierarchy", &CopyObjectHierarchy_);
+    def("InitChildRole",&InitChildRole);
+    def("InitParentRole", &InitParentRole);
 
 
 	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	Tue Mar  4 15:36:20 2014	(r4261)
+++ UDM/trunk/tests/test_UdmPythonDS/test.py	Wed Mar  5 22:36:25 2014	(r4262)
@@ -60,13 +60,14 @@
 walk_hierarchy_udmp(rf)
 
 
-l_children = rf.getLampChildren()
+l_children = rf.Lamp_kind_children()
 
 if l_children:
     print "I have found the following lamps: "
     for lamp in l_children:
         print lamp.ModelName
         print lamp.name
+        print type(lamp)
 
 
 


More information about the Mobies-commit mailing list