+// On intercepte cette méthode pour pouvoir ensuite
+// déterminer si on doit créer une instance sequentielle
+// ou parallèle d'un composant dans la méthode create_component_instance
+CORBA::Boolean
+Container_proxy_impl_final::load_component_Library(const char* componentName, CORBA::String_out reason)
+{
+ MESSAGE("Begin of load_component_Library on proxy : " << componentName);
+ reason=CORBA::string_dup("");
+
+ std::string aCompName = componentName;
+
+ CORBA::Boolean ret = true;
+ if (_libtype_map.count(aCompName) == 0)
+ {
+ _numInstanceMutex.lock(); // lock to be alone
+
+ // Default lib is seq
+ _libtype_map[aCompName] = "seq";
+
+ // --- try dlopen C++ component
+ // If is not a C++ or failed then is maybe
+ // a seq component...
+
+ MESSAGE("Try to load C++ component");
+#ifndef WIN32
+#ifdef __APPLE__
+ std::string impl_name = string ("lib") + aCompName + string("Engine.dylib");
+#else
+ std::string impl_name = string ("lib") + aCompName + string("Engine.so");
+#endif
+#else
+ std::string impl_name = aCompName + string("Engine.dll");
+#endif
+ void* handle;
+#ifndef WIN32
+ handle = dlopen( impl_name.c_str() , RTLD_LAZY | RTLD_GLOBAL ) ;
+#else
+ handle = dlopen( impl_name.c_str() , 0 ) ;
+#endif
+ if ( handle )
+ {
+ _library_map[impl_name] = handle;
+ MESSAGE("Library " << impl_name << " loaded");
+
+ //Test if lib could contain a parallel component
+
+ std::string paco_test_fct_signature = aCompName + std::string("_isAPACO_Component");
+ INFOS("SIG is : " << paco_test_fct_signature);
+ PACO_TEST_FUNCTION paco_test_fct = NULL;
+#ifndef WIN32
+ paco_test_fct = (PACO_TEST_FUNCTION)dlsym(handle, paco_test_fct_signature.c_str());
+#else
+ paco_test_fct = (PACO_TEST_FUNCTION)GetProcAddress((HINSTANCE)handle, paco_test_fct_signature.c_str());
+#endif
+ if (paco_test_fct)
+ {
+ // PaCO Component found
+ MESSAGE("PACO LIB FOUND");
+ _libtype_map[aCompName] = "par";
+ }
+ else
+ {
+ MESSAGE("SEQ LIB FOUND");
+#ifndef WIN32
+ MESSAGE("dlerror() result is : " << dlerror());
+#endif
+ }
+ }
+ else
+ {
+ MESSAGE("Error in importing Cpp component : " << impl_name);
+#ifndef WIN32
+ MESSAGE("dlerror() result is : " << dlerror());
+#endif
+
+ MESSAGE("Try to import Python component "<<componentName);
+ Py_ACQUIRE_NEW_THREAD;
+ PyObject *mainmod = PyImport_AddModule("__main__");
+ PyObject *globals = PyModule_GetDict(mainmod);
+ PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
+ PyObject *result = PyObject_CallMethod(pyCont,
+ (char*)"import_component",
+ (char*)"s",componentName);
+ std::string ret_p= PyUnicode_AsUTF8(result);
+ Py_XDECREF(result);
+ Py_RELEASE_NEW_THREAD;
+
+ if (ret_p=="") // import possible: Python component
+ {
+ MESSAGE("import Python: " << aCompName <<" OK");
+ }
+ else
+ {
+ MESSAGE("Error in importing Python component : " << aCompName);
+ ret = false;
+ }
+ }
+ _numInstanceMutex.unlock();
+ }
+
+ // Call load_component_Library in each node
+ if (ret)
+ {
+ for (CORBA::ULong i = 0; i < _infos.nodes.length(); i++)
+ {
+ MESSAGE("Call load_component_Library work node : " << i);
+ CORBA::Object_var object = _orb->string_to_object(_infos.nodes[i]);
+ Engines::Container_var node = Engines::Container::_narrow(object);
+ if (!CORBA::is_nil(node))
+ {
+ char* reason;
+ try
+ {
+ node->load_component_Library(componentName,reason);
+ MESSAGE("Call load_component_Library done node : " << i);
+ CORBA::string_free(reason);
+ }
+ catch (...)
+ {
+ INFOS("Exception catch during load_component_Library of node : " << i);
+ CORBA::string_free(reason);
+ ret = false;
+ }
+ }
+ else
+ {
+ INFOS("Cannot call load_component_Library node " << i << " ref is nil !");
+ ret = false;
+ }
+ }
+ }
+
+ // If ret is false -> lib is not loaded !
+ if (!ret)
+ {
+ INFOS("Cannot call load_component_Library " << aCompName);
+ _libtype_map.erase(aCompName);
+ }
+ return ret;
+}
+
+Engines::EngineComponent_ptr
+Container_proxy_impl_final::create_component_instance(const char* componentName)
+{
+ Engines::FieldsDict_var env = new Engines::FieldsDict;
+ char* reason;
+ Engines::EngineComponent_ptr compo = create_component_instance_env(componentName, env, reason);
+ CORBA::string_free(reason);
+ return compo;
+}
+
+// Il y a deux cas :
+// Composant sequentiel -> on le créer sur le noeud 0 (on pourrait faire une répartition de charge)
+// Composant parallèle -> création du proxy ici puis appel de la création de chaque objet participant
+// au composant parallèle
+Engines::EngineComponent_ptr
+Container_proxy_impl_final::create_component_instance_env(const char* componentName,
+ const Engines::FieldsDict& env, CORBA::String_out reason)
+{
+ reason=CORBA::string_dup("");
+
+ std::string aCompName = componentName;
+ if (_libtype_map.count(aCompName) == 0)
+ {
+ // Component is not loaded !
+ INFOS("Proxy: component is not loaded ! : " << aCompName);
+ return Engines::EngineComponent::_nil();
+ }
+
+ // If it is a sequential component
+ if (_libtype_map[aCompName] == "seq")
+ {
+ _numInstanceMutex.lock(); // lock on the instance number
+ _numInstance++;
+ _numInstanceMutex.unlock();
+ Engines::PACO_Container_proxy_impl::updateInstanceNumber();
+ return Engines::Container_proxy_impl::create_component_instance(componentName);
+ }
+
+ // Parallel Component !
+ Engines::EngineComponent_var component_proxy = Engines::EngineComponent::_nil();
+
+ // On commence par créer le proxy
+#ifndef WIN32
+#ifdef __APPLE__
+ std::string impl_name = string ("lib") + aCompName + string("Engine.dylib");
+#else
+ std::string impl_name = string ("lib") + aCompName + string("Engine.so");
+#endif
+#else
+ std::string impl_name = aCompName + string("Engine.dll");
+#endif
+ void* handle = _library_map[impl_name];
+ std::string factory_name = aCompName + std::string("EngineProxy_factory");
+
+ MESSAGE("Creating component proxy : " << factory_name);
+ FACTORY_FUNCTION component_proxy_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+
+ if (!component_proxy_factory)
+ {
+ INFOS("Can't resolve symbol: " + factory_name);
+#ifndef WIN32
+ INFOS("dlerror() result is : " << dlerror());
+#endif
+ return Engines::EngineComponent::_nil() ;
+ }
+ try {
+ _numInstanceMutex.lock() ; // lock on the instance number
+ _numInstance++ ;
+ int numInstance = _numInstance ;
+ _numInstanceMutex.unlock() ;
+
+ char aNumI[12];
+ sprintf( aNumI , "%d" , numInstance ) ;
+ string instanceName = aCompName + "_inst_" + aNumI ;
+ string component_registerName = _containerName + "/" + instanceName;
+
+ // --- Instantiate required CORBA object
+ Container_proxy_impl_final::proxy_object * proxy = new Container_proxy_impl_final::proxy_object();
+
+ proxy->proxy_id = (component_proxy_factory) (_orb,
+ _fab_thread,
+ _poa,
+ _id,
+ &(proxy->proxy_regist),
+ instanceName.c_str(),
+ _parallel_object_topology.total);
+
+ // --- get reference from id
+ CORBA::Object_var obj = _poa->id_to_reference(*(proxy->proxy_id));
+ component_proxy = Engines::EngineComponent::_narrow(obj);
+ proxy->proxy_corba_ref = component_proxy;
+
+ if (!CORBA::is_nil(component_proxy))
+ {
+ _cntInstances_map[impl_name] += 1;
+ _par_obj_inst_list.push_back(*proxy);
+ delete proxy;
+
+ // --- register the engine under the name
+ // containerName(.dir)/instanceName(.object)
+ _NS->Register(component_proxy , component_registerName.c_str()) ;
+ MESSAGE(component_registerName.c_str() << " bound" ) ;
+ }
+ else
+ {
+ INFOS("The factory returns a nil object !");
+ return Engines::EngineComponent::_nil();
+ }
+
+ }
+ catch (...)
+ {
+ INFOS( "Exception caught in Proxy creation" );
+ return Engines::EngineComponent::_nil();
+ }
+
+ // Create on each node a work node
+ for (CORBA::ULong i = 0; i < _infos.nodes.length(); i++)
+ {
+ MESSAGE("Call create_paco_component_node_instance on work node : " << i);
+ CORBA::Object_var object = _orb->string_to_object(_infos.nodes[i]);
+ Engines::PACO_Container_var node = Engines::PACO_Container::_narrow(object);
+ if (!CORBA::is_nil(node))
+ {
+ try
+ {
+ node->create_paco_component_node_instance(componentName, _containerName.c_str());
+ MESSAGE("Call create_paco_component_node_instance done on node : " << i);
+ }
+ catch (SALOME::SALOME_Exception & ex)
+ {
+ INFOS("SALOME_EXCEPTION : " << ex.details.text);
+ return Engines::EngineComponent::_nil();
+ }
+ catch (...)
+ {
+ INFOS("Unknown Exception catch during create_paco_component_node_instance on node : " << i);
+ return Engines::EngineComponent::_nil();
+ }
+ }
+ else
+ {
+ INFOS("Cannot call create_paco_component_node_instance on node " << i << " ref is nil !");
+ return Engines::EngineComponent::_nil();
+ }
+ }
+
+ // Start Parallel object
+ PaCO::InterfaceManager_var paco_proxy = PaCO::InterfaceManager::_narrow(component_proxy);
+ paco_proxy->start();
+
+ return component_proxy;
+}