[Mobies-commit] [commit] r3596 - in UDM/trunk: include src/Udm src/UdmBase src/UdmDom src/UdmGme

endre at redhat1.isis.vanderbilt.edu endre at redhat1.isis.vanderbilt.edu
Wed Jan 5 01:00:49 CST 2011


Author: endre
Date: Wed Jan  5 01:00:49 2011
New Revision: 3596

Log:
Implement the new reference ports methods for DOM and MEM backends

Modified:
   UDM/trunk/include/UdmBase.h
   UDM/trunk/include/UdmStatic.h
   UDM/trunk/src/Udm/ClassGen.cpp
   UDM/trunk/src/UdmBase/UdmBase.cpp
   UDM/trunk/src/UdmDom/UdmDom.cpp
   UDM/trunk/src/UdmGme/GmeObject.h
   UDM/trunk/src/UdmGme/UdmGme.cpp

Modified: UDM/trunk/include/UdmBase.h
==============================================================================
--- UDM/trunk/include/UdmBase.h	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/include/UdmBase.h	Wed Jan  5 01:00:49 2011	(r3596)
@@ -497,10 +497,10 @@
 		// association with reference ports
 		virtual void connectTo(
 			const ::Uml::AssociationRole &meta,
-			const ObjectImpl* target,
-			const vector<ObjectImpl*> &refs = vector<ObjectImpl*>()) = 0;
-		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) = 0;
-		virtual vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const = 0;
+			ObjectImpl* target,
+			const vector<ObjectImpl*> &refs = vector<ObjectImpl*>());
+		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, ObjectImpl* peer);
+		virtual vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const;
 
 	};
 
@@ -647,9 +647,9 @@
 
 		virtual void connectTo(
 			const ::Uml::AssociationRole &meta,
-			const ObjectImpl* target,
+			ObjectImpl* target,
 			const vector<ObjectImpl*> &refs = vector<ObjectImpl*>()) { throw e; }
-		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) { throw e; }
+		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, ObjectImpl* peer) { throw e; }
 		virtual vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const { throw e; }
 
 		virtual uniqueId_type uniqueId() const { return 0; }

Modified: UDM/trunk/include/UdmStatic.h
==============================================================================
--- UDM/trunk/include/UdmStatic.h	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/include/UdmStatic.h	Wed Jan  5 01:00:49 2011	(r3596)
@@ -339,21 +339,6 @@
 			int mode = Udm::TARGETFROMPEER,
 			const bool direct = true);
 	
-		void connectTo(const ::Uml::AssociationRole &meta, const ObjectImpl* target, const vector<ObjectImpl*> &refs = vector<ObjectImpl*>())
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
-		void disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer)
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
-		vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
 		// --- persistency
 		unsigned long Serialize(FILE * f);											// return the length of the object
 		void ValidatePointers(map<unsigned long, const StaticObject *>& tr_map);	// changing the associations and the children to the new pointers

Modified: UDM/trunk/src/Udm/ClassGen.cpp
==============================================================================
--- UDM/trunk/src/Udm/ClassGen.cpp	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/src/Udm/ClassGen.cpp	Wed Jan  5 01:00:49 2011	(r3596)
@@ -933,6 +933,12 @@
 				// association_class::meta_OTHER_ROLE_end_ = OTHER_ROLE_target::meta_ROLE_rev = ROLE_target::meta_OTHER_ROLE
 				meta_init_links.push_back( boost::format("%1%::meta_%2%_end_ = %3%::meta_%4%_rev = %5%::meta_%6%") % cl_name % orel_name % UmlClassCPPName(the_other.target(), c.parent_ns()) % rel_name % UmlClassCPPName(tclass, c.parent_ns()) % orel_name );
 
+				::Uml::AssociationRole orp_helper = the_other.rp_helper();
+				if (orp_helper) {
+					string orp_helper_name = ::Uml::MakeRoleName(orp_helper);
+					meta_init_links.push_back( boost::format("%1%::meta_%2%_end_.rp_helper() = %1%::meta_%3%") % cl_name % orel_name % orp_helper_name );
+				}
+
 				if (generate_rphelper_chains)
 				{
 					typedefs.push_back( boost::format("typedef pair< %1%, vector<Udm::Object> > %2%_chain_t") % tclass_cpp_name % rel_name );

Modified: UDM/trunk/src/UdmBase/UdmBase.cpp
==============================================================================
--- UDM/trunk/src/UdmBase/UdmBase.cpp	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/src/UdmBase/UdmBase.cpp	Wed Jan  5 01:00:49 2011	(r3596)
@@ -93,6 +93,7 @@
 #include "UmlExt.h"
 #include <UdmUtil.h>
 #include "UdmStatic.h"
+#include <algorithm>
 #include <string>
 #include <cstdlib>
 #include <cstring>
@@ -1689,6 +1690,169 @@
 		};
 
 
