CString ModelHandler::extractPortType(Udm::Object portObj)
{
	// whenever the connected port found is derived from DataPort then extract type from the enum attribute of the dstPort
	if(Udm::IsDerivedFrom(portObj.type(), SignalFlow::DataPort::meta))
	{
		return CString(((string) SignalFlow::DataPort::Cast(portObj).DataType()).c_str()).Trim();
	}
	// whenever the connected Port is derived from SF_Port then find the contained TypeRef Port to get the type
	else if(Udm::IsDerivedFrom(portObj.type(), Simulink::SF_Port::meta) ||
			Udm::IsDerivedFrom(portObj.type(), Simulink::SFStateDE::meta) ||
			Udm::IsDerivedFrom(portObj.type(), Simulink::StateDE::meta)
		)
	{
		// find type from the contained type ref
		set<Udm::Object> typerefSet = portObj.GetChildObjects(Simulink::TypeBaseRef::meta);
		// a port can have only a single type
		if(typerefSet.size() == 1)
		{
			Simulink::TypeBaseRef typeBaseRef = Simulink::TypeBaseRef::Cast(*(typerefSet.begin()));
			try
			{
				return CString(((string) Simulink::SF_Matrix::Cast(typeBaseRef.getReferencedObject()).Type()).c_str()).Trim();
			} catch(udm_exception e)
			{
				throw udm_exception(_T("Simulink::TypeBaseRef is currently allowed to refer to objects of only Simulink::SF_Matrix type! @[OBJECT:]") +
									MyUdmUtil::getHyperLinkPath_StdString(typeBaseRef));
			}
		}
		else if(typerefSet.size() > 1)
		{
			throw udm_exception(MyUdmUtil::getHyperLinkPath_StdString(portObj) + _T(" contains more than 1 Simulink::TypeBaseRef type objects. "));
		}
	}
	// the portObj is an InputSignalInterface of a ModelicaComponent
	else if(portObj.type().name() == "InputSignalInterface")
	{
		return CString(((string) InputSignalInterface::Cast(portObj).Class()).c_str()).Trim();
	}
	// the portObj is an OutputSignalInterface of a ModelicaComponent
	else if(portObj.type().name() == "OutputSignalInterface")
	{
		return CString(((string) OutputSignalInterface::Cast(portObj).Class()).c_str()).Trim();
	}
	// the portObj is a ParameterRef of a ModelicaComponent
	else if(portObj.type().name() == "ParameterRef")
	{
		return CString(((string) ParameterRef::Cast(portObj).Class()).c_str()).Trim();
	}

	return CString(_T(""));
}
Пример #2
0
bool UdmComparator::compareNodeAux( Udm::Object udmObject1, Udm::Object udmObject2 ) {

	bool retval = true;

	_udmObjectMap.insert(  std::make_pair( udmObject1, udmObject2 )  );

	const Uml::Class &umlClass1 = udmObject1.type();
	const Uml::Class &umlClass2 = udmObject2.type();

	if ( umlClass1 != umlClass2 ) {
		std::cerr << "Classes of objects \"" << udmObject1.getPath( "/" ) << "\" and \"" << udmObject2.getPath( "/" ) << "\" do not match!" << std::endl << std::endl;
		return false;
	}

	getObjectNameSingleton().ObjectNameCache.insert(std::make_pair(udmObject1, getObjectNameSingleton()(udmObject1)));
	getObjectNameSingleton().ObjectNameCache.insert(std::make_pair(udmObject2, getObjectNameSingleton()(udmObject2)));

	UmlAttributeSet umlAttributeSet = _classNameFilter.filterUmlAttributeSet( umlClass1 );
	for( UmlAttributeSet::iterator uasItr = umlAttributeSet.begin() ; uasItr != umlAttributeSet.end() ; ++uasItr ) {
		Uml::Attribute umlAttribute = *uasItr;
		std::string umlAttributeName = umlAttribute.name();
		std::string value1, value2;
		
		std::string umlAttributeType = umlAttribute.type();
		if ( umlAttributeType == "Boolean" ) {
			value1 = boost::lexical_cast< std::string >(  udmObject1.getBooleanAttr( umlAttribute )  );
			value2 = boost::lexical_cast< std::string >(  udmObject2.getBooleanAttr( umlAttribute )  );
		} else if ( umlAttributeType == "Integer" ) {
			value1 = boost::lexical_cast< std::string >(  udmObject1.getIntegerAttr( umlAttribute )  );
			value2 = boost::lexical_cast< std::string >(  udmObject2.getIntegerAttr( umlAttribute )  );
		} else if ( umlAttributeType == "Real" ) {
			value1 = boost::lexical_cast< std::string >(  udmObject1.getRealAttr( umlAttribute )  );
			value2 = boost::lexical_cast< std::string >(  udmObject2.getRealAttr( umlAttribute )  );
		} else {
			value1 = udmObject1.getStringAttr( umlAttribute );
			value2 = udmObject2.getStringAttr( umlAttribute );
		}

		if ( value1 != value2 ) {
			Report::get_singleton().incrementDifferences( udmObject1 );
			std::cerr << "Value of \"" << umlAttributeName << "\" attribute value differs for \"" << udmObject1.getPath( "/" ) << "\" objects:  \"" << value1 << "\" vs. \"" << value2 << "\"" << std::endl << std::endl;
			retval = false;
		}
	}

	UdmObjectSet udmObjectSet1 = _classNameFilter.filterUdmObjectSet( udmObject1.GetChildObjects() );
	UdmObjectSet udmObjectSet2 = _classNameFilter.filterUdmObjectSet( udmObject2.GetChildObjects() );

	if ( udmObjectSet1.size() != udmObjectSet2.size() ) {
		std::cerr << "\"" << udmObject1.getPath( "/" ) << "\" objects have a different number of children:  " << udmObjectSet1.size() << "," << udmObjectSet2.size() << std::endl << std::endl;
		tallyChildrenClasses( udmObjectSet1, udmObjectSet2 );
		retval = false;
	}

	udmObjectSet1 = _classNameFilter.filterConnections( udmObjectSet1 );
	udmObjectSet2 = _classNameFilter.filterConnections( udmObjectSet2 );

	UdmChildObjectSet udmChildObjectSet1;
	udmChildObjectSet1.rehash(udmObjectSet1.size());
	std::copy(udmObjectSet1.begin(), udmObjectSet1.end(), std::inserter(udmChildObjectSet1, udmChildObjectSet1.begin()));
	if ( udmChildObjectSet1.size() != udmObjectSet1.size() ) {
		std::cerr << "Object \"" << udmObject1.getPath( "/" ) << "\" in the first  model has children that cannot be distinguished (duplicate name?)." << std::endl << std::endl;
		retval = false;
	}

	UdmChildObjectSet udmChildObjectSet2;
	udmChildObjectSet2.rehash(udmObjectSet2.size());
	std::copy(udmObjectSet2.begin(), udmObjectSet2.end(), std::inserter(udmChildObjectSet2, udmChildObjectSet2.begin()));
	if ( udmChildObjectSet2.size() != udmObjectSet2.size() ) {
		std::cerr << "Object \"" << udmObject2.getPath( "/" ) << "\" in the second model has children that cannot be distinguished (duplicate name?)." << std::endl << std::endl;
		retval = false;
	}

	UdmChildObjectSet::iterator ucsItr1 = udmChildObjectSet1.begin();
	
	for (; ucsItr1 != udmChildObjectSet1.end(); ++ucsItr1) {

		UdmChildObjectSet::iterator ucsItr2 = udmChildObjectSet2.find(*ucsItr1);

		if (ucsItr2 == udmChildObjectSet2.end()) {
			std::cerr << "No corresponding object for \"" << ucsItr1->object.getPath( "/" ) << "\" in first model found in second model." << std::endl;
			Report::get_singleton().incrementDifferences( udmObject1 );
			retval = false;
			continue;
		} 

		if (compareNodeAux(ucsItr1->object, ucsItr2->object) == false) {
			retval = false;
			Report::get_singleton().addToDifferences( udmObject1 );
		}
		udmChildObjectSet2.erase(ucsItr2);
	}

	UdmChildObjectSet::iterator ucsItr2 = udmChildObjectSet2.begin();
	for (; ucsItr2 != udmChildObjectSet2.end(); ++ucsItr2) {
		std::cerr << "No corresponding object for \"" << ucsItr2->object.getPath( "/" ) << "\" in second model found in first model." << std::endl;
		Report::get_singleton().incrementDifferences( udmObject1 );
		retval = false;
	}
//	if ( !retval ) return false;


	UmlAssociationRoleSet umlAssociationRoleSet = getAllUmlAssociationRoles( umlClass1 );
	for( UmlAssociationRoleSet::iterator arsItr = umlAssociationRoleSet.begin() ; arsItr != umlAssociationRoleSet.end() ; ++arsItr ) {

		Uml::AssociationRole umlAssociationRole = *arsItr;
		UdmObjectSet udmObjectSet1 = _classNameFilter.filterUdmObjectSet(   udmObject1.getAssociation(  Uml::theOther( umlAssociationRole )  )   );
		UdmObjectSet udmObjectSet2 = _classNameFilter.filterUdmObjectSet(   udmObject2.getAssociation(  Uml::theOther( umlAssociationRole )  )   );

		if ( udmObjectSet1.size() != udmObjectSet2.size() ) {
			std::cerr << "Objects \"" << udmObject1.getPath( "/" ) << "\" and \"" << udmObject2.getPath( "/" ) << "\"" << std::endl;
			std::cerr << "have a different number of \"" << umlAssociationRole.name() << "\" associations: " << udmObjectSet1.size() << " vs. " << udmObjectSet2.size() << std::endl << std::endl;
			retval = false;
		}

		UdmAssociationObjectSet udmAssociationObjectSet1;
		udmAssociationObjectSet1.rehash(udmObjectSet1.size());
		std::copy(udmObjectSet1.begin(), udmObjectSet1.end(), std::inserter(udmAssociationObjectSet1, udmAssociationObjectSet1.begin()));
		if ( udmAssociationObjectSet1.size() != udmObjectSet1.size() ) {
			std::cerr << "Object \"" << udmObject1.getPath( "/" ) << "\" has \"" << umlAssociationRole.name() << "\" associated objects that cannot be distinguished (probably due to duplicate name)." << std::endl << std::endl;
			retval = false;
		}

		UdmAssociationObjectSet udmAssociationObjectSet2;
		udmAssociationObjectSet2.rehash(udmObjectSet2.size());
		std::copy(udmObjectSet2.begin(), udmObjectSet2.end(), std::inserter(udmAssociationObjectSet2, udmAssociationObjectSet2.begin()));
		if ( udmAssociationObjectSet2.size() != udmObjectSet2.size() ) {
			std::cerr << "Object \"" << udmObject2.getPath( "/" ) << "\" has \"" << umlAssociationRole.name() << "\" associated objects that cannot be distinguished (probably due to duplicate name)." << std::endl << std::endl;
			retval = false;
		}

		UdmAssociationObjectSet::iterator ucsItr1 = udmAssociationObjectSet1.begin();
		
		for( ; ucsItr1 != udmAssociationObjectSet1.end(); ++ucsItr1 ) {

			UdmAssociationObjectSet::iterator ucsItr2 = udmAssociationObjectSet2.find(*ucsItr1);

			if ( ucsItr2 == udmAssociationObjectSet2.end()) {
				std::cerr << "In first model, \"" << udmObject1.getPath( "/" ) << "\" has a \"" << umlAssociationRole.name() << "\" association object \"" << ucsItr1->object.getPath( "/" ) << "\", but not in the second model." << std::endl;
				Report::get_singleton().incrementDifferences( udmObject1 );
				retval = false;
				continue;
			}

			Udm::Object udmAssociationObject1 = ucsItr1->object;
			Udm::Object udmAssociationObject2 = ucsItr2->object;

			udmAssociationObjectSet2.erase(ucsItr2);

			if ( udmAssociationObject1 == Udm::null ) {
				if ( udmAssociationObject2 != Udm::null ) {
					Report::get_singleton().incrementDifferences( udmObject1 );
					std::cerr << "Association Error:" << std::endl;
					std::cerr << "In first model, object \"" << udmObject1.getPath( "/" ) << "is \"" << umlAssociationRole.name() << "\" associated with Udm::null" << std::endl;
					std::cerr << "However, in the second model, \"" << udmObject2.getPath( "/" ) << "\" is \"" << umlAssociationRole.name() << "\" associated with \"" << udmAssociationObject2.getPath( "/" ) << "\"" << std::endl << std::endl;
					retval = false;
				}
			} else if ( udmAssociationObject2 == Udm::null ) {
				Report::get_singleton().incrementDifferences( udmObject1 );
				std::cerr << "Association Error:" << std::endl;
				std::cerr << "In second model, object \"" << udmObject2.getPath( "/" ) << "is \"" << umlAssociationRole.name() << "\" associated with Udm::null" << std::endl;
				std::cerr << "However, in the first model, \"" << udmObject1.getPath( "/" ) << "\" is \"" << umlAssociationRole.name() << "\" associated with \"" << udmAssociationObject1.getPath( "/" ) << "\"" << std::endl << std::endl;
				retval = false;
			} else {

				UdmObjectMap::iterator uomItr = _udmObjectMap.find( udmAssociationObject1 );
				if ( uomItr != _udmObjectMap.end() ) {

					Udm::Object udmMappedObject = uomItr->second;
					if ( udmMappedObject != udmAssociationObject2 ) {
						Report::get_singleton().incrementDifferences( udmObject1 );
						std::cerr << "Association Error:" << std::endl;
						std::cerr << "In first  model, \"" << udmObject1.getPath( "/" ) << "\" is \"" << umlAssociationRole.name() << "\" associated with \"" << udmAssociationObject1.getPath( "/" ) << "\"." << std::endl;
						std::cerr << "In second model, \"" << udmObject2.getPath( "/" ) << "\" is \"" << umlAssociationRole.name() << "\" associated with \"" << udmAssociationObject2.getPath( "/" ) << "\"." << std::endl;
						std::cerr << "However, \"" << udmAssociationObject1.getPath( "/" ) << "\" of the first model corresponds to \"" << udmMappedObject.getPath( "/" ) << "\"" << std::endl;
						std::cerr << "instead of \"" << udmAssociationObject2.getPath( "/" ) << "\" as it should." << std::endl << std::endl;
						retval = false;
					}

				}
			}
		}

		UdmAssociationObjectSet::iterator ucsItr2 = udmAssociationObjectSet2.begin();
		for( ; ucsItr2 != udmAssociationObjectSet2.end(); ++ucsItr2 ) {
			std::cerr << "In second model, \"" << udmObject2.getPath( "/" ) << "\" has a \"" << umlAssociationRole.name() << "\" association object \"" << ucsItr2->object.getPath( "/" ) << "\", but not in the first model." << std::endl;
			Report::get_singleton().incrementDifferences( udmObject2 );
			retval = false;
			continue;
		}
	}

	Report::get_singleton().addToReport( udmObject1 );

	return retval;
}
TestBenchType CyPhyElaborate::expand(const TestBenchType& tb) {
	log("elaborate(TB)",tb.getPath());

	set<ComponentAssembly> caKids = tb.ComponentAssembly_kind_children();
	for (set<ComponentAssembly>::const_iterator i = caKids.begin(); i != caKids.end(); i++) {
		if (i->isSubtype() || i->isInstance())
		{
			DetachFromArchetype(*i);
		}
		expand(*i, "", std::set<Udm::Object>());
	}
	
    set<TopLevelSystemUnderTest> crToElaborate = tb.TopLevelSystemUnderTest_kind_children();
	// For each of these, replace the reference with an instance. Then replicate all connections.
	for (set<TopLevelSystemUnderTest>::const_iterator i = crToElaborate.begin(); i != crToElaborate.end(); i++) {
		TopLevelSystemUnderTest cri(*i);
		TestBenchType parent = cri.TestBenchType_parent();

		if (!Uml::IsDerivedFrom(static_cast<DesignEntity>(cri.ref()).type(), DesignElement::meta))
			continue;
		DesignElement cType = DesignElement::Cast(cri.ref());
		
		if (cType != Udm::null)
		{
			DesignElement instance;
			if (Uml::IsDerivedFrom(cType.type(), CyPhyML::ComponentType::meta))
			{
				if (cType.type() == CyPhyML::TestComponent::meta)
				{
					instance = DesignElement::Cast(Udm::Object::Create(cType.type(), parent, CyPhyML::TestBenchType::meta_TopLevelSystemUnderTest, cType.__impl(), false));
				}
				else
					instance = Component::Cast(cType).CreateInstance(parent);
				// traceability: save the instance to the map
				addCopy(instance, cType);

				set<Object> children = instance.GetChildObjects();
				for (auto childIt = children.begin(); childIt != children.end(); childIt++)
				{
					// traceability: save all child objects of a component
					addCopy(*childIt, (*childIt).archetype());
					SwitchConnections(childIt->archetype(), *childIt, cri, tb);
				}
				// TODO: cannot test this, since connections of this type is not possible
				//SwitchConnections(cri, instance, Udm::null, parent);

			}
			else
			{
				map<Object, Object> cam;
				deque<Object> queue;
				queue.push_back(cType);
				while (queue.size() > 0)
				{
					Object o = queue.front();
					queue.pop_front();
                    Udm::Object referred = getReferredOrNull(o);
					if (referred)
					{
						set<Object> refCompChildren = referred.GetChildObjects();
						for_each(refCompChildren.begin(), refCompChildren.end(), [&](const Object& o) { cam[o] = o; });
					}
					set<Object> qChildren = o.GetChildObjects();
					std::copy(qChildren.begin(), qChildren.end(), back_inserter(queue));
				}
				// instance = ComponentAssembly::Create(parent);
				// std::string d1 = cType.type().name();
				instance = DesignElement::Cast(parent.CreateObject(cType.type()));
				Store(instance, cType);
				UdmUtil::CopyObjectHierarchy(cType.__impl(), instance.__impl(), parent.__impl()->__getdn(), cam);

				set<Object> children = cType.GetChildObjects();
				for (auto childIt = children.begin(); childIt != children.end(); childIt++)
				{
					auto to = cam.find(*childIt);
					if (to == cam.end())
						throw udm_exception();
					//if (_ExtractName(to->second) != _ExtractName(*childIt))
					//	throw udm_exception();
					SwitchConnections(*childIt, to->second, cri, parent);
				}
				addCopies(cam);
				// TODO: cannot test this, since connections of this type is not possible
				//SwitchConnections(cri, instance, Udm::null, parent);
				expand(ComponentAssembly::Cast(instance));
				addCopy(instance, cType);
			}
			instance.name() = cri.name();
			// Copy layout information as well.
			string pos = cri.position();
			if (pos == "")
				instance.position() = "0,0";
			else
				instance.position() = pos;

			cri.DeleteObject();
			//cri.name() = std::string(cri.name()) + "tobedeleted";
		}
		else
		{
			cr_null_ref_set.insert(cri);			
		}
	}

	if (Uml::IsDerivedFrom(tb.type(), CyPhyML::BallisticTestBench::meta))
	{
		CyPhyElaborate::SwitchReference<CyPhyML::BallisticTarget>(tb);
		CyPhyElaborate::SwitchReference<CyPhyML::CriticalComponent>(tb);
	}
	CyPhyElaborate::SwitchReference<CyPhyML::TestInjectionPoint>(tb);

	return tb;
}
ComponentAssembly CyPhyElaborate::expand(const ComponentAssembly& ca, string ID_Prefix, std::set<Udm::Object> expandedInThisStack) {
	log("expand(CA)",ca.getPath());
	expandedInThisStack.insert(ca);

	set<ComponentAssembly> caKids = ca.ComponentAssembly_kind_children();
	for (set<ComponentAssembly>::const_iterator i = caKids.begin(); i != caKids.end(); i++) {
		if (i->isSubtype() || i->isInstance())
		{
			DetachFromArchetype(*i);
		}
		expand(*i, "", expandedInThisStack);
	}
	
	set<ComponentRef> crToElaborate = ca.ComponentRef_kind_children();
	// For each of these, replace the reference with an instance. Then replicate all connections.
	for (set<ComponentRef>::const_iterator i = crToElaborate.begin(); i != crToElaborate.end(); i++) {
		ComponentRef cri(*i);
		ComponentAssembly parent = cri.ComponentAssembly_parent();
		
		DesignElement cType = DesignElement::Cast(cri.ref());
		
		if (cType != Udm::null)
		{
			DesignElement instance;
			if (cType.type() == Component::meta)
			{
				instance = Component::Cast(cType).CreateInstance(parent);
				// traceability: save this component
				addCopy(instance, cType);
				addCopy(instance, cri);
				
				// Copy InstanceGUID
				string newInstanceGUID = ID_Prefix;
				newInstanceGUID.append(cri.InstanceGUID());
				(Component::Cast(instance)).InstanceGUID() = newInstanceGUID;

				set<Object> children = instance.GetChildObjects();
				for (auto childIt = children.begin(); childIt != children.end(); childIt++)
				{
					// traceability: save all child objects of a component
					addCopy(*childIt, (*childIt).archetype());
					addAllObjectsToTraceability(*childIt);

					SwitchConnections(childIt->archetype(), *childIt, cri, ca);
				}
				// TODO: cannot test this, since connections of this type is not possible
				SwitchConnections(cri, instance, Udm::null, parent);

				// DY: 9/9/11 - copy registry value from ref to instance
				this->copyCADPropertyRegistry2Inst(cri, CyPhyML::Component::Cast(instance));
			}
			else if (expandedInThisStack.find(cType) == expandedInThisStack.end())
			{
				map<Object, Object> cam;
				deque<Object> queue;
				queue.push_back(cType);
				while (queue.size() > 0)
				{
					Object o = queue.front();
					queue.pop_front();
                    Udm::Object referred = getReferredOrNull(o);
					if (referred)
					{
						set<Object> refCompChildren = referred.GetChildObjects();
						for_each(refCompChildren.begin(), refCompChildren.end(), [&](const Object& o) { cam[o] = o; });
					}
					set<Object> qChildren = o.GetChildObjects();
					std::copy(qChildren.begin(), qChildren.end(), back_inserter(queue));
				}
				// instance = ComponentAssembly::Create(parent);
				instance = DesignElement::Cast(parent.CreateObject(cType.type()));
				UdmUtil::CopyObjectHierarchy(cType.__impl(), instance.__impl(), parent.__impl()->__getdn(), cam);

				set<Object> children = cType.GetChildObjects();
				for (auto childIt = children.begin(); childIt != children.end(); childIt++)
				{
					auto to = cam.find(*childIt);
					if (to == cam.end())
						throw udm_exception();
					//if (_ExtractName(to->second) != _ExtractName(*childIt))
					//	throw udm_exception();
					SwitchConnections(*childIt, to->second, cri, parent);
				}
				addCopies(cam);
				// TODO: cannot test this, since connections of this type is not possible
				//SwitchConnections(cri, instance, Udm::null, parent);				
				expand(ComponentAssembly::Cast(instance), ID_Prefix + static_cast<std::string>(cri.InstanceGUID()), expandedInThisStack);
			} else {
				throw udm_exception(std::string("ComponentAssembly '") + static_cast<std::string>(cType.name())
					+ "' cannot contain a ComponentRef to itself");
			}
			instance.name() = cri.name();
			// Copy layout information as well.
			string pos = cri.position();
			if (pos == "")
				instance.position() = "0,0";
			else
				instance.position() = pos;

			// If "ID" is non-zero, copy it too.
			if (cri.ID() != 0)
				instance.ID() = cri.ID();

			cri.DeleteObject();
			// cri.name() = std::string(cri.name()) + "tobedeleted";
		}
		else
		{
			cr_null_ref_set.insert(cri);
		}
	}

	return ca;
};