[Mobies-commit] [commit] r3623 - UDM/trunk/src/UdmPython

ksmyth at redhat1.isis.vanderbilt.edu ksmyth at redhat1.isis.vanderbilt.edu
Fri Jan 28 16:05:28 CST 2011


Author: ksmyth
Date: Fri Jan 28 16:05:28 2011
New Revision: 3623

Log:
Fix .is_instance. Add .set_adjacent thus .ref= etc. Add udm.null. Add .__repr__. Add SmartDataNetwork.save_as(). Fix udmd.pyd.

Modified:
   UDM/trunk/src/UdmPython/UdmPython.cpp

Modified: UDM/trunk/src/UdmPython/UdmPython.cpp
==============================================================================
--- UDM/trunk/src/UdmPython/UdmPython.cpp	Fri Jan 28 16:01:29 2011	(r3622)
+++ UDM/trunk/src/UdmPython/UdmPython.cpp	Fri Jan 28 16:05:28 2011	(r3623)
@@ -98,7 +98,7 @@
 	throw std::runtime_error(std::string("Unsupported attribute type '") + static_cast<string>(attr.type()) + "' for class '" + static_cast<string>(self.type().name()) + "'");
 }
 
-object Object_setattr(Udm::Object& self, str _name, object value) {
+object Object_set_attr(Udm::Object& self, str _name, object value) {
 	std::string name = extract<std::string>(_name);
 
 	Uml::Attribute attr = getAttribute(self, name);
@@ -153,6 +153,108 @@
 	return Udm::Object(self.type());
 }
 
+void Object_set_adjacent_helper(Udm::Object& self, object _targets, object srcrolename, object dstrolename, object _associationClass, bool& /*out*/ foundApplicableAssociation) {
+	// based on UdmTomi.cpp: Object::GetAdjacentObjects
+	foundApplicableAssociation = false;
+	boost::python::list ret;
+
+	Uml::Class associationClass;
+	if (_associationClass != object()) {
+		associationClass = Uml::Class::Cast(extract<Udm::Object&>(_associationClass));
+	}
+
+	::Uml::Class srcClass = self.type();
+	set<::Uml::Class> ancestorClasses = ::Uml::AncestorClasses(srcClass);
+	set<::Uml::Class>::iterator ancestorClassesIt = ancestorClasses.begin();
+
+	for(; ancestorClassesIt != ancestorClasses.end(); ancestorClassesIt++) {
+		// Getting the association roles and iterating through them
+		set<::Uml::AssociationRole> assocRoles = ancestorClassesIt->associationRoles();
+		set<::Uml::AssociationRole>::iterator assocRolesIt = assocRoles.begin();
+		for(; assocRolesIt != assocRoles.end(); assocRolesIt++) {
+			::Uml::AssociationRole oRole = ::Uml::theOther(*assocRolesIt);
+			// Checking role names
+			if (srcrolename != object()) {
+				if (static_cast<std::string>(assocRolesIt->name()) != 
+					static_cast<const char*>(extract<const char*>(srcrolename))) {
+					continue;
+				}
+			}
+			if (dstrolename != object()) {
+				if (static_cast<std::string>(oRole.name()) != 
+					static_cast<const char*>(extract<const char*>(dstrolename))) {
+					continue;
+				}
+			}
+
+			// Check if there is an association class for this role
+			::Uml::Association assoc = assocRolesIt->parent();
+			::Uml::Class assoc_cls = assoc.assocClass();
+			if (associationClass && !assoc_cls) {
+				continue;
+			}
+			foundApplicableAssociation = true;
+
+			using namespace Udm;
+			std::vector<Udm::ObjectImpl*> targets_impl;
+			extract<Udm::Object&> singleton(_targets);
+			if (singleton.check()) {
+				Udm::Object& o = static_cast<Udm::Object&>(singleton);
+				if (o) {
+					targets_impl.push_back(o.__impl());
+				} else {
+					// i.e. set_adjacent(Udm::null)
+				}
+			} else {
+				// FIXME: should work with _targets.__iter__() instead
+				int len_targets = boost::python::len(_targets);
+				targets_impl.reserve(len_targets);
+				for (int i = 0; i < len_targets; i++) {
+					Udm::Object& o = extract<Udm::Object&>(_targets[i]);
+					targets_impl.push_back(o.__impl());
+					if (o.__impl()->__getdn()->uniqueId() != self.__impl()->__getdn()->uniqueId()) {
+						throw std::exception("Cannot set_adjacent with a target from a different DataNetwork");
+					}
+				}
+			}
+			self.__impl()->setAssociation(oRole, targets_impl, (!assoc_cls ? Udm::TARGETFROMPEER : Udm::TARGETFROMCLASS));
+			return;
+		}
+	}
+}
+
+void Object_set_adjacent(Udm::Object& self, object _targets, object srcrolename, object dstrolename, object _associationClass) {
+	bool foundApplicableAssociation;
+	Object_set_adjacent_helper(self, _targets, srcrolename, dstrolename, _associationClass, foundApplicableAssociation);
+	if (!foundApplicableAssociation) {
+		Uml::Class associationClass;
+		if (_associationClass != object()) {
+			associationClass = Uml::Class::Cast(extract<Udm::Object&>(_associationClass));
+		}
+		if (!foundApplicableAssociation && (srcrolename != object() && dstrolename != object() && !associationClass)) {
+			std::string errorMessage = "Object of type '";
+			errorMessage += static_cast<string>(self.type().name());
+			errorMessage += "' has no association defined";
+			if (srcrolename != object()) {
+				errorMessage += " with src_role '";
+				errorMessage += static_cast<std::string>(extract<std::string>(srcrolename));
+				errorMessage += "'";
+			}
+			if (dstrolename != object()) {
+				errorMessage += " with dst_role '";
+				errorMessage += static_cast<std::string>(extract<std::string>(dstrolename));
+				errorMessage += "'";
+			}
+			if (associationClass) {
+				errorMessage += " with assocation_class '";
+				errorMessage += static_cast<string>(associationClass.name());
+				errorMessage += "'";
+			}
+			throw std::runtime_error(errorMessage);
+		}
+	}
+}
+
 object Object_adjacent_helper(Udm::Object& self, object srcrolename, object dstrolename, object _associationClass, bool& /*out*/ foundApplicableAssociation) {
 	// based on UdmTomi.cpp: Object::GetAdjacentObjects
 	foundApplicableAssociation = false;
@@ -211,6 +313,10 @@
 
 					ret.append(object(dstObject));
 				}
+				if (dstrolename != object() && oRole.max() == 1) {
+					// FIXME: is this right?
+					return object(Udm::null);
+				}
 				continue;
 			}
 
