PG_Property_Set.cpp

Go to the documentation of this file.
00001 //=============================================================================
00002 /**
00003  *  @file    PG_Property_Set.cpp
00004  *
00005  *  PG_Property_Set.cpp,v 1.15 2006/03/14 06:14:34 jtc Exp
00006  *
00007  *  This file implements classes to help manage the Properties
00008  *  defined in the Portable Object Group.
00009  *
00010  *  Note: this started as a simple helper class to make decoding sets of properties
00011  *  easier, but expanded to provide more general support for managing sets of properties.
00012  *
00013  *  @author Dale Wilson <wilson_d@ociweb.com>
00014  */
00015 //=============================================================================
00016 #include "orbsvcs/PortableGroup/PG_Property_Set.h"
00017 #include "tao/debug.h"
00018 
00019 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 //////////////////////
00022 // PG_Property_Set
00023 
00024 TAO::PG_Property_Set::PG_Property_Set()
00025   : defaults_ (0)
00026 {
00027 }
00028 
00029 TAO::PG_Property_Set::PG_Property_Set (
00030   const PortableGroup::Properties & property_set
00031     ACE_ENV_ARG_DECL)
00032   ACE_THROW_SPEC ((CORBA::SystemException))
00033   : defaults_ (0)
00034 {
00035   this->decode (property_set ACE_ENV_ARG_PARAMETER);
00036 }
00037 
00038 TAO::PG_Property_Set::PG_Property_Set (
00039     const PortableGroup::Properties & property_set,
00040     PG_Property_Set * defaults
00041     ACE_ENV_ARG_DECL)
00042   ACE_THROW_SPEC ((CORBA::SystemException))
00043   : defaults_ (defaults)
00044 {
00045   this->decode (property_set ACE_ENV_ARG_PARAMETER);
00046 }
00047 
00048 
00049 TAO::PG_Property_Set::PG_Property_Set (
00050     PG_Property_Set * defaults)
00051   : defaults_ (defaults)
00052 {
00053 }
00054 
00055 TAO::PG_Property_Set::~PG_Property_Set ()
00056 {
00057   this->clear ();
00058 }
00059 
00060 void
00061 TAO::PG_Property_Set::decode (const PortableGroup::Properties & property_set
00062                               ACE_ENV_ARG_DECL)
00063   ACE_THROW_SPEC ((CORBA::SystemException))
00064 {
00065   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00066 
00067   size_t count = property_set.length ();
00068   for (size_t nItem = 0; nItem < count; ++nItem)
00069   {
00070     const PortableGroup::Property & property = property_set[nItem];
00071     const CosNaming::Name & nsName = property.nam;
00072     // note assumption one level name with no kind
00073     // @@ TODO: fix this
00074     const CosNaming::NameComponent & nc = nsName[0];
00075 
00076     this->set_property (static_cast<const char *> (nc.id),
00077                         property.val
00078                         ACE_ENV_ARG_PARAMETER);
00079     ACE_CHECK;
00080 
00081 #if 0
00082     ACE_CString name = static_cast<const char *> (nc.id);
00083 
00084     const PortableGroup::Value * value_copy;
00085     ACE_NEW_THROW_EX (value_copy,
00086                       PortableGroup::Value (property.val),
00087                       CORBA::NO_MEMORY ());
00088     ACE_CHECK;
00089 
00090     const PortableGroup::Value * replaced_value = 0;
00091     if (0 == this->values_.rebind (name, value_copy, replaced_value))
00092     {
00093       if (0 != replaced_value)
00094       {
00095         delete replaced_value;
00096       }
00097     }
00098     else
00099     {
00100       if (TAO_debug_level > 3)
00101       {
00102         ACE_ERROR ( (LM_ERROR,
00103           "%n\n%T: Property_set: rebind failed.\n"
00104           ));
00105       }
00106       // @@ should throw something here
00107       ACE_THROW (CORBA::NO_MEMORY ());
00108     }
00109 #endif
00110   }
00111 }
00112 
00113 void TAO::PG_Property_Set::clear ()
00114 {
00115   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00116   for (ValueMapIterator it = this->values_.begin ();
00117        it != this->values_.end ();
00118        ++it)
00119   {
00120     delete (*it).int_id_;
00121   }
00122   this->values_.unbind_all ();
00123 }
00124 
00125 void TAO::PG_Property_Set::remove (const PortableGroup::Properties & property_set)
00126   ACE_THROW_SPEC ((CORBA::SystemException))
00127 {
00128   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00129   size_t count = property_set.length ();
00130   for (size_t nItem = 0; nItem < count; ++nItem)
00131   {
00132     const PortableGroup::Property & property = property_set[nItem];
00133     const CosNaming::Name & nsName = property.nam;
00134     // note assumption one level name with no kind
00135     // @@ TODO: fix this
00136     const CosNaming::NameComponent & nc = nsName[0];
00137     ACE_CString name = static_cast<const char *> (nc.id);
00138 
00139     const PortableGroup::Value * deleted_value;
00140     if ( 0 == this->values_.unbind (name, deleted_value))
00141     {
00142       delete deleted_value;
00143     }
00144     else
00145     {
00146       // don't worry about it.
00147     }
00148   }
00149 }
00150 
00151 void TAO::PG_Property_Set::set_property (
00152   const char * name,
00153   const PortableGroup::Value & value
00154   ACE_ENV_ARG_DECL)
00155 {
00156   ACE_CString key (name);
00157   PortableGroup::Value * value_copy;
00158   ACE_NEW_THROW_EX (
00159     value_copy, PortableGroup::Value (value),
00160     CORBA::NO_MEMORY ());
00161   ACE_CHECK;
00162 
00163   const PortableGroup::Value * replaced_value = 0;
00164   if (0 == this->values_.rebind (name, value_copy, replaced_value))
00165   {
00166     if (0 != replaced_value)
00167     {
00168       delete replaced_value;
00169     }
00170   }
00171   else
00172   {
00173     if (TAO_debug_level > 3)
00174     {
00175       ACE_ERROR ( (LM_ERROR,
00176         "%n\n%T: Property_set: rebind failed.\n"
00177         ));
00178     }
00179     // @@ should throw something here
00180     ACE_THROW (CORBA::NO_MEMORY ());
00181   }
00182 }
00183 
00184 
00185 
00186 void TAO::PG_Property_Set::export_properties(PortableGroup::Properties & property_set) const
00187 {
00188   ValueMap merged_values;
00189   this->merge_properties (merged_values);
00190 
00191   property_set.length (merged_values.current_size ());
00192 
00193   size_t pos = 0;
00194   for (ValueMapIterator it = merged_values.begin ();
00195         it != merged_values.end ();
00196         ++it)
00197   {
00198     const ACE_CString & name = (*it).ext_id_;
00199     const PortableGroup::Value * value = (*it).int_id_;
00200 
00201     PortableGroup::Property & property = property_set[pos];
00202     CosNaming::Name & nsName = property.nam;
00203     //@@ note assumption: single level name, no kind
00204     nsName.length(1);
00205     CosNaming::NameComponent & nc = nsName[0];
00206     nc.id = CORBA::string_dup (name.c_str ());
00207     PortableGroup::Value & val = property.val;
00208     val = *value;  // NOTE: Any assignment does a deep copy
00209     ++pos;
00210   }
00211   ACE_ASSERT (pos == property_set.length ());
00212 }
00213 
00214 void TAO::PG_Property_Set::merge_properties (ValueMap & merged_values) const
00215 {
00216   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00217   if (0 != this->defaults_)
00218   {
00219     this->defaults_->merge_properties (merged_values);
00220   }
00221   // note AFICT ACE_Hash_Map does not support const iterators, hence the const cast.
00222   ValueMap & mutable_values = const_cast<ValueMap &> (this->values_);
00223   for (ValueMapIterator it = mutable_values.begin ();
00224         it != mutable_values.end ();
00225         ++it)
00226   {
00227     merged_values.rebind ( (*it).ext_id_, (*it).int_id_);
00228   }
00229 }
00230 
00231 
00232 
00233 int TAO::PG_Property_Set::find (
00234   const ACE_CString & key,
00235   const PortableGroup::Value *& pValue) const
00236 {
00237   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->internals_, 0);
00238   int found = (0 == this->values_.find (key, pValue));
00239   if (! found)
00240   {
00241     if (0 != this->defaults_)
00242     {
00243       found = this->defaults_->find (key, pValue);
00244     }
00245   }
00246   return found;
00247 }
00248 
00249 TAO_END_VERSIONED_NAMESPACE_DECL
00250 
00251 //#define PG_PS_UNIT_TEST
00252 #ifdef PG_PS_UNIT_TEST
00253 #include "orbsvcs/PortableGroup/PG_Properties_Encoder.h"
00254 
00255 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00256 
00257 int TAO_PG::test_encode_decode ()
00258 {
00259   int result = 1;
00260   static const long testLong = 123456L;
00261   static const char * testLongKey = "MyLong";
00262 
00263   static const char * testString = "Now is the time for all good people.";
00264   static const char * testStringKey = "plover";
00265 
00266   static const double testDouble = 3.1415;
00267   static const char * testDoubleKey = "pi";
00268 
00269   PortableGroup::Properties_var property_set = new PortableGroup::Properties;
00270   //scope encoder to be sure its gone before decoding
00271   {
00272     TAO_PG::Encoder encoder;
00273     PortableGroup::Value value;
00274     value <<= (CORBA::Long) testLong;
00275     encoder.add (testLongKey, value);
00276 
00277     value <<= testString;
00278     encoder.add (testStringKey, value);
00279 
00280     value <<= (CORBA::Double) testDouble;
00281     encoder.add (testDoubleKey, value);
00282 
00283     encoder.encode (property_set);
00284   }
00285 
00286   TAO::PG_Property_Set decoder (property_set);
00287 
00288   CORBA::Long longResult = 0;
00289   if (find (decoder, testLongKey, longResult) )
00290   {
00291     if (longResult != testLong)
00292     {
00293       ACE_ERROR ( (LM_ERROR,
00294         "%n\n%T: %s = %d expecting %d\n",
00295           testLongKey,
00296           (int)longResult,
00297           (int)testLong
00298         ));
00299       result = 0;
00300     }
00301   }
00302   else
00303   {
00304     ACE_ERROR ( (LM_ERROR,
00305       "%n\n%T: Can't find value for %s\n", testLongKey
00306       ));
00307     result = 0;
00308   }
00309 
00310   const char * stringResult = "";
00311   if (find (decoder, testStringKey, stringResult))
00312   {
00313     if (0 != ACE_OS::strcmp (testString, stringResult))
00314     {
00315       ACE_ERROR ( (LM_ERROR,
00316         "%n\n%T: %s = \"%s\" expecting \"%s\"\n",
00317           testStringKey,
00318           (int)stringResult,
00319           (int)testString
00320         ));
00321       result = 0;
00322     }
00323   }
00324   else
00325   {
00326     ACE_ERROR ( (LM_ERROR,
00327       "%n\n%T: Can't find value for %s\n", testStringKey
00328       ));
00329     result = 0;
00330   }
00331 
00332 
00333   CORBA::Double doubleResult = 0.0;
00334   if (find (decoder, testDoubleKey, doubleResult))
00335   {
00336     if (doubleResult != testDouble)
00337     {
00338       ACE_ERROR ( (LM_ERROR,
00339         "%n\n%T: %s = \"%f\" expecting \"%f\"\n",
00340           testDoubleKey,
00341           doubleResult,
00342           testDouble
00343         ));
00344       result = 0;
00345     }
00346   }
00347   else
00348   {
00349     ACE_ERROR ( (LM_ERROR,
00350       "%n\n%T: Can't find value for %s\n", testDoubleKey
00351       ));
00352     result = 0;
00353   }
00354 
00355   return result;
00356 }
00357 
00358 TAO_END_VERSIONED_NAMESPACE_DECL
00359 
00360 #endif // PG_PS_UNIT_TEST

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