PG_GenericFactory.cpp

Go to the documentation of this file.
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            "$Id: PG_GenericFactory.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
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 
00035   TAO_PG_Factory_Map::iterator end = this->factory_map_.end ();
00036   for (TAO_PG_Factory_Map::iterator i = this->factory_map_.begin ();
00037        i != end;
00038        ++i)
00039     {
00040       TAO_PG_Factory_Set & factory_set = (*i).int_id_;
00041 
00042       try
00043         {
00044           this->delete_object_i (factory_set,
00045                                  1 /* Ignore exceptions */);
00046         }
00047       catch (const CORBA::Exception&)
00048         {
00049           // Ignore all exceptions.
00050         }
00051     }
00052 
00053   (void) this->factory_map_.close ();
00054 }
00055 
00056 CORBA::Object_ptr
00057 TAO_PG_GenericFactory::create_object (
00058     const char * type_id,
00059     const PortableGroup::Criteria & the_criteria,
00060     PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id)
00061 {
00062   PortableGroup::Properties_var properties =
00063     this->property_manager_.get_type_properties (type_id);
00064 
00065   PortableGroup::MembershipStyleValue membership_style =
00066     TAO_PG_MEMBERSHIP_STYLE;
00067   PortableGroup::FactoriesValue factory_infos(0);
00068 
00069   PortableGroup::InitialNumberMembersValue initial_number_members =
00070     TAO_PG_INITIAL_NUMBER_MEMBERS;
00071   PortableGroup::MinimumNumberMembersValue minimum_number_members =
00072     TAO_PG_MINIMUM_NUMBER_MEMBERS;
00073 
00074   // Make sure the criteria for the object group being created are
00075   // valid.
00076   this->process_criteria (type_id,
00077                           the_criteria,
00078                           membership_style,
00079                           factory_infos,
00080                           initial_number_members,
00081                           minimum_number_members);
00082 
00083   CORBA::ULong fcid = 0;
00084 
00085   {
00086     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00087                       guard,
00088                       this->lock_,
00089                       CORBA::Object::_nil ());
00090 
00091     // Start out with an initial value.
00092     fcid = this->next_fcid_;
00093 
00094     // Loop until a free FactoryCreationId is found, being careful to
00095     // search through the range of FactoryCreationIds only once.
00096     while (this->factory_map_.find (this->next_fcid_) == 0)
00097       {
00098         this->next_fcid_++;
00099 
00100         // If this is true, then no FactoryCreationIds are available.
00101         // This is highly unlikely since TAO implements a
00102         // FactoryCreationId as a 32 bit unsigned integer, meaning
00103         // that over 4 billion object groups are being managed by this
00104         // generic factory!
00105         if (this->next_fcid_ == fcid)
00106           throw PortableGroup::ObjectNotCreated ();
00107       }
00108 
00109     // Just in case this->next_fcid_ was modified in the above search,
00110     // reassign the value.
00111     fcid = this->next_fcid_;
00112   }
00113 
00114   // The ObjectId for the newly created object group is comprised
00115   // solely of the FactoryCreationId.
00116   PortableServer::ObjectId_var oid;
00117   this->get_ObjectId (fcid, oid.out ());
00118 
00119   PortableGroup::ObjectGroup_var object_group =
00120     this->object_group_manager_.create_object_group (fcid,
00121                                                      oid.in (),
00122                                                      type_id,
00123                                                      the_criteria);
00124 
00125   TAO_PG_Factory_Set factory_set;
00126 
00127   const CORBA::ULong factory_infos_count = factory_infos.length ();
00128 
00129   try
00130     {
00131       if (factory_infos_count > 0
00132           && membership_style == PortableGroup::MEMB_INF_CTRL)
00133         {
00134           this->populate_object_group (object_group.in (),
00135                                        type_id,
00136                                        factory_infos,
00137                                        initial_number_members,
00138                                        factory_set);
00139 
00140           if (this->factory_map_.bind (fcid, factory_set) != 0)
00141             throw PortableGroup::ObjectNotCreated ();
00142 
00143         }
00144 
00145       // Allocate a new FactoryCreationId for use as an "out" parameter.
00146       PortableGroup::GenericFactory::FactoryCreationId * tmp = 0;
00147       ACE_NEW_THROW_EX (tmp,
00148                         PortableGroup::GenericFactory::FactoryCreationId,
00149                         CORBA::NO_MEMORY (
00150                           CORBA::SystemException::_tao_minor_code (
00151                             TAO::VMCID,
00152                             ENOMEM),
00153                           CORBA::COMPLETED_NO));
00154 
00155       factory_creation_id = tmp;
00156 
00157       *tmp <<= fcid;
00158     }
00159   catch (const CORBA::Exception&)
00160     {
00161       this->delete_object_i (factory_set,
00162                              1 /* Ignore exceptions */);
00163 
00164       this->object_group_manager_.destroy_object_group (oid.in ());
00165 
00166       throw;
00167     }
00168 
00169   {
00170     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00171                       guard,
00172                       this->lock_,
00173                       CORBA::Object::_nil ());
00174 
00175     // Object group was successfully created.  Increment the next
00176     // FactoryCreationId in preparation for the next object group.
00177     this->next_fcid_++;
00178   }
00179 
00180   return object_group._retn ();
00181 }
00182 
00183 void
00184 TAO_PG_GenericFactory::delete_object (
00185     const PortableGroup::GenericFactory::FactoryCreationId &
00186       factory_creation_id)
00187 {
00188   CORBA::ULong fcid = 0;
00189 
00190   if (factory_creation_id >>= fcid) // Extract the actual FactoryCreationId.
00191     {
00192       // Successfully extracted the FactoryCreationId.  Now find the
00193       // TAO_PG_Factory_Set corresponding to it.
00194 
00195       ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00196 
00197       // If no entry exists in the factory map, infrastructure
00198       // controlled membership was not used.
00199       TAO_PG_Factory_Map::ENTRY *entry = 0;
00200       if (this->factory_map_.find (fcid, entry) == 0)
00201         {
00202           TAO_PG_Factory_Set & factory_set = entry->int_id_;
00203 
00204           this->delete_object_i (factory_set,
00205                                  0  /* Do not ignore exceptions */);
00206 
00207           if (this->factory_map_.unbind (fcid) != 0)
00208             throw CORBA::INTERNAL ();
00209         }
00210     }
00211   else
00212     throw PortableGroup::ObjectNotFound ();  // @@
00213                                                    //    CORBA::BAD_PARAM
00214                                                    //    instead?
00215 
00216   // The ObjectId for the newly created object group is comprised
00217   // solely of the FactoryCreationId.
00218   PortableServer::ObjectId_var oid;
00219   this->get_ObjectId (fcid, oid.out ());
00220 
00221   // Destroy the object group entry.
00222   this->object_group_manager_.destroy_object_group (
00223     oid.in ());
00224 }
00225 
00226 void
00227 TAO_PG_GenericFactory::delete_object_i (TAO_PG_Factory_Set & factory_set,
00228                                         CORBA::Boolean ignore_exceptions)
00229 {
00230   const size_t len = factory_set.size ();
00231 
00232   size_t ilen = len;
00233   for (size_t i = 0; i != len; ++i)
00234     {
00235       // Destroy the object group member in reverse order in case the
00236       // array list is only partially destroyed and another call to
00237       // GenericFactory::delete_object() occurs afterwards.
00238       --ilen;
00239 
00240       TAO_PG_Factory_Node & factory_node = factory_set[ilen];
00241 
00242       PortableGroup::GenericFactory_ptr factory =
00243         factory_node.factory_info.the_factory.in ();
00244       const PortableGroup::GenericFactory::FactoryCreationId & member_fcid =
00245         factory_node.factory_creation_id.in ();
00246 
00247       try
00248         {
00249           factory->delete_object (member_fcid);
00250         }
00251       catch (const CORBA::Exception&)
00252         {
00253           // Exceptions are generally only ignored when this
00254           // GenericFactory (not the one being invoked above) is
00255           // destroyed.  The idea is to allow the GenericFactory to be
00256           // destroyed regardless of whether or not all object group
00257           // members have been destroyed, and minimize the number of
00258           // object group members that have not been destroyed.
00259           if (!ignore_exceptions)
00260             throw;
00261         }
00262 
00263       // Since GenericFactory::delete_object() can throw an exception,
00264       // decrease the size of the factory array incrementally since
00265       // some object group members may not have been destroyed yet.
00266       // Note that this size reduction is fast since no memory is
00267       // actually deallocated.
00268       factory_set.size (ilen);
00269     }
00270 }
00271 
00272 void
00273 TAO_PG_GenericFactory::delete_member (
00274   CORBA::ULong group_id,
00275   const PortableGroup::Location & location)
00276 {
00277   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00278 
00279   // If no entry exists in the factory map, infrastructure
00280   // controlled membership was not used.
00281   TAO_PG_Factory_Map::ENTRY *entry = 0;
00282   if (this->factory_map_.find (group_id, entry) == 0)
00283     {
00284       TAO_PG_Factory_Set & factory_set = entry->int_id_;
00285 
00286       const size_t len = factory_set.size ();
00287 
00288       // Iterate through the factory_set until a location match
00289       // occurs.  If a location match occurs, the member was created
00290       // by the infrastructure, i.e. this GenericFactory
00291       // implementation.  If no location matches, the member was
00292       // created by the application, and no operation will be
00293       // performed.
00294       //
00295       // @todo This is linear search.  Change to use a container with
00296       //       better search times.
00297       for (size_t i = 0; i < len; ++i)
00298         {
00299           TAO_PG_Factory_Node & node = factory_set[i];
00300           PortableGroup::FactoryInfo & info = node.factory_info;
00301 
00302           if (info.the_location == location)
00303             {
00304               info.the_factory->delete_object (node.factory_creation_id.in ());
00305 
00306               // The member has been successfully deleted.  Reduce the
00307               // size of the factory_set accordingly.
00308               if (len > 1)
00309                 {
00310                   // Move the last element to the location of the
00311                   // current one and reduce the size of the set by
00312                   // one.
00313                   const size_t new_len = len - 1;
00314                   node = factory_set[new_len]; // Memberwise copy
00315                   factory_set.size (new_len);
00316                 }
00317               else
00318                 {
00319                   // A copy isn't necessary if the last member was
00320                   // deleted.
00321                   factory_set.size (0);
00322                 }
00323 
00324               return;
00325             }
00326         }
00327     }
00328 }
00329 
00330 void
00331 TAO_PG_GenericFactory::poa (PortableServer::POA_ptr p)
00332 {
00333   ACE_ASSERT (CORBA::is_nil (this->poa_.in ())
00334               && !CORBA::is_nil (p));
00335 
00336   this->poa_ = PortableServer::POA::_duplicate (p);
00337 }
00338 
00339 void
00340 TAO_PG_GenericFactory::populate_object_group (
00341   PortableGroup::ObjectGroup_ptr object_group,
00342   const char * type_id,
00343   const PortableGroup::FactoryInfos & factory_infos,
00344   PortableGroup::InitialNumberMembersValue initial_number_members,
00345   TAO_PG_Factory_Set & factory_set)
00346 {
00347   CORBA::ULong factory_infos_count = factory_infos.length ();
00348   factory_set.size (factory_infos_count);
00349 
00350   for (CORBA::ULong j = 0; j < factory_infos_count; ++j)
00351     {
00352       TAO_PG_Factory_Node & factory_node = factory_set[j];
00353 
00354       const PortableGroup::FactoryInfo &factory_info = factory_infos[j];
00355 
00356       if (j < static_cast<CORBA::ULong> (initial_number_members))
00357         {
00358           PortableGroup::GenericFactory_ptr factory =
00359             factory_info.the_factory.in ();
00360 
00361           if (CORBA::is_nil (factory))
00362             {
00363               // @@ instead InvalidProperty?
00364               throw PortableGroup::NoFactory (
00365                 factory_info.the_location,
00366                 type_id);
00367             }
00368 
00369           // Do not allow the PortableGroup::MemberAlreadyPresent
00370           // exception to be propagated to this scope.
00371           const CORBA::Boolean propagate_member_already_present = 0;
00372 
00373           factory_node.factory_creation_id =
00374             this->create_member (object_group,
00375                                  factory_info,
00376                                  type_id,
00377                                  propagate_member_already_present);
00378         }
00379 
00380       factory_node.factory_info = factory_info;  // Memberwise copy
00381     }
00382 }
00383 
00384 void
00385 TAO_PG_GenericFactory::get_ObjectId (
00386   CORBA::ULong fcid,
00387   PortableServer::ObjectId_out oid)
00388 {
00389   // Since the POA used by the LoadManager uses the NON_RETAIN
00390   // policy, explicitly choose an ObjectId that is unique to a given
00391   // type.
00392 
00393   // Make the ObjectId be the next value of the number of types that
00394   // have been registered with the LoadManager.  For example, if two
00395   // types of objects have been registered with the LoadManager, then
00396   // the ObjectId for the object currently being registered will be
00397   // "3" since the object will be the third type of object registered
00398   // with the LoadManager.  Previously used values will not be reused
00399   // to ensure that a ServantLocator does not inadvertently return a
00400   // reference to an object that had a previously used ObjectId.
00401   // Specifcally, the numerical value used for the ObjectId increases
00402   // monotonically.
00403 
00404   // 4294967295UL -- Largest 32 bit unsigned integer
00405   // 123456789012 -- 10 digits
00406   //                + 2 for "UL"  (unnecessary, but let's be safe)
00407   //                + 1 for null terminator
00408   //                + 1 for good luck. :-)
00409   const size_t MAX_OID_LEN = 14;
00410 
00411   char oid_str[MAX_OID_LEN] = { 0 };
00412   ACE_OS::sprintf (oid_str,
00413                    "%ul",
00414                    fcid);
00415 
00416   oid = PortableServer::string_to_ObjectId (oid_str);
00417 }
00418 
00419 void
00420 TAO_PG_GenericFactory::process_criteria (
00421   const char * type_id,
00422   const PortableGroup::Criteria & criteria,
00423   PortableGroup::MembershipStyleValue & membership_style,
00424   PortableGroup::FactoriesValue & factory_infos,
00425   PortableGroup::InitialNumberMembersValue & initial_number_members,
00426   PortableGroup::MinimumNumberMembersValue & minimum_number_members)
00427 {
00428   // Get type-specific properties.
00429   PortableGroup::Properties_var props =
00430     this->property_manager_.get_type_properties (type_id);
00431 
00432   // Merge the given criteria with the type-specific criteria.
00433   TAO_PG::override_properties (criteria, props.inout ());
00434 
00435   PortableGroup::Criteria unmet_criteria;
00436   unmet_criteria.length (4);  // The four criteria understood by this
00437                               // method.
00438 
00439   // Unmet criteria count.
00440   CORBA::ULong uc = 0;
00441 
00442   PortableGroup::Name name (1);
00443   name.length (1);
00444 
00445   PortableGroup::Value value;
00446   PortableGroup::Value value1;
00447   PortableGroup::Value value2;
00448   PortableGroup::Value value3;
00449 
00450   // MembershipStyle
00451   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
00452   if (TAO_PG::get_property_value (name, props.in (), value)
00453       && (!(value >>= membership_style)
00454           || (membership_style != PortableGroup::MEMB_APP_CTRL
00455               && membership_style != PortableGroup::MEMB_INF_CTRL)))
00456     {
00457       // This only occurs if extraction of the actual value from the
00458       // Any fails.
00459       throw PortableGroup::InvalidProperty (name, value);
00460     }
00461 
00462   // Factories
00463   const PortableGroup::FactoryInfos * factory_infos_tmp = 0;
00464   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00465   if (TAO_PG::get_property_value (name, props.in (), value1)
00466       && !(value1 >>= factory_infos_tmp))
00467     {
00468       // This only occurs if extraction of the actual value from the
00469       // Any fails.
00470       throw PortableGroup::InvalidProperty (name, value1);
00471     }
00472 
00473   const CORBA::ULong factory_infos_count =
00474     (factory_infos_tmp == 0 ? 0 : factory_infos_tmp->length ());
00475 
00476   // InitialNumberMembers
00477   name[0].id =
00478     CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00479   if (TAO_PG::get_property_value (name, props.in (), value2)
00480       && !(value2 >>= initial_number_members))
00481     {
00482       // This only occurs if extraction of the actual value from the
00483       // Any fails.
00484       throw PortableGroup::InvalidProperty (name, value2);
00485     }
00486 
00487   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00488     {
00489       // If the number of factories is less than the initial number of
00490       // members or the desired number of initial members cannot
00491       // possibly be created.
00492 
00493       if (factory_infos_count < static_cast<CORBA::ULong> (initial_number_members))
00494         {
00495           unmet_criteria[uc].nam = name;
00496           unmet_criteria[uc++].val = value2;
00497         }
00498     }
00499 
00500   // MinimumNumberMembers
00501   name[0].id =
00502     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00503   if (TAO_PG::get_property_value (name, props.in (), value3)
00504       && !(value3 >>= minimum_number_members))
00505     {
00506       // This only occurs if extraction of the actual value from the
00507       // Any fails.
00508       throw PortableGroup::InvalidProperty (name, value3);
00509     }
00510 
00511   // If the minimum number of members is less than the initial number
00512   // of members, the MinimumNumberMembers property is cannot be
00513   // initially met.
00514   //
00515   // @note This code is not part of the above "MEMB_INF_CTRL" criteria
00516   //       check since the "name" and "value" variables have been
00517   //       changed.
00518   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00519     {
00520       if (minimum_number_members < initial_number_members
00521           || static_cast<CORBA::ULong> (minimum_number_members) > factory_infos_count)
00522         {
00523           unmet_criteria[uc].nam = name;
00524           unmet_criteria[uc++].val = value3;
00525         }
00526       else if (factory_infos_tmp != 0)
00527       {
00528         factory_infos.length (factory_infos_count);
00529         factory_infos = *factory_infos_tmp;
00530       }
00531     }
00532 
00533   if (uc > 0)
00534     {
00535       // Reduce the length of the unmet criteria sequence in an effort
00536       // to optimize the copying that will occur when the below
00537       // exception is thrown.  Reducing the length is fast since no
00538       // deallocations should occur.
00539       unmet_criteria.length (uc);
00540 
00541       throw PortableGroup::CannotMeetCriteria (unmet_criteria);
00542     }
00543 }
00544 
00545 void
00546 TAO_PG_GenericFactory::check_minimum_number_members (
00547   PortableGroup::ObjectGroup_ptr object_group,
00548   CORBA::ULong group_id,
00549   const char * type_id)
00550 {
00551   // Check if we've dropped below the MinimumNumberMembers threshold.
00552   // If so, attempt to create enough new members to fill the gap.
00553 
00554   // If no entry exists in the factory map, infrastructure (this
00555   // GenericFactory implementation) controlled membership was not
00556   // used.
00557   TAO_PG_Factory_Map::ENTRY *entry = 0;
00558   if (this->factory_map_.find (group_id, entry) != 0)
00559     return;
00560 
00561   TAO_PG_Factory_Set & factory_set = entry->int_id_;
00562 
00563   PortableGroup::Properties_var props =
00564     this->property_manager_.get_properties (object_group);
00565 
00566   PortableGroup::Name name (1);
00567   name.length (1);
00568 
00569   PortableGroup::Value value;
00570 
00571   // MinimumNumberMembers
00572   name[0].id =
00573     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00574 
00575   PortableGroup::MinimumNumberMembersValue minimum_number_members;
00576 
00577   if (TAO_PG::get_property_value (name, props.in (), value))
00578     {
00579       if (!(value >>= minimum_number_members))
00580         {
00581           // This only occurs if extraction of the actual value from
00582           // the Any fails.  It shouldn't fail at this point.
00583           throw CORBA::INTERNAL ();
00584         }
00585 
00586       const CORBA::ULong count =
00587         this->object_group_manager_.member_count (object_group);
00588 
00589       if (count >= static_cast<CORBA::ULong> (minimum_number_members))
00590         return;
00591 
00592       const CORBA::ULong gap =
00593         static_cast<CORBA::ULong> (minimum_number_members) - count;
00594 
00595       CORBA::ULong creation_count = 0;
00596 
00597       const size_t len = factory_set.size ();
00598 
00599       static const PortableGroup::GenericFactory::FactoryCreationId *
00600         nil_fcid = 0;
00601 
00602       for (size_t i = 0; i < len; ++i)
00603         {
00604           TAO_PG_Factory_Node & node = factory_set[i];
00605 
00606           PortableGroup::GenericFactory::FactoryCreationId * const tmp_fcid =
00607             node.factory_creation_id;
00608 
00609           // Check if the application supplied GenericFactory was
00610           // already invoked.
00611           if (tmp_fcid != nil_fcid)
00612             continue;
00613 
00614           try
00615             {
00616               const CORBA::Boolean propagate_member_already_present = 1;
00617 
00618               node.factory_creation_id =
00619                 this->create_member (object_group,
00620                                      node.factory_info,
00621                                      type_id,
00622                                      propagate_member_already_present);
00623 
00624               ++creation_count;
00625 
00626               // Check if the MinimumNumberMembers threshold gap has
00627               // been filled.
00628               if (gap == creation_count)
00629                 return;
00630             }
00631           catch (const PortableGroup::MemberAlreadyPresent&)
00632             {
00633               // Ignore this exception and continue.
00634             }
00635         }
00636 
00637       // @todo If we get this far, and the MinimumNumberMembers
00638       //       threshold gap hasn't been filled, what do we do?  Throw
00639       //       a CORBA::TRANSIENT?
00640     }
00641 }
00642 
00643 PortableGroup::GenericFactory::FactoryCreationId *
00644 TAO_PG_GenericFactory::create_member (
00645     PortableGroup::ObjectGroup_ptr object_group,
00646     const PortableGroup::FactoryInfo & factory_info,
00647     const char * type_id,
00648     const CORBA::Boolean propagate_member_already_present)
00649 {
00650   PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00651 
00652   CORBA::Object_var member =
00653     factory_info.the_factory->create_object (type_id,
00654                                              factory_info.the_criteria,
00655                                              fcid.out ());
00656 
00657   try
00658     {
00659       // @@ Should an "_is_a()" be performed here?  While it
00660       //    appears to be the right thing to do, it can be
00661       //    expensive.
00662       //
00663       // Make sure an Object of the correct type was created.
00664       // It is possible that an object of the wrong type was
00665       // created if the type_id parameter does not match the
00666       // type of object the GenericFactory creates.
00667       CORBA::Boolean right_type_id =
00668         member->_is_a (type_id);
00669 
00670       // @todo Strategize this -- e.g. strict type checking.
00671       if (!right_type_id)
00672         {
00673           // An Object of incorrect type was created.  Delete
00674           // it, and throw a NoFactory exception.
00675           factory_info.the_factory->delete_object (fcid.in ());
00676 
00677           throw PortableGroup::NoFactory (factory_info.the_location, type_id);
00678         }
00679 
00680       this->object_group_manager_._tao_add_member (
00681         object_group,
00682         factory_info.the_location,
00683         member.in (),
00684         type_id,
00685         propagate_member_already_present);
00686     }
00687   catch (const CORBA::Exception&)
00688     {
00689       // If the member reference is not nil, then the factory
00690       // was successfully invoked.  Since an exception was
00691       // thrown, clean up the up created member.
00692       if (!CORBA::is_nil (member.in ()))
00693         {
00694           factory_info.the_factory->delete_object (fcid.in ());
00695         }
00696 
00697       throw;
00698     }
00699 
00700   return fcid._retn ();
00701 }
00702 
00703 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:49:50 2010 for TAO_PortableGroup by  doxygen 1.4.7