PG_PropertyManager.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "orbsvcs/PortableGroup/PG_PropertyManager.h"
00004 #include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h"
00005 #include "orbsvcs/PortableGroup/PG_Property_Utils.h"
00006 
00007 #include "tao/ORB_Constants.h"
00008 
00009 #include "ace/SString.h"
00010 
00011 ACE_RCSID (PortableGroup,
00012            PG_PropertyManager,
00013            "$Id: PG_PropertyManager.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
00014 
00015 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 TAO_PG_PropertyManager::TAO_PG_PropertyManager (
00018   TAO_PG_ObjectGroupManager & object_group_manager)
00019   : object_group_manager_ (object_group_manager),
00020     default_properties_ (),
00021     type_properties_ (),
00022     lock_ (),
00023     property_validator_ ()
00024 {
00025 }
00026 
00027 
00028 void
00029 TAO_PG_PropertyManager::set_default_properties (
00030     const PortableGroup::Properties & props)
00031 {
00032   // First verify that the "Factories" property is not in the
00033   // Properties sequence.  According to the spec, it is not allowed to
00034   // be set as part of the default properties.
00035   PortableGroup::Name factories;
00036   factories.length (1);
00037   factories[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00038 
00039   CORBA::ULong len = props.length ();
00040   for (CORBA::ULong i = 0; i < len; ++i)
00041     {
00042       PortableGroup::Property property = props[i];
00043 
00044       if (property.nam == factories)
00045         throw PortableGroup::InvalidProperty (property.nam, property.val);
00046     }
00047 
00048   this->property_validator_.validate_property (props);
00049 
00050   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00051 
00052   this->default_properties_ = props;
00053 }
00054 
00055 
00056 PortableGroup::Properties *
00057 TAO_PG_PropertyManager::get_default_properties ()
00058 {
00059   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00060 
00061   PortableGroup::Properties * props = 0;
00062   ACE_NEW_THROW_EX (props,
00063                     PortableGroup::Properties (this->default_properties_),
00064                     CORBA::NO_MEMORY (
00065                       CORBA::SystemException::_tao_minor_code (
00066                         TAO::VMCID,
00067                         ENOMEM),
00068                       CORBA::COMPLETED_NO));
00069 
00070   return props;
00071 }
00072 
00073 
00074 void
00075 TAO_PG_PropertyManager::remove_default_properties (
00076     const PortableGroup::Properties &props)
00077 {
00078   if (props.length () == 0)
00079     return;  // @@ Throw CORBA::BAD_PARAM instead?
00080 
00081   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00082 
00083   this->remove_properties (props,
00084                            this->default_properties_);
00085 }
00086 
00087 
00088 void
00089 TAO_PG_PropertyManager::set_type_properties (
00090     const char * type_id,
00091     const PortableGroup::Properties & overrides)
00092 {
00093   this->property_validator_.validate_property (overrides);
00094 
00095   CORBA::ULong num_overrides = overrides.length ();
00096 
00097   if (num_overrides == 0)
00098     return;  // Throw CORBA::BAD_PARAM exception instead?
00099 
00100   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00101 
00102   Type_Prop_Table::ENTRY * entry = 0;
00103   if (this->type_properties_.find (type_id, entry) != 0)
00104     throw CORBA::BAD_PARAM ();
00105 
00106   PortableGroup::Properties & props = entry->int_id_;
00107   props = overrides;
00108 }
00109 
00110 
00111 PortableGroup::Properties *
00112 TAO_PG_PropertyManager::get_type_properties (
00113     const char * type_id)
00114 {
00115   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00116 
00117 
00118   Type_Prop_Table::ENTRY * entry = 0;
00119   PortableGroup::Properties * type_properties = 0;
00120 
00121   if (this->type_properties_.find (type_id, entry) == 0)
00122     type_properties = &entry->int_id_;
00123 
00124   const CORBA::ULong def_props_len = this->default_properties_.length ();
00125   const CORBA::ULong type_props_len =
00126     (type_properties == 0 ? 0 : type_properties->length ());
00127   const CORBA::ULong props_len =
00128     (def_props_len > type_props_len ? def_props_len : type_props_len);
00129 
00130   PortableGroup::Properties * tmp_properties = 0;
00131   ACE_NEW_THROW_EX (tmp_properties,
00132                     PortableGroup::Properties (props_len),
00133                     CORBA::NO_MEMORY (
00134                       CORBA::SystemException::_tao_minor_code (
00135                         TAO::VMCID,
00136                         ENOMEM),
00137                       CORBA::COMPLETED_NO));
00138 
00139   PortableGroup::Properties_var properties = tmp_properties;
00140 
00141   // Set the length to the length of the largest of the two property
00142   // sequences.  The idea is to keep the cost of the incremental
00143   // growth that may occur in TAO_PG::override_properties() to a
00144   // minimum.
00145   properties->length (props_len);
00146 
00147   *tmp_properties = this->default_properties_;
00148 
00149   if (type_properties != 0 && type_props_len > 0)
00150     TAO_PG::override_properties (*type_properties, *tmp_properties);
00151 
00152   return properties._retn ();
00153 }
00154 
00155 
00156 void
00157 TAO_PG_PropertyManager::remove_type_properties (
00158     const char * type_id,
00159     const PortableGroup::Properties & props)
00160 {
00161   if (props.length () == 0)
00162     return;  // @@ Throw CORBA::BAD_PARAM instead?
00163 
00164   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00165 
00166   Type_Prop_Table::ENTRY * entry = 0;
00167   if (this->type_properties_.find (type_id, entry) != 0)
00168     throw CORBA::BAD_PARAM ();
00169 
00170   PortableGroup::Properties & type_properties = entry->int_id_;
00171 
00172   this->remove_properties (props,
00173                            type_properties);
00174 }
00175 
00176 
00177 void
00178 TAO_PG_PropertyManager::set_properties_dynamically (
00179     PortableGroup::ObjectGroup_ptr /* object_group */,
00180     const PortableGroup::Properties & /* overrides */)
00181 {
00182 #if 0
00183   // First verify that the "InitialNumberMembers" property is not in
00184   // the Properties sequence.  According to the spec, it is not
00185   // allowed to be set as part of the default properties.
00186   PortableGroup::Name factories;
00187   factories.length (1);
00188   factories[0].id =
00189     CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00190 
00191   CORBA::ULong len = props.length ();
00192   for (CORBA::ULong i = 0; i < len; ++i)
00193     {
00194       PortableGroup::Property property = props[i];
00195 
00196       if (property.nam == factories)
00197         throw PortableGroup::InvalidProperty (property.nam, property.val);
00198     }
00199 
00200   this->property_validator_.validate_property (overrides);
00201 
00202   // @todo Set the properties in the object group map entry.
00203 #endif  /* 0 */
00204 
00205   throw CORBA::NO_IMPLEMENT ();
00206 }
00207 
00208 
00209 PortableGroup::Properties *
00210 TAO_PG_PropertyManager::get_properties (
00211     PortableGroup::ObjectGroup_ptr object_group)
00212 {
00213   CORBA::ULong properties_len = 0;
00214 
00215   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, property_map_guard, this->lock_, 0);
00216 
00217   // @@ Race condition here!
00218   PortableGroup::Properties_var dynamic_properties =
00219     this->object_group_manager_.get_properties (object_group);
00220 
00221   CORBA::ULong dyn_props_len = dynamic_properties->length ();
00222   if (dyn_props_len > properties_len)
00223     properties_len = dyn_props_len;
00224 
00225   CORBA::String_var type_id =
00226     this->object_group_manager_.type_id (object_group);
00227 
00228   CORBA::ULong type_props_len = 0;
00229   PortableGroup::Properties * type_properties = 0;
00230   Type_Prop_Table::ENTRY * type_entry = 0;
00231   if (this->type_properties_.find (type_id.in (), type_entry) == 0)
00232     {
00233       type_properties = &type_entry->int_id_;
00234       type_props_len = type_properties->length ();
00235 
00236       if (type_props_len > properties_len)
00237         properties_len = type_props_len;
00238     }
00239 
00240   CORBA::ULong def_props_len = this->default_properties_.length ();
00241   if (def_props_len > properties_len)
00242     properties_len = def_props_len;
00243 
00244   PortableGroup::Properties * tmp_properties = 0;
00245   ACE_NEW_THROW_EX (tmp_properties,
00246                     PortableGroup::Properties (properties_len),
00247                     CORBA::NO_MEMORY (
00248                       CORBA::SystemException::_tao_minor_code (
00249                         TAO::VMCID,
00250                         ENOMEM),
00251                       CORBA::COMPLETED_NO));
00252 
00253   PortableGroup::Properties_var properties = tmp_properties;
00254 
00255   // Set the length to the length of the largest of the three property
00256   // sequences.  The idea is to keep the cost of the incremental
00257   // growth that may occur in TAO_PG::override_properties() to a
00258   // minimum.
00259   properties->length (properties_len);
00260 
00261   // Start out with a copy of the default properties.
00262   *tmp_properties = this->default_properties_;
00263 
00264   // Override default properties with type-specific properties.
00265   if (type_properties != 0)
00266     TAO_PG::override_properties (*type_properties, *tmp_properties);
00267 
00268   // Now override with the dynamic (object group) properties.
00269   TAO_PG::override_properties (dynamic_properties.in (), *tmp_properties);
00270 
00271   return properties._retn ();
00272 }
00273 
00274 
00275 void
00276 TAO_PG_PropertyManager::remove_properties (
00277     const PortableGroup::Properties & to_be_removed,
00278     PortableGroup::Properties &properties)
00279 {
00280   const CORBA::ULong num_removed = to_be_removed.length ();
00281   if (num_removed == 0)
00282     return;  // @@ Throw CORBA::BAD_PARAM instead?
00283 
00284   const CORBA::ULong old_length = properties.length ();
00285 
00286   const CORBA::ULong new_length = old_length - num_removed;
00287 
00288   PortableGroup::Properties new_properties (new_length);
00289   new_properties.length (new_length);
00290 
00291   // @@ Slow O(n^2) operation.  Switching to a faster container for
00292   //    the default properties might be a good idea at some point in
00293   //    the future.
00294   CORBA::ULong n = 0;
00295   for (CORBA::ULong i = 0; i < num_removed; ++i)
00296     {
00297       const CORBA::ULong old_n = n;
00298       const PortableGroup::Property &remove = to_be_removed[i];
00299 
00300       for (CORBA::ULong j = 0; j < old_length; ++j)
00301         if (remove.nam != properties[j].nam)
00302           new_properties[n++] = properties[j];
00303 
00304       // The property to be removed doesn't exist in the current list
00305       // of default properties.
00306       if (n == old_n)
00307         throw PortableGroup::InvalidProperty (remove.nam, remove.val);
00308     }
00309 
00310   // All properties were successfully removed, and the remaining ones
00311   // were placed in the "new_properties" variable.  Now copy that
00312   // variable.
00313   properties = new_properties;
00314 }
00315 
00316 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 16:22:31 2008 for TAO_PortableGroup by doxygen 1.3.6