diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp new file mode 100644 index 00000000000..bda9edab8c9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp @@ -0,0 +1,316 @@ +// -*- C++ -*- + +#include "orbsvcs/PortableGroup/PG_PropertyManager.h" +#include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h" +#include "orbsvcs/PortableGroup/PG_Property_Utils.h" + +#include "tao/ORB_Constants.h" + +#include "ace/SString.h" + +ACE_RCSID (PortableGroup, + PG_PropertyManager, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_PG_PropertyManager::TAO_PG_PropertyManager ( + TAO_PG_ObjectGroupManager & object_group_manager) + : object_group_manager_ (object_group_manager), + default_properties_ (), + type_properties_ (), + lock_ (), + property_validator_ () +{ +} + + +void +TAO_PG_PropertyManager::set_default_properties ( + const PortableGroup::Properties & props) +{ + // First verify that the "Factories" property is not in the + // Properties sequence. According to the spec, it is not allowed to + // be set as part of the default properties. + PortableGroup::Name factories; + factories.length (1); + factories[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories"); + + CORBA::ULong len = props.length (); + for (CORBA::ULong i = 0; i < len; ++i) + { + PortableGroup::Property property = props[i]; + + if (property.nam == factories) + throw PortableGroup::InvalidProperty (property.nam, property.val); + } + + this->property_validator_.validate_property (props); + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->default_properties_ = props; +} + + +PortableGroup::Properties * +TAO_PG_PropertyManager::get_default_properties () +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0); + + PortableGroup::Properties * props = 0; + ACE_NEW_THROW_EX (props, + PortableGroup::Properties (this->default_properties_), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + return props; +} + + +void +TAO_PG_PropertyManager::remove_default_properties ( + const PortableGroup::Properties &props) +{ + if (props.length () == 0) + return; // @@ Throw CORBA::BAD_PARAM instead? + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->remove_properties (props, + this->default_properties_); +} + + +void +TAO_PG_PropertyManager::set_type_properties ( + const char * type_id, + const PortableGroup::Properties & overrides) +{ + this->property_validator_.validate_property (overrides); + + CORBA::ULong num_overrides = overrides.length (); + + if (num_overrides == 0) + return; // Throw CORBA::BAD_PARAM exception instead? + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + Type_Prop_Table::ENTRY * entry = 0; + if (this->type_properties_.find (type_id, entry) != 0) + throw CORBA::BAD_PARAM (); + + PortableGroup::Properties & props = entry->int_id_; + props = overrides; +} + + +PortableGroup::Properties * +TAO_PG_PropertyManager::get_type_properties ( + const char * type_id) +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0); + + + Type_Prop_Table::ENTRY * entry = 0; + PortableGroup::Properties * type_properties = 0; + + if (this->type_properties_.find (type_id, entry) == 0) + type_properties = &entry->int_id_; + + const CORBA::ULong def_props_len = this->default_properties_.length (); + const CORBA::ULong type_props_len = + (type_properties == 0 ? 0 : type_properties->length ()); + const CORBA::ULong props_len = + (def_props_len > type_props_len ? def_props_len : type_props_len); + + PortableGroup::Properties * tmp_properties = 0; + ACE_NEW_THROW_EX (tmp_properties, + PortableGroup::Properties (props_len), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + PortableGroup::Properties_var properties = tmp_properties; + + // Set the length to the length of the largest of the two property + // sequences. The idea is to keep the cost of the incremental + // growth that may occur in TAO_PG::override_properties() to a + // minimum. + properties->length (props_len); + + *tmp_properties = this->default_properties_; + + if (type_properties != 0 && type_props_len > 0) + TAO_PG::override_properties (*type_properties, *tmp_properties); + + return properties._retn (); +} + + +void +TAO_PG_PropertyManager::remove_type_properties ( + const char * type_id, + const PortableGroup::Properties & props) +{ + if (props.length () == 0) + return; // @@ Throw CORBA::BAD_PARAM instead? + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + Type_Prop_Table::ENTRY * entry = 0; + if (this->type_properties_.find (type_id, entry) != 0) + throw CORBA::BAD_PARAM (); + + PortableGroup::Properties & type_properties = entry->int_id_; + + this->remove_properties (props, + type_properties); +} + + +void +TAO_PG_PropertyManager::set_properties_dynamically ( + PortableGroup::ObjectGroup_ptr /* object_group */, + const PortableGroup::Properties & /* overrides */) +{ +#if 0 + // First verify that the "InitialNumberMembers" property is not in + // the Properties sequence. According to the spec, it is not + // allowed to be set as part of the default properties. + PortableGroup::Name factories; + factories.length (1); + factories[0].id = + CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers"); + + CORBA::ULong len = props.length (); + for (CORBA::ULong i = 0; i < len; ++i) + { + PortableGroup::Property property = props[i]; + + if (property.nam == factories) + throw PortableGroup::InvalidProperty (property.nam, property.val); + } + + this->property_validator_.validate_property (overrides); + + // @todo Set the properties in the object group map entry. +#endif /* 0 */ + + throw CORBA::NO_IMPLEMENT (); +} + + +PortableGroup::Properties * +TAO_PG_PropertyManager::get_properties ( + PortableGroup::ObjectGroup_ptr object_group) +{ + CORBA::ULong properties_len = 0; + + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, property_map_guard, this->lock_, 0); + + // @@ Race condition here! + PortableGroup::Properties_var dynamic_properties = + this->object_group_manager_.get_properties (object_group); + + CORBA::ULong dyn_props_len = dynamic_properties->length (); + if (dyn_props_len > properties_len) + properties_len = dyn_props_len; + + CORBA::String_var type_id = + this->object_group_manager_.type_id (object_group); + + CORBA::ULong type_props_len = 0; + PortableGroup::Properties * type_properties = 0; + Type_Prop_Table::ENTRY * type_entry = 0; + if (this->type_properties_.find (type_id.in (), type_entry) == 0) + { + type_properties = &type_entry->int_id_; + type_props_len = type_properties->length (); + + if (type_props_len > properties_len) + properties_len = type_props_len; + } + + CORBA::ULong def_props_len = this->default_properties_.length (); + if (def_props_len > properties_len) + properties_len = def_props_len; + + PortableGroup::Properties * tmp_properties = 0; + ACE_NEW_THROW_EX (tmp_properties, + PortableGroup::Properties (properties_len), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + PortableGroup::Properties_var properties = tmp_properties; + + // Set the length to the length of the largest of the three property + // sequences. The idea is to keep the cost of the incremental + // growth that may occur in TAO_PG::override_properties() to a + // minimum. + properties->length (properties_len); + + // Start out with a copy of the default properties. + *tmp_properties = this->default_properties_; + + // Override default properties with type-specific properties. + if (type_properties != 0) + TAO_PG::override_properties (*type_properties, *tmp_properties); + + // Now override with the dynamic (object group) properties. + TAO_PG::override_properties (dynamic_properties.in (), *tmp_properties); + + return properties._retn (); +} + + +void +TAO_PG_PropertyManager::remove_properties ( + const PortableGroup::Properties & to_be_removed, + PortableGroup::Properties &properties) +{ + const CORBA::ULong num_removed = to_be_removed.length (); + if (num_removed == 0) + return; // @@ Throw CORBA::BAD_PARAM instead? + + const CORBA::ULong old_length = properties.length (); + + const CORBA::ULong new_length = old_length - num_removed; + + PortableGroup::Properties new_properties (new_length); + new_properties.length (new_length); + + // @@ Slow O(n^2) operation. Switching to a faster container for + // the default properties might be a good idea at some point in + // the future. + CORBA::ULong n = 0; + for (CORBA::ULong i = 0; i < num_removed; ++i) + { + const CORBA::ULong old_n = n; + const PortableGroup::Property &remove = to_be_removed[i]; + + for (CORBA::ULong j = 0; j < old_length; ++j) + if (remove.nam != properties[j].nam) + new_properties[n++] = properties[j]; + + // The property to be removed doesn't exist in the current list + // of default properties. + if (n == old_n) + throw PortableGroup::InvalidProperty (remove.nam, remove.val); + } + + // All properties were successfully removed, and the remaining ones + // were placed in the "new_properties" variable. Now copy that + // variable. + properties = new_properties; +} + +TAO_END_VERSIONED_NAMESPACE_DECL |