Trader_Utils.cpp

Go to the documentation of this file.
00001 // Trader_Utils.cpp,v 1.57 2006/04/25 11:35:29 jwillemsen Exp
00002 
00003 #include "orbsvcs/Trader/Trader_Utils.h"
00004 #include "ace/OS_NS_string.h"
00005 
00006 ACE_RCSID(Trader, Trader_Utils, "Trader_Utils.cpp,v 1.57 2006/04/25 11:35:29 jwillemsen Exp")
00007 
00008 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00009 
00010 bool
00011 operator== (CORBA::String_var const & lhs,
00012             CORBA::String_var const & rhs)
00013 {
00014   return (ACE_OS::strcmp (lhs.in (), rhs.in ()) == 0);
00015 }
00016 
00017 TAO_Policy_Creator::TAO_Policy_Creator (int num_policies)
00018   : policies_ (num_policies),
00019     num_policies_ (0)
00020 {
00021   for (int i = 0; i < TAO_Policies::REQUEST_ID + 1; i++)
00022     this->poltable_[i] = -1;
00023 }
00024 
00025 void
00026 TAO_Policy_Creator::search_card (CORBA::ULong scard)
00027 {
00028   CosTrading::Policy& policy =
00029     this->fetch_next_policy (TAO_Policies::SEARCH_CARD);
00030   policy.value <<= scard;
00031 }
00032 
00033 void
00034 TAO_Policy_Creator::match_card (CORBA::ULong mcard)
00035 {
00036   CosTrading::Policy& policy =
00037     this->fetch_next_policy (TAO_Policies::MATCH_CARD);
00038   policy.value <<= mcard;
00039 }
00040 
00041 void
00042 TAO_Policy_Creator::return_card (CORBA::ULong rcard)
00043 {
00044   CosTrading::Policy& policy =
00045     this->fetch_next_policy (TAO_Policies::RETURN_CARD);
00046   policy.value <<= rcard;
00047 }
00048 
00049 void
00050 TAO_Policy_Creator::use_modifiable_properties (CORBA::Boolean mod_props)
00051 {
00052   CosTrading::Policy& policy =
00053     this->fetch_next_policy (TAO_Policies::USE_MODIFIABLE_PROPERTIES);
00054   policy.value <<= CORBA::Any::from_boolean (mod_props);
00055 }
00056 
00057 void
00058 TAO_Policy_Creator::use_dynamic_properties (CORBA::Boolean dyn_props)
00059 {
00060   CosTrading::Policy& policy =
00061     this->fetch_next_policy (TAO_Policies::USE_DYNAMIC_PROPERTIES);
00062   policy.value <<= CORBA::Any::from_boolean (dyn_props);
00063 }
00064 
00065 void
00066 TAO_Policy_Creator::use_proxy_offers (CORBA::Boolean prox_offs)
00067 {
00068   CosTrading::Policy& policy =
00069     this->fetch_next_policy (TAO_Policies::USE_PROXY_OFFERS);
00070   policy.value <<= CORBA::Any::from_boolean (prox_offs);
00071 }
00072 
00073 void
00074 TAO_Policy_Creator::starting_trader (const CosTrading::TraderName& name)
00075 {
00076   CosTrading::Policy& policy =
00077     this->fetch_next_policy (TAO_Policies::STARTING_TRADER);
00078   policy.value <<= name;
00079 }
00080 
00081 void
00082 TAO_Policy_Creator::starting_trader (CosTrading::TraderName* name)
00083 {
00084   CosTrading::Policy& policy =
00085     this->fetch_next_policy (TAO_Policies::STARTING_TRADER);
00086   policy.value <<= name;
00087 }
00088 
00089 void
00090 TAO_Policy_Creator::
00091 link_follow_rule (CosTrading::FollowOption follow_option)
00092 {
00093   CosTrading::Policy& policy =
00094     this->fetch_next_policy (TAO_Policies::LINK_FOLLOW_RULE);
00095   policy.value <<= follow_option;
00096 }
00097 
00098 void
00099 TAO_Policy_Creator::hop_count (CORBA::ULong hop_count)
00100 {
00101   CosTrading::Policy& policy =
00102     this->fetch_next_policy (TAO_Policies::HOP_COUNT);
00103   policy.value <<= hop_count;
00104 }
00105 
00106 void
00107 TAO_Policy_Creator::exact_type_match (CORBA::Boolean exact_type)
00108 {
00109   CosTrading::Policy& policy =
00110     this->fetch_next_policy (TAO_Policies::EXACT_TYPE_MATCH);
00111   policy.value <<= CORBA::Any::from_boolean (exact_type);
00112 }
00113 
00114 void
00115 TAO_Policy_Creator::request_id (const CosTrading::Admin::OctetSeq& request_id)
00116 {
00117   CosTrading::Policy& policy =
00118     this->fetch_next_policy (TAO_Policies::REQUEST_ID);
00119   policy.value <<= request_id;
00120 }
00121 
00122 TAO_Policy_Creator::operator const CosTrading::PolicySeq& (void) const
00123 {
00124   return this->policies_;
00125 }
00126 
00127 const CosTrading::PolicySeq&
00128 TAO_Policy_Creator::policy_seq (void) const
00129 {
00130   return this->policies_;
00131 }
00132 
00133 CosTrading::Policy&
00134 TAO_Policy_Creator::fetch_next_policy (TAO_Policies::POLICY_TYPE pol_type)
00135 {
00136   CORBA::ULong index = 0;
00137 
00138   if (this->poltable_[pol_type] == -1)
00139     {
00140       // Expand the policy sequence, and copy in the policy name into
00141       // the new element.
00142       CORBA::ULong length = this->policies_.length ();
00143       this->num_policies_++;
00144 
00145       if (length < this->num_policies_)
00146         this->policies_.length (this->num_policies_);
00147 
00148       index = this->num_policies_ - 1;
00149 
00150       // Ensure the starting trader policy gets the first slot.
00151       if (pol_type != TAO_Policies::STARTING_TRADER
00152           || index == 0)
00153         {
00154           this->policies_[index].name = TAO_Policies::POLICY_NAMES[pol_type];
00155           this->poltable_[pol_type] = index;
00156         }
00157       else
00158         {
00159           // Copy the element in the first slot to the newly
00160           // allocated slot.
00161           TAO_Policies::POLICY_TYPE occupying_policy =
00162             TAO_Policies::STARTING_TRADER;
00163           for (CORBA::ULong i = 0; i < this->num_policies_ - 1; i++)
00164             {
00165               if (this->poltable_[i] == 0)
00166                 {
00167                   occupying_policy =
00168                     static_cast<TAO_Policies::POLICY_TYPE> (i);
00169                   break;
00170                 }
00171             }
00172 
00173           this->poltable_[occupying_policy] = index;
00174           this->poltable_[TAO_Policies::STARTING_TRADER] = 0;
00175           this->policies_[index].name =
00176             TAO_Policies::POLICY_NAMES[occupying_policy];
00177           this->policies_[index].value = this->policies_[0].value;
00178           this->policies_[0].name =
00179             TAO_Policies::POLICY_NAMES[TAO_Policies::STARTING_TRADER];
00180 
00181           index = 0;
00182         }
00183     }
00184   else
00185     index = this->poltable_[pol_type];
00186 
00187   return this->policies_[index];
00188 }
00189 
00190 // Constructor
00191 
00192 TAO_Property_Evaluator::
00193 TAO_Property_Evaluator(const CosTrading::PropertySeq& props,
00194                        CORBA::Boolean supports_dp)
00195   : props_ (props),
00196     supports_dp_ (supports_dp),
00197     dp_cache_ (new CORBA::Any*[props.length ()])
00198 {
00199   if (this->dp_cache_ != 0)
00200     {
00201       for (CORBA::ULong i = 0; i < this->props_.length (); i++)
00202         this->dp_cache_[i] = 0;
00203     }
00204 }
00205 
00206 
00207 TAO_Property_Evaluator::
00208 TAO_Property_Evaluator(CosTrading::Offer& offer,
00209                        CORBA::Boolean supports_dp)
00210   : props_ (offer.properties),
00211     supports_dp_ (supports_dp),
00212     dp_cache_ (new CORBA::Any*[offer.properties.length ()])
00213 {
00214   if (this->dp_cache_ != 0)
00215     for (CORBA::ULong i = 0; i < this->props_.length (); i++)
00216       this->dp_cache_[i] = 0;
00217 }
00218 
00219 TAO_Property_Evaluator::~TAO_Property_Evaluator (void)
00220 {
00221   // Clean up the results of any dynamic properties.
00222   for (CORBA::ULong i = 0; i < this->props_.length (); i++)
00223     if (this->dp_cache_[i] != 0)
00224       delete this->dp_cache_[i];
00225 
00226   delete [] this->dp_cache_;
00227 }
00228 
00229 int
00230 TAO_Property_Evaluator::is_dynamic_property (int index)
00231 {
00232   int return_value = 0;
00233   int num_properties = this->props_.length();
00234 
00235   // Ensure index is in bounds.
00236   if (index >= 0 && index < num_properties)
00237     {
00238       // Obtain the value of the property at index <index>.
00239       const CORBA::Any& value = this->props_[index].value;
00240       CORBA::TypeCode_var type = value.type ();
00241 
00242       // @@ Seth, this will not work on platforms using environment variable.
00243       ACE_DECLARE_NEW_CORBA_ENV;
00244       CORBA::Boolean equal = type->equal (CosTradingDynamic::_tc_DynamicProp
00245                                           ACE_ENV_ARG_PARAMETER);
00246       ACE_CHECK_RETURN (0);
00247 
00248       if (equal)
00249         return_value = 1;
00250     }
00251 
00252   return return_value;
00253 }
00254 
00255 CORBA::Any*
00256 TAO_Property_Evaluator::property_value (int index
00257                                         ACE_ENV_ARG_DECL)
00258     ACE_THROW_SPEC ((CosTradingDynamic::DPEvalFailure))
00259 {
00260   CORBA::Any* prop_val = 0;
00261   CORBA::Boolean in_cache =
00262     this->dp_cache_ != 0 && this->dp_cache_[index] != 0;
00263 
00264   int dynamic = this->is_dynamic_property (index);
00265 
00266   if (!dynamic)
00267     prop_val = (CORBA::Any *) &(this->props_[index].value);
00268   else if (this->supports_dp_ && in_cache)
00269     prop_val = this->dp_cache_[index];
00270   else if (this->supports_dp_)
00271     {
00272       // Property is defined at this point.
00273       CosTradingDynamic::DynamicProp* dp_struct;
00274       const CORBA::String_var name = this->props_[index].name.in ();
00275       const CORBA::Any& value = this->props_[index].value;
00276 
00277       // Extract the DP_Struct.
00278       value >>= dp_struct;
00279 
00280       CosTradingDynamic::DynamicPropEval_var dp_eval =
00281         CosTradingDynamic::DynamicPropEval::_duplicate (dp_struct->eval_if.in ());
00282 
00283       if (CORBA::is_nil (dp_eval.in ()))
00284         {
00285           ACE_THROW_RETURN (CosTradingDynamic::
00286                             DPEvalFailure (name,
00287                                            CORBA::TypeCode::_nil (),
00288                                            CORBA::Any ()),
00289                             prop_val);
00290         }
00291       else
00292         {
00293           CORBA::TypeCode* type = dp_struct->returned_type.in ();
00294           CORBA::Any& info = dp_struct->extra_info;
00295 
00296           ACE_TRY
00297             {
00298               // Retrieve the value of the dynamic property.
00299               prop_val = dp_eval->evalDP(name, type, info ACE_ENV_ARG_PARAMETER);
00300               ACE_TRY_CHECK;
00301 
00302               if (this->dp_cache_ != 0)
00303                 this->dp_cache_[index] = prop_val;
00304             }
00305           ACE_CATCH (CORBA::SystemException, excp)
00306             {
00307               ACE_TRY_THROW
00308                 (CosTradingDynamic::DPEvalFailure (name, type, info));
00309             }
00310           ACE_ENDTRY;
00311           ACE_CHECK_RETURN (prop_val);
00312         }
00313     }
00314 
00315   return prop_val;
00316 }
00317 
00318 CORBA::TypeCode_ptr
00319 TAO_Property_Evaluator::property_type (int index)
00320 {
00321   CORBA::TypeCode_ptr prop_type = CORBA::TypeCode::_nil();
00322 
00323   // Determine if property is both defined and dynamic.
00324   if (this->is_dynamic_property (index))
00325     {
00326       // Extract type information from the DP_Struct.
00327       const CORBA::Any& value = this->props_[index].value;
00328       CosTradingDynamic::DynamicProp* dp_struct = 0;
00329       value >>= dp_struct;
00330 
00331       // Grab a pointer to the returned_type description
00332       prop_type = CORBA::TypeCode::_duplicate (dp_struct->returned_type.in ());
00333     }
00334   else
00335     // TypeCode is self-evident at this point.
00336     prop_type = this->props_[index].value.type ();
00337 
00338   return prop_type;
00339 }
00340 
00341 TAO_Property_Evaluator_By_Name::
00342 TAO_Property_Evaluator_By_Name (const CosTrading::PropertySeq& properties
00343                                 ACE_ENV_ARG_DECL,
00344                                 CORBA::Boolean supports_dp)
00345   ACE_THROW_SPEC ((CosTrading::DuplicatePropertyName,
00346                    CosTrading::IllegalPropertyName))
00347     : TAO_Property_Evaluator (properties, supports_dp)
00348 {
00349   int length = this->props_.length();
00350 
00351   for (int i = 0; i < length; i++)
00352     {
00353       const CosTrading::Property& prop = this->props_[i];
00354 
00355       if (! TAO_Trader_Base::is_valid_property_name (prop.name))
00356         ACE_THROW (CosTrading::IllegalPropertyName (prop.name));
00357 
00358       CORBA::String_var prop_name = prop.name.in ();
00359       if (this->table_.bind (prop_name, i))
00360         ACE_THROW (CosTrading::DuplicatePropertyName (prop.name));
00361     }
00362 }
00363 
00364 TAO_Property_Evaluator_By_Name::
00365 TAO_Property_Evaluator_By_Name(CosTrading::Offer& offer,
00366                                CORBA::Boolean supports_dp)
00367   : TAO_Property_Evaluator(offer, supports_dp)
00368 {
00369   int length = this->props_.length();
00370 
00371   for (int i = 0; i < length; i++)
00372     {
00373       CORBA::String_var prop_name = (const char*) this->props_[i].name;
00374       this->table_.bind (prop_name, i);
00375     }
00376 }
00377 
00378 int
00379 TAO_Property_Evaluator_By_Name::
00380 is_dynamic_property(const char* property_name)
00381 {
00382   int predicate = 0;
00383   int index = 0;
00384   CORBA::String_var prop_name (property_name);
00385 
00386   // If the property name is in the map, delegate evaluation to our
00387   // superclass. Otherwise, throw an exception.
00388   if (this->table_.find (prop_name, index) == 0)
00389     predicate = this->TAO_Property_Evaluator::is_dynamic_property(index);
00390 
00391   return predicate;
00392 }
00393 
00394 CORBA::Any*
00395 TAO_Property_Evaluator_By_Name::property_value (const char* property_name
00396                                                 ACE_ENV_ARG_DECL)
00397   ACE_THROW_SPEC ((CosTradingDynamic::DPEvalFailure))
00398 {
00399   int index = 0;
00400   CORBA::Any* prop_value = 0;
00401   CORBA::String_var prop_name (property_name);
00402 
00403   // If the property name is in the map, delegate evaluation to our
00404   // superclass. Otherwise, throw an exception.
00405   if (this->table_.find (prop_name, index) == 0)
00406     {
00407       prop_value =
00408         this->TAO_Property_Evaluator::property_value (index
00409                                                       ACE_ENV_ARG_PARAMETER);
00410       ACE_CHECK_RETURN (0);
00411     }
00412 
00413   return prop_value;
00414 }
00415 
00416 CORBA::TypeCode_ptr
00417 TAO_Property_Evaluator_By_Name::property_type (const char* property_name)
00418 {
00419   int index = 0;
00420   CORBA::String_var prop_name (property_name);
00421   CORBA::TypeCode_ptr prop_type = CORBA::TypeCode::_nil();
00422 
00423   // If the property name is in the map, delegate evaluation to our
00424   // superclass. Otherwise, throw an exception.
00425   if (this->table_.find (prop_name, index) == 0)
00426     prop_type = this->TAO_Property_Evaluator::property_type (index);
00427 
00428   return prop_type;
00429 }
00430 
00431 const CosTrading::Property*
00432 TAO_Property_Evaluator_By_Name::get_property (const char* property_name)
00433 {
00434   int index = 0;
00435   CosTrading::Property* property = 0;
00436   CORBA::String_var prop_name (property_name);
00437 
00438   if (this->table_.find (prop_name, index) == 0)
00439     property = (CosTrading::Property *) &this->props_[index];
00440 
00441   return property;
00442 }
00443 
00444 TAO_Dynamic_Property::~TAO_Dynamic_Property (void)
00445 {
00446 }
00447 
00448 CosTradingDynamic::DynamicProp*
00449 TAO_Dynamic_Property::
00450 construct_dynamic_prop (const char* name,
00451                         CORBA::TypeCode_ptr returned_type,
00452                         const CORBA::Any& extra_info)
00453 {
00454   ACE_UNUSED_ARG (name);
00455 
00456   CosTradingDynamic::DynamicProp* dp_struct = 0;
00457 
00458   ACE_NEW_RETURN (dp_struct,
00459                   CosTradingDynamic::DynamicProp,
00460                   0);
00461 
00462   if (this->prop_.in () == CosTradingDynamic::DynamicPropEval::_nil ())
00463     {
00464       // Seth, we need a way to either propagate exceptions out.
00465       ACE_DECLARE_NEW_CORBA_ENV;
00466 
00467       this->prop_ = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
00468       ACE_CHECK_RETURN (0);
00469 
00470       this->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00471       ACE_CHECK_RETURN (0);
00472     }
00473 
00474   dp_struct->eval_if =
00475     CosTradingDynamic::DynamicPropEval::_duplicate (this->prop_.in ());
00476 
00477   dp_struct->returned_type =
00478     CORBA::TypeCode::_duplicate (returned_type);
00479   dp_struct->extra_info = extra_info;
00480 
00481   return dp_struct;
00482 }
00483 
00484 void
00485 TAO_Dynamic_Property::destroy (void)
00486 {
00487   if (this->prop_.in () != CosTradingDynamic::DynamicPropEval::_nil ())
00488     {
00489       // @@ Seth, we need a way to propagate exceptions out.
00490       ACE_DECLARE_NEW_CORBA_ENV;
00491       PortableServer::POA_var poa = this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
00492       ACE_CHECK;
00493 
00494       PortableServer::ObjectId_var id =
00495         poa->servant_to_id (this
00496                             ACE_ENV_ARG_PARAMETER);
00497       ACE_CHECK;
00498 
00499       poa->deactivate_object (id.in ()
00500                               ACE_ENV_ARG_PARAMETER);
00501       ACE_CHECK;
00502     }
00503 }
00504 
00505 const char* TAO_Policies::POLICY_NAMES[] =
00506 {
00507   "starting_trader",
00508   "exact_type_match",
00509   "hop_count",
00510   "link_follow_rule",
00511   "match_card",
00512   "return_card",
00513   "search_card",
00514   "use_dynamic_properties",
00515   "use_modifiable_properties",
00516   "use_proxy_offers",
00517   "request_id"
00518 };
00519 
00520 TAO_Policies::TAO_Policies (TAO_Trader_Base& trader,
00521                             const CosTrading::PolicySeq& policies
00522                             ACE_ENV_ARG_DECL)
00523   ACE_THROW_SPEC ((CosTrading::Lookup::IllegalPolicyName,
00524                   CosTrading::DuplicatePolicyName))
00525   : trader_ (trader)
00526 {
00527   for (int i = 0; i < TAO_NUM_POLICIES; i++)
00528     this->policies_[i] = 0;
00529 
00530   for (CORBA::ULong j = 0; j < policies.length (); j++)
00531     {
00532       const char *pol_name = (const char *) policies[j].name;
00533       size_t length = (pol_name == 0) ? 0 : ACE_OS::strlen (pol_name);
00534       int index = -1;
00535 
00536       if (length < ACE_OS::strlen (POLICY_NAMES[HOP_COUNT]))
00537         ACE_THROW (CosTrading::Lookup::IllegalPolicyName (pol_name));
00538 
00539       switch (pol_name[0])
00540         {
00541         case 'e':
00542           index = EXACT_TYPE_MATCH;
00543           break;
00544         case 'h':
00545           index = HOP_COUNT;
00546           break;
00547         case 'l':
00548           index = LINK_FOLLOW_RULE;
00549           break;
00550         case 'm':
00551           index = MATCH_CARD;
00552           break;
00553         case 'r':
00554           if (pol_name[2] == 't')
00555             index = RETURN_CARD;
00556           else if (pol_name[2] == 'q')
00557             index = REQUEST_ID;
00558           break;
00559         case 's':
00560           if (pol_name[1] == 't')
00561             index = STARTING_TRADER;
00562           else if (pol_name[1] == 'e')
00563             index = SEARCH_CARD;
00564           break;
00565         case 'u':
00566           if (pol_name[4] == 'd')
00567             index = USE_DYNAMIC_PROPERTIES;
00568           if (pol_name[4] == 'm')
00569             index = USE_MODIFIABLE_PROPERTIES;
00570           if (pol_name[4] == 'p')
00571             index = USE_PROXY_OFFERS;
00572         }
00573 
00574       // Match the name of the policy, and insert its value into the
00575       // vector.
00576       if (index == -1 || ACE_OS::strcmp (POLICY_NAMES[index], pol_name) != 0)
00577         ACE_THROW (CosTrading::Lookup::IllegalPolicyName (pol_name));
00578       else if (this->policies_[index] != 0)
00579         ACE_THROW (CosTrading::DuplicatePolicyName (pol_name));
00580       else
00581         this->policies_[index] = (CosTrading::Policy *) &(policies[j]);
00582     }
00583 }
00584 
00585 TAO_Policies::~TAO_Policies (void)
00586 {
00587 }
00588 
00589 CORBA::ULong
00590 TAO_Policies::ulong_prop (POLICY_TYPE pol
00591                           ACE_ENV_ARG_DECL) const
00592   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00593 {
00594   CORBA::ULong return_value = 0, max_value = 0;
00595   const TAO_Import_Attributes_i& import_attrs =
00596     this->trader_.import_attributes ();
00597 
00598   // Discover the default values for each of the possible cardinality
00599   // policies.
00600   switch (pol)
00601     {
00602     case SEARCH_CARD:
00603       return_value = import_attrs.def_search_card ();
00604       max_value = import_attrs.max_search_card ();
00605       break;
00606     case MATCH_CARD:
00607       return_value = import_attrs.def_match_card ();
00608       max_value = import_attrs.max_match_card ();
00609       break;
00610     case RETURN_CARD:
00611       return_value = import_attrs.def_return_card ();
00612       max_value = import_attrs.max_return_card ();
00613       break;
00614     case HOP_COUNT:
00615       return_value = import_attrs.def_hop_count ();
00616       max_value = import_attrs.max_hop_count ();
00617       break;
00618     default:
00619       break;
00620     }
00621 
00622   if (this->policies_[pol] != 0)
00623     {
00624       // Extract the desired policy value.
00625       const CosTrading::Policy* policy = this->policies_[pol];
00626       const CosTrading::PolicyValue& value = policy->value;
00627       CORBA::TypeCode_var type = value.type ();
00628 
00629       CORBA::Boolean equal_ulong = type->equal (CORBA::_tc_ulong ACE_ENV_ARG_PARAMETER);
00630       ACE_CHECK_RETURN (return_value);
00631 
00632       if (!equal_ulong)
00633         ACE_THROW_RETURN (CosTrading::Lookup::PolicyTypeMismatch (*policy),
00634                           return_value);
00635       else
00636         value >>= return_value;
00637 
00638       if (max_value < return_value)
00639         return_value = max_value;
00640     }
00641 
00642   return return_value;
00643 }
00644 
00645 CORBA::ULong
00646 TAO_Policies::search_card (ACE_ENV_SINGLE_ARG_DECL) const
00647   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00648 {
00649   return this->ulong_prop (SEARCH_CARD ACE_ENV_ARG_PARAMETER);
00650 }
00651 
00652 CORBA::ULong
00653 TAO_Policies::match_card (ACE_ENV_SINGLE_ARG_DECL) const
00654   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00655 {
00656   return this->ulong_prop (MATCH_CARD ACE_ENV_ARG_PARAMETER);
00657 }
00658 
00659 CORBA::ULong
00660 TAO_Policies::return_card (ACE_ENV_SINGLE_ARG_DECL) const
00661   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00662 {
00663   return this->ulong_prop (RETURN_CARD ACE_ENV_ARG_PARAMETER);
00664 }
00665 
00666 CORBA::Boolean
00667 TAO_Policies::boolean_prop (POLICY_TYPE pol
00668                             ACE_ENV_ARG_DECL) const
00669   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00670 {
00671   CORBA::Boolean def_value = 1,
00672     return_value = 1;
00673   const TAO_Support_Attributes_i& support_attrs =
00674     this->trader_.support_attributes ();
00675 
00676   switch (pol)
00677     {
00678     case USE_MODIFIABLE_PROPERTIES:
00679       def_value = support_attrs.supports_modifiable_properties ();
00680       break;
00681     case USE_DYNAMIC_PROPERTIES:
00682       def_value = support_attrs.supports_dynamic_properties ();
00683       break;
00684     case USE_PROXY_OFFERS:
00685       def_value = support_attrs.supports_proxy_offers ();
00686       break;
00687     case EXACT_TYPE_MATCH:
00688       def_value = 0;
00689       break;
00690     default:
00691       break;
00692     }
00693 
00694   if (this->policies_[pol] != 0)
00695     {
00696       const CosTrading::Policy* policy = this->policies_[pol];
00697       const CosTrading::PolicyValue& value = policy->value;
00698       CORBA::TypeCode_var type = value.type ();
00699 
00700       CORBA::Boolean equal_boolean =
00701         type->equal (CORBA::_tc_boolean ACE_ENV_ARG_PARAMETER);
00702       ACE_CHECK_RETURN (return_value);
00703 
00704       if (!equal_boolean)
00705         ACE_THROW_RETURN (CosTrading::Lookup::PolicyTypeMismatch (*policy),
00706                           return_value);
00707       else
00708         value >>= CORBA::Any::to_boolean (return_value);
00709 
00710       if (def_value == 0 &&
00711           pol != EXACT_TYPE_MATCH)
00712         return_value = 0;
00713     }
00714   else
00715     return_value = def_value;
00716 
00717   return return_value;
00718 }
00719 
00720 
00721 CORBA::Boolean
00722 TAO_Policies::use_modifiable_properties (ACE_ENV_SINGLE_ARG_DECL) const
00723   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00724 {
00725   return this->boolean_prop (USE_MODIFIABLE_PROPERTIES ACE_ENV_ARG_PARAMETER);
00726 }
00727 
00728 CORBA::Boolean
00729 TAO_Policies::use_dynamic_properties (ACE_ENV_SINGLE_ARG_DECL) const
00730   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00731 {
00732   return this->boolean_prop (USE_DYNAMIC_PROPERTIES ACE_ENV_ARG_PARAMETER);
00733 }
00734 
00735 CORBA::Boolean
00736 TAO_Policies::use_proxy_offers (ACE_ENV_SINGLE_ARG_DECL) const
00737   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00738 {
00739   return this->boolean_prop (USE_PROXY_OFFERS ACE_ENV_ARG_PARAMETER);
00740 }
00741 
00742 CORBA::Boolean
00743 TAO_Policies::exact_type_match (ACE_ENV_SINGLE_ARG_DECL) const
00744     ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00745 {
00746   return this->boolean_prop (EXACT_TYPE_MATCH ACE_ENV_ARG_PARAMETER);
00747 }
00748 
00749 
00750 CosTrading::TraderName*
00751 TAO_Policies::starting_trader (ACE_ENV_SINGLE_ARG_DECL) const
00752   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch,
00753                    CosTrading::Lookup::InvalidPolicyValue))
00754 {
00755   CosTrading::TraderName* trader_name = 0;
00756 
00757   if (this->policies_[STARTING_TRADER] != 0)
00758     {
00759       CosTrading::Policy* policy = this->policies_[STARTING_TRADER];
00760       CosTrading::PolicyValue& value = policy->value;
00761       CORBA::TypeCode_var type = value.type ();
00762 
00763       CORBA::Boolean equal_tradername =
00764         type->equal (CosTrading::_tc_TraderName ACE_ENV_ARG_PARAMETER);
00765       ACE_CHECK_RETURN (trader_name);
00766 
00767       CORBA::Boolean equal_linknameseq =
00768         type->equal (CosTrading::_tc_LinkNameSeq ACE_ENV_ARG_PARAMETER);
00769       ACE_CHECK_RETURN (trader_name);
00770 
00771       if (!equal_tradername ||
00772           !equal_linknameseq)
00773         ACE_THROW_RETURN (CosTrading::Lookup::PolicyTypeMismatch (*policy),
00774                           trader_name);
00775       else
00776         value >>= trader_name;
00777     }
00778 
00779   return trader_name;
00780 }
00781 
00782 CosTrading::FollowOption
00783 TAO_Policies::link_follow_rule (ACE_ENV_SINGLE_ARG_DECL) const
00784     ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00785 {
00786   CosTrading::FollowOption return_value =
00787     this->trader_.import_attributes ().def_follow_policy ();
00788 
00789   if (this->policies_[LINK_FOLLOW_RULE] != 0)
00790     {
00791       CosTrading::FollowOption max_follow_policy =
00792         this->trader_.import_attributes ().max_follow_policy ();
00793 
00794       CosTrading::Policy* policy = this->policies_[LINK_FOLLOW_RULE];
00795       CosTrading::PolicyValue& value = policy->value;
00796       CORBA::TypeCode_var type = value.type ();
00797 
00798       // Extract the link follow rule
00799       CORBA::Boolean type_equal =
00800         type->equal (CosTrading::_tc_FollowOption ACE_ENV_ARG_PARAMETER);
00801       ACE_CHECK_RETURN (return_value);
00802 
00803       if (!type_equal)
00804         ACE_THROW_RETURN (CosTrading::Lookup::PolicyTypeMismatch (*policy),
00805                           return_value);
00806       else
00807         value >>= return_value;
00808 
00809       if (return_value > max_follow_policy)
00810         return_value = max_follow_policy;
00811     }
00812 
00813   return return_value;
00814 }
00815 
00816 CosTrading::FollowOption
00817 TAO_Policies::link_follow_rule (const CosTrading::Link::LinkInfo& link_info
00818                                 ACE_ENV_ARG_DECL) const
00819   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch,
00820                    CosTrading::Lookup::InvalidPolicyValue,
00821                    CosTrading::Link::IllegalLinkName,
00822                    CosTrading::Link::UnknownLinkName))
00823 {
00824   CosTrading::FollowOption return_value = CosTrading::local_only;
00825   CosTrading::FollowOption trader_max_follow_policy =
00826     this->trader_.import_attributes ().max_follow_policy ();
00827   CosTrading::FollowOption link_limiting_follow_rule =
00828     link_info.limiting_follow_rule;
00829 
00830   // If not defined defaults to trader.def_link_follow_rule
00831   CosTrading::FollowOption query_link_follow_rule =
00832     this->link_follow_rule (ACE_ENV_SINGLE_ARG_PARAMETER);
00833   ACE_CHECK_RETURN (return_value);
00834 
00835   return_value = (query_link_follow_rule < trader_max_follow_policy)
00836     ? query_link_follow_rule : trader_max_follow_policy;
00837   return_value = (return_value < link_limiting_follow_rule)
00838     ? return_value : link_limiting_follow_rule;
00839 
00840   return return_value;
00841 }
00842 
00843 CORBA::ULong
00844 TAO_Policies::hop_count (ACE_ENV_SINGLE_ARG_DECL) const
00845   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00846 {
00847   return this->ulong_prop (HOP_COUNT ACE_ENV_ARG_PARAMETER);
00848 }
00849 
00850 CosTrading::Admin::OctetSeq*
00851 TAO_Policies::request_id (ACE_ENV_SINGLE_ARG_DECL) const
00852   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch))
00853 {
00854   CosTrading::Admin::OctetSeq* request_id = 0;
00855 
00856   if (this->policies_[REQUEST_ID] != 0)
00857     {
00858       CosTrading::Policy* policy = this->policies_[REQUEST_ID];
00859       CosTrading::PolicyValue& value = policy->value;
00860       CORBA::TypeCode_var type = value.type ();
00861 
00862       CORBA::Boolean equal_octetseq =
00863         type->equal (CosTrading::Admin::_tc_OctetSeq ACE_ENV_ARG_PARAMETER);
00864       ACE_CHECK_RETURN (request_id);
00865 
00866       if (!equal_octetseq)
00867         ACE_THROW_RETURN (CosTrading::Lookup::PolicyTypeMismatch (*policy),
00868                           request_id);
00869       else
00870         value >>= request_id;
00871     }
00872 
00873   return request_id;
00874 }
00875 
00876 void
00877 TAO_Policies::
00878 copy_in_follow_option (CosTrading::PolicySeq& policy_seq,
00879                        const CosTrading::Link::LinkInfo& link_info
00880                        ACE_ENV_ARG_DECL) const
00881   ACE_THROW_SPEC ((CosTrading::Lookup::PolicyTypeMismatch,
00882                    CosTrading::Lookup::InvalidPolicyValue))
00883 {
00884   CosTrading::FollowOption follow_option = CosTrading::local_only;
00885   CosTrading::FollowOption trader_max_follow_policy =
00886     this->trader_.import_attributes ().max_follow_policy ();
00887 
00888   if (this->policies_[LINK_FOLLOW_RULE] != 0)
00889     {
00890       CosTrading::FollowOption query_link_follow_rule =
00891         this->link_follow_rule (ACE_ENV_SINGLE_ARG_PARAMETER);
00892       ACE_CHECK;
00893 
00894       follow_option = (CosTrading::FollowOption)
00895         (link_info.limiting_follow_rule < trader_max_follow_policy
00896          ? (link_info.limiting_follow_rule < query_link_follow_rule
00897             ? link_info.limiting_follow_rule
00898             : query_link_follow_rule)
00899          : (trader_max_follow_policy < query_link_follow_rule
00900             ? trader_max_follow_policy
00901             : query_link_follow_rule));
00902     }
00903   else
00904     follow_option = (CosTrading::FollowOption)
00905       (link_info.def_pass_on_follow_rule < trader_max_follow_policy
00906        ? link_info.def_pass_on_follow_rule
00907        : trader_max_follow_policy);
00908 
00909   CORBA::ULong i = 0;
00910   for (i = 0; i < policy_seq.length (); i++)
00911     if (ACE_OS::strcmp (policy_seq[i].name,
00912                         POLICY_NAMES[LINK_FOLLOW_RULE]) == 0)
00913       {
00914         policy_seq[i].value <<= follow_option;
00915         break;
00916       }
00917 
00918   if (i == policy_seq.length ())
00919     {
00920       policy_seq.length (i + 1);
00921       policy_seq[i].name = POLICY_NAMES[LINK_FOLLOW_RULE];
00922       policy_seq[i].value <<= follow_option;
00923     }
00924 }
00925 
00926 void
00927 TAO_Policies::
00928 copy_to_pass (CosTrading::PolicySeq& policy_seq,
00929               const CosTrading::Admin::OctetSeq& request_id
00930               ACE_ENV_ARG_DECL) const
00931 {
00932   CORBA::ULong counter = 0;
00933   CosTrading::Policy* policy_buffer =
00934     CosTrading::PolicySeq::allocbuf (REQUEST_ID + 1);
00935 
00936   if (policy_buffer == 0)
00937     return;
00938 
00939   for (int i = 0; i <= REQUEST_ID; i++)
00940     {
00941       CosTrading::Policy& new_policy = policy_buffer[counter];
00942 
00943        if (i == REQUEST_ID)
00944         {
00945           // Set the new request id.
00946           new_policy.name = POLICY_NAMES[REQUEST_ID];
00947           new_policy.value <<= request_id;
00948           counter++;
00949         }
00950        else if (this->policies_[i] != 0)
00951         {
00952           // Copy in the existing policies.
00953           new_policy.name = POLICY_NAMES[i];
00954           new_policy.value = this->policies_[i]->value;
00955           counter++;
00956         }
00957 
00958       // We always require a hop count.
00959       if (i == HOP_COUNT)
00960         {
00961           CORBA::ULong count = this->hop_count (ACE_ENV_SINGLE_ARG_PARAMETER);
00962           ACE_CHECK;
00963 
00964           new_policy.name = POLICY_NAMES[HOP_COUNT];
00965           new_policy.value <<= count - 1;
00966 
00967           // Don't count hop count twice.
00968           if (this->policies_[i] == 0)
00969             counter++;
00970         }
00971     }
00972 
00973   policy_seq.replace (REQUEST_ID + 1,
00974                       counter,
00975                       policy_buffer,
00976                       1);
00977 }
00978 
00979 void
00980 TAO_Policies::copy_to_forward (CosTrading::PolicySeq& policy_seq,
00981                                const CosTrading::TraderName& trader_name) const
00982 {
00983   // Create a new policy sequence, shortening the starting trader
00984   // policy by one link.
00985 
00986   CORBA::ULong counter = 0;
00987   CosTrading::Policy* policy_buffer =
00988     CosTrading::PolicySeq::allocbuf (REQUEST_ID + 1);
00989 
00990   if (policy_buffer == 0)
00991     return;
00992 
00993   for (int i = 0; i <= REQUEST_ID; i++)
00994     {
00995       CosTrading::Policy& new_policy = policy_buffer[counter];
00996 
00997       if (this->policies_[i] != 0)
00998         {
00999           // Copy in the existing policies.
01000           if (i == STARTING_TRADER && trader_name.length () > 1)
01001             {
01002               // Eliminate the first link of the trader name.
01003               // Only pass on the property if the sequence
01004               // contains more links after us.
01005 
01006               // The any will sieze control of this memory.
01007               // Allocating here avoids copying in the policy
01008               // any.
01009               CORBA::ULong length = trader_name.length ();
01010               CosTrading::LinkName* buf =
01011                 CosTrading::TraderName::allocbuf (length - 1);
01012 
01013               if (buf != 0)
01014                 {
01015                   for (CORBA::ULong j = 1; j < length; j++)
01016                     buf[j - 1] = CORBA::string_dup (trader_name[j]);
01017 
01018                   new_policy.name = this->policies_[i]->name;
01019                   CosTrading::TraderName new_name (length - 1,
01020                                                    length - 1,
01021                                                    buf,
01022                                                    1);
01023 
01024                   new_policy.value <<= new_name;
01025                   counter++;
01026                 }
01027             }
01028           else if (i != STARTING_TRADER)
01029             {
01030               new_policy.name = this->policies_[i]->name;
01031               new_policy.value = this->policies_[i]->value;
01032               counter++;
01033             }
01034         }
01035     }
01036 
01037   // Create the new sequence
01038   policy_seq.replace (REQUEST_ID + 1,
01039                       counter,
01040                       policy_buffer, 1);
01041 }
01042 
01043 TAO_Offer_Modifier::
01044 TAO_Offer_Modifier (const char* type_name,
01045                     const CosTradingRepos::ServiceTypeRepository::TypeStruct& type_struct,
01046                     CosTrading::Offer* offer)
01047   : type_ (type_name),
01048     offer_ (offer)
01049 {
01050   const CosTradingRepos::ServiceTypeRepository::PropStructSeq&
01051     pstructs = type_struct.props;
01052   CosTrading::PropertySeq& prop_seq = this->offer_->properties;
01053   CORBA::ULong pstructs_length = pstructs.length (),
01054     props_length = prop_seq.length (),
01055     i = 0;
01056 
01057   // Create a mapping of property names to their types.
01058   for (i = 0; i < pstructs_length; i++)
01059     {
01060       CORBA::String_var prop_name = pstructs[i].name.in ();
01061       CORBA::TypeCode_ptr type_code =
01062         CORBA::TypeCode::_duplicate (pstructs[i].value_type.in ());
01063       this->prop_types_.bind (prop_name, type_code);
01064     }
01065 
01066   // Separate the type defined properties into mandatory and readonly
01067   for (i = 0; i < pstructs_length; i++)
01068     {
01069       const char* pname = pstructs[i].name;
01070 
01071       if (pstructs[i].mode ==
01072           CosTradingRepos::ServiceTypeRepository::PROP_MANDATORY)
01073         {
01074           CORBA::String_var prop_name (pname);
01075           this->mandatory_.insert (prop_name);
01076         }
01077       else if (pstructs[i].mode ==
01078                CosTradingRepos::ServiceTypeRepository::PROP_READONLY)
01079         {
01080           CORBA::String_var prop_name (pname);
01081           this->readonly_.insert (prop_name);
01082         }
01083     }
01084 
01085   // Insert the indices of the offer properties into a map.
01086   for (i = 0; i < props_length; i++)
01087     {
01088       CORBA::String_var prop_name =
01089         static_cast<const char*> (prop_seq[i].name);
01090       this->props_.bind (prop_name, &prop_seq[i]);
01091     }
01092 }
01093 
01094 TAO_Offer_Modifier::~TAO_Offer_Modifier (void)
01095 {
01096   for (TAO_Typecode_Table::iterator type_iter (this->prop_types_);
01097        ! type_iter.done ();
01098        type_iter++)
01099     {
01100       CORBA::TypeCode_ptr corba_type = (*type_iter).int_id_;
01101       CORBA::release (corba_type);
01102     }
01103 }
01104 
01105 void
01106 TAO_Offer_Modifier::
01107 delete_properties (const CosTrading::PropertyNameSeq& deletes
01108                    ACE_ENV_ARG_DECL)
01109   ACE_THROW_SPEC ((CosTrading::Register::UnknownPropertyName,
01110                   CosTrading::Register::MandatoryProperty,
01111                   CosTrading::IllegalPropertyName,
01112                   CosTrading::DuplicatePropertyName))
01113 {
01114   // Validate that the listed property names can be deleted
01115   CORBA::ULong i = 0,
01116     length = deletes.length ();
01117   TAO_String_Set delete_me;
01118 
01119   for (i = 0; i < length; i++)
01120     {
01121       const char* dname = static_cast<const char*> (deletes[i]);
01122       if (! TAO_Trader_Base::is_valid_property_name (dname))
01123         ACE_THROW (CosTrading::IllegalPropertyName (dname));
01124       else
01125         {
01126           CORBA::String_var prop_name (dname);
01127           if (this->mandatory_.find (prop_name) == 0)
01128             ACE_THROW (CosTrading::Register::MandatoryProperty (this->type_, dname));
01129           else if (delete_me.insert (prop_name) == 1)
01130             ACE_THROW (CosTrading::DuplicatePropertyName (dname));
01131           else if (this->props_.find (prop_name) == -1)
01132             ACE_THROW (CosTrading::Register::UnknownPropertyName (dname));
01133         }
01134     }
01135 
01136   // Delete those properties from the offer.
01137   for (i = 0; i < length; i++)
01138     {
01139       CORBA::String_var prop_name =
01140         static_cast<const char *> (deletes[i]);
01141       this->props_.unbind (prop_name);
01142     }
01143 }
01144 
01145 void
01146 TAO_Offer_Modifier::
01147 merge_properties (const CosTrading::PropertySeq& modifies
01148                   ACE_ENV_ARG_DECL)
01149   ACE_THROW_SPEC ((CosTrading::IllegalPropertyName,
01150                    CosTrading::DuplicatePropertyName,
01151                    CosTrading::PropertyTypeMismatch,
01152                    CosTrading::ReadonlyDynamicProperty,
01153                    CosTrading::Register::ReadonlyProperty))
01154 {
01155   int i = 0, length = 0;
01156   TAO_String_Set modify_me;
01157 
01158   // Ensure that the proposed changes aren't to readonly properties or
01159   // otherwise invalid.
01160   TAO_Property_Evaluator prop_eval (modifies);
01161   for (i = 0, length = modifies.length (); i < length; i++)
01162     {
01163       const char* mname = modifies[i].name;
01164       if (TAO_Trader_Base::is_valid_property_name (mname))
01165         {
01166           CORBA::String_var prop_name (mname);
01167           if (this->readonly_.find (prop_name) == 0)
01168             {
01169               // Can't assign a dynamic property to a property with
01170               // readonly mode, and can't reassign a readonly property.
01171               if (prop_eval.is_dynamic_property (i))
01172                 ACE_THROW (CosTrading::ReadonlyDynamicProperty (this->type_, mname));
01173               else if (this->props_.find (prop_name) == 0)
01174                 ACE_THROW (CosTrading::Register::ReadonlyProperty (this->type_, mname));
01175             }
01176 
01177           // Validate the property type if the property is defined in
01178           // the service type description.
01179           CORBA::TypeCode_ptr type_def = 0;
01180           if (this->prop_types_.find (prop_name, type_def) == 0)
01181             {
01182               CORBA::TypeCode_var prop_type = prop_eval.property_type (i);
01183 
01184               // @@ Frank: This code used to have this comment and line
01185               //    of code before I fixed the "ACE_TRY" fuzz warning here.
01186               // @@ Seth, are we trying to ignore the exception here?
01187               // CORBA::Environment ACE_TRY_ENV;
01188               // @@ Frank: It seems clear that this is not going to work as
01189               // expected.  Is the purpose to ignore any exceptions from
01190               // equal ()?  For now, exceptions are returned since this
01191               // seemed "safest".
01192 
01193               CORBA::Boolean td_equal =
01194                 type_def->equal (prop_type.in () ACE_ENV_ARG_PARAMETER);
01195               ACE_CHECK;
01196 
01197               if (!td_equal)
01198                 ACE_THROW (CosTrading::PropertyTypeMismatch (mname, modifies[i]));
01199             }
01200 
01201           if (modify_me.insert (prop_name) == 1)
01202             ACE_THROW (CosTrading::DuplicatePropertyName (mname));
01203         }
01204       else
01205         ACE_THROW (CosTrading::IllegalPropertyName (mname));
01206     }
01207 }
01208 
01209 void
01210 TAO_Offer_Modifier::affect_change (const CosTrading::PropertySeq& modifies)
01211 {
01212   // Create a new property list reflecting the deletes, modifies, and
01213   // add operations performed, and place this property list in the
01214   // offer.
01215 
01216   // Merge these properties with the original set.
01217   CORBA::ULong i = 0,
01218     merge_length = modifies.length ();
01219 
01220   for (i = 0; i < merge_length; i++)
01221     {
01222       Property_Table::ENTRY* entry = 0;
01223       CORBA::String_var prop_name = modifies[i].name.in ();
01224 
01225       CosTrading::Property* prop =
01226         const_cast<CosTrading::Property*> (&modifies[i]);
01227       if (this->props_.bind (prop_name, prop, entry) == 1)
01228         // We need to rebind here.
01229         entry->int_id_ = prop;
01230     }
01231 
01232   CORBA::ULong num_modified = 0,
01233     original_length = this->offer_->properties.length (),
01234     total_length = static_cast<CORBA::ULong> (this->props_.current_size ());
01235 
01236   // Scrap the existing property sequence and begin a new one
01237   CosTrading::PropertySeq prop_seq (total_length);
01238   //  this->offer_->properties.length (total_length);
01239 
01240   // Copy in the unaffected and modified props into the offer,
01241   // excluding those that were deleted. Let's try and retain their
01242   // relative ordering.
01243   for (i = 0; i < original_length; i++)
01244     {
01245       CosTrading::Property* prop_value = 0;
01246       const char* name = this->offer_->properties[i].name;
01247       CORBA::String_var prop_name (name);
01248       if (this->props_.unbind (prop_name, prop_value) == 0)
01249         prop_seq[num_modified++] = *prop_value;
01250     }
01251 
01252   for (i = 0; i < merge_length; i++)
01253     {
01254       CosTrading::Property* prop_value = 0;
01255       const char* name = modifies[i].name;
01256       CORBA::String_var prop_name (name);
01257       if (this->props_.unbind (prop_name, prop_value) == 0)
01258         prop_seq[num_modified++] = *prop_value;
01259     }
01260 
01261   this->offer_->properties.length (total_length);
01262   for (i = 0; i < total_length; i++)
01263     this->offer_->properties[i] = prop_seq[i];
01264   // Free the old, orphaned sequence.
01265   //  CosTrading::PropertySeq::freebuf (prop_buf);
01266 }
01267 
01268 TAO_Offer_Filter::TAO_Offer_Filter (TAO_Policies& policies
01269                                     ACE_ENV_ARG_DECL)
01270 {
01271   search_card_ = policies.search_card (ACE_ENV_SINGLE_ARG_PARAMETER);
01272   ACE_CHECK;
01273 
01274   match_card_ = policies.match_card (ACE_ENV_SINGLE_ARG_PARAMETER);
01275   ACE_CHECK;
01276 
01277   return_card_ = policies.return_card (ACE_ENV_SINGLE_ARG_PARAMETER);
01278   ACE_CHECK;
01279 
01280   dp_ = policies.use_dynamic_properties (ACE_ENV_SINGLE_ARG_PARAMETER);
01281   ACE_CHECK;
01282 
01283   mod_ = policies.use_modifiable_properties (ACE_ENV_SINGLE_ARG_PARAMETER);
01284   ACE_CHECK;
01285 
01286   CORBA::Boolean exact_type_match =
01287     policies.exact_type_match (ACE_ENV_SINGLE_ARG_PARAMETER);
01288   ACE_CHECK;
01289 
01290   if (exact_type_match == 1)
01291     {
01292       CORBA::String_var exact_match
01293         (TAO_Policies::POLICY_NAMES[TAO_Policies::EXACT_TYPE_MATCH]);
01294       this->limits_.insert (exact_match);
01295     }
01296 }
01297 
01298 void
01299 TAO_Offer_Filter::
01300 configure_type (CosTradingRepos::ServiceTypeRepository::TypeStruct* type_struct)
01301 {
01302   CosTradingRepos::ServiceTypeRepository::PropStructSeq&
01303     prop_seq = type_struct->props;
01304 
01305   // Take note of non-modifiable properties in the type_struct
01306   this->not_mod_props_.reset ();
01307   for (int i = prop_seq.length () - 1; i >= 0; i--)
01308     {
01309       CosTradingRepos::ServiceTypeRepository::PropertyMode mode = prop_seq[i].mode;
01310       if (mode == CosTradingRepos::ServiceTypeRepository::PROP_MANDATORY_READONLY ||
01311           mode == CosTradingRepos::ServiceTypeRepository::PROP_READONLY)
01312         {
01313           CORBA::String_var prop_name ((const char*) prop_seq[i].name);
01314           this->not_mod_props_.insert (prop_name);
01315         }
01316     }
01317 }
01318 
01319 CORBA::Boolean
01320 TAO_Offer_Filter::ok_to_consider (CosTrading::Offer* offer)
01321 {
01322   CORBA::String_var use_mods =
01323     TAO_Policies::POLICY_NAMES[TAO_Policies::USE_MODIFIABLE_PROPERTIES];
01324   CORBA::String_var use_dyns =
01325     TAO_Policies::POLICY_NAMES[TAO_Policies::USE_DYNAMIC_PROPERTIES];
01326   CORBA::Boolean return_value = 1;
01327   TAO_Property_Evaluator prop_eval (*offer);
01328 
01329   // If we should screen offers, determine if this offer is unworthy
01330   // for consideration.
01331   if (! (this->mod_ && this->dp_))
01332     {
01333       for (int i = offer->properties.length () - 1;
01334            i >= 0 && return_value;
01335            i--)
01336         {
01337           // Winnow away the unwanted offers with modifiable or
01338           // dynamic properties.
01339           if (! this->mod_)
01340             {
01341               // Determine if this property name is found in the set
01342               // of modifiable properties for the type being considered.
01343               CORBA::String_var prop_name ((const char*) offer->properties[i].name);
01344               if (this->not_mod_props_.find (prop_name) == -1)
01345                 {
01346                   this->limits_.insert (use_mods);
01347                   return_value = 0;
01348                 }
01349             }
01350 
01351           if (! this->dp_ && return_value)
01352             {
01353               // Determine if this property is dynamic.
01354               if (prop_eval.is_dynamic_property (i))
01355                 {
01356                   this->limits_.insert (use_dyns);
01357                   return_value = 0;
01358                 }
01359             }
01360 
01361           if (return_value == 0)
01362             break;
01363         }
01364     }
01365 
01366   // If we're good to go, consider this offer considered and decrement
01367   // the search cardinality counter.
01368   if (return_value)
01369     {
01370       this->search_card_--;
01371       if (this->search_card_ == 0)
01372         {
01373           CORBA::String_var search_card =
01374             TAO_Policies::POLICY_NAMES[TAO_Policies::SEARCH_CARD];
01375           this->limits_.insert (search_card);
01376         }
01377     }
01378 
01379   return return_value;
01380 }
01381 
01382 CORBA::Boolean
01383 TAO_Offer_Filter::ok_to_consider_more (void)
01384 {
01385   return this->search_card_ > 0 && this->match_card_ > 0;
01386 }
01387 
01388 void
01389 TAO_Offer_Filter::matched_offer (void)
01390 {
01391   this->match_card_--;
01392   this->return_card_--;
01393 
01394   if (this->match_card_ == 0)
01395     {
01396       CORBA::String_var match_card =
01397         TAO_Policies::POLICY_NAMES[TAO_Policies::MATCH_CARD];
01398       this->limits_.insert (match_card);
01399     }
01400 
01401   if (this->return_card_ == 0)
01402     {
01403       CORBA::String_var return_card =
01404         TAO_Policies::POLICY_NAMES[TAO_Policies::MATCH_CARD];
01405       this->limits_.insert (return_card);
01406     }
01407 }
01408 
01409 CORBA::ULong
01410 TAO_Offer_Filter::search_card_remaining (void) const
01411 {
01412   return this->search_card_;
01413 }
01414 
01415 CORBA::ULong
01416 TAO_Offer_Filter::match_card_remaining (void) const
01417 {
01418   return this->match_card_;
01419 }
01420 
01421 CosTrading::PolicyNameSeq*
01422 TAO_Offer_Filter::limits_applied (void)
01423 {
01424   int i = 0;
01425   CORBA::ULong size = static_cast<CORBA::ULong> (this->limits_.size ());
01426   CosTrading::PolicyName* temp =
01427     CosTrading::PolicyNameSeq::allocbuf (size);
01428 
01429   for (TAO_String_Set::iterator p_iter (this->limits_.begin());
01430        ! p_iter.done ();
01431        p_iter.advance ())
01432     {
01433       CORBA::String_var* policy_name_ptr = 0;
01434       p_iter.next (policy_name_ptr);
01435       temp[i++] = CORBA::string_dup (policy_name_ptr->in ());
01436     }
01437 
01438   return new CosTrading::PolicyNameSeq (size, size, temp, 1);
01439 }
01440 
01441 TAO_Property_Filter::
01442 TAO_Property_Filter (const SPECIFIED_PROPS& desired_props
01443                      ACE_ENV_ARG_DECL)
01444   ACE_THROW_SPEC ((CosTrading::IllegalPropertyName,
01445                    CosTrading::DuplicatePropertyName))
01446   : policy_  (desired_props._d ())
01447 {
01448   if (this->policy_ == CosTrading::Lookup::some)
01449     {
01450       const CosTrading::PropertyNameSeq&
01451         prop_seq = desired_props.prop_names ();
01452       int length = prop_seq.length ();
01453 
01454       for (int i = 0; i < length; i++)
01455         {
01456           const char* pname = prop_seq[i];
01457 
01458           // Check for errors or duplicates
01459           if (TAO_Trader_Base::is_valid_property_name (pname))
01460             {
01461               CORBA::String_var prop_name (pname);
01462               if (this->props_.insert (prop_name) == 1)
01463                 ACE_THROW (CosTrading::DuplicatePropertyName (pname));
01464             }
01465           else
01466             ACE_THROW (CosTrading::IllegalPropertyName (pname));
01467         }
01468     }
01469 }
01470 
01471 TAO_Property_Filter::
01472 TAO_Property_Filter (const TAO_Property_Filter& prop_filter)
01473   : props_ (prop_filter.props_),
01474     policy_ (prop_filter.policy_)
01475 {
01476 }
01477 
01478 TAO_Property_Filter&
01479 TAO_Property_Filter::operator= (const TAO_Property_Filter& other)
01480 {
01481   this->props_ = other.props_;
01482   this->policy_ = other.policy_;
01483 
01484   return *this;
01485 }
01486 
01487 void
01488 TAO_Property_Filter::filter_offer (CosTrading::Offer* source,
01489                                    CosTrading::Offer& destination)
01490 {
01491   Prop_Queue prop_queue;
01492   CosTrading::PropertySeq& s_props = source->properties;
01493   CosTrading::PropertySeq& d_props = destination.properties;
01494   CORBA::ULong length = static_cast<CORBA::ULong> (s_props.length ()),
01495                elem = 0;
01496 
01497   destination.reference = CORBA::Object::_duplicate (source->reference.in ());
01498   if (this->policy_ == CosTrading::Lookup::some)
01499     {
01500       for (CORBA::ULong i = 0; i < length; i++)
01501         {
01502           if (this->policy_ == CosTrading::Lookup::all)
01503             prop_queue.enqueue_tail (&s_props[i]);
01504           else
01505             {
01506               const char* p_name = s_props[i].name;
01507               CORBA::String_var prop_name (p_name);
01508 
01509               // Save those property that match.
01510               if (this->props_.find (prop_name) == 0)
01511                 prop_queue.enqueue_tail (&s_props[i]);
01512             }
01513         }
01514 
01515       // Shove the matched properties into the destination property
01516       // sequence.
01517       length = static_cast<CORBA::ULong> (prop_queue.size ());
01518       d_props.length (length);
01519       for (Prop_Queue::ITERATOR prop_iter (prop_queue);
01520            ! prop_iter.done ();
01521            prop_iter.advance (), elem++)
01522         {
01523           CosTrading::Property** prop_ptr = 0;
01524 
01525           prop_iter.next (prop_ptr);
01526           d_props[elem] = **prop_ptr;
01527         }
01528     }
01529   else if (this->policy_ == CosTrading::Lookup::all)
01530     //      CosTrading::Property* props = s_props.get_buffer (0);
01531     //      d_props.replace (length, length, props, 0);
01532     d_props = s_props;
01533 }
01534 
01535 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:59:59 2006 for TAO_CosTrader by doxygen 1.3.6