PG_Property_Set.cpp

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

Generated on Tue Feb 2 17:49:50 2010 for TAO_PortableGroup by  doxygen 1.4.7