00001
00002
00003
00004 #include "orbsvcs/PortableGroup/PG_FactoryRegistry.h"
00005
00006 #include "ace/Get_Opt.h"
00007 #include "ace/Vector_T.h"
00008 #include "ace/OS_NS_stdio.h"
00009 #include "ace/OS_NS_unistd.h"
00010 #include "ace/Auto_Ptr.h"
00011 #include "tao/debug.h"
00012 #include "tao/ORB_Constants.h"
00013 #include "tao/PortableServer/POAManagerC.h"
00014 #include "orbsvcs/PortableGroup/PG_Operators.h"
00015
00016 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00017
00018
00019
00020 #define METHOD_ENTRY(name) \
00021 if (TAO_debug_level <= 6){} else \
00022 ACE_DEBUG (( LM_DEBUG, \
00023 "Enter %s\n", #name \
00024 ))
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define METHOD_RETURN(name) \
00038 if (TAO_debug_level <= 6){} else \
00039 ACE_DEBUG (( LM_DEBUG, \
00040 "Leave %s\n", #name \
00041 )); \
00042 return
00043
00044 TAO::PG_FactoryRegistry::PG_FactoryRegistry (const char * name)
00045 : identity_(name)
00046 , orb_ (0)
00047 , poa_ (0)
00048 , object_id_ (0)
00049 , this_obj_ (0)
00050 , ior_output_file_(0)
00051 , ns_name_(0)
00052 , naming_context_(0)
00053 , this_name_(1)
00054 , quit_on_idle_(0)
00055 , quit_state_(LIVE)
00056 , linger_(0)
00057 {
00058 }
00059
00060 TAO::PG_FactoryRegistry::~PG_FactoryRegistry (void)
00061 {
00062 }
00063
00064
00065
00066
00067 int TAO::PG_FactoryRegistry::parse_args (int argc, char * argv[])
00068 {
00069 ACE_Get_Opt get_opts (argc, argv, "o:n:q");
00070 int c;
00071
00072 while ((c = get_opts ()) != -1)
00073 {
00074 switch (c)
00075 {
00076 case 'o':
00077 {
00078 this->ior_output_file_ = get_opts.opt_arg ();
00079 break;
00080 }
00081 case 'n':
00082 {
00083 this->ns_name_ = get_opts.opt_arg();
00084 break;
00085 }
00086 case 'q':
00087 {
00088 this->quit_on_idle_ = 1;
00089 break;
00090 }
00091
00092 case '?':
00093
00094 default:
00095 ACE_ERROR_RETURN ((LM_ERROR,
00096 "usage: %s"
00097 " -o <registry ior file>"
00098 " -n <name to use to register with name service>"
00099 " -q{uit on idle}"
00100 "\n",
00101 argv [0]),
00102 -1);
00103 break;
00104 }
00105 }
00106
00107 return 0;
00108 }
00109
00110 const char * TAO::PG_FactoryRegistry::identity () const
00111 {
00112 return this->identity_.c_str();
00113 }
00114
00115 void TAO::PG_FactoryRegistry::_remove_ref (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00116 {
00117 this->quit_state_ = GONE;
00118 }
00119
00120 int TAO::PG_FactoryRegistry::idle (int & result ACE_ENV_ARG_DECL_NOT_USED)
00121 {
00122 result = 0;
00123 int quit = 0;
00124 if (this->quit_state_ == GONE)
00125 {
00126 if (linger_ < 2)
00127 {
00128 ++linger_;
00129 }
00130 else
00131 {
00132 quit = 1;
00133 }
00134 }
00135 return quit;
00136 }
00137
00138
00139 int TAO::PG_FactoryRegistry::fini (ACE_ENV_SINGLE_ARG_DECL)
00140 {
00141 if (this->ior_output_file_ != 0)
00142 {
00143 ACE_OS::unlink (this->ior_output_file_);
00144 this->ior_output_file_ = 0;
00145 }
00146 if (this->ns_name_ != 0)
00147 {
00148 this->naming_context_->unbind (this_name_
00149 ACE_ENV_ARG_PARAMETER);
00150 this->ns_name_ = 0;
00151 }
00152 return 0;
00153 }
00154
00155
00156 void TAO::PG_FactoryRegistry::init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ACE_ENV_ARG_DECL)
00157 {
00158 ACE_ASSERT (CORBA::is_nil (this->orb_.in ()));
00159 ACE_ASSERT (CORBA::is_nil (this->poa_.in ()));
00160 this->orb_ = CORBA::ORB::_duplicate (orb);
00161 this->poa_ = PortableServer::POA::_duplicate (poa);
00162 ACE_ASSERT ( ! CORBA::is_nil (this->orb_.in ()));
00163 ACE_ASSERT ( ! CORBA::is_nil (this->poa_.in ()));
00164
00165
00166 this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER);
00167 ACE_CHECK;
00168
00169
00170 this->this_obj_ =
00171 this->poa_->id_to_reference (object_id_.in ()
00172 ACE_ENV_ARG_PARAMETER);
00173 ACE_CHECK;
00174
00175
00176 this->ior_ = this->orb_->object_to_string (this->this_obj_.in ()
00177 ACE_ENV_ARG_PARAMETER);
00178 ACE_CHECK;
00179
00180 }
00181
00182 int TAO::PG_FactoryRegistry::init (CORBA::ORB_ptr orb
00183 ACE_ENV_ARG_DECL)
00184 {
00185 int result = 0;
00186
00187 this->orb_ = CORBA::ORB::_duplicate (orb);
00188
00189
00190 CORBA::Object_var poa_object =
00191 this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA
00192 ACE_ENV_ARG_PARAMETER);
00193 ACE_CHECK_RETURN (-1);
00194
00195 if (CORBA::is_nil (poa_object.in ()))
00196 ACE_ERROR_RETURN ((LM_ERROR,
00197 ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")),
00198 -1);
00199
00200
00201 this->poa_ =
00202 PortableServer::POA::_narrow (poa_object.in ()
00203 ACE_ENV_ARG_PARAMETER);
00204
00205 ACE_CHECK_RETURN (-1);
00206
00207 if (CORBA::is_nil (this->poa_.in()))
00208 {
00209 ACE_ERROR_RETURN ((LM_ERROR,
00210 ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")),
00211 -1);
00212 }
00213
00214 PortableServer::POAManager_var poa_manager =
00215 this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
00216 ACE_CHECK_RETURN(-1);
00217
00218 poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
00219 ACE_CHECK_RETURN(-1);
00220
00221
00222 this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER);
00223 ACE_CHECK_RETURN(-1);
00224
00225
00226 this->this_obj_ =
00227 this->poa_->id_to_reference (object_id_.in ()
00228 ACE_ENV_ARG_PARAMETER);
00229 ACE_CHECK_RETURN(-1);
00230
00231
00232
00233 this->ior_ = this->orb_->object_to_string (this->this_obj_.in ()
00234 ACE_ENV_ARG_PARAMETER);
00235 ACE_CHECK_RETURN(-1);
00236
00237
00238 if (this->ior_output_file_ != 0)
00239 {
00240 this->identity_ = "file:";
00241 this->identity_ += this->ior_output_file_;
00242 result = write_ior_file (this->ior_output_file_,
00243 this->ior_.in ());
00244 }
00245
00246 if (this->ns_name_ != 0)
00247 {
00248 this->identity_ = "name:";
00249 this->identity_ += this->ns_name_;
00250
00251 CORBA::Object_var naming_obj =
00252 this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER);
00253 ACE_CHECK_RETURN(-1);
00254
00255 if (CORBA::is_nil(naming_obj.in ())){
00256 ACE_ERROR_RETURN ((LM_ERROR,
00257 "%T %n (%P|%t) Unable to find the Naming Service\n"),
00258 1);
00259 }
00260
00261 this->naming_context_ =
00262 CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER);
00263 ACE_CHECK_RETURN(-1);
00264
00265 this->this_name_.length (1);
00266 this->this_name_[0].id = CORBA::string_dup (this->ns_name_);
00267
00268 this->naming_context_->rebind (this->this_name_, this->this_obj_.in()
00269 ACE_ENV_ARG_PARAMETER);
00270 ACE_CHECK_RETURN(-1);
00271 }
00272
00273 return result;
00274 }
00275
00276
00277 ::PortableGroup::FactoryRegistry_ptr TAO::PG_FactoryRegistry::reference()
00278 {
00279
00280 return ::PortableGroup::FactoryRegistry::_narrow(this->this_obj_.in ());
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 TAO::PG_FactoryRegistry::RoleInfo::RoleInfo(size_t estimated_number_entries)
00299 : infos_(estimated_number_entries)
00300 {
00301 }
00302
00303
00304 void TAO::PG_FactoryRegistry::register_factory (
00305 const char * role,
00306 const char * type_id,
00307 const PortableGroup::FactoryInfo & factory_info
00308 ACE_ENV_ARG_DECL
00309 )
00310 ACE_THROW_SPEC ((
00311 CORBA::SystemException
00312 , PortableGroup::MemberAlreadyPresent
00313 , PortableGroup::TypeConflict))
00314 {
00315 METHOD_ENTRY(TAO::PG_FactoryRegistry::register_factory);
00316
00317 RoleInfo * role_info = 0;
00318 auto_ptr<RoleInfo> safe_entry;
00319 if (this->registry_.find(role, role_info) != 0)
00320 {
00321 ACE_DEBUG(( LM_DEBUG,
00322 "%s: adding new role: %s:%s\n",
00323 this->identity_.c_str(), role, type_id));
00324
00325
00326
00327
00328 ACE_NEW_THROW_EX (role_info,
00329 RoleInfo(5),
00330 CORBA::NO_MEMORY());
00331 ACE_CHECK;
00332
00333 ACE_AUTO_PTR_RESET (safe_entry, role_info, RoleInfo);
00334 role_info->type_id_ = type_id;
00335 }
00336 else
00337 {
00338 if (role_info->type_id_ != type_id)
00339 {
00340 ACE_THROW ( PortableGroup::TypeConflict() );
00341 }
00342 }
00343
00344 PortableGroup::FactoryInfos & infos = role_info->infos_;;
00345 size_t length = infos.length();
00346 for (size_t nInfo = 0; nInfo < length; ++nInfo)
00347 {
00348 PortableGroup::FactoryInfo & info = infos[nInfo];
00349 if (info.the_location == factory_info.the_location)
00350 {
00351 ACE_ERROR(( LM_ERROR,
00352 "%s: Attempt to register duplicate location %s for role: %s\n" ,
00353 this->identity_.c_str(),
00354 static_cast<const char *> (info.the_location[0].id),
00355 role));
00356 ACE_THROW (PortableGroup::MemberAlreadyPresent() );
00357 }
00358 }
00359
00360 infos.length(length + 1);
00361 infos[length] = factory_info;
00362
00363 if (safe_entry.get() != 0)
00364 {
00365 this->registry_.bind(role, safe_entry.release());
00366 }
00367
00368 ACE_DEBUG(( LM_DEBUG,
00369 "%s: Added factory: [%d] %s@%s \n",
00370 this->identity_.c_str(),
00371 static_cast<int> (length + 1),
00372 role,
00373 static_cast<const char *> (factory_info.the_location[0].id)
00374 ));
00375
00376 METHOD_RETURN(TAO::PG_FactoryRegistry::register_factory);
00377 }
00378
00379 void TAO::PG_FactoryRegistry::unregister_factory (
00380 const char * role,
00381 const PortableGroup::Location & location
00382 ACE_ENV_ARG_DECL
00383 )
00384 ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberNotFound))
00385 {
00386 METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory);
00387
00388 RoleInfo * role_info = 0;
00389 if (this->registry_.find(role, role_info) == 0)
00390 {
00391 PortableGroup::FactoryInfos & infos = role_info->infos_;
00392 int found = 0;
00393 size_t length = infos.length();
00394 for (size_t nInfo = 0; !found && nInfo < length; ++nInfo)
00395 {
00396 PortableGroup::FactoryInfo & info = infos[nInfo];
00397 if (info.the_location == location)
00398 {
00399 found = 1;
00400
00401 ACE_ERROR(( LM_INFO,
00402 "%s: Unregistering factory %s@%s\n",
00403 this->identity_.c_str(),
00404 role,
00405 static_cast<const char *> (location[0].id)
00406 ));
00407 if (length > 1)
00408 {
00409
00410 if (nInfo + 1 < length)
00411 {
00412
00413 infos[nInfo] = infos[length - 1];
00414 nInfo = length -1;
00415 }
00416 infos.length(nInfo);
00417 }
00418 else
00419 {
00420 ACE_ASSERT ( length == 1 );
00421 if (this->registry_.unbind (role) == 0)
00422 {
00423 ACE_DEBUG(( LM_INFO,
00424 "%s: No more factories registered for %s\n",
00425 this->identity_.c_str(),
00426 role
00427 ));
00428 delete role_info;
00429 }
00430 else
00431 {
00432 ACE_ERROR ((LM_ERROR,
00433 "%s: LOGIC ERROR AT " __FILE__ " (%d): Entry to be deleted disappeared\n",
00434 this->identity_.c_str(),
00435 __LINE__));
00436 }
00437 }
00438 }
00439 }
00440 }
00441 else
00442 {
00443 ACE_ERROR(( LM_ERROR,
00444 "%s, Attempt to unregister factory for unknown role %s\n",
00445 this->identity_.c_str(),
00446 role
00447 ));
00448 ACE_THROW ( PortableGroup::MemberNotFound() );
00449 }
00450
00451
00452
00453
00454 if (registry_.current_size() == 0 && quit_state_ == LIVE)
00455 {
00456 ACE_ERROR(( LM_INFO,
00457 "%s is idle\n",
00458 identity()
00459 ));
00460 if (quit_on_idle_)
00461 {
00462 this->poa_->deactivate_object (this->object_id_.in ()
00463 ACE_ENV_ARG_PARAMETER);
00464 quit_state_ = DEACTIVATED;
00465 }
00466 }
00467
00468 METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory);
00469 }
00470
00471 void TAO::PG_FactoryRegistry::unregister_factory_by_role (
00472 const char * role
00473 ACE_ENV_ARG_DECL
00474 )
00475 ACE_THROW_SPEC ((CORBA::SystemException))
00476 {
00477 METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory_by_role);
00478
00479 RoleInfo * role_info = 0;
00480 if (this->registry_.unbind(role, role_info) == 0)
00481 {
00482 ACE_DEBUG(( LM_DEBUG,
00483 "%s: Unregistering all factories for role %s\n",
00484 this->identity_.c_str(),
00485 role
00486 ));
00487
00488 delete role_info;
00489 }
00490 else
00491 {
00492 ACE_ERROR(( LM_INFO,
00493 "%s: Unregister_factory_by_role: unknown role: %s\n",
00494 this->identity_.c_str(),
00495 role
00496 ));
00497 }
00498
00499
00500
00501
00502 if (registry_.current_size() == 0 && quit_state_ == LIVE)
00503 {
00504 ACE_ERROR(( LM_INFO,
00505 "%s is idle\n",
00506 identity()
00507 ));
00508 if (quit_on_idle_)
00509 {
00510 this->poa_->deactivate_object (this->object_id_.in ()
00511 ACE_ENV_ARG_PARAMETER);
00512 quit_state_ = DEACTIVATED;
00513 }
00514 }
00515
00516 METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory_by_role);
00517 }
00518
00519 void TAO::PG_FactoryRegistry::unregister_factory_by_location (
00520 const PortableGroup::Location & location
00521 ACE_ENV_ARG_DECL
00522 )
00523 ACE_THROW_SPEC ((CORBA::SystemException))
00524 {
00525 METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory_by_location);
00526
00527
00528
00529 ACE_Vector<ACE_CString> emptyRoles;
00530
00531
00532 for (RegistryType_Iterator it = this->registry_.begin();
00533 it != this->registry_.end();
00534 ++it)
00535 {
00536 RegistryType_Entry & entry = *it;
00537 ACE_CString & role = entry.ext_id_;
00538 RoleInfo * role_info = entry.int_id_;
00539
00540 PortableGroup::FactoryInfos & infos = role_info->infos_;
00541
00542
00543 int found = 0;
00544 size_t length = infos.length();
00545 for (size_t nInfo = 0; !found && nInfo < length; ++nInfo)
00546 {
00547 PortableGroup::FactoryInfo & info = infos[nInfo];
00548 if (info.the_location == location)
00549 {
00550
00551 ACE_ERROR((LM_INFO,
00552 "%s: Unregister_factory_by_location: Removing: [%d] %s@%s\n",
00553 this->identity_.c_str(),
00554 static_cast<int> (nInfo),
00555 role.c_str(),
00556 static_cast<const char *> (location[0].id)
00557 ));
00558 found = 1;
00559 if (length > 1)
00560 {
00561 while (nInfo + 1 < length)
00562 {
00563 ACE_ERROR((LM_INFO,
00564 "%s: Unregister_factory_by_location: Move: [%d] %s to [%d]\n",
00565 this->identity_.c_str(),
00566 (int)nInfo + 1, role.c_str(), (int)nInfo
00567 ));
00568 infos[nInfo] = infos[nInfo + 1];
00569 nInfo += 1;
00570 }
00571 ACE_ERROR((LM_INFO,
00572 "%s: unregister_factory_by_location: New length [%d] %s\n",
00573 this->identity_.c_str(),
00574 (int)nInfo, role.c_str()
00575 ));
00576 infos.length(nInfo);
00577 }
00578 else
00579 {
00580 ACE_ERROR((LM_INFO,
00581 "%s: Removed all entries for %s\n",
00582 this->identity_.c_str(),
00583 role.c_str()
00584 ));
00585 ACE_ASSERT ( length == 1 );
00586
00587 emptyRoles.push_back(entry.ext_id_);
00588 }
00589 }
00590 }
00591 }
00592
00593
00594
00595 for (size_t nRole = 0; nRole < emptyRoles.size(); ++nRole)
00596 {
00597 ACE_ERROR((LM_INFO,
00598 "%s: Remove role %s\n",
00599 this->identity_.c_str(),
00600 emptyRoles[nRole].c_str()
00601 ));
00602 RoleInfo * role_info;
00603 if (this->registry_.unbind(emptyRoles[nRole], role_info) == 0)
00604 {
00605 delete role_info;
00606 }
00607 else
00608 {
00609 ACE_ERROR ((LM_ERROR,
00610 "%s: LOGIC ERROR AT " __FILE__ " (%d): Role to be deleted disappeared\n",
00611 this->identity_.c_str(),
00612 __LINE__));
00613 }
00614 }
00615
00616
00617 if (registry_.current_size() == 0 && quit_state_ == LIVE)
00618 {
00619 ACE_ERROR(( LM_INFO,
00620 "%s is idle\n",
00621 identity()
00622 ));
00623 if (quit_on_idle_)
00624 {
00625 this->poa_->deactivate_object (this->object_id_.in ()
00626 ACE_ENV_ARG_PARAMETER);
00627 quit_state_ = DEACTIVATED;
00628 }
00629 }
00630
00631 METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory_by_location);
00632 }
00633
00634 ::PortableGroup::FactoryInfos * TAO::PG_FactoryRegistry::list_factories_by_role (
00635 const char * role,
00636 CORBA::String_out type_id
00637 ACE_ENV_ARG_DECL
00638 )
00639 ACE_THROW_SPEC ((CORBA::SystemException))
00640 {
00641 METHOD_ENTRY(TAO::PG_FactoryRegistry::list_factories_by_role);
00642
00643
00644 PortableGroup::FactoryInfos_var result = 0;
00645 ACE_NEW_THROW_EX (result, ::PortableGroup::FactoryInfos(),
00646 CORBA::NO_MEMORY (TAO::VMCID, CORBA::COMPLETED_NO));
00647
00648 ACE_CHECK_RETURN (0);
00649
00650 RoleInfo * role_info = 0;
00651 if (this->registry_.find(role, role_info) == 0)
00652 {
00653 type_id = CORBA::string_dup(role_info->type_id_.c_str());
00654 (*result) = role_info->infos_;
00655 }
00656 else
00657 {
00658 type_id = CORBA::string_dup("");
00659 ACE_ERROR(( LM_INFO,
00660 "%s: list_factories_by_role: unknown role %s\n",
00661 this->identity_.c_str(),
00662 role
00663 ));
00664 }
00665 METHOD_RETURN(TAO::PG_FactoryRegistry::list_factories_by_role) result._retn();
00666 }
00667
00668 ::PortableGroup::FactoryInfos * TAO::PG_FactoryRegistry::list_factories_by_location (
00669 const PortableGroup::Location & location
00670 ACE_ENV_ARG_DECL
00671 )
00672 ACE_THROW_SPEC ((CORBA::SystemException))
00673 {
00674 METHOD_ENTRY(TAO::PG_FactoryRegistry::list_factories_by_location);
00675 ::PortableGroup::FactoryInfos_var result;
00676 ACE_NEW_THROW_EX (result, ::PortableGroup::FactoryInfos(this->registry_.current_size()),
00677 CORBA::NO_MEMORY (TAO::VMCID, CORBA::COMPLETED_NO));
00678
00679 ACE_CHECK_RETURN (0);
00680
00681 size_t result_length = 0;
00682
00683
00684 for (RegistryType_Iterator it = this->registry_.begin();
00685 it != this->registry_.end();
00686 ++it)
00687 {
00688 RegistryType_Entry & entry = *it;
00689 RoleInfo * role_info = entry.int_id_;
00690
00691 PortableGroup::FactoryInfos & found_infos = role_info->infos_;
00692
00693 int found = 0;
00694 size_t length = found_infos.length();
00695 for (size_t nInfo = 0; !found && nInfo < length; ++nInfo)
00696 {
00697 PortableGroup::FactoryInfo & info = found_infos[nInfo];
00698 if (info.the_location == location)
00699 {
00700 found = 1;
00701 result_length += 1;
00702 result->length(result_length);
00703 (*result)[result_length-1] = info;
00704 }
00705 }
00706 }
00707
00708 METHOD_RETURN(TAO::PG_FactoryRegistry::list_factories_by_location) result._retn();
00709 }
00710
00711
00712
00713
00714 int TAO::PG_FactoryRegistry::write_ior_file(const char * outputFile, const char * ior)
00715 {
00716 int result = -1;
00717 FILE* out = ACE_OS::fopen (outputFile, "w");
00718 if (out)
00719 {
00720 ACE_OS::fprintf (out, "%s", ior);
00721 ACE_OS::fclose (out);
00722 result = 0;
00723 }
00724 else
00725 {
00726 ACE_ERROR ((LM_ERROR,
00727 "Open failed for %s\n", outputFile
00728 ));
00729 }
00730 return result;
00731 }
00732
00733 TAO_END_VERSIONED_NAMESPACE_DECL