00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "ColCOWS_NodeServant.hh"
00029 #include "ColCOWS_Node.hh"
00030
00031 using namespace std;
00032
00033 __COLCOWS_BEGIN__
00034
00035
00036 const unsigned int RESOLVE_RETRY = 15;
00037
00038
00039 const unsigned int REGISTER_RETRY = 15;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 NodeServant::NodeServant()
00050 {
00051 COLCOWS_IN_DEBUG();
00052
00053 _my_node = new IdlNodeDesc;
00054 _local_workspace = new IdlWorkspaceDesc;
00055 _father_node = new IdlNodeDesc;
00056 _children_nodes = new IdlNodeDescSeq;
00057 _remote_workspaces = new IdlWorkspaceDescSeq;
00058
00059 pthread_mutex_init(&_children_mut, NULL);
00060 pthread_mutex_init(&_activation_mut, NULL);
00061 pthread_cond_init(&_activation_cond, NULL);
00062
00063 _ready = false;
00064 _auto_activation = false;
00065 _current_num_connection = NOT_CONNECTED;
00066
00067 COLCOWS_OUT_DEBUG();
00068 return;
00069 }
00070
00071
00072
00073 NodeServant::~NodeServant()
00074 {
00075 COLCOWS_IN_DEBUG();
00076
00077 try {
00078
00079
00080 if(! CORBA::is_nil( _colcows_pman ) ) {
00081 COLCOWS_DEBUG( dblTest, "Deactivate ColCOWS POA Manager");
00082 _colcows_pman->deactivate(true,true);
00083 }
00084
00085 if(! CORBA::is_nil( _naming_ctxt ) ) {
00086 COLCOWS_DEBUG( dblTest, "Unbind ColCOWS from Naming Service");
00087
00088 CosNaming::Name objectName;
00089 objectName.length(1);
00090 objectName[0].id = CORBA::string_dup(_local_workspace->ws_id);
00091 objectName[0].kind = CORBA::string_dup(_local_workspace->ws_kind);
00092
00093 try {
00094 _naming_ctxt->unbind(objectName);
00095 }
00096 catch(CosNaming::NamingContext::NotFound& ex) {
00097
00098 }
00099 }
00100 }
00101 catch( ... ) {
00102 cerr << "Service required is invalid [does not exist]." << endl;
00103 }
00104
00105 pthread_mutex_destroy(&_children_mut);
00106 pthread_mutex_destroy(&_activation_mut);
00107 pthread_cond_destroy(&_activation_cond);
00108
00109 COLCOWS_OUT_DEBUG();
00110 return;
00111 }
00112
00113
00114 NodeServant * NodeServant::New(const char* ws_id,
00115 const char* ws_kind,
00116 const char* node_kind,
00117 unsigned long num_node,
00118 unsigned long max_descendant,
00119 unsigned long nb_nodes,
00120 unsigned long num_father,
00121 CORBA::ORB_ptr orbp)
00122 {
00123 COLCOWS_IN_DEBUG();
00124
00125 NodeServant * new_node_servant = new NodeServant;
00126 new_node_servant->lockChildrenMutex();
00127 new_node_servant->lockActivationMutex();
00128
00129 try {
00130 CORBA::Object_var obj_ref;
00131
00132
00133 COLCOWS_ASSERT( ( !CORBA::is_nil( orbp ) ), "Got a nil ORB pointer.");
00134
00135 new_node_servant->_orbp = orbp;
00136
00137
00138 COLCOWS_DEBUG( dblTest, "Obtain a reference of the root POA");
00139 obj_ref = orbp->resolve_initial_references("RootPOA");
00140 new_node_servant->_root_poa = PortableServer::POA::_narrow(obj_ref);
00141
00142
00143 stringstream colcows_poa_name (stringstream::in | stringstream::out);
00144 colcows_poa_name << "ColCOWSPOA" << "_" << ws_id << "_" << ws_kind ;
00145
00146 try {
00147
00148 COLCOWS_DEBUG( dblTest, "Create the ColCOWS POA");
00149
00150 CORBA::PolicyList policies;
00151 policies.length(1);
00152 policies[0] = new_node_servant->_root_poa->create_lifespan_policy( PortableServer::PERSISTENT );
00153
00154 new_node_servant->_colcows_poa = new_node_servant->_root_poa->create_POA( colcows_poa_name.str().c_str(),
00155 PortableServer::POAManager::_nil(),
00156 policies );
00157 }
00158 catch ( ... ) {
00159 COLCOWS_DEBUG( dblTest, "Failed to create ColCOWS POA" << ", let' s try to find it ...");
00160 }
00161
00162 if( CORBA::is_nil( new_node_servant->_colcows_poa ) ) {
00163
00164 COLCOWS_DEBUG( dblTest, "Find the reference of the ColCOWS POA");
00165
00166 new_node_servant->_colcows_poa = new_node_servant->_root_poa->find_POA(colcows_poa_name.str().c_str(), false );
00167 }
00168
00169 COLCOWS_DEBUG( dblTest, "Activate new node servant in ColCOWS POA");
00170 new_node_servant->_colcows_poa->activate_object( new_node_servant );
00171
00172 COLCOWS_DEBUG( dblTest, "Get ColCOWS POA Manager");
00173 new_node_servant->_colcows_pman = new_node_servant->_colcows_poa->the_POAManager( );
00174
00175 COLCOWS_DEBUG( dblTest, "Activate ColCOWS POA Manager");
00176 new_node_servant->_colcows_pman->activate();
00177
00178
00179 COLCOWS_DEBUG( dblTest, "Obtain a reference of the Naming Service");
00180 try {
00181 obj_ref = orbp->resolve_initial_references("NameService");
00182 new_node_servant->_naming_ctxt = CosNaming::NamingContext::_narrow(obj_ref);
00183 }
00184 catch ( ... ) {
00185 COLCOWS_ERROR( "Failed to resolve NameService");
00186 }
00187 COLCOWS_DEBUG( dblTest, "Naming Service resolved!");
00188 COLCOWS_ASSERT( !(CORBA::is_nil( new_node_servant->_naming_ctxt )), "Failed to narrow the root naming context.");
00189
00190 new_node_servant->_my_node->node_kind = CORBA::string_dup(node_kind);
00191 new_node_servant->_my_node->num_node = num_node;
00192 new_node_servant->_my_node->max_descendant = max_descendant;
00193 new_node_servant->_my_node->activated = false;
00194 new_node_servant->_my_node->node_ref = new_node_servant->_this();
00195
00196 new_node_servant->_local_workspace->ws_id = CORBA::string_dup(ws_id);
00197 new_node_servant->_local_workspace->ws_kind = CORBA::string_dup(ws_kind);
00198 new_node_servant->_local_workspace->nb_nodes = nb_nodes;
00199 new_node_servant->_local_workspace->activated = false;
00200
00201
00202 if (num_node == 0) {
00203
00204 try {
00205
00206 CosNaming::Name objectName;
00207 objectName.length(1);
00208 objectName[0].id = CORBA::string_dup(ws_id);
00209 objectName[0].kind = CORBA::string_dup(ws_kind);
00210
00211 try {
00212 new_node_servant->_naming_ctxt->bind(objectName, new_node_servant->_this());
00213 }
00214 catch(CosNaming::NamingContext::AlreadyBound& ex) {
00215 COLCOWS_DEBUG( dblMajor, "Proxy must do a rebind on the Naming Service." );
00216 new_node_servant->_naming_ctxt->rebind(objectName, new_node_servant->_this());
00217 }
00218
00219 }
00220 catch(...) {
00221 COLCOWS_ERROR( "Cannot bind root proxy in the naming service." );
00222 }
00223
00224 COLCOWS_DEBUG( dblTest, "Object bind in the Naming Service!");
00225
00226 new_node_servant->_local_workspace->enter_node_ref = new_node_servant->_this();
00227
00228 new_node_servant->_registred_to_father = true;
00229 }
00230 else {
00231
00232 COLCOWS_DEBUG( dblTest, "Try to resolve object from the Naming Service");
00233 unsigned long retry = RESOLVE_RETRY;
00234
00235
00236 CosNaming::Name name;
00237 name.length(1);
00238 name[0].id = (const char*) CORBA::string_dup(ws_id);
00239 name[0].kind = (const char*) CORBA::string_dup(ws_kind);
00240
00241 while ( true ) {
00242 try {
00243 obj_ref = new_node_servant->_naming_ctxt->resolve(name);
00244
00245 if (( CORBA::is_nil( obj_ref ) == false ) && ( obj_ref->_non_existent() == false )) break;
00246
00247 }
00248 catch(CosNaming::NamingContext::NotFound& ex) {
00249 COLCOWS_DEBUG( dblWarning, "reference on " << ws_id << ":" << ws_kind <<" not found in naming service" );
00250 }
00251 catch(CORBA::TRANSIENT& ex) {
00252 COLCOWS_DEBUG( dblWarning, "reference on " << ws_id << ":" << ws_kind <<" raise TRANSIENT exception" );
00253 }
00254
00255 if ( --retry > 0) {
00256
00257 COLCOWS_DEBUG( dblWarning, "Keep trying " << retry << " chances left ..." );
00258 sleep(1);
00259 }
00260 else {
00261 COLCOWS_ERROR( "Cannot resolve reference on " << ws_id << ":" << ws_kind <<" (no more retry)" );
00262 }
00263 }
00264
00265 COLCOWS_DEBUG( dblTest, "Object resolved from the Naming Service!");
00266
00267 new_node_servant->_local_workspace->enter_node_ref = ColCOWS::NodeInterface::_narrow(obj_ref);
00268
00269 COLCOWS_ASSERT( !(CORBA::is_nil(new_node_servant->_local_workspace->enter_node_ref)),
00270 "Failed to narrow the enter node .");
00271
00272 COLCOWS_ASSERT( (num_father < num_node), "Father num is greater than node num");
00273 new_node_servant->_father_node->num_node = num_father;
00274 new_node_servant->_registred_to_father = false;
00275
00276
00277 new_node_servant->registerToFather( );
00278 }
00279
00280 }
00281 catch ( ... ) {
00282 COLCOWS_DEBUG( dblException, "Got a ColCOWS exception in constructor" );
00283 delete new_node_servant;
00284 throw;
00285 }
00286
00287 new_node_servant->unlockChildrenMutex();
00288 new_node_servant->unlockActivationMutex();
00289
00290 COLCOWS_OUT_DEBUG();
00291 return new_node_servant;
00292 }
00293
00294
00295
00296 bool NodeServant::registerToFather( unsigned long max_retry )
00297 {
00298 COLCOWS_IN_DEBUG();
00299
00300 unsigned long num_father = _father_node->num_node;
00301
00302 while (_registred_to_father == false) {
00303 COLCOWS_DEBUG( dblTest,"in while, ( max_retry = " << max_retry << " )");
00304
00305 try {
00306
00307
00308 IdlNodeDesc_var node_desc = new IdlNodeDesc;
00309 _local_workspace->enter_node_ref->getNode( num_father, node_desc.out());
00310 _father_node = node_desc;
00311
00312 if (!(CORBA::is_nil(_father_node->node_ref)) && !(_father_node->node_ref->_non_existent()))
00313 {
00314
00315 _father_node->node_ref->setChildNode(_my_node.in());
00316
00317 _registred_to_father = true;
00318 }
00319
00320 }
00321 catch (CorbaException & e) {
00322 if (e.kind == cstNotReadyException) {
00323 COLCOWS_DEBUG( dblException, "Got a NotReady exception when trying to register to father(set child wsnode).");
00324 }
00325 else {
00326 COLCOWS_DEBUG( dblException, "Got a ColCOWS exception when trying to register to father(set child wsnode).");
00327 throw;
00328 }
00329 }
00330 catch(CORBA::TRANSIENT& ex) {
00331 COLCOWS_DEBUG( dblException, "Got a TRANSIENT exception when trying to register to father(set child wsnode).");
00332 }
00333 catch(CORBA::COMM_FAILURE& ex) {
00334 COLCOWS_ERROR( "Got a COMM_FAILURE exception when trying to register to father(set child wsnode).");
00335 }
00336 catch (const CORBA::SystemException & e) {
00337 COLCOWS_ERROR( "Got a CORBA exception when trying to register to father(set child wsnode).");
00338 }
00339 catch ( ... ) {
00340 COLCOWS_ERROR( "Got an unknown exception when trying to register to father(set child wsnode).");
00341 }
00342
00343 if ((max_retry > 0) && (_registred_to_father == false)) {
00344 sleep(1);
00345 COLCOWS_DEBUG( dblWarning, "retrying registration.");
00346 max_retry --;
00347 }
00348 else
00349 break;
00350
00351 }
00352
00353 COLCOWS_OUT_DEBUG();
00354 return _registred_to_father;
00355 }
00356
00357
00358
00359 void NodeServant::activate( )
00360 {
00361 COLCOWS_IN_DEBUG();
00362
00363 COLCOWS_ASSERT( (!_my_node->activated), "Workspace Node is already activated." );
00364
00365 pthread_mutex_lock(&_activation_mut);
00366 pthread_mutex_lock(&_children_mut);
00367
00368 COLCOWS_ASSERT( registerToFather( REGISTER_RETRY ), "Cannot register the Workspace to his father." );
00369
00370
00371 unsigned long nb_descendants_activated = 0;
00372 for (unsigned long i = 0; ((i < _children_nodes->length()) && (_children_nodes[i].activated)); i++) {
00373 nb_descendants_activated += _children_nodes[i].max_descendant - _children_nodes[i].num_node + 1;
00374 }
00375
00376 pthread_mutex_unlock(&_children_mut);
00377
00378 bool ready_for_activation = (nb_descendants_activated == _my_node->max_descendant - _my_node->num_node);
00379
00380 COLCOWS_DEBUG(dblAccessory, "nb descendants activated " << nb_descendants_activated << " on " << ( _my_node->max_descendant - _my_node->num_node ) );
00381 COLCOWS_DEBUG(dblAccessory, "Is ready for activation ? " << ready_for_activation );
00382
00383
00384 if (ready_for_activation == false) {
00385
00386 COLCOWS_DEBUG(dblAccessory, "set auto_activation");
00387 _auto_activation = true;
00388
00389 }
00390 else{
00391
00392 _colcows_node->updateIdl(_my_node);
00393
00394 COLCOWS_DEBUG(dblAccessory, "Node is activated");
00395 _my_node->activated = true;
00396
00397
00398 _auto_activation = false;
00399
00400
00401 IdlNodeDesc_var wsnode = new IdlNodeDesc((const IdlNodeDesc) _my_node);
00402
00403 unsigned long current_child = wsnode->num_node + 1;
00404 unsigned long order_num_child = 0;
00405 wsnode->children_seq.length( _children_nodes->length() );
00406
00407 while (current_child <= wsnode->max_descendant) {
00408
00409 COLCOWS_ASSERT( (order_num_child < _children_nodes->length()), "Reaching the end of _children_nodes sequence.");
00410
00411 unsigned long num_child;
00412 for (num_child = 0;
00413 ( (num_child < _children_nodes->length())
00414 && (_children_nodes[num_child].num_node != current_child)) ;
00415 num_child++) { }
00416
00417
00418 COLCOWS_ASSERT( (num_child != _children_nodes->length()), "There is a hole in the descendants.");
00419
00420 IdlNodeDesc_var child_node = new IdlNodeDesc((const IdlNodeDesc) _children_nodes[num_child]);
00421
00422 wsnode->children_seq[order_num_child] = child_node;
00423
00424 current_child = _children_nodes[num_child].max_descendant + 1;
00425 order_num_child ++;
00426
00427 }
00428
00429
00430 if (_my_node->num_node != 0) {
00431
00432
00433 COLCOWS_DEBUG(dblAccessory, "Forwarding the activation to the father" );
00434 _father_node->node_ref->setChildNode(wsnode.in());
00435
00436 }
00437
00438 else {
00439
00440 _local_workspace->activated = true;
00441 _local_workspace->enter_node = wsnode;
00442
00443 unsigned long nb_children = _children_nodes->length();
00444
00445 for (unsigned long j = 0; j < nb_children ; j++)
00446 _children_nodes[j].node_ref->setWorkspace(_local_workspace.in());
00447
00448
00449 _colcows_node->onActivation( _local_workspace );
00450 }
00451 }
00452
00453 pthread_mutex_unlock(&_activation_mut);
00454
00455 COLCOWS_OUT_DEBUG();
00456 return ;
00457 }
00458
00459
00460
00461 void NodeServant::deactivate( )
00462 {
00463 COLCOWS_IN_DEBUG();
00464
00465 pthread_mutex_lock(&_activation_mut);
00466
00467
00468 _auto_activation = false;
00469
00470 _my_node->activated = false;
00471
00472
00473 if (_my_node->num_node != 0) {
00474 COLCOWS_DEBUG( dblAccessory, "forward the activation to the father node if any.");
00475
00476 _father_node->node_ref->setChildNode(_my_node.in());
00477 }
00478
00479 else {
00480 COLCOWS_DEBUG( dblAccessory, "The root propagate the deactivation of the WS to its children");
00481 _local_workspace->activated = false;
00482
00483 IdlNodeDesc_var wsnode = new IdlNodeDesc((const IdlNodeDesc) _my_node);
00484 _local_workspace->enter_node = wsnode;
00485
00486
00487 unsigned long nb_children = _children_nodes->length();
00488 for (unsigned long j = 0; j < nb_children; j++) {
00489 _children_nodes[j].node_ref->setWorkspace(_local_workspace);
00490 }
00491
00492
00493 _colcows_node->onDeactivation( _local_workspace );
00494 }
00495
00496 pthread_mutex_unlock(&_activation_mut);
00497
00498 COLCOWS_OUT_DEBUG();
00499 return ;
00500 }
00501
00502
00503
00504 unsigned long NodeServant::connect( const std::string & ws_id, const std::string & ws_kind, const std::string & nameservice_str )
00505 {
00506 COLCOWS_IN_DEBUG();
00507
00508 COLCOWS_ASSERT( ( _my_node->num_node == 0 ), "Only the proxy can connect" );
00509 COLCOWS_ASSERT( ( getNumConnection(ws_id.c_str(), ws_kind.c_str()) == NOT_CONNECTED ), "Already connected" );
00510 COLCOWS_ASSERT( isReady(), "Workspace not ready for connection" );
00511
00512 CosNaming::NamingContext_var naming_ctxt;
00513 if ( !nameservice_str.empty() )
00514 {
00515
00516 COLCOWS_DEBUG( dblTest, "Obtain a reference of the Naming Service");
00517 try {
00518 CORBA::Object_var obj_ref;
00519 obj_ref = _orbp->string_to_object( nameservice_str.c_str() );
00520 naming_ctxt = CosNaming::NamingContext::_narrow(obj_ref);
00521 }
00522 catch ( ... ) {
00523 THROW_CORBA_EXCEPTION( cstCorbaException, "Failed to resolve NameService");
00524 }
00525 }
00526 else
00527 {
00528 naming_ctxt = _naming_ctxt;
00529 }
00530
00531
00532 CORBA::Object_var obj_ref;
00533
00534 unsigned long retry = RESOLVE_RETRY;
00535
00536
00537 CosNaming::Name name;
00538 name.length(1);
00539 name[0].id = (const char*) CORBA::string_dup(ws_id.c_str());
00540 name[0].kind = (const char*) CORBA::string_dup(ws_kind.c_str());
00541
00542 while ( true ) {
00543 try {
00544 obj_ref = naming_ctxt->resolve(name);
00545
00546 if (( CORBA::is_nil( obj_ref ) == false ) && ( obj_ref->_non_existent() == false )) break;
00547
00548 }
00549 catch(CosNaming::NamingContext::NotFound& ex) {
00550 COLCOWS_DEBUG( dblWarning, "reference on " << ws_id << ":" << ws_kind <<" not found in naming service" );
00551 }
00552 catch(CORBA::TRANSIENT& ex) {
00553 COLCOWS_DEBUG( dblWarning, "reference on " << ws_id << ":" << ws_kind <<" raise TRANSIENT exception" );
00554 }
00555
00556 if ( --retry > 0) {
00557
00558 COLCOWS_DEBUG( dblWarning, "Keep trying " << retry << " chances left ..." );
00559 sleep(1);
00560 }
00561 else {
00562 THROW_CORBA_EXCEPTION( cstCorbaException,
00563 "Cannot resolve reference on " << ws_id << ":" << ws_kind <<" (no more retry)");
00564 }
00565 }
00566
00567 NodeInterface_var remote_node_servant = ColCOWS::NodeInterface::_narrow(obj_ref);
00568
00569 _current_num_connection++;
00570
00571 remote_node_servant->getCommonNumConnection( (CORBA::ULong&)_current_num_connection );
00572
00573
00574
00575
00576 IdlWorkspaceDesc_var remote_workspace ;
00577 remote_node_servant->getWorkspace(remote_workspace.out());
00578
00579 bool initiator = false;
00580 remote_node_servant->setRemoteWorkspace( _current_num_connection, _local_workspace.in(), initiator );
00581
00582 initiator = true;
00583 _local_workspace->enter_node_ref->setRemoteWorkspace( _current_num_connection, remote_workspace.in(), initiator );
00584
00585 COLCOWS_OUT_DEBUG();
00586 return getNumConnection(ws_id.c_str(), ws_kind.c_str());
00587 }
00588
00589
00590
00591
00592 void NodeServant::disconnect( unsigned long num_connection )
00593 {
00594 COLCOWS_IN_DEBUG();
00595
00596 COLCOWS_ASSERT( isConnected(num_connection), "Not connected" );
00597 long num_ws = indexConnection(num_connection);
00598 COLCOWS_ASSERT( num_ws != -1 , "Incoherent index value" );
00599
00600 _remote_workspaces[num_ws].enter_node_ref->releaseRemoteWorkspace( num_connection );
00601 _local_workspace->enter_node_ref->releaseRemoteWorkspace( num_connection );
00602
00603 COLCOWS_OUT_DEBUG();
00604 return ;
00605 }
00606
00607
00608
00609
00610 void NodeServant::disconnectAll( )
00611 {
00612 COLCOWS_IN_DEBUG();
00613
00614 long num_ws;
00615 unsigned long nb_ws = _remote_workspaces->length();
00616
00617 for (num_ws = nb_ws - 1 ; num_ws >= 0; num_ws--)
00618 {
00619 unsigned long num_connection = _remote_workspaces[num_ws].num_connection;
00620
00621 _remote_workspaces[num_ws].enter_node_ref->releaseRemoteWorkspace( num_connection );
00622 _local_workspace->enter_node_ref->releaseRemoteWorkspace( num_connection );
00623 }
00624
00625
00626 COLCOWS_OUT_DEBUG();
00627 return ;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637 void NodeServant::getNode(CORBA::ULong num_node, IdlNodeDesc_out node) throw (CorbaException)
00638
00639 {
00640 COLCOWS_IN_DEBUG();
00641 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00642
00643
00644 COLCOWS_ASSERT( (num_node >= 0), "Invalid node number");
00645
00646
00647 if (num_node == _my_node->num_node){
00648 node = new IdlNodeDesc((const IdlNodeDesc) _my_node);
00649 }
00650
00651 else if ((num_node > _my_node->num_node) && (num_node <= _my_node->max_descendant)) {
00652 unsigned long num_child;
00653
00654 for (num_child = 0;
00655 ( (num_child < _children_nodes->length())
00656 && ( (num_node < _children_nodes[num_child].num_node)
00657 || (num_node > _children_nodes[num_child].max_descendant) ) );
00658 num_child ++){}
00659
00660
00661 COLCOWS_ASSERT( (num_child != _children_nodes->length()), "Node " << num_node << " is not hold by any registred child.");
00662
00663
00664 if ((num_node == _children_nodes[num_child].num_node) && _children_nodes[num_child].activated) {
00665 node = new IdlNodeDesc((const IdlNodeDesc) _children_nodes[num_child]);
00666 }
00667
00668 else if ( !CORBA::is_nil(_children_nodes[num_child].node_ref)) {
00669 _children_nodes[num_child].node_ref->getNode(num_node, node);
00670 }
00671 else {
00672 THROW_CORBA_EXCEPTION( cstNotReadyException, "Node " << num_node << " is not hold by any registred child." );
00673 }
00674
00675 }
00676
00677 else if ((num_node < _my_node->num_node) || (num_node > _my_node->max_descendant)) {
00678 _father_node->node_ref->getNode(num_node, node);
00679 }
00680
00681 else {
00682 COLCOWS_ERROR( "Unexpected case !!!" );
00683 }
00684
00685 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00686 COLCOWS_OUT_DEBUG();
00687 return ;
00688 }
00689
00690
00691
00692
00693 void NodeServant::setChildNode(const IdlNodeDesc& node) throw (CorbaException)
00694
00695 {
00696 COLCOWS_IN_DEBUG();
00697 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00698
00699 COLCOWS_DEBUG( dblAccessory,"Set child " << node.num_node << " on node " << _my_node->num_node);
00700
00701 COLCOWS_ASSERT( ((node.max_descendant <= _my_node->max_descendant)&&(node.num_node > _my_node->num_node)),
00702 "Node " << node.num_node << " is not one of my descendants" );
00703
00704 pthread_mutex_lock(&_children_mut);
00705
00706 unsigned long num_child;
00707 bool trigger_activation = false;
00708 bool trigger_deactivation = false;
00709
00710
00711 for (num_child = 0;
00712 ( (num_child < _children_nodes->length())
00713 && ( (node.num_node != _children_nodes[num_child].num_node)
00714 || (node.max_descendant != _children_nodes[num_child].max_descendant) ) );
00715 num_child ++){}
00716
00717
00718
00719 if(num_child == _children_nodes->length()) {
00720
00721
00722 for (num_child = 0;
00723 ( (num_child < _children_nodes->length())
00724 && ( (node.max_descendant < _children_nodes[num_child].num_node)
00725 || (node.num_node > _children_nodes[num_child].max_descendant) ) );
00726 num_child ++){}
00727
00728
00729 COLCOWS_ASSERT( (num_child >= _children_nodes->length()),"Node " << num_child << " can't be inserted" );
00730
00731
00732 _children_nodes->length(num_child+1);
00733
00734 if (node.activated) {
00735 COLCOWS_DEBUG( dblAccessory, "Child " << node.num_node << " has been added (activated)" );
00736 trigger_activation = true;
00737 }
00738 else {
00739 COLCOWS_DEBUG( dblAccessory, "Child " << node.num_node << " has been added (not activated)" );
00740 }
00741 }
00742
00743 else {
00744 if ((! _children_nodes[num_child].activated) && ( node.activated)) {
00745 COLCOWS_DEBUG( dblAccessory, "Child " << node.num_node << " is now activated" );
00746 trigger_activation = true;
00747 }
00748 else if (( _children_nodes[num_child].activated) && (! node.activated)) {
00749 COLCOWS_DEBUG( dblAccessory, "Child " << node.num_node << " is no more activated" );
00750 trigger_deactivation = true;
00751 }
00752 else if (( _children_nodes[num_child].activated) && ( node.activated)) {
00753 COLCOWS_ERROR( "Child " << node.num_node << " already activated" );
00754 }
00755 }
00756
00757
00758 IdlNodeDesc_var node_tmp = new IdlNodeDesc((const IdlNodeDesc) node);
00759 _children_nodes[num_child] = node_tmp;
00760
00761 pthread_mutex_unlock(&_children_mut);
00762
00763 if ((trigger_activation) && (! _my_node->activated) && (_auto_activation == true))
00764 activate();
00765 else if ((trigger_deactivation) && (_my_node->activated))
00766 deactivate();
00767
00768 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00769 COLCOWS_OUT_DEBUG();
00770 return ;
00771
00772 }
00773
00774
00775
00776 CORBA::Boolean NodeServant::isActivated() throw (CorbaException)
00777
00778 {
00779 COLCOWS_IN_DEBUG();
00780
00781 COLCOWS_OUT_DEBUG();
00782 return _local_workspace->activated;
00783 }
00784
00785
00786
00787 CORBA::Boolean NodeServant::isReady() throw (CorbaException)
00788
00789 {
00790 COLCOWS_IN_DEBUG();
00791
00792 COLCOWS_OUT_DEBUG();
00793
00794 return _local_workspace->activated;
00795 }
00796
00797
00798
00799 long NodeServant::indexConnection( CORBA::ULong num_connection )
00800 {
00801 COLCOWS_IN_DEBUG();
00802
00803 long index = -1;
00804
00805 unsigned long num_ws;
00806 for (num_ws = 0; num_ws < _remote_workspaces->length(); num_ws++)
00807 {
00808 if ( num_connection = _remote_workspaces[num_ws].num_connection )
00809 {
00810 index = num_ws;
00811 break;
00812 }
00813 }
00814
00815 COLCOWS_OUT_DEBUG();
00816 return index;
00817 }
00818
00819
00820
00821 CORBA::Boolean NodeServant::isConnected( CORBA::ULong num_connection ) throw (CorbaException)
00822
00823 {
00824 COLCOWS_IN_DEBUG();
00825
00826 COLCOWS_OUT_DEBUG();
00827 return (indexConnection(num_connection) != -1 );
00828 }
00829
00830
00831
00832
00833 CORBA::ULong NodeServant::getNumConnection( const char* ws_id, const char * ws_kind ) throw (CorbaException)
00834 {
00835 COLCOWS_IN_DEBUG();
00836
00837 CORBA::ULong num_connection = NOT_CONNECTED;
00838
00839 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00840
00841 unsigned long num_ws;
00842 for (num_ws = 0; num_ws < _remote_workspaces->length(); num_ws++)
00843 {
00844 if ( (strcmp(ws_id,_remote_workspaces[num_ws].ws_id) == 0)
00845 && (strcmp(ws_kind,_remote_workspaces[num_ws].ws_kind) == 0))
00846 {
00847 num_connection = _remote_workspaces[num_ws].num_connection;
00848 break;
00849 }
00850 }
00851
00852 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00853 COLCOWS_OUT_DEBUG();
00854 return num_connection;
00855 }
00856
00857
00858
00859 void NodeServant::getCommonNumConnection( CORBA::ULong & num_connection ) throw (CorbaException)
00860 {
00861 COLCOWS_IN_DEBUG();
00862 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00863
00864 COLCOWS_ASSERT( ( _my_node->num_node == 0 ), "Only the proxy can assign a new number of connection" );
00865
00866 if (_my_node->num_node == 0) {
00867
00868 if ( num_connection <= _current_num_connection) {
00869 ++_current_num_connection;
00870 num_connection = _current_num_connection;
00871 COLCOWS_DEBUG( dblAccessory, "num_connection = " << num_connection);
00872 }
00873 else {
00874 _current_num_connection = num_connection;
00875 COLCOWS_DEBUG( dblAccessory, "num_connection = " << num_connection);
00876 }
00877
00878 }
00879 else {
00880 COLCOWS_DEBUG( dblWarning, "Should not call getNewNumConnection on a non-root node ..." );
00881 return;
00882 }
00883
00884 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00885 COLCOWS_OUT_DEBUG();
00886 return;
00887 }
00888
00889
00890
00891
00892 void NodeServant::getWorkspace(IdlWorkspaceDesc_out ws_desc) throw (CorbaException)
00893 {
00894 COLCOWS_IN_DEBUG();
00895 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00896
00897 COLCOWS_ASSERT((_local_workspace->activated ), "Node is not activated" );
00898
00899 ws_desc = new IdlWorkspaceDesc((const IdlWorkspaceDesc)_local_workspace);
00900
00901 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00902 COLCOWS_OUT_DEBUG();
00903 return ;
00904 }
00905
00906
00907
00908
00909 void NodeServant::setWorkspace(const IdlWorkspaceDesc& ws_desc)
00910 {
00911 COLCOWS_IN_DEBUG();
00912 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00913
00914 bool new_activation=false;
00915 bool new_deactivation=false;
00916
00917 if ((! _local_workspace->activated) && ( ws_desc.activated)) { new_activation=true; }
00918 else if (( _local_workspace->activated) && (! ws_desc.activated)) { new_deactivation=true; }
00919 else if ((! _local_workspace->activated) && (! ws_desc.activated)) { }
00920 else
00921 { COLCOWS_ERROR( "Workspace already activated" ); }
00922
00923
00924 _local_workspace = new IdlWorkspaceDesc((const IdlWorkspaceDesc) ws_desc);
00925
00926
00927
00928 unsigned long nb_children = _children_nodes->length();
00929 for (unsigned long j = 0; j < nb_children; j++) {
00930 _children_nodes[j].node_ref->setWorkspace(ws_desc);
00931 }
00932
00933
00934 if ( new_activation == true )
00935 _colcows_node->onActivation( _local_workspace );
00936 else if ( new_deactivation == true )
00937 _colcows_node->onDeactivation( _local_workspace );
00938
00939 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00940 COLCOWS_OUT_DEBUG();
00941 return ;
00942 }
00943
00944
00945
00946
00947 void NodeServant::getRemoteWorkspace(CORBA::ULong num_connection, IdlWorkspaceDesc_out ws_desc) throw (CorbaException)
00948 {
00949 COLCOWS_IN_DEBUG();
00950 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00951
00952 bool is_local = false;
00953
00954 unsigned long num_ws;
00955 for (num_ws = 0; num_ws < _remote_workspaces->length(); num_ws++)
00956 {
00957 if ( _remote_workspaces[num_ws].num_connection == num_connection )
00958 {
00959 ws_desc = new IdlWorkspaceDesc ((const IdlWorkspaceDesc)_remote_workspaces[num_ws]);
00960 is_local = true;
00961 break;
00962 }
00963 }
00964
00965
00966 if (is_local == true) {
00967
00968 }
00969 else {
00970 COLCOWS_ERROR( "Remote Workspace is not connected." );
00971 }
00972
00973 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00974 COLCOWS_OUT_DEBUG();
00975 return ;
00976 }
00977
00978
00979
00980
00981 void NodeServant::setRemoteWorkspace( CORBA::ULong num_connection,
00982 const IdlWorkspaceDesc& ws_desc,
00983 CORBA::Boolean connection_initiator)
00984 {
00985 COLCOWS_IN_DEBUG();
00986 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
00987
00988 unsigned long num_ws;
00989 for (num_ws = 0; num_ws < _remote_workspaces->length(); num_ws++)
00990 {
00991 if ( _remote_workspaces[num_ws].num_connection == num_connection )
00992 {
00993 break;
00994 }
00995 }
00996
00997 COLCOWS_ASSERT( (num_ws == _remote_workspaces->length()),
00998 "The connection already exists." );
00999
01000 _remote_workspaces->length(num_ws+1);
01001
01002 IdlWorkspaceDesc_var new_ws_desc = new IdlWorkspaceDesc ((const IdlWorkspaceDesc) ws_desc);
01003 new_ws_desc->num_connection = num_connection;
01004 _remote_workspaces[num_ws] = new_ws_desc;
01005
01006
01007 _colcows_node->onConnection( num_connection, new_ws_desc, connection_initiator );
01008
01009 unsigned long nb_children = _children_nodes->length();
01010
01011 for (unsigned long j = 0; j < nb_children; j++) {
01012 _children_nodes[j].node_ref->setRemoteWorkspace(num_connection, new_ws_desc, connection_initiator);
01013 }
01014
01015 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
01016 COLCOWS_OUT_DEBUG();
01017 return ;
01018 }
01019
01020
01021
01022
01023 void NodeServant::releaseRemoteWorkspace(CORBA::ULong num_connection )
01024 {
01025 COLCOWS_IN_DEBUG();
01026 __BEGIN_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
01027
01028 unsigned long num_ws;
01029 unsigned long nb_ws = _remote_workspaces->length();
01030 for (num_ws = 0; num_ws < nb_ws; num_ws++)
01031 {
01032 if ( _remote_workspaces[num_ws].num_connection == num_connection )
01033 {
01034 break;
01035 }
01036 }
01037
01038 if (num_ws != nb_ws) {
01039
01040 if (num_ws != nb_ws - 1) {
01041
01042 _remote_workspaces[num_ws] = _remote_workspaces[nb_ws - 1];
01043 }
01044
01045 _remote_workspaces->length(nb_ws-1);
01046
01047
01048 _colcows_node->onDisconnection( num_connection );
01049
01050 unsigned long nb_children = _children_nodes->length();
01051
01052
01053 for (unsigned long j = 0; j < nb_children; j++) {
01054 _children_nodes[j].node_ref->releaseRemoteWorkspace(num_connection);
01055 }
01056
01057 }
01058 else
01059 COLCOWS_ASSERT( dblWarning, "Cannot find connection ..."
01060 << "The connection " << num_connection << " may have been already disconnected." );
01061
01062
01063 __END_REDIRECT_ALL_EXCEPTIONS_TO_CORBA__
01064 COLCOWS_OUT_DEBUG();
01065 return ;
01066 }
01067
01068
01069
01070 void NodeServant::printself(ostream & stream) const
01071 {
01072 stream << "IdlNodeDesc : " << _my_node << endl;
01073 stream << "IdlWorkspaceDesc : " << _local_workspace << endl;
01074 stream << "IdlWorkspaceDescSeq : " << _remote_workspaces << endl;
01075 }
01076
01077
01078
01079 ostream& operator <<(ostream& stream, const NodeServant & _this)
01080 {
01081 stream << "Node {" << flush;
01082 _this.printself(stream);
01083 stream << "}" << flush;
01084 return stream;
01085 }
01086
01087
01088
01089
01090 std::ostream& operator <<(std::ostream& stream, const IdlWorkspaceDesc& wsdesc)
01091 {
01092 stream << endl;
01093 stream << "( ws_id : " << wsdesc.ws_id << flush;
01094 stream << endl;
01095 stream << "( ws_kind : " << wsdesc.ws_kind << flush;
01096 stream << endl;
01097 stream << ", nb_nodes : " << wsdesc.nb_nodes << flush;
01098 stream << endl;
01099 stream << ", activated : " << wsdesc.activated << flush;
01100 stream << endl;
01101 stream << ", enter_node_ref : " << "..." << flush;
01102 stream << " )" << flush;
01103 return stream;
01104 }
01105
01106
01107
01108 std::ostream& operator <<(std::ostream& stream, const IdlWorkspaceDescSeq& wsdesc_seq)
01109 {
01110 stream << "{" << flush;
01111 for (unsigned long i = 0; i < wsdesc_seq.length(); i++) {
01112 stream << endl;
01113 stream << " " << wsdesc_seq[i] << flush;
01114 }
01115 stream << " }" << flush;
01116 return stream;
01117 }
01118
01119
01120
01121 std::ostream& operator <<(std::ostream& stream, const IdlNodeDesc& wsnode)
01122 {
01123 stream << endl << "(" << flush;
01124 stream << " node_kind : " << wsnode.node_kind << flush;
01125 stream << endl;
01126 stream << ", num_node : " << wsnode.num_node << flush;
01127 stream << endl;
01128 stream << ", max_descendant : " << wsnode.max_descendant << flush;
01129 stream << endl;
01130 stream << ", activated : " << wsnode.activated << flush;
01131 stream << endl;
01132 stream << ", node : " << "..." << flush;
01133 stream << endl;
01134 stream << ", ref_seq : " << wsnode.ref_seq << flush;
01135 stream << " )" << flush;
01136 return stream;
01137 }
01138
01139
01140
01141 std::ostream& operator <<(std::ostream& stream, const IdlNodeDescSeq& wsnode_seq)
01142 {
01143 stream << "{" << flush;
01144 for (unsigned long i = 0; i < wsnode_seq.length(); i++) {
01145 stream << endl;
01146 stream << " " << wsnode_seq[i] << flush;
01147 }
01148 stream << " }" << flush;
01149 return stream;
01150 }
01151
01152
01153
01154 std::ostream& operator <<(std::ostream& stream, const IdlObjectDesc& ref)
01155 {
01156
01157 stream << "( obj_id : " << ref.obj_id << flush;
01158 stream << ", obj_kind : " << ref.obj_kind << flush;
01159 stream << ", obj_ref : " << "..." << flush;
01160 stream << " )" << flush;
01161 return stream;
01162 }
01163
01164
01165
01166 std::ostream& operator <<(std::ostream& stream, const IdlObjectDescSeq& ref_seq)
01167 {
01168 stream << "{" << flush;
01169 for (unsigned long i = 0; i < ref_seq.length(); i++)
01170 stream << " " << ref_seq[i] << flush;
01171 stream << " }" << flush;
01172 return stream;
01173 }
01174
01175
01176
01177 __COLCOWS_END__
01178
01179