+		bool canCompleteRefsChain(const ObjectImpl* target, const vector<ObjectImpl*> &refs)
+		{
+			ASSERT(refs.size());
+
+			ObjectImpl* ref = refs.back();
+
+			// exit loop when reaching the parent of the reference port
+			const ObjectImpl *target_parent = target->getParent(NULLPARENTROLE);
+
+			while (ref != &_null) {
+
+				Object referred = Object(ref->clone()).getReferencedObject();
+				if (referred.uniqueId() == target_parent->uniqueId())
+					break;
+
+				ref = referred.__impl()->clone();
+			}
+
+			return ref != &_null;
+		}
+
+		UDM_DLL void ObjectImpl::connectTo(const ::Uml::AssociationRole &meta, ObjectImpl* target, const vector<ObjectImpl*> &refs)
+		{
+			if ((string)type().stereotype() != "Connection")
+				throw udm_exception("Only setting the connection src/dst is supported");
+
+			::Uml::AssociationRole rp_helper = meta.rp_helper();
+			ObjectImpl* rp_helper_ref = &_null;
+			if (rp_helper) {
+				vector<ObjectImpl*> v = getAssociation(rp_helper);
+				if (v.size())
+					rp_helper_ref = v.front();
+			}
+
+			if (refs.size()) {
+				if (!canCompleteRefsChain(target, refs))
+					throw udm_exception("Could not reach target " + UdmUtil::ExtractName(target) + " starting with the given chain of references");
+				
+				// change rp_helper because the user is requesting a specific chain
+				if (rp_helper_ref != &_null && rp_helper_ref != refs.front()) {
+					vector<ObjectImpl*> v;
+					v.push_back(refs.front());
+					setAssociation(rp_helper, v);
+				}
+			} else {
+				if (rp_helper_ref != &_null) {
+					// if a reference port helper is set then check if it can be used to reach the target
+					// is there a reference port helper set for this connection?
+					vector<ObjectImpl*> v;
+					v.push_back(rp_helper_ref);
+					if (!canCompleteRefsChain(target, v))
+						throw udm_exception("Could not reach target " + UdmUtil::ExtractName(target) + " starting with the reference port helper set in the model");
+				} else {
+					ObjectImpl* parent = getParent(NULLPARENTROLE);
+					if (parent != target->getParent(NULLPARENTROLE)) {
+						vector<ObjectImpl*> children = parent->getChildren(NULL, NULL);
+						vector<ObjectImpl*>::const_iterator i = children.begin();
+						for (; i != children.end(); i++) {
+							ObjectImpl *child = *i;
+							vector<ObjectImpl*> v;
+							v.push_back(child);
+							if (child->type().stereotype() == "Reference" && canCompleteRefsChain(target, v)) {
+								// found a child that can be used to reach the target
+								setAssociation(rp_helper, v);
+								break;
+							}
+						}
+						if (i == children.end())
+							throw udm_exception("Could not reach target " + UdmUtil::ExtractName(target) + " from any reference found in the parent of connection");
+					}
+				}
+			}
+
+			vector<ObjectImpl*> v;
+			v.push_back(target);
+			setAssociation(meta, v, TARGETFROMCLASS);
+		}
+
+		UDM_DLL void ObjectImpl::disconnectFrom(const ::Uml::AssociationRole &meta, ObjectImpl* peer)
+		{
+			bool peer_is_conn = peer->type().stereotype() == "Connection";
+
+			vector<ObjectImpl*> empty_v;
+
+#if 0
+			// Don't disconnect the references, they may have been set explicitly by user.
+			// Maybe this method should accept a boolean parameter telling us whether to
+			// disconnect the references or not?
+			::Uml::AssociationRole rp_helper = meta.rp_helper();
+			if (rp_helper) {
+
+				// unset references from reference port helper to reference port parent
+				vector<ObjectImpl*> chain = getConnectingChain(meta, peer);
+
+				if (peer_is_conn)
+					std::reverse(chain.begin(), chain.end());
+
+				for (vector<ObjectImpl*>::const_reverse_iterator i = chain.rbegin(); i != chain.rend(); i++) {
+					ObjectImpl *ref = *i;
+					set< ::Uml::AssociationRole> aroles = Uml::AncestorAssociationTargetRoles(ref->type());
+					for (set< ::Uml::AssociationRole>::const_iterator aroles_i = aroles.begin(); aroles_i != aroles.end(); aroles_i++) {
+						::Uml::AssociationRole arole = *aroles_i;
+						if ((string)arole.name() == "ref") {
+							ref->setAssociation(arole, empty_v);
+							break;
+						}
+					}
+				}
+			}
+#endif
+
+			if (peer_is_conn)
+				peer->setAssociation(meta, empty_v, TARGETFROMCLASS);
+			else
+				setAssociation(meta, empty_v, TARGETFROMCLASS);
+		}
+
+		UDM_DLL vector<ObjectImpl*> ObjectImpl::getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const
+		{
+			vector<ObjectImpl*> ret;
+
+			::Uml::AssociationRole rp_helper = meta.rp_helper();
+			if (!rp_helper) return ret;
+
+			const ObjectImpl *conn, *target;
+			if (this->type().stereotype() == "Connection") {
+				conn = this;
+				target = peer;
+			} else if (peer->type().stereotype() == "Connection") {
+				conn = peer;
+				target = this;
+			} else
+				throw udm_exception("Neither this object nor its peer seems to be a type of connection");
+
+			vector<ObjectImpl*> v = conn->getAssociation(rp_helper);
+			if (v.size()) {
+				ObjectImpl* ref = v[0];
+
+				// exit loop when reaching the parent of the reference port
+				const ObjectImpl *target_parent = target->getParent(NULLPARENTROLE);
+
+				do {
+					ret.push_back(ref);
+
+					Object referred = Object(ref->clone()).getReferencedObject();
+					if (referred.uniqueId() == target_parent->uniqueId())
+						break;
+
+					ref = referred.__impl()->clone();
+				} while (ref != &_null);
+
+				if (ref == &_null)
+					// the chain of references does not reach the reference port parent
+					ret.clear();
+			}
+
+			if (conn == peer)
+				std::reverse(ret.begin(), ret.end());
+
+			return ret;
+		}
+
+
 		//the map for static metadepository
 		map<string, const UdmDiagram*>* MetaDepository::meta_dep = NULL;
 		