@@ -239,6 +345,11 @@
 
 					ret.append(object(dstObject));
 				}
+				if (dstrolename != object() && oRole.max() == 1) {
+					// FIXME: is this right?
+					return object(Udm::null);
+				}
+
 			}
 		}
 	}
@@ -277,7 +388,18 @@
 	return ret;
 }
 
-object Object_getattr(object& self, str _name) {
+object Object___setattr__(object& self, str _name, object value) {
+	bool foundApplicableAssociation;
+	Object_set_adjacent_helper(extract<Udm::Object&>(self), value, object(), _name, object(), foundApplicableAssociation);
+	if (foundApplicableAssociation) {
+		return object();
+	}
+
+	object(self).attr("set_attr")(_name, value);
+	return object();
+}
+
+object Object___getattr__(object& self, str _name) {
 	str _role_children = "_role_children";
 	if (_name.endswith(_role_children)) {
 		return object(self).attr("children")(static_cast<string>(extract<string>(_name[slice(0,-14)])));
@@ -323,6 +445,7 @@
 			const ::Uml::CompositionChildRole& role,
 			const Udm::ObjectImpl* archetype = &Udm::_null,
 			const bool subtype = false) {
+				// FIXME: does this leak?
 				return __Create(meta, parent, role, archetype, subtype);
 		}
 	};
@@ -341,7 +464,11 @@
 }
 }
 
+#ifdef _DEBUG
+BOOST_PYTHON_MODULE(udmd)
+#else
 BOOST_PYTHON_MODULE(udm)
+#endif
 {
 	class_<Udm::Object>("Object")
 		.add_property("type", Object_type)
@@ -352,14 +479,17 @@
 		.def("_children", Object_children)
 		.def("_adjacent", Object_adjacent)
 		.def("attr", &Object_attr)
-		.def("__getattr__", &Object_getattr)
-		.def("__setattr__", &Object_setattr)
+		.def("set_attr", &Object_set_attr)
+		.def("__getattr__", &Object___getattr__)
+		.def("__setattr__", &Object___setattr__)
+		// FIXME: these should use object's DataNetwork id too
 		.def(self == self)
 		.def(self != self)
 		.def("__hash__", &Udm::Object::uniqueId)
+		.def("_set_adjacent", &Object_set_adjacent)
 
 		.add_property("has_real_archetype", &Udm::Object::hasRealArchetype)
-		.add_property("is_instance", &Udm::Object::isSubtype)
+		.add_property("is_instance", &Udm::Object::isInstance)
 		.add_property("is_subtype", &Udm::Object::isSubtype)
 		.add_property("archetype", &Udm::Object::archetype)
 		.add_property("derived", &Object_derived)
@@ -371,6 +501,10 @@
 		;
 	scope().attr("Object").attr("adjacent") = eval("lambda self, src_role=None, dst_role=None, association_class=None: self._adjacent(src_role, dst_role, association_class)");
 	scope().attr("Object").attr("children") = eval("lambda self, child_role=None, parent_role=None, child_type=None: self._children(child_role, parent_role, child_type)");
+	scope().attr("Object").attr("set_adjacent") = eval("lambda self, targets, src_role=None, dst_role=None, association_class=None: self._set_adjacent(targets, src_role, dst_role, association_class)");
+	scope().attr("Object").attr("__repr__") = eval("lambda self: \"udm.null\" if self.id==0 else (\"<udm.Object id\" + str(self.id) + \">\")");
+
+	scope().attr("null") = Udm::null;
 
 	class_<Uml::Diagram>("_UmlDiagram")
 		;
@@ -387,6 +521,7 @@
 		.def("create", SDN_CreateNew)
 		.def("close_with_update", &Udm::SmartDataNetwork::CloseWithUpdate)
 		.def("close_no_update", &Udm::SmartDataNetwork::CloseNoUpdate)
+		.def("save_as", &Udm::SmartDataNetwork::SaveAs)
 		.add_property("root", &Udm::SmartDataNetwork::GetRootObject)
 	;
 	scope().attr("SmartDataNetwork").attr("__init__") = eval("lambda self, *args: None");


More information about the Mobies-commit mailing list