summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp316
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