Modified: UDM/trunk/src/UdmDom/UdmDom.cpp
==============================================================================
--- UDM/trunk/src/UdmDom/UdmDom.cpp	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/src/UdmDom/UdmDom.cpp	Wed Jan  5 01:00:49 2011	(r3596)
@@ -2863,21 +2863,6 @@
 				delete do_parent;
 			}		
 		}
-		void connectTo(const ::Uml::AssociationRole &meta, const ObjectImpl* target, const vector<ObjectImpl*> &refs = vector<ObjectImpl*>())
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
-		void disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer)
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
-		vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const
-		{
-			throw udm_exception("Unsupported yet method");
-		}
-
 		vector<ObjectImpl*> getDerived() const
 		{
 			vector<ObjectImpl*> ret;

Modified: UDM/trunk/src/UdmGme/GmeObject.h
==============================================================================
--- UDM/trunk/src/UdmGme/GmeObject.h	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/src/UdmGme/GmeObject.h	Wed Jan  5 01:00:49 2011	(r3596)
@@ -156,8 +156,8 @@
 		virtual vector<ObjectImpl*> getAssociation(const ::Uml::AssociationRole &meta, int mode) const ;
 		virtual void setAssociation(const ::Uml::AssociationRole &meta, const vector<ObjectImpl*> &nvect, int mode, const bool direct = true);
 
-		virtual void connectTo(const ::Uml::AssociationRole &meta, const ObjectImpl* target, const vector<ObjectImpl*> &refs = vector<ObjectImpl*>());
-		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer);
+		virtual void connectTo(const ::Uml::AssociationRole &meta, ObjectImpl* target, const vector<ObjectImpl*> &refs = vector<ObjectImpl*>());
+		virtual void disconnectFrom(const ::Uml::AssociationRole &meta, ObjectImpl* peer);
 		virtual vector<ObjectImpl*> getConnectingChain(const ::Uml::AssociationRole &meta, const ObjectImpl* peer) const;
 	// ---- archetype/derived/instances
 

Modified: UDM/trunk/src/UdmGme/UdmGme.cpp
==============================================================================
--- UDM/trunk/src/UdmGme/UdmGme.cpp	Wed Jan  5 00:44:07 2011	(r3595)
+++ UDM/trunk/src/UdmGme/UdmGme.cpp	Wed Jan  5 01:00:49 2011	(r3596)
@@ -1276,7 +1276,7 @@
 		return ret;
 	}
 
-	void GmeObject::connectTo(const ::Uml::AssociationRole &meta, const ObjectImpl* target, const vector<ObjectImpl*> &refs)
+	void GmeObject::connectTo(const ::Uml::AssociationRole &meta, ObjectImpl* target, const vector<ObjectImpl*> &refs)
 	{
 		::Uml::Association assoc = meta.parent();
 		string rname = meta.name();
@@ -1317,7 +1317,7 @@
 			COMTHROW(conn->SetSrc(references, target_go->self));
 	}
 
-	void GmeObject::disconnectFrom(const ::Uml::AssociationRole &meta, const ObjectImpl* peer)
+	void GmeObject::disconnectFrom(const ::Uml::AssociationRole &meta, ObjectImpl* peer)
 	{
 		::Uml::Association assoc = meta.parent();
 		assocmapitem *nn = ((UdmGme::GmeDataNetwork*) mydn)->amap.find(assoc.uniqueId())->second;


More information about the Mobies-commit mailing list