00001 #include "orbsvcs/PortableGroup/PG_GenericFactory.h"
00002 #include "orbsvcs/PortableGroup/PG_MemberInfo.h"
00003 #include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h"
00004 #include "orbsvcs/PortableGroup/PG_PropertyManager.h"
00005 #include "orbsvcs/PortableGroup/PG_Property_Utils.h"
00006 #include "orbsvcs/PortableGroup/PG_conf.h"
00007
00008 #include "ace/OS_NS_stdio.h"
00009
00010 #include "tao/ORB_Constants.h"
00011
00012 ACE_RCSID (PortableGroup,
00013 PG_GenericFactory,
00014 "PG_GenericFactory.cpp,v 1.26 2006/03/14 06:14:34 jtc Exp")
00015
00016
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018
00019 TAO_PG_GenericFactory::TAO_PG_GenericFactory (
00020 TAO_PG_ObjectGroupManager & object_group_manager,
00021 TAO_PG_PropertyManager & property_manager)
00022 : poa_ (),
00023 object_group_manager_ (object_group_manager),
00024 property_manager_ (property_manager),
00025 factory_map_ (TAO_PG_MAX_OBJECT_GROUPS),
00026 next_fcid_ (0),
00027 lock_ ()
00028 {
00029 this->object_group_manager_.generic_factory (this);
00030 }
00031
00032 TAO_PG_GenericFactory::~TAO_PG_GenericFactory (void)
00033 {
00034 ACE_DECLARE_NEW_CORBA_ENV;
00035
00036 TAO_PG_Factory_Map::iterator end = this->factory_map_.end ();
00037 for (TAO_PG_Factory_Map::iterator i = this->factory_map_.begin ();
00038 i != end;
00039 ++i)
00040 {
00041 TAO_PG_Factory_Set & factory_set = (*i).int_id_;
00042
00043 ACE_TRY
00044 {
00045 this->delete_object_i (factory_set,
00046 1
00047 ACE_ENV_ARG_PARAMETER);
00048 ACE_TRY_CHECK;
00049 }
00050 ACE_CATCHANY
00051 {
00052
00053 }
00054 ACE_ENDTRY;
00055 }
00056
00057 (void) this->factory_map_.close ();
00058 }
00059
00060 CORBA::Object_ptr
00061 TAO_PG_GenericFactory::create_object (
00062 const char * type_id,
00063 const PortableGroup::Criteria & the_criteria,
00064 PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id
00065 ACE_ENV_ARG_DECL)
00066 ACE_THROW_SPEC ((CORBA::SystemException,
00067 PortableGroup::NoFactory,
00068 PortableGroup::ObjectNotCreated,
00069 PortableGroup::InvalidCriteria,
00070 PortableGroup::InvalidProperty,
00071 PortableGroup::CannotMeetCriteria))
00072 {
00073 PortableGroup::Properties_var properties =
00074 this->property_manager_.get_type_properties (type_id
00075 ACE_ENV_ARG_PARAMETER);
00076 ACE_CHECK_RETURN (CORBA::Object::_nil ());
00077
00078 PortableGroup::MembershipStyleValue membership_style =
00079 TAO_PG_MEMBERSHIP_STYLE;
00080 PortableGroup::FactoriesValue factory_infos(0);
00081
00082 PortableGroup::InitialNumberMembersValue initial_number_members =
00083 TAO_PG_INITIAL_NUMBER_MEMBERS;
00084 PortableGroup::MinimumNumberMembersValue minimum_number_members =
00085 TAO_PG_MINIMUM_NUMBER_MEMBERS;
00086
00087
00088
00089 this->process_criteria (type_id,
00090 the_criteria,
00091 membership_style,
00092 factory_infos,
00093 initial_number_members,
00094 minimum_number_members
00095 ACE_ENV_ARG_PARAMETER);
00096 ACE_CHECK_RETURN (CORBA::Object::_nil ());
00097
00098 CORBA::ULong fcid = 0;
00099
00100 {
00101 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00102 guard,
00103 this->lock_,
00104 CORBA::Object::_nil ());
00105
00106
00107 fcid = this->next_fcid_;
00108
00109
00110
00111 while (this->factory_map_.find (this->next_fcid_) == 0)
00112 {
00113 this->next_fcid_++;
00114
00115
00116
00117
00118
00119
00120 if (this->next_fcid_ == fcid)
00121 ACE_THROW_RETURN (PortableGroup::ObjectNotCreated (),
00122 CORBA::Object::_nil ());
00123 }
00124
00125
00126
00127 fcid = this->next_fcid_;
00128 }
00129
00130
00131
00132 PortableServer::ObjectId_var oid;
00133 this->get_ObjectId (fcid, oid.out ());
00134
00135 PortableGroup::ObjectGroup_var object_group =
00136 this->object_group_manager_.create_object_group (fcid,
00137 oid.in (),
00138 type_id,
00139 the_criteria
00140 ACE_ENV_ARG_PARAMETER);
00141 ACE_CHECK_RETURN (CORBA::Object::_nil ());
00142
00143 TAO_PG_Factory_Set factory_set;
00144
00145 const CORBA::ULong factory_infos_count = factory_infos.length ();
00146
00147 ACE_TRY
00148 {
00149 if (factory_infos_count > 0
00150 && membership_style == PortableGroup::MEMB_INF_CTRL)
00151 {
00152 this->populate_object_group (object_group.in (),
00153 type_id,
00154 factory_infos,
00155 initial_number_members,
00156 factory_set
00157 ACE_ENV_ARG_PARAMETER);
00158 ACE_TRY_CHECK;
00159
00160 if (this->factory_map_.bind (fcid, factory_set) != 0)
00161 ACE_TRY_THROW (PortableGroup::ObjectNotCreated ());
00162
00163 }
00164
00165
00166 PortableGroup::GenericFactory::FactoryCreationId * tmp = 0;
00167 ACE_NEW_THROW_EX (tmp,
00168 PortableGroup::GenericFactory::FactoryCreationId,
00169 CORBA::NO_MEMORY (
00170 CORBA::SystemException::_tao_minor_code (
00171 TAO::VMCID,
00172 ENOMEM),
00173 CORBA::COMPLETED_NO));
00174 ACE_CHECK_RETURN (CORBA::Object::_nil ());
00175
00176 factory_creation_id = tmp;
00177
00178 *tmp <<= fcid;
00179 }
00180 ACE_CATCHANY
00181 {
00182 this->delete_object_i (factory_set,
00183 1
00184 ACE_ENV_ARG_PARAMETER);
00185 ACE_TRY_CHECK;
00186
00187 this->object_group_manager_.destroy_object_group (oid.in ()
00188 ACE_ENV_ARG_PARAMETER);
00189 ACE_TRY_CHECK;
00190
00191 ACE_RE_THROW;
00192 }
00193 ACE_ENDTRY;
00194 ACE_CHECK_RETURN (CORBA::Object::_nil ());
00195
00196 {
00197 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00198 guard,
00199 this->lock_,
00200 CORBA::Object::_nil ());
00201
00202
00203
00204 this->next_fcid_++;
00205 }
00206
00207 return object_group._retn ();
00208 }
00209
00210 void
00211 TAO_PG_GenericFactory::delete_object (
00212 const PortableGroup::GenericFactory::FactoryCreationId &
00213 factory_creation_id
00214 ACE_ENV_ARG_DECL)
00215 ACE_THROW_SPEC ((CORBA::SystemException,
00216 PortableGroup::ObjectNotFound))
00217 {
00218 CORBA::ULong fcid = 0;
00219
00220 if (factory_creation_id >>= fcid)
00221 {
00222
00223
00224
00225 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00226
00227
00228
00229 TAO_PG_Factory_Map::ENTRY *entry = 0;
00230 if (this->factory_map_.find (fcid, entry) == 0)
00231 {
00232 TAO_PG_Factory_Set & factory_set = entry->int_id_;
00233
00234 this->delete_object_i (factory_set,
00235 0
00236 ACE_ENV_ARG_PARAMETER);
00237 ACE_CHECK;
00238
00239 if (this->factory_map_.unbind (fcid) != 0)
00240 ACE_THROW (CORBA::INTERNAL ());
00241 }
00242 }
00243 else
00244 ACE_THROW (PortableGroup::ObjectNotFound ());
00245
00246
00247
00248
00249
00250 PortableServer::ObjectId_var oid;
00251 this->get_ObjectId (fcid, oid.out ());
00252
00253
00254 this->object_group_manager_.destroy_object_group (
00255 oid.in ()
00256 ACE_ENV_ARG_PARAMETER);
00257 ACE_CHECK;
00258 }
00259
00260 void
00261 TAO_PG_GenericFactory::delete_object_i (TAO_PG_Factory_Set & factory_set,
00262 CORBA::Boolean ignore_exceptions
00263 ACE_ENV_ARG_DECL)
00264 {
00265 const size_t len = factory_set.size ();
00266
00267 size_t ilen = len;
00268 for (size_t i = 0; i != len; ++i)
00269 {
00270
00271
00272
00273 --ilen;
00274
00275 TAO_PG_Factory_Node & factory_node = factory_set[ilen];
00276
00277 PortableGroup::GenericFactory_ptr factory =
00278 factory_node.factory_info.the_factory.in ();
00279 const PortableGroup::GenericFactory::FactoryCreationId & member_fcid =
00280 factory_node.factory_creation_id.in ();
00281
00282 ACE_TRY
00283 {
00284 factory->delete_object (member_fcid
00285 ACE_ENV_ARG_PARAMETER);
00286 ACE_TRY_CHECK;
00287 }
00288 ACE_CATCHANY
00289 {
00290
00291
00292
00293
00294
00295
00296 if (!ignore_exceptions)
00297 ACE_RE_THROW;
00298 }
00299 ACE_ENDTRY;
00300 ACE_CHECK;
00301
00302
00303
00304
00305
00306
00307 factory_set.size (ilen);
00308 }
00309 }
00310
00311 void
00312 TAO_PG_GenericFactory::delete_member (
00313 CORBA::ULong group_id,
00314 const PortableGroup::Location & location
00315 ACE_ENV_ARG_DECL)
00316 {
00317 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00318
00319
00320
00321 TAO_PG_Factory_Map::ENTRY *entry = 0;
00322 if (this->factory_map_.find (group_id, entry) == 0)
00323 {
00324 TAO_PG_Factory_Set & factory_set = entry->int_id_;
00325
00326 const size_t len = factory_set.size ();
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 for (size_t i = 0; i < len; ++i)
00338 {
00339 TAO_PG_Factory_Node & node = factory_set[i];
00340 PortableGroup::FactoryInfo & info = node.factory_info;
00341
00342 if (info.the_location == location)
00343 {
00344 info.the_factory->delete_object (node.factory_creation_id.in ()
00345 ACE_ENV_ARG_PARAMETER);
00346 ACE_CHECK;
00347
00348
00349
00350 if (len > 1)
00351 {
00352
00353
00354
00355 const size_t new_len = len - 1;
00356 node = factory_set[new_len];
00357 factory_set.size (new_len);
00358 }
00359 else
00360 {
00361
00362
00363 factory_set.size (0);
00364 }
00365
00366 return;
00367 }
00368 }
00369 }
00370 }
00371
00372 void
00373 TAO_PG_GenericFactory::poa (PortableServer::POA_ptr p)
00374 {
00375 ACE_ASSERT (CORBA::is_nil (this->poa_.in ())
00376 && !CORBA::is_nil (p));
00377
00378 this->poa_ = PortableServer::POA::_duplicate (p);
00379 }
00380
00381 void
00382 TAO_PG_GenericFactory::populate_object_group (
00383 PortableGroup::ObjectGroup_ptr object_group,
00384 const char * type_id,
00385 const PortableGroup::FactoryInfos & factory_infos,
00386 PortableGroup::InitialNumberMembersValue initial_number_members,
00387 TAO_PG_Factory_Set & factory_set
00388 ACE_ENV_ARG_DECL)
00389 {
00390 CORBA::ULong factory_infos_count = factory_infos.length ();
00391 factory_set.size (factory_infos_count);
00392
00393 for (CORBA::ULong j = 0; j < factory_infos_count; ++j)
00394 {
00395 TAO_PG_Factory_Node & factory_node = factory_set[j];
00396
00397 const PortableGroup::FactoryInfo &factory_info = factory_infos[j];
00398
00399 if (j < static_cast<CORBA::ULong> (initial_number_members))
00400 {
00401 PortableGroup::GenericFactory_ptr factory =
00402 factory_info.the_factory.in ();
00403
00404 if (CORBA::is_nil (factory))
00405 {
00406
00407 ACE_THROW (PortableGroup::NoFactory (factory_info.the_location,
00408 type_id));
00409 }
00410
00411
00412
00413 const CORBA::Boolean propagate_member_already_present = 0;
00414
00415 factory_node.factory_creation_id =
00416 this->create_member (object_group,
00417 factory_info,
00418 type_id,
00419 propagate_member_already_present
00420 ACE_ENV_ARG_PARAMETER);
00421 ACE_CHECK;
00422 }
00423
00424 factory_node.factory_info = factory_info;
00425 }
00426 }
00427
00428 void
00429 TAO_PG_GenericFactory::get_ObjectId (
00430 CORBA::ULong fcid,
00431 PortableServer::ObjectId_out oid)
00432 {
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 const size_t MAX_OID_LEN = 14;
00454
00455 char oid_str[MAX_OID_LEN] = { 0 };
00456 ACE_OS::sprintf (oid_str,
00457 "%ul",
00458 fcid);
00459
00460 oid = PortableServer::string_to_ObjectId (oid_str);
00461 }
00462
00463 void
00464 TAO_PG_GenericFactory::process_criteria (
00465 const char * type_id,
00466 const PortableGroup::Criteria & criteria,
00467 PortableGroup::MembershipStyleValue & membership_style,
00468 PortableGroup::FactoriesValue & factory_infos,
00469 PortableGroup::InitialNumberMembersValue & initial_number_members,
00470 PortableGroup::MinimumNumberMembersValue & minimum_number_members
00471 ACE_ENV_ARG_DECL)
00472 {
00473
00474 PortableGroup::Properties_var props =
00475 this->property_manager_.get_type_properties (type_id
00476 ACE_ENV_ARG_PARAMETER);
00477 ACE_CHECK;
00478
00479
00480 TAO_PG::override_properties (criteria, props.inout ());
00481
00482 PortableGroup::Criteria unmet_criteria;
00483 unmet_criteria.length (4);
00484
00485
00486
00487 CORBA::ULong uc = 0;
00488
00489 PortableGroup::Name name (1);
00490 name.length (1);
00491
00492 PortableGroup::Value value;
00493 PortableGroup::Value value1;
00494 PortableGroup::Value value2;
00495 PortableGroup::Value value3;
00496
00497
00498 name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
00499 if (TAO_PG::get_property_value (name, props.in (), value)
00500 && (!(value >>= membership_style)
00501 || (membership_style != PortableGroup::MEMB_APP_CTRL
00502 && membership_style != PortableGroup::MEMB_INF_CTRL)))
00503 {
00504
00505
00506 ACE_THROW (PortableGroup::InvalidProperty (name, value));
00507 }
00508
00509
00510 const PortableGroup::FactoryInfos * factory_infos_tmp = 0;
00511 name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00512 if (TAO_PG::get_property_value (name, props.in (), value1)
00513 && !(value1 >>= factory_infos_tmp))
00514 {
00515
00516
00517 ACE_THROW (PortableGroup::InvalidProperty (name, value1));
00518 }
00519
00520 const CORBA::ULong factory_infos_count =
00521 (factory_infos_tmp == 0 ? 0 : factory_infos_tmp->length ());
00522
00523
00524 name[0].id =
00525 CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00526 if (TAO_PG::get_property_value (name, props.in (), value2)
00527 && !(value2 >>= initial_number_members))
00528 {
00529
00530
00531 ACE_THROW (PortableGroup::InvalidProperty (name, value2));
00532 }
00533
00534 if (membership_style == PortableGroup::MEMB_INF_CTRL)
00535 {
00536
00537
00538
00539
00540 if (factory_infos_count < static_cast<CORBA::ULong> (initial_number_members))
00541 {
00542 unmet_criteria[uc].nam = name;
00543 unmet_criteria[uc++].val = value2;
00544 }
00545 }
00546
00547
00548 name[0].id =
00549 CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00550 if (TAO_PG::get_property_value (name, props.in (), value3)
00551 && !(value3 >>= minimum_number_members))
00552 {
00553
00554
00555 ACE_THROW (PortableGroup::InvalidProperty (name, value3));
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565 if (membership_style == PortableGroup::MEMB_INF_CTRL)
00566 {
00567 if (minimum_number_members < initial_number_members
00568 || static_cast<CORBA::ULong> (minimum_number_members) > factory_infos_count)
00569 {
00570 unmet_criteria[uc].nam = name;
00571 unmet_criteria[uc++].val = value3;
00572 }
00573 else if (factory_infos_tmp != 0)
00574 {
00575 factory_infos.length (factory_infos_count);
00576 factory_infos = *factory_infos_tmp;
00577 }
00578 }
00579
00580 if (uc > 0)
00581 {
00582
00583
00584
00585
00586 unmet_criteria.length (uc);
00587
00588 ACE_THROW (PortableGroup::CannotMeetCriteria (unmet_criteria));
00589 }
00590 }
00591
00592 void
00593 TAO_PG_GenericFactory::check_minimum_number_members (
00594 PortableGroup::ObjectGroup_ptr object_group,
00595 CORBA::ULong group_id,
00596 const char * type_id
00597 ACE_ENV_ARG_DECL)
00598 {
00599
00600
00601
00602
00603
00604
00605 TAO_PG_Factory_Map::ENTRY *entry = 0;
00606 if (this->factory_map_.find (group_id, entry) != 0)
00607 return;
00608
00609 TAO_PG_Factory_Set & factory_set = entry->int_id_;
00610
00611 PortableGroup::Properties_var props =
00612 this->property_manager_.get_properties (object_group
00613 ACE_ENV_ARG_PARAMETER);
00614 ACE_CHECK;
00615
00616 PortableGroup::Name name (1);
00617 name.length (1);
00618
00619 PortableGroup::Value value;
00620
00621
00622 name[0].id =
00623 CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00624
00625 PortableGroup::MinimumNumberMembersValue minimum_number_members;
00626
00627 if (TAO_PG::get_property_value (name, props.in (), value))
00628 {
00629 if (!(value >>= minimum_number_members))
00630 {
00631
00632
00633 ACE_THROW (CORBA::INTERNAL ());
00634 }
00635
00636 const CORBA::ULong count =
00637 this->object_group_manager_.member_count (object_group
00638 ACE_ENV_ARG_PARAMETER);
00639 ACE_CHECK;
00640
00641 if (count >= static_cast<CORBA::ULong> (minimum_number_members))
00642 return;
00643
00644 const CORBA::ULong gap =
00645 static_cast<CORBA::ULong> (minimum_number_members) - count;
00646
00647 CORBA::ULong creation_count = 0;
00648
00649 const size_t len = factory_set.size ();
00650
00651 static const PortableGroup::GenericFactory::FactoryCreationId *
00652 nil_fcid = 0;
00653
00654 for (size_t i = 0; i < len; ++i)
00655 {
00656 TAO_PG_Factory_Node & node = factory_set[i];
00657
00658 PortableGroup::GenericFactory::FactoryCreationId * const tmp_fcid =
00659 node.factory_creation_id;
00660
00661
00662
00663 if (tmp_fcid != nil_fcid)
00664 continue;
00665
00666 ACE_TRY
00667 {
00668 const CORBA::Boolean propagate_member_already_present = 1;
00669
00670 node.factory_creation_id =
00671 this->create_member (object_group,
00672 node.factory_info,
00673 type_id,
00674 propagate_member_already_present
00675 ACE_ENV_ARG_PARAMETER);
00676 ACE_TRY_CHECK;
00677
00678 ++creation_count;
00679
00680
00681
00682 if (gap == creation_count)
00683 return;
00684 }
00685 ACE_CATCH (PortableGroup::MemberAlreadyPresent, ex)
00686 {
00687
00688 }
00689 ACE_ENDTRY;
00690 ACE_CHECK;
00691 }
00692
00693
00694
00695
00696 }
00697 }
00698
00699 PortableGroup::GenericFactory::FactoryCreationId *
00700 TAO_PG_GenericFactory::create_member (
00701 PortableGroup::ObjectGroup_ptr object_group,
00702 const PortableGroup::FactoryInfo & factory_info,
00703 const char * type_id,
00704 const CORBA::Boolean propagate_member_already_present
00705 ACE_ENV_ARG_DECL)
00706 ACE_THROW_SPEC ((CORBA::SystemException,
00707 PortableGroup::NoFactory,
00708 PortableGroup::ObjectNotCreated,
00709 PortableGroup::InvalidCriteria,
00710 PortableGroup::InvalidProperty,
00711 PortableGroup::CannotMeetCriteria,
00712 PortableGroup::MemberAlreadyPresent))
00713 {
00714 PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00715
00716 CORBA::Object_var member =
00717 factory_info.the_factory->create_object (type_id,
00718 factory_info.the_criteria,
00719 fcid.out ()
00720 ACE_ENV_ARG_PARAMETER);
00721 ACE_CHECK_RETURN (0);
00722
00723 ACE_TRY
00724 {
00725
00726
00727
00728
00729
00730
00731
00732
00733 CORBA::Boolean right_type_id =
00734 member->_is_a (type_id
00735 ACE_ENV_ARG_PARAMETER);
00736 ACE_TRY_CHECK;
00737
00738
00739 if (!right_type_id)
00740 {
00741
00742
00743 factory_info.the_factory->delete_object (fcid.in ()
00744 ACE_ENV_ARG_PARAMETER);
00745 ACE_TRY_CHECK;
00746
00747 ACE_TRY_THROW (PortableGroup::NoFactory (factory_info.the_location,
00748 type_id));
00749 }
00750
00751 this->object_group_manager_._tao_add_member (
00752 object_group,
00753 factory_info.the_location,
00754 member.in (),
00755 type_id,
00756 propagate_member_already_present
00757 ACE_ENV_ARG_PARAMETER);
00758 ACE_TRY_CHECK;
00759 }
00760 ACE_CATCHANY
00761 {
00762
00763
00764
00765 if (!CORBA::is_nil (member.in ()))
00766 {
00767 factory_info.the_factory->delete_object (fcid.in ()
00768 ACE_ENV_ARG_PARAMETER);
00769 ACE_TRY_CHECK;
00770 }
00771
00772 ACE_RE_THROW;
00773 }
00774 ACE_ENDTRY;
00775 ACE_CHECK_RETURN (0);
00776
00777 return fcid._retn ();
00778 }
00779
00780 TAO_END_VERSIONED_NAMESPACE_DECL