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            "PG_PropertyManager.cpp,v 1.16 2006/03/14 06:14:34 jtc Exp")
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     ACE_ENV_ARG_DECL)
00032   ACE_THROW_SPEC ((CORBA::SystemException,
00033                    PortableGroup::InvalidProperty,
00034                    PortableGroup::UnsupportedProperty))
00035 {
00036   // First verify that the "Factories" property is not in the
00037   // Properties sequence.  According to the spec, it is not allowed to
00038   // be set as part of the default properties.
00039   PortableGroup::Name factories;
00040   factories.length (1);
00041   factories[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00042 
00043   CORBA::ULong len = props.length ();
00044   for (CORBA::ULong i = 0; i < len; ++i)
00045     {
00046       PortableGroup::Property property = props[i];
00047 
00048       if (property.nam == factories)
00049         ACE_THROW (PortableGroup::InvalidProperty (property.nam,
00050                                                    property.val));
00051     }
00052 
00053   this->property_validator_.validate_property (props
00054                                                ACE_ENV_ARG_PARAMETER);
00055   ACE_CHECK;
00056 
00057   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00058 
00059   this->default_properties_ = props;
00060 }
00061 
00062 
00063 PortableGroup::Properties *
00064 TAO_PG_PropertyManager::get_default_properties (
00065     ACE_ENV_SINGLE_ARG_DECL)
00066   ACE_THROW_SPEC ((CORBA::SystemException))
00067 {
00068   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00069 
00070   PortableGroup::Properties * props = 0;
00071   ACE_NEW_THROW_EX (props,
00072                     PortableGroup::Properties (this->default_properties_),
00073                     CORBA::NO_MEMORY (
00074                       CORBA::SystemException::_tao_minor_code (
00075                         TAO::VMCID,
00076                         ENOMEM),
00077                       CORBA::COMPLETED_NO));
00078   ACE_CHECK_RETURN (0);
00079 
00080   return props;
00081 }
00082 
00083 
00084 void
00085 TAO_PG_PropertyManager::remove_default_properties (
00086     const PortableGroup::Properties &props
00087     ACE_ENV_ARG_DECL)
00088   ACE_THROW_SPEC ((CORBA::SystemException,
00089                    PortableGroup::InvalidProperty,
00090                    PortableGroup::UnsupportedProperty))
00091 {
00092   if (props.length () == 0)
00093     return;  // @@ Throw CORBA::BAD_PARAM instead?
00094 
00095   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00096 
00097   this->remove_properties (props,
00098                            this->default_properties_
00099                            ACE_ENV_ARG_PARAMETER);
00100   ACE_CHECK;
00101 }
00102 
00103 
00104 void
00105 TAO_PG_PropertyManager::set_type_properties (
00106     const char * type_id,
00107     const PortableGroup::Properties & overrides
00108     ACE_ENV_ARG_DECL)
00109   ACE_THROW_SPEC ((CORBA::SystemException,
00110                    PortableGroup::InvalidProperty,
00111                    PortableGroup::UnsupportedProperty))
00112 {
00113   this->property_validator_.validate_property (overrides
00114                                                ACE_ENV_ARG_PARAMETER);
00115   ACE_CHECK;
00116 
00117   CORBA::ULong num_overrides = overrides.length ();
00118 
00119   if (num_overrides == 0)
00120     return;  // Throw CORBA::BAD_PARAM exception instead?
00121 
00122   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00123 
00124   Type_Prop_Table::ENTRY * entry = 0;
00125   if (this->type_properties_.find (type_id, entry) != 0)
00126     ACE_THROW (CORBA::BAD_PARAM ());
00127 
00128   PortableGroup::Properties & props = entry->int_id_;
00129   props = overrides;
00130 }
00131 
00132 
00133 PortableGroup::Properties *
00134 TAO_PG_PropertyManager::get_type_properties (
00135     const char * type_id
00136     ACE_ENV_ARG_DECL)
00137   ACE_THROW_SPEC ((CORBA::SystemException))
00138 {
00139   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00140 
00141 
00142   Type_Prop_Table::ENTRY * entry = 0;
00143   PortableGroup::Properties * type_properties = 0;
00144 
00145   if (this->type_properties_.find (type_id, entry) == 0)
00146     type_properties = &entry->int_id_;
00147 
00148   const CORBA::ULong def_props_len = this->default_properties_.length ();
00149   const CORBA::ULong type_props_len =
00150     (type_properties == 0 ? 0 : type_properties->length ());
00151   const CORBA::ULong props_len =
00152     (def_props_len > type_props_len ? def_props_len : type_props_len);
00153 
00154   PortableGroup::Properties * tmp_properties = 0;
00155   ACE_NEW_THROW_EX (tmp_properties,
00156                     PortableGroup::Properties (props_len),
00157                     CORBA::NO_MEMORY (
00158                       CORBA::SystemException::_tao_minor_code (
00159                         TAO::VMCID,
00160                         ENOMEM),
00161                       CORBA::COMPLETED_NO));
00162   ACE_CHECK_RETURN (0);
00163 
00164   PortableGroup::Properties_var properties = tmp_properties;
00165 
00166   // Set the length to the length of the largest of the two property
00167   // sequences.  The idea is to keep the cost of the incremental
00168   // growth that may occur in TAO_PG::override_properties() to a
00169   // minimum.
00170   properties->length (props_len);
00171 
00172   *tmp_properties = this->default_properties_;
00173 
00174   if (type_properties != 0 && type_props_len > 0)
00175     TAO_PG::override_properties (*type_properties, *tmp_properties);
00176 
00177   return properties._retn ();
00178 }
00179 
00180 
00181 void
00182 TAO_PG_PropertyManager::remove_type_properties (
00183     const char * type_id,
00184     const PortableGroup::Properties & props
00185     ACE_ENV_ARG_DECL)
00186   ACE_THROW_SPEC ((CORBA::SystemException,
00187                    PortableGroup::InvalidProperty,
00188                    PortableGroup::UnsupportedProperty))
00189 {
00190   if (props.length () == 0)
00191     return;  // @@ Throw CORBA::BAD_PARAM instead?
00192 
00193   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00194 
00195   Type_Prop_Table::ENTRY * entry = 0;
00196   if (this->type_properties_.find (type_id, entry) != 0)
00197     ACE_THROW (CORBA::BAD_PARAM ());
00198 
00199   PortableGroup::Properties & type_properties = entry->int_id_;
00200 
00201   this->remove_properties (props,
00202                            type_properties
00203                            ACE_ENV_ARG_PARAMETER);
00204   ACE_CHECK;
00205 }
00206 
00207 
00208 void
00209 TAO_PG_PropertyManager::set_properties_dynamically (
00210     PortableGroup::ObjectGroup_ptr /* object_group */,
00211     const PortableGroup::Properties & /* overrides */
00212     ACE_ENV_ARG_DECL)
00213   ACE_THROW_SPEC ((CORBA::SystemException,
00214                    PortableGroup::ObjectGroupNotFound,
00215                    PortableGroup::InvalidProperty,
00216                    PortableGroup::UnsupportedProperty))
00217 {
00218 #if 0
00219   // First verify that the "InitialNumberMembers" property is not in
00220   // the Properties sequence.  According to the spec, it is not
00221   // allowed to be set as part of the default properties.
00222   PortableGroup::Name factories;
00223   factories.length (1);
00224   factories[0].id =
00225     CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00226 
00227   CORBA::ULong len = props.length ();
00228   for (CORBA::ULong i = 0; i < len; ++i)
00229     {
00230       PortableGroup::Property property = props[i];
00231 
00232       if (property.nam == factories)
00233         ACE_THROW (PortableGroup::InvalidProperty (property.nam,
00234                                                    property.val));
00235     }
00236 
00237   this->property_validator_.validate_property (overrides
00238                                                ACE_ENV_ARG_PARAMETER);
00239   ACE_CHECK;
00240 
00241   // @todo Set the properties in the object group map entry.
00242 #endif  /* 0 */
00243 
00244   ACE_THROW (CORBA::NO_IMPLEMENT ());
00245 }
00246 
00247 
00248 PortableGroup::Properties *
00249 TAO_PG_PropertyManager::get_properties (
00250     PortableGroup::ObjectGroup_ptr object_group
00251     ACE_ENV_ARG_DECL)
00252   ACE_THROW_SPEC ((CORBA::SystemException,
00253                    PortableGroup::ObjectGroupNotFound))
00254 {
00255   CORBA::ULong properties_len = 0;
00256 
00257   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, property_map_guard, this->lock_, 0);
00258 
00259   // @@ Race condition here!
00260   PortableGroup::Properties_var dynamic_properties =
00261     this->object_group_manager_.get_properties (object_group
00262                                                 ACE_ENV_ARG_PARAMETER);
00263   ACE_CHECK_RETURN (0);
00264 
00265   CORBA::ULong dyn_props_len = dynamic_properties->length ();
00266   if (dyn_props_len > properties_len)
00267     properties_len = dyn_props_len;
00268 
00269   CORBA::String_var type_id =
00270     this->object_group_manager_.type_id (object_group
00271                                          ACE_ENV_ARG_PARAMETER);
00272   ACE_CHECK_RETURN (0);
00273 
00274   CORBA::ULong type_props_len = 0;
00275   PortableGroup::Properties * type_properties = 0;
00276   Type_Prop_Table::ENTRY * type_entry = 0;
00277   if (this->type_properties_.find (type_id.in (), type_entry) == 0)
00278     {
00279       type_properties = &type_entry->int_id_;
00280       type_props_len = type_properties->length ();
00281 
00282       if (type_props_len > properties_len)
00283         properties_len = type_props_len;
00284     }
00285 
00286   CORBA::ULong def_props_len = this->default_properties_.length ();
00287   if (def_props_len > properties_len)
00288     properties_len = def_props_len;
00289 
00290   PortableGroup::Properties * tmp_properties = 0;
00291   ACE_NEW_THROW_EX (tmp_properties,
00292                     PortableGroup::Properties (properties_len),
00293                     CORBA::NO_MEMORY (
00294                       CORBA::SystemException::_tao_minor_code (
00295                         TAO::VMCID,
00296                         ENOMEM),
00297                       CORBA::COMPLETED_NO));
00298   ACE_CHECK_RETURN (0);
00299 
00300   PortableGroup::Properties_var properties = tmp_properties;
00301 
00302   // Set the length to the length of the largest of the three property
00303   // sequences.  The idea is to keep the cost of the incremental
00304   // growth that may occur in TAO_PG::override_properties() to a
00305   // minimum.
00306   properties->length (properties_len);
00307 
00308   // Start out with a copy of the default properties.
00309   *tmp_properties = this->default_properties_;
00310 
00311   // Override default properties with type-specific properties.
00312   if (type_properties != 0)
00313     TAO_PG::override_properties (*type_properties, *tmp_properties);
00314 
00315   // Now override with the dynamic (object group) properties.
00316   TAO_PG::override_properties (dynamic_properties.in (), *tmp_properties);
00317 
00318   return properties._retn ();
00319 }
00320 
00321 
00322 void
00323 TAO_PG_PropertyManager::remove_properties (
00324     const PortableGroup::Properties & to_be_removed,
00325     PortableGroup::Properties &properties
00326     ACE_ENV_ARG_DECL)
00327   ACE_THROW_SPEC ((CORBA::SystemException,
00328                    PortableGroup::InvalidProperty,
00329                    PortableGroup::UnsupportedProperty))
00330 {
00331   const CORBA::ULong num_removed = to_be_removed.length ();
00332   if (num_removed == 0)
00333     return;  // @@ Throw CORBA::BAD_PARAM instead?
00334 
00335   const CORBA::ULong old_length = properties.length ();
00336 
00337   const CORBA::ULong new_length = old_length - num_removed;
00338 
00339   PortableGroup::Properties new_properties (new_length);
00340   new_properties.length (new_length);
00341 
00342   // @@ Slow O(n^2) operation.  Switching to a faster container for
00343   //    the default properties might be a good idea at some point in
00344   //    the future.
00345   CORBA::ULong n = 0;
00346   for (CORBA::ULong i = 0; i < num_removed; ++i)
00347     {
00348       const CORBA::ULong old_n = n;
00349       const PortableGroup::Property &remove = to_be_removed[i];
00350 
00351       for (CORBA::ULong j = 0; j < old_length; ++j)
00352         if (remove.nam != properties[j].nam)
00353           new_properties[n++] = properties[j];
00354 
00355       // The property to be removed doesn't exist in the current list
00356       // of default properties.
00357       if (n == old_n)
00358         ACE_THROW (PortableGroup::InvalidProperty (remove.nam,
00359                                                    remove.val));
00360     }
00361 
00362   // All properties were successfully removed, and the remaining ones
00363   // were placed in the "new_properties" variable.  Now copy that
00364   // variable.
00365   properties = new_properties;
00366 }
00367 
00368 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 14:03:34 2006 for TAO_PortableGroup by doxygen 1.3.6