00001 #include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h"
00002 #include "orbsvcs/PortableGroup/PG_GenericFactory.h"
00003 #include "orbsvcs/PortableGroup/PG_conf.h"
00004 #include "orbsvcs/PortableGroup/PG_Operators.h"
00005
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Constants.h"
00008
00009 #include "ace/Auto_Ptr.h"
00010 #include "ace/Reverse_Lock_T.h"
00011
00012 ACE_RCSID (PortableGroup,
00013 PG_ObjectGroupManager,
00014 "$Id: PG_ObjectGroupManager.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
00015
00016
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018
00019 TAO_PG_ObjectGroupManager::TAO_PG_ObjectGroupManager (void)
00020 : poa_ (),
00021 object_group_map_ (TAO_PG_MAX_OBJECT_GROUPS),
00022 location_map_ (TAO_PG_MAX_LOCATIONS),
00023 generic_factory_ (0),
00024 lock_ ()
00025 {
00026 }
00027
00028 TAO_PG_ObjectGroupManager::~TAO_PG_ObjectGroupManager (void)
00029 {
00030 for (TAO_PG_Location_Map::iterator i = this->location_map_.begin ();
00031 i != this->location_map_.end ();
00032 ++i)
00033 {
00034
00035 delete (*i).int_id_;
00036 }
00037 (void) this->location_map_.close ();
00038
00039 for (TAO_PG_ObjectGroup_Map::iterator j = this->object_group_map_.begin ();
00040 j != this->object_group_map_.end ();
00041 ++j)
00042 {
00043
00044 delete (*j).int_id_;
00045 }
00046 (void) this->object_group_map_.close ();
00047 }
00048
00049 PortableGroup::ObjectGroup_ptr
00050 TAO_PG_ObjectGroupManager::create_member (
00051 PortableGroup::ObjectGroup_ptr ,
00052 const PortableGroup::Location & ,
00053 const char * ,
00054 const PortableGroup::Criteria & )
00055 {
00056 throw CORBA::NO_IMPLEMENT ();
00057 }
00058
00059 PortableGroup::ObjectGroup_ptr
00060 TAO_PG_ObjectGroupManager::add_member (
00061 PortableGroup::ObjectGroup_ptr object_group,
00062 const PortableGroup::Location & the_location,
00063 CORBA::Object_ptr member)
00064 {
00065 if (CORBA::is_nil (member))
00066 throw CORBA::BAD_PARAM ();
00067
00068 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00069 guard,
00070 this->lock_,
00071 PortableGroup::ObjectGroup::_nil ());
00072
00073
00074
00075 const CORBA::Boolean check_type_id = 1;
00076
00077 return this->add_member_i (object_group,
00078 the_location,
00079 member,
00080 check_type_id);
00081
00082 }
00083
00084
00085 PortableGroup::ObjectGroup_ptr
00086 TAO_PG_ObjectGroupManager::_tao_add_member (
00087 PortableGroup::ObjectGroup_ptr object_group,
00088 const PortableGroup::Location & the_location,
00089 CORBA::Object_ptr member,
00090 const char * type_id,
00091 const CORBA::Boolean propagate_member_already_present)
00092 {
00093 if (CORBA::is_nil (member))
00094 throw CORBA::BAD_PARAM ();
00095
00096 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00097 guard,
00098 this->lock_,
00099 PortableGroup::ObjectGroup::_nil ());
00100
00101 PortableGroup::ObjectGroup_var new_group;
00102
00103 try
00104 {
00105
00106 const CORBA::Boolean check_type_id = 0;
00107
00108 new_group = this->add_member_i (object_group,
00109 the_location,
00110 member,
00111 check_type_id);
00112 }
00113 catch (const PortableGroup::ObjectGroupNotFound&)
00114 {
00115 throw CORBA::INTERNAL ();
00116 }
00117 catch (const PortableGroup::MemberAlreadyPresent&)
00118 {
00119 if (propagate_member_already_present)
00120 throw;
00121 else
00122 throw CORBA::INTERNAL ();
00123 }
00124 catch (const PortableGroup::ObjectNotAdded&)
00125 {
00126 throw PortableGroup::NoFactory (the_location, type_id);
00127 }
00128
00129 return new_group._retn ();
00130 }
00131
00132 PortableGroup::ObjectGroup_ptr
00133 TAO_PG_ObjectGroupManager::add_member_i (
00134 PortableGroup::ObjectGroup_ptr object_group,
00135 const PortableGroup::Location & the_location,
00136 CORBA::Object_ptr member,
00137 const CORBA::Boolean check_type_id)
00138 {
00139 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00140 this->get_group_entry (object_group);
00141
00142 if (check_type_id)
00143 {
00144 CORBA::Boolean right_type_id =
00145 this->valid_type_id (object_group,
00146 group_entry,
00147 member);
00148
00149 if (!right_type_id)
00150 {
00151
00152
00153 throw PortableGroup::ObjectNotAdded ();
00154 }
00155 }
00156
00157 TAO_PG_ObjectGroup_Array * groups = 0;
00158 if (this->location_map_.find (the_location, groups) == 0
00159 && this->member_already_present (*groups, group_entry))
00160 throw PortableGroup::MemberAlreadyPresent ();
00161
00162 TAO_PG_MemberInfo member_info;
00163 member_info.member = CORBA::Object::_duplicate (member);
00164 member_info.location = the_location;
00165
00166 if (groups == 0)
00167 {
00168 ACE_NEW_THROW_EX (groups,
00169 TAO_PG_ObjectGroup_Array,
00170 CORBA::NO_MEMORY (
00171 CORBA::SystemException::_tao_minor_code (
00172 TAO::VMCID,
00173 ENOMEM),
00174 CORBA::COMPLETED_NO));
00175
00176 auto_ptr<TAO_PG_ObjectGroup_Array> safe_groups (groups);
00177
00178
00179 if (this->location_map_.bind (the_location, groups) != 0)
00180 {
00181 throw PortableGroup::ObjectNotAdded ();
00182 }
00183
00184 (void) safe_groups.release ();
00185 }
00186
00187
00188
00189
00190 const size_t groups_len = groups->size ();
00191 groups->size (groups_len + 1);
00192 (*groups)[groups_len] = group_entry;
00193
00194
00195
00196 if (group_entry->member_infos.insert_tail (member_info) != 0)
00197 throw PortableGroup::ObjectNotAdded ();
00198
00199 return PortableGroup::ObjectGroup::_duplicate (object_group);
00200 }
00201
00202 PortableGroup::ObjectGroup_ptr
00203 TAO_PG_ObjectGroupManager::remove_member (
00204 PortableGroup::ObjectGroup_ptr object_group,
00205 const PortableGroup::Location & the_location)
00206 {
00207 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00208
00209 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00210 this->get_group_entry (object_group);
00211
00212 TAO_PG_ObjectGroup_Array * groups = 0;
00213 if (this->location_map_.find (the_location, groups) != 0)
00214 throw PortableGroup::ObjectGroupNotFound ();
00215
00216
00217
00218
00219 size_t to_be_removed = 0;
00220
00221
00222 to_be_removed = this->get_object_group_position (*groups, group_entry);
00223
00224
00225 const size_t groups_len = groups->size ();
00226 size_t j;
00227 for (size_t i = to_be_removed; i < groups_len - 1; ++i)
00228 {
00229 j = i + 1;
00230 (*groups)[i] = (*groups)[j];
00231 }
00232
00233 groups->size (groups_len - 1);
00234
00235 TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00236
00237 TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00238
00239 for (TAO_PG_MemberInfo_Set::iterator iter = member_infos.begin ();
00240 iter != end;
00241 ++iter)
00242 {
00243 const TAO_PG_MemberInfo & info = *iter;
00244
00245 if (info.location == the_location)
00246 {
00247
00248
00249 if (this->generic_factory_)
00250 {
00251 this->generic_factory_->delete_member (group_entry->group_id,
00252 the_location);
00253 }
00254
00255 if (member_infos.remove (info) == 0)
00256 {
00257 if (this->generic_factory_)
00258 {
00259 this->generic_factory_->check_minimum_number_members (
00260 object_group,
00261 group_entry->group_id,
00262 group_entry->type_id.in ());
00263 }
00264
00265 return PortableGroup::ObjectGroup::_duplicate (object_group);
00266 }
00267 else
00268 break;
00269 }
00270 }
00271
00272 throw PortableGroup::MemberNotFound ();
00273 }
00274
00275 PortableGroup::Locations *
00276 TAO_PG_ObjectGroupManager::locations_of_members (
00277 PortableGroup::ObjectGroup_ptr object_group)
00278 {
00279 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00280
00281 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00282 this->get_group_entry (object_group);
00283
00284 PortableGroup::Locations *temp = 0;
00285 ACE_NEW_THROW_EX (temp,
00286 PortableGroup::Locations,
00287 CORBA::NO_MEMORY (
00288 CORBA::SystemException::_tao_minor_code (
00289 TAO::VMCID,
00290 ENOMEM),
00291 CORBA::COMPLETED_NO));
00292
00293 PortableGroup::Locations_var locations = temp;
00294
00295 TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00296
00297 locations->length (static_cast<CORBA::ULong> (member_infos.size ()));
00298
00299 CORBA::ULong loc = 0;
00300 TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00301
00302 for (TAO_PG_MemberInfo_Set::iterator i = member_infos.begin ();
00303 i != end;
00304 ++i)
00305 locations[loc++] = (*i).location;
00306
00307 return locations._retn ();
00308 }
00309
00310 PortableGroup::ObjectGroups *
00311 TAO_PG_ObjectGroupManager::groups_at_location (
00312 const PortableGroup::Location & the_location)
00313 {
00314 PortableGroup::ObjectGroups * ogs;
00315 ACE_NEW_THROW_EX (ogs,
00316 PortableGroup::ObjectGroups,
00317 CORBA::NO_MEMORY ());
00318
00319 PortableGroup::ObjectGroups_var object_groups = ogs;
00320
00321 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00322
00323 TAO_PG_ObjectGroup_Array * groups;
00324 if (this->location_map_.find (the_location, groups) == 0)
00325 {
00326 CORBA::ULong len = static_cast<CORBA::ULong> (groups->size ());
00327
00328 ogs->length (len);
00329
00330 for (CORBA::ULong i = 0; i < len; ++i)
00331 {
00332 object_groups[i] =
00333 PortableGroup::ObjectGroup::_duplicate (
00334 (*groups)[i]->object_group.in ());
00335 }
00336 }
00337
00338 return object_groups._retn ();
00339 }
00340
00341 PortableGroup::ObjectGroupId
00342 TAO_PG_ObjectGroupManager::get_object_group_id (
00343 PortableGroup::ObjectGroup_ptr object_group)
00344 {
00345 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00346 guard,
00347 this->lock_,
00348 0);
00349
00350 TAO_PG_ObjectGroup_Map_Entry * entry =
00351 this->get_group_entry (object_group);
00352
00353 if (entry == 0)
00354 throw CORBA::INTERNAL ();
00355
00356
00357
00358 return entry->group_id;
00359 }
00360
00361 PortableGroup::ObjectGroup_ptr
00362 TAO_PG_ObjectGroupManager::get_object_group_ref (
00363 PortableGroup::ObjectGroup_ptr object_group)
00364 {
00365 TAO_PG_ObjectGroup_Map_Entry * entry = 0;
00366
00367 {
00368 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00369 guard,
00370 this->lock_,
00371 PortableGroup::ObjectGroup::_nil ());
00372
00373
00374 entry = this->get_group_entry (object_group);
00375 }
00376
00377 if (entry == 0)
00378 throw CORBA::INTERNAL ();
00379
00380
00381 return PortableGroup::ObjectGroup::_duplicate (object_group);
00382 }
00383
00384 CORBA::Object_ptr
00385 TAO_PG_ObjectGroupManager::get_member_ref (
00386 PortableGroup::ObjectGroup_ptr object_group,
00387 const PortableGroup::Location & loc)
00388 {
00389 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00390 guard,
00391 this->lock_,
00392 CORBA::Object::_nil ());
00393
00394 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00395 this->get_group_entry (object_group);
00396
00397
00398
00399
00400
00401 TAO_PG_ObjectGroup_Array * groups = 0;
00402 if (this->location_map_.find (loc, groups) == 0
00403 && this->member_already_present (*groups, group_entry))
00404 {
00405 TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00406
00407 TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00408
00409
00410
00411
00412
00413 for (TAO_PG_MemberInfo_Set::iterator i = member_infos.begin ();
00414 i != end;
00415 ++i)
00416 if ((*i).location == loc)
00417 return CORBA::Object::_duplicate ((*i).member.in ());
00418 }
00419
00420
00421
00422 throw PortableGroup::MemberNotFound ();
00423 }
00424
00425 PortableGroup::ObjectGroup_ptr
00426 TAO_PG_ObjectGroupManager::get_object_group_ref_from_id (
00427 PortableGroup::ObjectGroupId group_id
00428 )
00429 {
00430
00431
00432
00433
00434 TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00435 {
00436 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00437 guard,
00438 this->lock_,
00439 PortableGroup::ObjectGroup::_nil ());
00440
00441 if (this->object_group_map_.find (ACE_U64_TO_U32 (group_id),
00442 group_entry)
00443 != 0)
00444 {
00445 throw PortableGroup::ObjectGroupNotFound ();
00446 }
00447 }
00448
00449 if (group_entry == 0)
00450 {
00451 throw CORBA::INTERNAL ();
00452 }
00453
00454 return
00455 PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ());
00456 }
00457
00458 PortableGroup::ObjectGroup_ptr
00459 TAO_PG_ObjectGroupManager::create_object_group (
00460 CORBA::ULong group_id,
00461 const PortableServer::ObjectId &oid,
00462 const char * type_id,
00463 const PortableGroup::Criteria & the_criteria)
00464 {
00465 if (CORBA::is_nil (this->poa_.in ()))
00466 throw CORBA::INTERNAL ();
00467
00468
00469
00470 CORBA::Object_var object_group =
00471 this->poa_->create_reference_with_id (oid,
00472 type_id);
00473
00474 TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00475 ACE_NEW_THROW_EX (group_entry,
00476 TAO_PG_ObjectGroup_Map_Entry,
00477 CORBA::NO_MEMORY (
00478 CORBA::SystemException::_tao_minor_code (
00479 TAO::VMCID,
00480 ENOMEM),
00481 CORBA::COMPLETED_NO));
00482
00483 auto_ptr<TAO_PG_ObjectGroup_Map_Entry> safe_group_entry (group_entry);
00484
00485
00486
00487 group_entry->type_id = CORBA::string_dup (type_id);
00488
00489 group_entry->group_id = group_id;
00490
00491 group_entry->object_group = object_group;
00492
00493 CORBA::ULong len = the_criteria.length ();
00494 group_entry->properties.length (len);
00495 for (CORBA::ULong i = 0; i < len; ++i)
00496 group_entry->properties[i] = the_criteria[i];
00497
00498 {
00499 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00500 guard,
00501 this->lock_,
00502 0);
00503
00504 if (this->object_group_map_.bind (oid, group_entry) != 0)
00505 throw PortableGroup::ObjectNotCreated ();
00506 }
00507
00508 (void) safe_group_entry.release ();
00509
00510 return object_group._retn ();
00511 }
00512
00513 void
00514 TAO_PG_ObjectGroupManager::destroy_object_group (
00515 const PortableServer::ObjectId & oid)
00516 {
00517 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00518
00519 TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00520 if (this->object_group_map_.unbind (oid, group_entry) != 0)
00521 throw PortableGroup::ObjectNotFound ();
00522
00523 delete group_entry;
00524 }
00525
00526 char *
00527 TAO_PG_ObjectGroupManager::type_id (
00528 PortableGroup::ObjectGroup_ptr object_group)
00529 {
00530 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00531 guard,
00532 this->lock_,
00533 0);
00534
00535 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00536 this->get_group_entry (object_group);
00537
00538 return CORBA::string_dup (group_entry->type_id.in ());
00539 }
00540
00541 PortableGroup::ObjectGroup_ptr
00542 TAO_PG_ObjectGroupManager::object_group (const PortableServer::ObjectId & oid)
00543 {
00544 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00545 guard,
00546 this->lock_,
00547 PortableGroup::ObjectGroup::_nil ());
00548
00549 TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00550 if (this->object_group_map_.find (oid, group_entry) == 0)
00551 return
00552 PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ());
00553 else
00554 return PortableGroup::ObjectGroup::_nil ();
00555 }
00556
00557 CORBA::ULong
00558 TAO_PG_ObjectGroupManager::member_count (
00559 PortableGroup::ObjectGroup_ptr group)
00560 {
00561
00562
00563
00564
00565
00566 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00567 this->get_group_entry (group);
00568
00569 return static_cast<CORBA::ULong> (group_entry->member_infos.size ());
00570 }
00571
00572 void
00573 TAO_PG_ObjectGroupManager::poa (PortableServer::POA_ptr p)
00574 {
00575 this->poa_ = PortableServer::POA::_duplicate (p);
00576 }
00577
00578
00579 PortableGroup::Properties *
00580 TAO_PG_ObjectGroupManager::get_properties (
00581 PortableGroup::ObjectGroup_ptr object_group)
00582 {
00583 PortableGroup::Properties * properties = 0;
00584 ACE_NEW_THROW_EX (properties,
00585 PortableGroup::Properties,
00586 CORBA::NO_MEMORY (
00587 CORBA::SystemException::_tao_minor_code (
00588 TAO::VMCID,
00589 ENOMEM),
00590 CORBA::COMPLETED_NO));
00591
00592 PortableGroup::Properties_var safe_properties = properties;
00593
00594 {
00595 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00596 guard,
00597 this->lock_,
00598 0);
00599
00600 TAO_PG_ObjectGroup_Map_Entry * group_entry =
00601 this->get_group_entry (object_group);
00602
00603 *properties = group_entry->properties;
00604 }
00605
00606 return safe_properties._retn ();
00607 }
00608
00609 TAO_PG_ObjectGroup_Map_Entry *
00610 TAO_PG_ObjectGroupManager::get_group_entry (
00611 CORBA::Object_ptr object_group)
00612 {
00613 if (CORBA::is_nil (this->poa_.in ()))
00614 throw CORBA::INTERNAL ();
00615
00616 PortableServer::ObjectId_var oid;
00617 try
00618 {
00619 oid = this->poa_->reference_to_id (object_group);
00620 }
00621 catch (const PortableServer::POA::WrongAdapter& ex)
00622 {
00623 if (TAO_debug_level > 0)
00624 ex._tao_print_exception ("TAO_PG (%P|%t) Unexpected exception\n");
00625
00626 throw CORBA::INTERNAL ();
00627 }
00628 catch (const PortableServer::POA::WrongPolicy& ex)
00629 {
00630 if (TAO_debug_level > 0)
00631 ex._tao_print_exception ("TAO_PG (%P|%t) Unexpected exception\n");
00632
00633 throw CORBA::INTERNAL ();
00634 }
00635
00636 TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00637 if (this->object_group_map_.find (oid.in (), group_entry) != 0)
00638 throw PortableGroup::ObjectGroupNotFound ();
00639
00640 return group_entry;
00641 }
00642
00643 CORBA::Boolean
00644 TAO_PG_ObjectGroupManager::member_already_present (
00645 const TAO_PG_ObjectGroup_Array &groups,
00646 TAO_PG_ObjectGroup_Map_Entry * group_entry)
00647 {
00648
00649
00650
00651 size_t len = groups.size ();
00652 for (size_t i = 0; i < len; ++i)
00653 {
00654
00655
00656
00657 if (groups[i]->group_id == group_entry->group_id)
00658 {
00659
00660
00661 return 1;
00662 }
00663 }
00664
00665
00666 return 0;
00667 }
00668
00669 size_t
00670 TAO_PG_ObjectGroupManager::get_object_group_position (
00671 const TAO_PG_ObjectGroup_Array &groups,
00672 TAO_PG_ObjectGroup_Map_Entry * group_entry)
00673 {
00674
00675
00676
00677 size_t len = groups.size ();
00678 for (size_t i = 0; i < len; ++i)
00679 {
00680
00681
00682
00683 if (groups[i]->group_id == group_entry->group_id)
00684 {
00685
00686
00687 return i;
00688 }
00689 }
00690
00691
00692 return 0;
00693 }
00694
00695 CORBA::Boolean
00696 TAO_PG_ObjectGroupManager::valid_type_id (
00697 PortableGroup::ObjectGroup_ptr object_group,
00698 TAO_PG_ObjectGroup_Map_Entry * group_entry,
00699 CORBA::Object_ptr member)
00700 {
00701
00702
00703 if (CORBA::is_nil (member))
00704 throw CORBA::BAD_PARAM ();
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 CORBA::String_var type_id =
00717 CORBA::string_dup (group_entry->type_id.in ());
00718
00719 CORBA::Boolean right_type_id = 0;
00720 {
00721
00722
00723 ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock (this->lock_);
00724
00725 ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>,
00726 reverse_guard,
00727 reverse_lock,
00728 right_type_id);
00729
00730
00731
00732
00733
00734 right_type_id =
00735 member->_is_a (type_id.in ());
00736 }
00737
00738
00739
00740 group_entry = this->get_group_entry (object_group);
00741
00742 return right_type_id;
00743 }
00744
00745 void
00746 TAO_PG_ObjectGroupManager::generic_factory (
00747 TAO_PG_GenericFactory * generic_factory)
00748 {
00749 this->generic_factory_ = generic_factory;
00750 }
00751
00752 TAO_END_VERSIONED_NAMESPACE_DECL