Ejemplo n.º 1
0
// This is the main component method for interpereters and plugins. 
// May als be used in case of invokeable addons
STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project,  IMgaFCO *currentobj,  
									IMgaFCOs *selectedobjs,  long param) 
{
	CUdmApp udmApp;

	CComPtr<IMgaProject>ccpProject(project);
    long status = 0;
    ccpProject->get_ProjectStatus(&status);

	try
	{
		// Setting up the console
		GMEConsole::Console::SetupConsole(ccpProject);

		CComBSTR projname;
		CComBSTR focusname = "<nothing>";
		CComPtr<IMgaTerritory> terr;
		COMTHROW(ccpProject->CreateTerritory(NULL, &terr));

		// Setting up Udm
		// Loading the project
		UdmGme::GmeDataNetwork dngBackend(META_NAMESPACE::diagram);
		try
		{
			// Opening backend
		if (!(status & 8))
			COMTHROW(ccpProject->BeginTransactionInNewTerr(TRANSACTION_NON_NESTED, &terr));
			dngBackend.OpenExisting(ccpProject, Udm::CHANGES_LOST_DEFAULT, true);

			std::string metapath;
			HKEY software_meta;
			if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\META", 0, KEY_READ, &software_meta) == ERROR_SUCCESS)
			{
				BYTE data[MAX_PATH];
				DWORD type, size = sizeof(data) / sizeof(data[0]);
				if (RegQueryValueExA(software_meta, "META_PATH", 0, &type, data, &size) == ERROR_SUCCESS)
				{
					metapath = std::string(data, data + strnlen((const char*)data, size));
				}
				RegCloseKey(software_meta);
			}
			if (!metapath.length())
			{
				throw udm_exception("Could not read META_PATH from HKLM\\Software\\META");
			}
			udmApp.meta_path = metapath;
			std::string python_dll_path = metapath + "\\bin\\Python27\\Scripts\\python27.dll";
			HMODULE python_dll = LoadLibraryA(python_dll_path.c_str());
			if (python_dll == nullptr)
				throw udm_exception("Could not load Python27.dll at " + python_dll_path);
			RAIIFreeLibrary python_dll_cleanup;
			python_dll_cleanup.module = python_dll;
			
			CComPtr<IMgaFCO> ccpFocus(currentobj);
			Udm::Object currentObject;
			if(ccpFocus)
			{
				currentObject=dngBackend.Gme2Udm(ccpFocus);
			}

			std::set<Udm::Object> selectedObjects;

			CComPtr<IMgaFCOs> ccpSelObject(selectedobjs);

			MGACOLL_ITERATE(IMgaFCO,ccpSelObject){
				Udm::Object currObj;
				if(MGACOLL_ITER)
				{
					currObj=dngBackend.Gme2Udm(MGACOLL_ITER);
				}
			 selectedObjects.insert(currObj);
			}MGACOLL_ITERATE_END;

			std::string workingDir;
			_bstr_t tmpbstr;
			const char* mgaFile = 0;
			auto original_project_it = componentParameters.find(_bstr_t(L"original_project_file"));
			if (original_project_it != componentParameters.end() && original_project_it->second.vt == VT_BSTR && wcslen(original_project_it->second.bstrVal))
			{
				tmpbstr = original_project_it->second.bstrVal;
				mgaFile = static_cast<const char*>(tmpbstr);
			}
			else
			{
				COMTHROW(project->get_ProjectConnStr(tmpbstr.GetAddress()));
				if (wcsnicmp(L"MGA=", tmpbstr, 4) == 0)
				{
					mgaFile = (static_cast<const char*>(tmpbstr) + 4);
				}
			}
			if (mgaFile)
			{
				char fullPath[MAX_PATH] = { '\0' };
				LPSTR filepart;
				if (GetFullPathNameA(mgaFile, sizeof(fullPath) / sizeof(fullPath[0]), fullPath, &filepart))
				{
					*(filepart-1) = '\0';
					workingDir = fullPath;
				}
			}


			// Calling the main entry point
			udmApp.UdmMain(&dngBackend, currentObject, selectedObjects, param, componentParameters, workingDir);
			// Closing backend
			dngBackend.CloseWithUpdate();
            if (!(status & 8))
                COMTHROW(ccpProject->CommitTransaction());
            terr = 0;

		}
		catch(udm_exception &exc)
		{
			dngBackend.CloseNoUpdate();
            if (!(status & 8))
                COMTHROW(ccpProject->AbortTransaction());

			GMEConsole::Console::Error::writeLine(exc.what());
			return S_FALSE;
		}
        catch (python_error &exc)
        {
            dngBackend.CloseNoUpdate();
            if (!(status & 8))
                COMTHROW(ccpProject->AbortTransaction());
            throw;
        }
    }
// This is the main component method for interpereters and plugins. 
// May als be used in case of invokeable addons
STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project,  IMgaFCO *currentobj,  
									IMgaFCOs *selectedobjs,  long param) 
{
	CUdmApp udmApp;
	// Calling the user's initialization function
	if(udmApp.Initialize())
	{
		return S_FALSE;
	}

	CComPtr<IMgaProject>ccpProject(project);

	try
	{
		// Setting up the console
		GMEConsole::Console::setupConsole(ccpProject);
		GMEConsole::Console::clear();

		char tmpbuf[128];
		_strdate_s(tmpbuf,128);
		std::string date(tmpbuf);
		_strtime_s(tmpbuf,128);
		std::string time(tmpbuf);

		GMEConsole::Console::writeLine(date + " " + time + " Starting CyPhyElaborate Tester Interpreter", MSG_INFO);


	  if(interactive)
	  {
		CComBSTR projname;
		CComBSTR focusname = "<nothing>";
		CComPtr<IMgaTerritory> terr;
		//COMTHROW(ccpProject->CreateTerritory(NULL, &terr));
		//COMTHROW(ccpProject->BeginTransaction(terr));

		// Setting up Udm
#ifdef _DYNAMIC_META
	#ifdef _DYNAMIC_META_DOM
			// Loading the meta for the project
			UdmDom::DomDataNetwork  ddnMeta(Uml::diagram);
			Uml::Diagram theUmlDiagram;

			// Opening the XML meta of the project
			ddnMeta.OpenExisting(META_PATH,"uml.dtd", Udm::CHANGES_LOST_DEFAULT);

			// Casting the DataNetwork to diagram
			theUmlDiagram = Uml::Diagram::Cast(ddnMeta.GetRootObject());

			// Creating the UDM diagram
			Udm::UdmDiagram udmDataDiagram;
			udmDataDiagram.dgr = &theUmlDiagram;
			udmDataDiagram.init = dummy;

	#elif defined _DYNAMIC_META_STATIC
			// Loading the meta for the project
			Udm::SmartDataNetwork  dnsMeta(Uml::diagram);
			Uml::Diagram theUmlDiagram;

			// Opening the static meta of the project
			dnsMeta.OpenExisting(META_PATH, "", Udm::CHANGES_LOST_DEFAULT);

			// Casting the DataNetwork to diagram
			theUmlDiagram = Uml::Diagram::Cast(dnsMeta.GetRootObject());

			// Creating the UDM diagram
			Udm::UdmDiagram udmDataDiagram;
			udmDataDiagram.dgr = &theUmlDiagram;
			udmDataDiagram.init = dummy;

	#else
			#error "Neither _DYNAMIC_META_DOM or _DYNAMIC_META_STATIC defined for dynamic loading"
	#endif
			// Loading the project
			UdmGme::GmeDataNetwork dngBackend(udmDataDiagram);

#else
		using namespace META_NAMESPACE;

		// Loading the project
		UdmGme::GmeDataNetwork dngBackend(META_NAMESPACE::diagram);

#endif
		try
		{
			long status;
			COMTHROW(ccpProject->get_ProjectStatus(&status));
			if (!(status & 8))
				COMTHROW(ccpProject->BeginTransactionInNewTerr(TRANSACTION_NON_NESTED, &terr));

            try {
            // Opening backend if it is not already opened
            dngBackend.OpenExisting(ccpProject, Udm::CHANGES_LOST_DEFAULT, true);


			CComPtr<IMgaFCO> ccpFocus(currentobj);
			Udm::Object currentObject;
			if(ccpFocus)
			{
				currentObject=dngBackend.Gme2Udm(ccpFocus);
			}

			std::set<Udm::Object> selectedObjects;

			CComPtr<IMgaFCOs> ccpSelObject(selectedobjs);

			MGACOLL_ITERATE(IMgaFCO,ccpSelObject){
				Udm::Object currObj;
				if(MGACOLL_ITER)
				{
					currObj=dngBackend.Gme2Udm(MGACOLL_ITER);
				}
			 selectedObjects.insert(currObj);
			}MGACOLL_ITERATE_END;

#ifdef _ACCESS_MEMORY
			// Creating Cache
	#ifdef _DYNAMIC_META
			Udm::SmartDataNetwork dnsCacheBackend(udmDataDiagram);
	#else
			Udm::SmartDataNetwork dnsCacheBackend(META_NAMESPACE::diagram);
	#endif

			const Uml::Class & safeType = Uml::SafeTypeContainer::GetSafeType(dngBackend.GetRootObject().type());

			dnsCacheBackend.CreateNew("tmp.mem","",safeType, Udm::CHANGES_LOST_DEFAULT);

			Udm::Object nullObject(&Udm::_null);
			UdmUtil::copy_assoc_map copyAssocMap;
			copyAssocMap[currentObject]=nullObject; // currentObject may be null object

			std::set<Udm::Object>::iterator p_CurrSelObject;
			for(p_CurrSelObject=selectedObjects.begin();
				p_CurrSelObject!=selectedObjects.end();p_CurrSelObject++)
			{
					std::pair<Udm::Object const, Udm::Object> item(*p_CurrSelObject, nullObject);

					std::pair<UdmUtil::copy_assoc_map::iterator, bool> insRes = copyAssocMap.insert(item);

					if (!insRes.second)
					{
						assert(false);
					}

			}

			// Copying from GME to memory
			UdmUtil::CopyObjectHierarchy(
				dngBackend.GetRootObject().__impl(),
				dnsCacheBackend.GetRootObject().__impl(),
				&dnsCacheBackend,
				copyAssocMap);

			// Searching for focus object
			Udm::Object currentObjectCache;
			UdmUtil::copy_assoc_map::iterator currObject = copyAssocMap.find(currentObject);
			if (currObject != copyAssocMap.end()) // It is in the map
			{
				currentObjectCache=currObject->second;
			}


			// Searching for selected objects
			std::set<Udm::Object> selectedObjectsCache;

			for( p_CurrSelObject=selectedObjects.begin();
				p_CurrSelObject!=selectedObjects.end();p_CurrSelObject++)
			{
				Udm::Object object;
				UdmUtil::copy_assoc_map::iterator currSelObjectIt = copyAssocMap.find(*p_CurrSelObject);
				if (currSelObjectIt != copyAssocMap.end()) // It is in the map
				{
					object=currSelObjectIt->second;
					selectedObjectsCache.insert(object);
				}
			}


			// Closing GME backend
			dngBackend.CloseNoUpdate();

			// Calling the main entry point
			CUdmApp::UdmMain(&dnsCacheBackend,currentObjectCache,selectedObjectsCache,param);
			// Close cache backend
			dnsCacheBackend.CloseNoUpdate();

#else
			// Calling the main entry point
			udmApp.UdmMain(&dngBackend,currentObject,selectedObjects,param);
			traceability = std::move(udmApp.traceability);
			// Closing backend
			dngBackend.CloseWithUpdate();
			if (!(status & 8))
				ccpProject->CommitTransaction();
			} catch (...) {
				if (!(status & 8))
					ccpProject->AbortTransaction();
				throw;
			}
#endif

		}
		catch(udm_exception &exc)
		{
#ifdef _META_ACCESS_MEMORY
			dnCacheBackend.CloseNoUpdate();
#endif
			// Close GME Backend (we may close it twice, but GmeDataNetwork handles it)
			dngBackend.CloseNoUpdate();
			//COMTHROW(ccpProject->AbortTransaction());

			GMEConsole::Console::Error::writeLine(exc.what());
			return S_FALSE;
		}
	  }